mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
refactor(frontend): use new useForm hook
This commit is contained in:
@@ -13,13 +13,12 @@ import { Button, Grid, Paper, Typography } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { useConfirmAccount, useLogin } from "@/hooks/entities/auth-hooks";
|
||||
import { useAuth } from "@/hooks/useAuth";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { useValidationRules } from "@/hooks/useValidationRules";
|
||||
import { ILoginAttributes } from "@/types/auth/login.types";
|
||||
|
||||
import { PublicContentWrapper } from "../../components/anonymous/PublicContentWrapper";
|
||||
@@ -64,18 +63,15 @@ export const Login = () => {
|
||||
handleSubmit,
|
||||
} = useForm<ILoginAttributes>({
|
||||
defaultValues: DEFAULT_VALUES,
|
||||
rules: {
|
||||
identifier: {
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
password: {
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const rules = useValidationRules();
|
||||
const validationRules = {
|
||||
email: {
|
||||
...rules.email,
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
password: {
|
||||
...rules.password,
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
};
|
||||
const onSubmitForm = (data: ILoginAttributes) => {
|
||||
login(data);
|
||||
};
|
||||
@@ -106,7 +102,7 @@ export const Login = () => {
|
||||
startAdornment: <Adornment Icon={EmailIcon} />,
|
||||
}}
|
||||
helperText={errors.identifier ? errors.identifier.message : null}
|
||||
{...register("identifier", validationRules.email)}
|
||||
{...register("identifier")}
|
||||
/>
|
||||
|
||||
<PasswordInput
|
||||
@@ -117,7 +113,7 @@ export const Login = () => {
|
||||
startAdornment: <Adornment Icon={KeyIcon} />,
|
||||
}}
|
||||
helperText={errors.password ? errors.password.message : null}
|
||||
{...register("password", validationRules.password)}
|
||||
{...register("password")}
|
||||
/>
|
||||
<Grid container gap={2} justifyContent="space-between">
|
||||
<Grid alignContent="center">
|
||||
|
||||
@@ -21,12 +21,11 @@ import {
|
||||
} from "@mui/material";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { useAcceptInvite } from "@/hooks/entities/auth-hooks";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { useValidationRules } from "@/hooks/useValidationRules";
|
||||
import { IRegisterAttributes } from "@/types/auth/register.types";
|
||||
import { JWT } from "@/utils/Jwt";
|
||||
|
||||
@@ -71,43 +70,38 @@ export const Register = () => {
|
||||
handleSubmit,
|
||||
} = useForm<TRegisterExtendedPayload>({
|
||||
defaultValues: DEFAULT_VALUES,
|
||||
rules: {
|
||||
first_name: {
|
||||
required: t("message.first_name_is_required"),
|
||||
},
|
||||
last_name: {
|
||||
required: t("message.last_name_is_required"),
|
||||
},
|
||||
username: {
|
||||
required: t("message.username_is_required"),
|
||||
},
|
||||
email: {
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
password: {
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
password2: {
|
||||
validate: (val) => {
|
||||
if (val !== watch("password")) {
|
||||
trigger("password");
|
||||
|
||||
return t("message.password_match");
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const [isTermsAccepted, setIsTermsAccepted] = useState<boolean>(false);
|
||||
const [readonlyEmail, setReadonlyEmail] = useState<boolean>(false);
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsTermsAccepted(event.target.checked);
|
||||
};
|
||||
const rules = useValidationRules();
|
||||
const validationRules = {
|
||||
first_name: {
|
||||
required: t("message.first_name_is_required"),
|
||||
},
|
||||
last_name: {
|
||||
required: t("message.last_name_is_required"),
|
||||
},
|
||||
username: {
|
||||
required: t("message.username_is_required"),
|
||||
},
|
||||
email: {
|
||||
...rules.email,
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
roles: {},
|
||||
token: {},
|
||||
password: {
|
||||
...rules.password,
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
password2: {
|
||||
validate: (val?: string) => {
|
||||
if (val !== watch("password")) {
|
||||
trigger("password");
|
||||
|
||||
return t("message.password_match");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const onSubmitForm = ({
|
||||
password2: _password2,
|
||||
...rest
|
||||
@@ -126,8 +120,6 @@ export const Register = () => {
|
||||
toast.error("Invalid Token");
|
||||
} else {
|
||||
setValue("token", String(queryToken));
|
||||
|
||||
// (decodedToken);
|
||||
setValue("email", decodedToken.email);
|
||||
if (decodedToken.roles.length) setValue("roles", decodedToken.roles);
|
||||
|
||||
@@ -157,7 +149,7 @@ export const Register = () => {
|
||||
error={!!errors.first_name}
|
||||
required
|
||||
autoFocus
|
||||
{...register("first_name", validationRules.first_name)}
|
||||
{...register("first_name")}
|
||||
InputProps={{
|
||||
startAdornment: <Adornment Icon={AbcIcon} />,
|
||||
}}
|
||||
@@ -171,7 +163,7 @@ export const Register = () => {
|
||||
label={t("placeholder.last_name")}
|
||||
error={!!errors.last_name}
|
||||
required
|
||||
{...register("last_name", validationRules.last_name)}
|
||||
{...register("last_name")}
|
||||
InputProps={{
|
||||
startAdornment: <Adornment Icon={AbcIcon} />,
|
||||
}}
|
||||
@@ -183,7 +175,7 @@ export const Register = () => {
|
||||
label={t("placeholder.username")}
|
||||
error={!!errors.username}
|
||||
required
|
||||
{...register("username", validationRules.username)}
|
||||
{...register("username")}
|
||||
InputProps={{
|
||||
startAdornment: <Adornment Icon={PersonIcon} />,
|
||||
}}
|
||||
@@ -195,7 +187,7 @@ export const Register = () => {
|
||||
label={t("placeholder.email")}
|
||||
error={!!errors.email}
|
||||
required
|
||||
{...register("email", validationRules.email)}
|
||||
{...register("email")}
|
||||
helperText={errors.email ? errors.email.message : null}
|
||||
InputProps={{
|
||||
disabled: readonlyEmail,
|
||||
@@ -209,7 +201,7 @@ export const Register = () => {
|
||||
label={t("label.auth_pass")}
|
||||
error={!!errors.password}
|
||||
required
|
||||
{...register("password", validationRules.password)}
|
||||
{...register("password")}
|
||||
helperText={errors.password ? errors.password.message : null}
|
||||
InputProps={{
|
||||
startAdornment: <Adornment Icon={KeyIcon} />,
|
||||
@@ -221,7 +213,7 @@ export const Register = () => {
|
||||
label={t("placeholder.password2")}
|
||||
error={!!errors.password2}
|
||||
required
|
||||
{...register("password2", validationRules.password2)}
|
||||
{...register("password2")}
|
||||
helperText={errors.password2 ? errors.password2.message : null}
|
||||
InputProps={{
|
||||
startAdornment: <Adornment Icon={KeyIcon} />,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@@ -10,12 +10,11 @@ import KeyIcon from "@mui/icons-material/Key";
|
||||
import { Button, Grid, Paper, Typography } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { useResetPassword } from "@/hooks/entities/reset-hooks";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { useValidationRules } from "@/hooks/useValidationRules";
|
||||
|
||||
import { PublicContentWrapper } from "../../components/anonymous/PublicContentWrapper";
|
||||
import { ContentContainer } from "../dialogs";
|
||||
@@ -25,23 +24,20 @@ import { PasswordInput } from "../inputs/PasswordInput";
|
||||
export const ResetPassword = () => {
|
||||
const { t } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const rules = useValidationRules();
|
||||
const validationRules = {
|
||||
password: {
|
||||
...rules.password,
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
password2: {
|
||||
...rules.password2,
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
};
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<{ password: string; password2: string }>({
|
||||
defaultValues: { password: "", password2: "" },
|
||||
rules: {
|
||||
password: {
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
password2: {
|
||||
required: t("message.password_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const { query, replace } = useRouter();
|
||||
// the following typecasting is due to the fact that the query object is not typed
|
||||
@@ -76,7 +72,7 @@ export const ResetPassword = () => {
|
||||
startAdornment: <Adornment Icon={KeyIcon} />,
|
||||
}}
|
||||
helperText={errors.password ? errors.password.message : null}
|
||||
{...register("password", validationRules.password)}
|
||||
{...register("password")}
|
||||
/>
|
||||
|
||||
<PasswordInput
|
||||
@@ -87,7 +83,7 @@ export const ResetPassword = () => {
|
||||
startAdornment: <Adornment Icon={KeyIcon} />,
|
||||
}}
|
||||
helperText={errors.password2 ? errors.password2.message : null}
|
||||
{...register("password2", validationRules.password2)}
|
||||
{...register("password2")}
|
||||
/>
|
||||
<Grid container gap={1} justifyContent="flex-end">
|
||||
<Button type="submit">{t("button.submit")}</Button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
import { Button, Grid, Paper, Typography } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { useRequestResetPassword } from "@/hooks/entities/reset-hooks";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
|
||||
@@ -27,6 +27,11 @@ export const ResetPasswordRequest = () => {
|
||||
formState: { errors },
|
||||
} = useForm<{ email: string }>({
|
||||
defaultValues: { email: "" },
|
||||
rules: {
|
||||
email: {
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const { mutate: requestReset } = useRequestResetPassword({
|
||||
onSuccess: () => {
|
||||
@@ -55,9 +60,7 @@ export const ResetPasswordRequest = () => {
|
||||
error={!!errors.email}
|
||||
required
|
||||
autoFocus
|
||||
{...register("email", {
|
||||
required: t("message.email_is_required"),
|
||||
})}
|
||||
{...register("email")}
|
||||
helperText={errors.email ? errors.email.message : null}
|
||||
/>
|
||||
<Grid container gap={1} justifyContent="flex-end">
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
import { MenuItem } from "@mui/material";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { ToggleableInput } from "@/app-components/inputs/ToggleableInput";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -60,19 +61,18 @@ export const MenuForm: FC<ComponentFormProps<MenuFormData>> = ({
|
||||
handleSubmit,
|
||||
} = useForm<IMenuItemAttributes>({
|
||||
defaultValues: DEFAULT_VALUES,
|
||||
rules: {
|
||||
type: {
|
||||
required: t("message.type_is_required"),
|
||||
},
|
||||
title: { required: t("message.title_is_required") },
|
||||
url: {
|
||||
required: t("message.url_is_invalid"),
|
||||
validate: (value: string = "") =>
|
||||
isAbsoluteUrl(value) || t("message.url_is_invalid"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
type: {
|
||||
required: t("message.type_is_required"),
|
||||
},
|
||||
title: { required: t("message.title_is_required") },
|
||||
url: {
|
||||
required: t("message.url_is_invalid"),
|
||||
validate: (value: string = "") =>
|
||||
isAbsoluteUrl(value) || t("message.url_is_invalid"),
|
||||
},
|
||||
payload: {},
|
||||
};
|
||||
const typeValue = watch("type");
|
||||
const titleValue = watch("title");
|
||||
const onSubmitForm = (params: IMenuItemAttributes) => {
|
||||
@@ -102,46 +102,35 @@ export const MenuForm: FC<ComponentFormProps<MenuFormData>> = ({
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<ContentContainer>
|
||||
<ContentContainer flexDirection="row">
|
||||
<ContentItem>
|
||||
<Controller
|
||||
name="type"
|
||||
rules={validationRules.type}
|
||||
control={control}
|
||||
render={({ field }) => {
|
||||
const { onChange, ...rest } = field;
|
||||
|
||||
return (
|
||||
<Input
|
||||
select
|
||||
label={t("placeholder.type")}
|
||||
error={!!errors.type}
|
||||
inputRef={field.ref}
|
||||
required
|
||||
onChange={({ target: { value } }) => {
|
||||
onChange(value);
|
||||
resetField("url");
|
||||
}}
|
||||
helperText={errors.type ? errors.type.message : null}
|
||||
{...rest}
|
||||
>
|
||||
{Object.keys(MenuType).map((value, key) => (
|
||||
<MenuItem value={value} key={key}>
|
||||
{t(`label.${value}`)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Input>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</ContentItem>
|
||||
<ContentItem flex={1}>
|
||||
<Input
|
||||
select
|
||||
label={t("placeholder.type")}
|
||||
error={!!errors.type}
|
||||
required
|
||||
{...register("type", {
|
||||
onChange: () => {
|
||||
resetField("url");
|
||||
},
|
||||
})}
|
||||
helperText={errors.type ? errors.type.message : null}
|
||||
{...rest}
|
||||
>
|
||||
{Object.keys(MenuType).map((value, key) => (
|
||||
<MenuItem value={value} key={key}>
|
||||
{t(`label.${value}`)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Input>
|
||||
</ContentItem>
|
||||
<ContentItem flex={2}>
|
||||
<Input
|
||||
label={t("placeholder.title")}
|
||||
error={!!errors.title}
|
||||
required
|
||||
autoFocus
|
||||
helperText={errors.title ? errors.title.message : null}
|
||||
{...register("title", validationRules.title)}
|
||||
{...register("title")}
|
||||
/>
|
||||
</ContentItem>
|
||||
</ContentContainer>
|
||||
@@ -152,7 +141,7 @@ export const MenuForm: FC<ComponentFormProps<MenuFormData>> = ({
|
||||
error={!!errors.url}
|
||||
required
|
||||
helperText={errors.url ? errors.url.message : null}
|
||||
{...register("url", validationRules.url)}
|
||||
{...register("url")}
|
||||
/>
|
||||
) : typeValue === MenuType.postback ? (
|
||||
<Controller
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType, RouterType } from "@/services/types";
|
||||
@@ -48,13 +48,10 @@ export const CategoryForm: FC<ComponentFormProps<ICategory>> = ({
|
||||
formState: { errors },
|
||||
handleSubmit,
|
||||
} = useForm<ICategoryAttributes>({
|
||||
defaultValues: { label: category?.label || "" },
|
||||
});
|
||||
const validationRules = {
|
||||
label: {
|
||||
required: t("message.label_is_required"),
|
||||
rules: {
|
||||
label: { required: t("message.label_is_required") },
|
||||
},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = (params: ICategoryAttributes) => {
|
||||
if (category) {
|
||||
updateCategory({ id: category.id, params });
|
||||
@@ -81,7 +78,7 @@ export const CategoryForm: FC<ComponentFormProps<ICategory>> = ({
|
||||
<Input
|
||||
label={t("placeholder.label")}
|
||||
error={!!errors.label}
|
||||
{...register("label", validationRules.label)}
|
||||
{...register("label")}
|
||||
required
|
||||
autoFocus
|
||||
helperText={errors.label ? errors.label.message : null}
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import { Button } from "@mui/material";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import { useFieldArray } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -44,6 +45,11 @@ export const ContentTypeForm: FC<ComponentFormProps<IContentType>> = ({
|
||||
name: contentType?.name || "",
|
||||
fields: contentType?.fields || FIELDS_FORM_DEFAULT_VALUES,
|
||||
},
|
||||
rules: {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const { append, fields, remove } = useFieldArray({
|
||||
name: "fields",
|
||||
@@ -113,9 +119,7 @@ export const ContentTypeForm: FC<ComponentFormProps<IContentType>> = ({
|
||||
<Input
|
||||
label={t("label.name")}
|
||||
error={!!errors.name}
|
||||
{...register("name", {
|
||||
required: t("message.name_is_required"),
|
||||
})}
|
||||
{...register("name")}
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
required
|
||||
autoFocus
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
Controller,
|
||||
ControllerRenderProps,
|
||||
FieldErrors,
|
||||
useForm,
|
||||
} from "react-hook-form";
|
||||
|
||||
import AttachmentInput from "@/app-components/attachment/AttachmentInput";
|
||||
@@ -22,6 +21,7 @@ import { Adornment } from "@/app-components/inputs/Adornment";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
|
||||
import { FormControlLabel, FormHelperText, Switch } from "@mui/material";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -60,18 +61,18 @@ export const ContextVarForm: FC<ComponentFormProps<IContextVar>> = ({
|
||||
label: contextVar?.label || "",
|
||||
permanent: contextVar?.permanent || false,
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
name: {
|
||||
pattern: {
|
||||
value: /^[a-z_0-9]+$/,
|
||||
message: t("message.context_vars_name_is_invalid"),
|
||||
rules: {
|
||||
name: {
|
||||
pattern: {
|
||||
value: /^[a-z_0-9]+$/,
|
||||
message: t("message.context_vars_name_is_invalid"),
|
||||
},
|
||||
},
|
||||
label: {
|
||||
required: t("message.label_is_required"),
|
||||
},
|
||||
},
|
||||
label: {
|
||||
required: t("message.label_is_required"),
|
||||
},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = (params: IContextVarAttributes) => {
|
||||
if (contextVar) {
|
||||
updateContextVar({ id: contextVar.id, params });
|
||||
@@ -102,7 +103,7 @@ export const ContextVarForm: FC<ComponentFormProps<IContextVar>> = ({
|
||||
error={!!errors.label}
|
||||
required
|
||||
autoFocus
|
||||
{...register("label", validationRules.label)}
|
||||
{...register("label")}
|
||||
InputProps={{
|
||||
onChange: ({ target: { value } }) => {
|
||||
setValue("label", value);
|
||||
@@ -117,7 +118,7 @@ export const ContextVarForm: FC<ComponentFormProps<IContextVar>> = ({
|
||||
label={t("label.name")}
|
||||
error={!!errors.name}
|
||||
disabled
|
||||
{...register("name", validationRules.name)}
|
||||
{...register("name")}
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
*/
|
||||
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -52,14 +52,12 @@ export const LabelForm: FC<ComponentFormProps<ILabel>> = ({
|
||||
title: label?.title || "",
|
||||
description: label?.description || "",
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
title: {
|
||||
required: t("message.title_is_required"),
|
||||
rules: {
|
||||
title: {
|
||||
required: t("message.title_is_required"),
|
||||
},
|
||||
},
|
||||
name: {},
|
||||
description: {},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = (params: ILabelAttributes) => {
|
||||
if (label) {
|
||||
updateLabel({ id: label.id, params });
|
||||
@@ -90,7 +88,7 @@ export const LabelForm: FC<ComponentFormProps<ILabel>> = ({
|
||||
error={!!errors.title}
|
||||
required
|
||||
autoFocus
|
||||
{...register("title", validationRules.title)}
|
||||
{...register("title")}
|
||||
InputProps={{
|
||||
onChange: ({ target: { value } }) => {
|
||||
setValue("title", value);
|
||||
@@ -104,7 +102,7 @@ export const LabelForm: FC<ComponentFormProps<ILabel>> = ({
|
||||
<Input
|
||||
placeholder={t("placeholder.name")}
|
||||
error={!!errors.name}
|
||||
{...register("name", validationRules.name)}
|
||||
{...register("name")}
|
||||
disabled
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
/>
|
||||
@@ -113,7 +111,7 @@ export const LabelForm: FC<ComponentFormProps<ILabel>> = ({
|
||||
<Input
|
||||
label={t("label.description")}
|
||||
error={!!errors.description}
|
||||
{...register("description", validationRules.description)}
|
||||
{...register("description")}
|
||||
helperText={
|
||||
errors.description ? errors.description.message : null
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
|
||||
import { FormControlLabel, Switch } from "@mui/material";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -52,15 +53,15 @@ export const LanguageForm: FC<ComponentFormProps<ILanguage>> = ({
|
||||
code: language?.code || "",
|
||||
isRTL: language?.isRTL || false,
|
||||
},
|
||||
rules: {
|
||||
title: {
|
||||
required: t("message.title_is_required"),
|
||||
},
|
||||
code: {
|
||||
required: t("message.code_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
title: {
|
||||
required: t("message.title_is_required"),
|
||||
},
|
||||
code: {
|
||||
required: t("message.code_is_required"),
|
||||
},
|
||||
};
|
||||
const onSubmitForm = (params: ILanguageAttributes) => {
|
||||
if (language) {
|
||||
updateLanguage({ id: language.id, params });
|
||||
@@ -87,9 +88,10 @@ export const LanguageForm: FC<ComponentFormProps<ILanguage>> = ({
|
||||
<ContentContainer>
|
||||
<ContentItem>
|
||||
<Input
|
||||
required
|
||||
label={t("label.title")}
|
||||
error={!!errors.title}
|
||||
{...register("title", validationRules.title)}
|
||||
{...register("title")}
|
||||
multiline={true}
|
||||
autoFocus
|
||||
helperText={errors.title ? errors.title.message : null}
|
||||
@@ -97,9 +99,10 @@ export const LanguageForm: FC<ComponentFormProps<ILanguage>> = ({
|
||||
</ContentItem>
|
||||
<ContentItem>
|
||||
<Input
|
||||
required
|
||||
label={t("label.code")}
|
||||
error={!!errors.code}
|
||||
{...register("code", validationRules.code)}
|
||||
{...register("code")}
|
||||
multiline={true}
|
||||
helperText={errors.code ? errors.code.message : null}
|
||||
/>
|
||||
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
RadioGroup,
|
||||
} from "@mui/material";
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -62,14 +62,12 @@ export const NlpEntityVarForm: FC<ComponentFormProps<INlpEntity>> = ({
|
||||
lookups: nlpEntity?.lookups || ["keywords"],
|
||||
weight: nlpEntity?.weight || 1,
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
rules: {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
},
|
||||
},
|
||||
lookups: {},
|
||||
isChecked: {},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = (params: INlpEntityAttributes) => {
|
||||
if (nlpEntity) {
|
||||
updateNlpEntity({ id: nlpEntity.id, params });
|
||||
@@ -122,7 +120,7 @@ export const NlpEntityVarForm: FC<ComponentFormProps<INlpEntity>> = ({
|
||||
<Input
|
||||
label={t("label.name")}
|
||||
error={!!errors.name}
|
||||
{...register("name", validationRules.name)}
|
||||
{...register("name")}
|
||||
required
|
||||
autoFocus
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
||||
import { Controller, useFieldArray } from "react-hook-form";
|
||||
import { useQuery } from "react-query";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
@@ -32,6 +32,7 @@ import AutoCompleteSelect from "@/app-components/inputs/AutoCompleteSelect";
|
||||
import Selectable from "@/app-components/inputs/Selectable";
|
||||
import { useGetFromCache } from "@/hooks/crud/useGet";
|
||||
import { useApiClient } from "@/hooks/useApiClient";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useNlp } from "@/hooks/useNlp";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType, Format } from "@/services/types";
|
||||
@@ -322,9 +323,7 @@ const NlpDatasetSample: FC<NlpDatasetSampleProps> = ({
|
||||
</ContentItem>
|
||||
))}
|
||||
</Box>
|
||||
{
|
||||
/* Keyword entities */
|
||||
}
|
||||
{/* Keyword entities */}
|
||||
<Box display="flex" flexDirection="column">
|
||||
{keywordEntities.map((keywordEntity, index) => (
|
||||
<ContentItem
|
||||
|
||||
@@ -12,7 +12,7 @@ import KeyIcon from "@mui/icons-material/Key";
|
||||
import LanguageIcon from "@mui/icons-material/Language";
|
||||
import { Box, Button, Grid, MenuItem, Typography } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
import { useQueryClient } from "react-query";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
@@ -22,9 +22,9 @@ import { Input } from "@/app-components/inputs/Input";
|
||||
import { PasswordInput } from "@/app-components/inputs/PasswordInput";
|
||||
import { useUpdateProfile } from "@/hooks/entities/auth-hooks";
|
||||
import { CURRENT_USER_KEY } from "@/hooks/useAuth";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { useValidationRules } from "@/hooks/useValidationRules";
|
||||
import { IProfileAttributes, IUser } from "@/types/user.types";
|
||||
import { MIME_TYPES } from "@/utils/attachment";
|
||||
|
||||
@@ -58,27 +58,18 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
email: user.email,
|
||||
language: user.language,
|
||||
},
|
||||
});
|
||||
const rules = useValidationRules();
|
||||
const validationRules = {
|
||||
...rules,
|
||||
email: {
|
||||
...rules.email,
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
password: {
|
||||
...rules.password,
|
||||
},
|
||||
password2: {
|
||||
validate: (val?: string) => {
|
||||
if (val !== watch("password")) {
|
||||
trigger("password");
|
||||
rules: {
|
||||
password2: {
|
||||
validate: (val) => {
|
||||
if (val !== watch("password")) {
|
||||
trigger("password");
|
||||
|
||||
return t("message.password_match");
|
||||
}
|
||||
return t("message.password_match");
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = ({
|
||||
password,
|
||||
password2: _password2,
|
||||
@@ -124,7 +115,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
<ContentItem>
|
||||
<Input
|
||||
label={t("label.user_first_name")}
|
||||
{...register("first_name", validationRules.first_name)}
|
||||
{...register("first_name")}
|
||||
autoFocus
|
||||
error={!!errors.first_name}
|
||||
helperText={
|
||||
@@ -135,7 +126,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
<ContentItem>
|
||||
<Input
|
||||
label={t("label.last_name")}
|
||||
{...register("last_name", validationRules.last_name)}
|
||||
{...register("last_name")}
|
||||
error={!!errors.last_name}
|
||||
helperText={errors.last_name ? errors.last_name.message : null}
|
||||
/>
|
||||
@@ -166,7 +157,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
<ContentItem>
|
||||
<Input
|
||||
label={t("label.email")}
|
||||
{...register("email", validationRules.email)}
|
||||
{...register("email")}
|
||||
required
|
||||
error={!!errors.email}
|
||||
helperText={errors.email ? errors.email.message : null}
|
||||
@@ -178,7 +169,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
<ContentItem>
|
||||
<PasswordInput
|
||||
label={t("placeholder.password")}
|
||||
{...register("password", validationRules.password)}
|
||||
{...register("password")}
|
||||
required
|
||||
error={!!errors.password}
|
||||
helperText={errors.password ? errors.password.message : null}
|
||||
@@ -190,7 +181,7 @@ export const ProfileForm: FC<ProfileFormProps> = ({ user }) => {
|
||||
<ContentItem>
|
||||
<PasswordInput
|
||||
label={t("placeholder.password2")}
|
||||
{...register("password2", validationRules.password2)}
|
||||
{...register("password2")}
|
||||
required
|
||||
error={!!errors.password2}
|
||||
helperText={errors.password2 ? errors.password2.message : null}
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
*/
|
||||
|
||||
import { FC, Fragment, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useCreate } from "@/hooks/crud/useCreate";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -45,12 +45,12 @@ export const RoleForm: FC<ComponentFormProps<IRole>> = ({
|
||||
formState: { errors },
|
||||
} = useForm<IRoleAttributes>({
|
||||
defaultValues: { name: "" },
|
||||
});
|
||||
const validationRules = {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
rules: {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
const onSubmitForm = (params: IRoleAttributes) => {
|
||||
if (role) {
|
||||
updateRole({ id: role.id, params });
|
||||
@@ -80,7 +80,7 @@ export const RoleForm: FC<ComponentFormProps<IRole>> = ({
|
||||
required
|
||||
autoFocus
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
{...register("name", validationRules.name)}
|
||||
{...register("name")}
|
||||
/>
|
||||
</ContentItem>
|
||||
</ContentContainer>
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
|
||||
import { FormLabel, Grid, Typography } from "@mui/material";
|
||||
import { FC, Fragment } from "react";
|
||||
import { Controller, ControllerRenderProps, useForm } from "react-hook-form";
|
||||
import { Controller, ControllerRenderProps } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useFind } from "@/hooks/crud/useFind";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
*/
|
||||
|
||||
import { FC, Fragment } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntitySelect";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import { useSendInvitation } from "@/hooks/entities/invitation-hooks";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { useValidationRules } from "@/hooks/useValidationRules";
|
||||
import { EntityType, Format } from "@/services/types";
|
||||
import { ComponentFormProps } from "@/types/common/dialogs.types";
|
||||
import { IInvitationAttributes } from "@/types/invitation.types";
|
||||
@@ -47,17 +47,12 @@ export const InviteUserForm: FC<ComponentFormProps<undefined>> = ({
|
||||
handleSubmit,
|
||||
} = useForm<IInvitationAttributes>({
|
||||
defaultValues: DEFAULT_VALUES,
|
||||
rules: {
|
||||
email: {
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const rules = useValidationRules();
|
||||
const validationRules = {
|
||||
email: {
|
||||
...rules.email,
|
||||
required: t("message.email_is_required"),
|
||||
},
|
||||
roles: {
|
||||
required: t("message.roles_is_required"),
|
||||
},
|
||||
};
|
||||
const onSubmitForm = (params: IInvitationAttributes) =>
|
||||
sendInvitation(params);
|
||||
|
||||
@@ -71,14 +66,16 @@ export const InviteUserForm: FC<ComponentFormProps<undefined>> = ({
|
||||
error={!!errors.email}
|
||||
required
|
||||
autoFocus
|
||||
{...register("email", validationRules.email)}
|
||||
{...register("email")}
|
||||
helperText={errors.email ? errors.email.message : null}
|
||||
/>
|
||||
</ContentItem>
|
||||
<ContentItem>
|
||||
<Controller
|
||||
name="roles"
|
||||
rules={validationRules.roles}
|
||||
rules={{
|
||||
required: t("message.roles_is_required"),
|
||||
}}
|
||||
control={control}
|
||||
render={({ field }) => {
|
||||
const { onChange, ...rest } = field;
|
||||
|
||||
@@ -10,13 +10,14 @@ import ChatBubbleOutlineOutlinedIcon from "@mui/icons-material/ChatBubbleOutline
|
||||
import SettingsApplicationsIcon from "@mui/icons-material/SettingsApplications";
|
||||
import { FormControlLabel, Grid, Switch, Tab, Tabs } from "@mui/material";
|
||||
import { FC, Fragment, useEffect, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
import { ContentContainer, ContentItem } from "@/app-components/dialogs";
|
||||
import { Input } from "@/app-components/inputs/Input";
|
||||
import TriggerIcon from "@/app-components/svg/TriggerIcon";
|
||||
import { TabPanel } from "@/app-components/tabs/TabPanel";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useForm } from "@/hooks/useForm";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { EntityType } from "@/services/types";
|
||||
@@ -82,6 +83,11 @@ export const BlockEditForm: FC<ComponentFormProps<IBlock>> = ({
|
||||
} as IBlockAttributes;
|
||||
const methods = useForm<IBlockAttributes>({
|
||||
defaultValues: DEFAULT_VALUES,
|
||||
rules: {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const {
|
||||
reset,
|
||||
@@ -90,11 +96,6 @@ export const BlockEditForm: FC<ComponentFormProps<IBlock>> = ({
|
||||
handleSubmit,
|
||||
control,
|
||||
} = methods;
|
||||
const validationRules = {
|
||||
name: {
|
||||
required: t("message.name_is_required"),
|
||||
},
|
||||
};
|
||||
const onSubmitForm = (params: IBlockAttributes) => {
|
||||
if (block) {
|
||||
updateBlock({ id: block.id, params });
|
||||
@@ -121,8 +122,9 @@ export const BlockEditForm: FC<ComponentFormProps<IBlock>> = ({
|
||||
<ContentContainer>
|
||||
<ContentItem display="flex" gap={5}>
|
||||
<Input
|
||||
required
|
||||
label={t("placeholder.name")}
|
||||
{...register("name", validationRules.name)}
|
||||
{...register("name")}
|
||||
error={!!errors.name}
|
||||
autoFocus
|
||||
helperText={errors.name ? errors.name.message : null}
|
||||
|
||||
Reference in New Issue
Block a user