Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: email profile table default #216

Merged
merged 7 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.0.3] - 2024-01-19

### Added
- Add `en-US` translation to `Google API page`.
- Add `en-US` translation to `Google API page` (https://github.com/emoss08/Trenova/pull/216).
- Add default profile field to `Email Profile` model (https://github.com/emoss08/Trenova/pull/216).

### Changed
- Change `inter` font to `geist` font.
- Change Admin Page Sidebar icons to Font Awesome DuoTone icons.
- Change `inter` font to `geist` font (https://github.com/emoss08/Trenova/pull/215).
- Change Admin Page Sidebar icons to Font Awesome DuoTone icons (https://github.com/emoss08/Trenova/pull/215).

### Fixed
- Fix typo on General Ledger Account sub table component.
- Fix typo on General Ledger Account sub table component. (https://github.com/emoss08/Trenova/pull/215)

## [0.0.2] - 2024-01-18

Expand Down
52 changes: 52 additions & 0 deletions client/public/locales/en/admin.emailprofile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"title": "Create New Email Profile",
"subTitle": "Please fill out the form below to create a new Email Profile.",
"formMessages": {
"postSuccess": "Email profile saved successfully.",
"postError": "There was an error saving the email profile.",
"updateSuccess": "Email profile updated successfully.",
"updateError": "There was an error updating the email profile."
},
"fields": {
"defaultProfile": {
"placeholder": "Default?",
"label": "Default?",
"description": "Whether this email profile should be the default profile."
},
"name": {
"placeholder": "Name",
"label": "Name",
"description": "The name of the email profile."
},
"email": {
"placeholder": "Email",
"label": "Email",
"description": "The email address that will be used for outgoing emails."
},
"protocol": {
"placeholder": "Protocol",
"label": "Protocol",
"description": "The protocol that will be used to send emails."
},
"host": {
"placeholder": "Host",
"label": "Host",
"description": "The host that will be used to send emails."
},
"port": {
"placeholder": "Port",
"label": "Port",
"description": "The port that will be used to send emails."
},
"username": {
"placeholder": "Username",
"label": "Username",
"description": "The username that will be used to send emails."
},
"password": {
"placeholder": "Password",
"label": "Password",
"description": "The password of the email address that will be used to send emails."
}
}
}
3 changes: 2 additions & 1 deletion client/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"buttons": {
"cancel": "Cancel",
"confirm": "Confirm",
"save": "Save"
"save": "Save",
"savingText": "Saving changes..."
}
}
2 changes: 1 addition & 1 deletion client/src/components/admin-page/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const links = [
group: "Data & Integrations",
},
{
href: "#",
href: "/admin/table-change-alerts/",
title: "Table Change Alerts",
icon: (
<FontAwesomeIcon
Expand Down
7 changes: 5 additions & 2 deletions client/src/components/common/fields/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ export function CheckboxInput<T extends FieldValues>({
}: CheckboxInputProps & UseControllerProps<T>) {
const { field, fieldState } = useController(props);

const { label, description, id } = props;
const { label, description, id, className } = props;

return (
<label htmlFor={id} className="items-top flex cursor-pointer space-x-2">
<label
htmlFor={id}
className={cn("items-top flex cursor-pointer space-x-2", className)}
>
<Checkbox
{...field}
onCheckedChange={(e) => {
Expand Down
84 changes: 55 additions & 29 deletions client/src/components/email-profile/email-profile-table-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

import { InputField } from "@/components/common/fields/input";
import { SelectInput } from "@/components/common/fields/select-input";
import { Button } from "@/components/ui/button";
import {
Dialog,
Expand All @@ -25,54 +26,74 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { useCustomMutation } from "@/hooks/useCustomMutation";
import { TableSheetProps } from "@/types/tables";
import React from "react";
import { Control, useForm } from "react-hook-form";
import { EmailProfileFormValues as FormValues } from "@/types/organization";
import { Form, FormControl, FormGroup } from "@/components/ui/form";
import { SelectInput } from "@/components/common/fields/select-input";
import { useCustomMutation } from "@/hooks/useCustomMutation";
import { emailProtocolChoices } from "@/lib/choices";
import { emailProfileSchema } from "@/lib/validations/OrganizationSchema";
import { EmailProfileFormValues as FormValues } from "@/types/organization";
import { TableSheetProps } from "@/types/tables";
import { yupResolver } from "@hookform/resolvers/yup";
import React from "react";
import { Control, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { CheckboxInput } from "../common/fields/checkbox";

export function EmailProfileForm({
control,
}: {
control: Control<FormValues>;
}) {
const { t } = useTranslation("admin.emailprofile");

return (
<Form>
<FormGroup className="lg:grid-cols-1">
<FormGroup className="lg:grid-cols-2">
<FormControl>
<CheckboxInput
name="defaultProfile"
control={control}
className="mt-4"
rules={{
required: true,
}}
label={t("fields.defaultProfile.label")}
description={t("fields.defaultProfile.description")}
/>
</FormControl>
<FormControl>
<InputField
name="name"
control={control}
label="Name"
rules={{
required: true,
}}
description="The name of the email profile."
label={t("fields.name.label")}
placeholder={t("fields.name.placeholder")}
description={t("fields.name.description")}
/>
</FormControl>
</FormGroup>
<FormGroup className="lg:grid-cols-1">
<FormControl>
<InputField
name="email"
control={control}
label="Email"
rules={{
required: true,
}}
description="The email address that will be used for outgoing emails."
label={t("fields.email.label")}
placeholder={t("fields.email.placeholder")}
description={t("fields.email.description")}
/>
</FormControl>
<FormControl>
<SelectInput
name="protocol"
options={emailProtocolChoices}
control={control}
label="Protocol"
description="The protocol that will be used to send emails."
label={t("fields.protocol.label")}
placeholder={t("fields.protocol.placeholder")}
description={t("fields.protocol.description")}
/>
</FormControl>
</FormGroup>
Expand All @@ -81,34 +102,38 @@ export function EmailProfileForm({
<InputField
name="host"
control={control}
label="Host"
description="The host that will be used to send emails."
label={t("fields.host.label")}
placeholder={t("fields.host.placeholder")}
description={t("fields.host.description")}
/>
</FormControl>
<FormControl>
<InputField
name="port"
control={control}
label="Port"
description="The port that will be used to send emails."
label={t("fields.port.label")}
placeholder={t("fields.port.placeholder")}
description={t("fields.port.description")}
/>
</FormControl>
<FormControl>
<InputField
name="username"
control={control}
label="Username"
description="The username that will be used to send emails."
label={t("fields.username.label")}
placeholder={t("fields.username.placeholder")}
description={t("fields.username.description")}
/>
</FormControl>
<FormControl>
<InputField
name="password"
control={control}
label="Password"
type="password"
autoComplete="new-password"
description="The password that will be used to send emails."
label={t("fields.password.label")}
placeholder={t("fields.password.placeholder")}
description={t("fields.password.description")}
/>
</FormControl>
</FormGroup>
Expand All @@ -117,6 +142,8 @@ export function EmailProfileForm({
}

export function EmailProfileDialog({ onOpenChange, open }: TableSheetProps) {
const { t } = useTranslation(["admin.emailprofile", "common"]);

const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false);
const { control, reset, handleSubmit } = useForm<FormValues>({
resolver: yupResolver(emailProfileSchema),
Expand All @@ -128,6 +155,7 @@ export function EmailProfileDialog({ onOpenChange, open }: TableSheetProps) {
port: undefined,
username: "",
password: "",
defaultProfile: false,
},
});

Expand All @@ -136,10 +164,10 @@ export function EmailProfileDialog({ onOpenChange, open }: TableSheetProps) {
{
method: "POST",
path: "/email_profiles/",
successMessage: "Email Profile created successfully.",
successMessage: t("formMessages.postSuccess"),
queryKeysToInvalidate: ["email-profile-table-data"],
closeModal: true,
errorMessage: "Failed to create new email profile.",
errorMessage: t("formMessages.postError"),
},
() => setIsSubmitting(false),
reset,
Expand All @@ -154,20 +182,18 @@ export function EmailProfileDialog({ onOpenChange, open }: TableSheetProps) {
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle>Create New Email Profile</DialogTitle>
<DialogTitle>{t("title")}</DialogTitle>
</DialogHeader>
<DialogDescription>
Please fill out the form below to create a new Email Profile.
</DialogDescription>
<DialogDescription>{t("subTitle")}</DialogDescription>
<form onSubmit={handleSubmit(onSubmit)}>
<EmailProfileForm control={control} />
<DialogFooter className="mt-6">
<Button
type="submit"
isLoading={isSubmitting}
loadingText="Saving Changes..."
loadingText={t("buttons.savingText", { ns: "common" })}
>
Save
{t("buttons.save", { ns: "common" })}
</Button>
</DialogFooter>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Grant, and not modifying the license in any other way.
*/

import { EmailProfileForm } from "@/components/email-profile/email-profile-table-dialog";
import { Button } from "@/components/ui/button";
import {
Dialog,
Expand All @@ -26,16 +27,15 @@ import {
} from "@/components/ui/dialog";
import { useCustomMutation } from "@/hooks/useCustomMutation";
import { formatDate } from "@/lib/date";
import { useTableStore } from "@/stores/TableStore";
import { yupResolver } from "@hookform/resolvers/yup";
import React from "react";
import { useForm } from "react-hook-form";
import { EmailProfileForm } from "@/components/email-profile/email-profile-table-dialog";
import { emailProfileSchema } from "@/lib/validations/OrganizationSchema";
import { useTableStore } from "@/stores/TableStore";
import {
EmailProfile,
EmailProfileFormValues as FormValues,
} from "@/types/organization";
import { yupResolver } from "@hookform/resolvers/yup";
import React from "react";
import { useForm } from "react-hook-form";

function EmailProfileEditForm({
emailProfile,
Expand All @@ -46,9 +46,20 @@ function EmailProfileEditForm({

const { control, reset, handleSubmit } = useForm<FormValues>({
resolver: yupResolver(emailProfileSchema),
defaultValues: emailProfile,
defaultValues: {
name: emailProfile.name,
email: emailProfile.email,
host: emailProfile.host,
port: emailProfile.port || undefined,
username: emailProfile.username,
password: emailProfile.password,
protocol: emailProfile.protocol,
defaultProfile: emailProfile.defaultProfile,
},
});

console.info("emailProfile", emailProfile);

const mutation = useCustomMutation<FormValues>(
control,
{
Expand Down
23 changes: 4 additions & 19 deletions client/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,9 @@ import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";

i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
ns: [
"common",
"homepage",
"admin.generalpage",
"admin.accountingcontrol",
"admin.billingcontrol",
"admin.invoicecontrol",
"admin.dispatchcontrol",
"admin.shipmentcontrol",
"admin.googleapi",
"pages.hazardousmaterial",
],
});
i18n.use(Backend).use(LanguageDetector).use(initReactI18next).init({
fallbackLng: "en",
debug: true,
});

export default i18n;
1 change: 1 addition & 0 deletions client/src/lib/validations/OrganizationSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const emailProfileSchema: ObjectSchema<EmailProfileFormValues> =
port: Yup.number().notRequired(),
username: Yup.string().notRequired(),
password: Yup.string().notRequired(),
defaultProfile: Yup.boolean().required("Default Profile is required."),
});

export const googleAPISchema: ObjectSchema<GoogleAPIFormValues> =
Expand Down
Loading
Loading