From bb8e4f31ee89291081dea646c918f02d595cfb66 Mon Sep 17 00:00:00 2001 From: LASER-Yi Date: Tue, 27 Sep 2022 03:18:06 +0800 Subject: [PATCH] Refactor form validation and fix issues --- .../src/components/forms/ColorToolForm.tsx | 6 +++++- .../src/components/forms/FrameRateForm.tsx | 11 ++++++++-- .../src/components/forms/MovieUploadForm.tsx | 5 +++-- .../src/components/forms/ProfileEditForm.tsx | 12 ++++++++--- .../src/components/forms/SeriesUploadForm.tsx | 20 +++++++++++-------- .../src/components/forms/TimeOffsetForm.tsx | 12 +++++++---- .../src/components/forms/TranslationForm.tsx | 3 ++- .../Settings/Notifications/components.tsx | 11 ++++++++-- frontend/src/utilities/form.ts | 15 ++++++++++++++ 9 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 frontend/src/utilities/form.ts diff --git a/frontend/src/components/forms/ColorToolForm.tsx b/frontend/src/components/forms/ColorToolForm.tsx index 3bbb5a295..af4d2b6e5 100644 --- a/frontend/src/components/forms/ColorToolForm.tsx +++ b/frontend/src/components/forms/ColorToolForm.tsx @@ -2,6 +2,7 @@ import { useSubtitleAction } from "@/apis/hooks"; import { Selector, SelectorOption } from "@/components"; import { useModals, withModal } from "@/modules/modals"; import { task } from "@/modules/task"; +import FormUtils from "@/utilities/form"; import { Button, Divider, Stack } from "@mantine/core"; import { useForm } from "@mantine/form"; import { FunctionComponent } from "react"; @@ -93,7 +94,10 @@ const ColorToolForm: FunctionComponent = ({ selections, onSubmit }) => { color: "", }, validate: { - color: (c) => colorOptions.find((op) => op.value === c) !== undefined, + color: FormUtils.validation( + (value) => colorOptions.find((op) => op.value === value) !== undefined, + "Must select a color" + ), }, }); diff --git a/frontend/src/components/forms/FrameRateForm.tsx b/frontend/src/components/forms/FrameRateForm.tsx index 5da616790..81068ee92 100644 --- a/frontend/src/components/forms/FrameRateForm.tsx +++ b/frontend/src/components/forms/FrameRateForm.tsx @@ -1,6 +1,7 @@ import { useSubtitleAction } from "@/apis/hooks"; import { useModals, withModal } from "@/modules/modals"; import { task } from "@/modules/task"; +import FormUtils from "@/utilities/form"; import { Button, Divider, Group, NumberInput, Stack } from "@mantine/core"; import { useForm } from "@mantine/form"; import { FunctionComponent } from "react"; @@ -26,8 +27,14 @@ const FrameRateForm: FunctionComponent = ({ selections, onSubmit }) => { to: 0, }, validate: { - from: (v) => v > 0, - to: (v) => v > 0, + from: FormUtils.validation( + (value) => value > 0, + "The From value must be larger than 0" + ), + to: FormUtils.validation( + (value) => value > 0, + "The To value must be larger than 0" + ), }, }); diff --git a/frontend/src/components/forms/MovieUploadForm.tsx b/frontend/src/components/forms/MovieUploadForm.tsx index faaa05b13..e1232afc3 100644 --- a/frontend/src/components/forms/MovieUploadForm.tsx +++ b/frontend/src/components/forms/MovieUploadForm.tsx @@ -3,6 +3,7 @@ import { useModals, withModal } from "@/modules/modals"; import { task, TaskGroup } from "@/modules/task"; import { useTableStyles } from "@/styles"; import { useArrayAction, useSelectorOptions } from "@/utilities"; +import FormUtils from "@/utilities/form"; import { useLanguageProfileBy, useProfileItemsToLanguages, @@ -113,7 +114,7 @@ const MovieUploadForm: FunctionComponent = ({ })), }, validate: { - files: (values) => { + files: FormUtils.validation((values) => { return ( values.find( (v) => @@ -122,7 +123,7 @@ const MovieUploadForm: FunctionComponent = ({ v.validateResult.state === "error" ) === undefined ); - }, + }, "Some files cannot be uploaded, please check"), }, }); diff --git a/frontend/src/components/forms/ProfileEditForm.tsx b/frontend/src/components/forms/ProfileEditForm.tsx index 19ae1cd3f..9a58a9f36 100644 --- a/frontend/src/components/forms/ProfileEditForm.tsx +++ b/frontend/src/components/forms/ProfileEditForm.tsx @@ -3,6 +3,7 @@ import { useModals, withModal } from "@/modules/modals"; import { useTableStyles } from "@/styles"; import { useArrayAction, useSelectorOptions } from "@/utilities"; import { LOG } from "@/utilities/console"; +import FormUtils from "@/utilities/form"; import { faTrash } from "@fortawesome/free-solid-svg-icons"; import { Accordion, @@ -49,9 +50,14 @@ const ProfileEditForm: FunctionComponent = ({ const form = useForm({ initialValues: profile, validate: { - name: (value) => (value.length > 0 ? null : "Must have a name"), - items: (value) => - value.length > 0 ? null : "Must contain at lease 1 language", + name: FormUtils.validation( + (value) => value.length > 0, + "Must have a name" + ), + items: FormUtils.validation( + (value) => value.length > 0, + "Must contain at lease 1 language" + ), }, }); diff --git a/frontend/src/components/forms/SeriesUploadForm.tsx b/frontend/src/components/forms/SeriesUploadForm.tsx index 5619dbb44..e7363d15e 100644 --- a/frontend/src/components/forms/SeriesUploadForm.tsx +++ b/frontend/src/components/forms/SeriesUploadForm.tsx @@ -7,6 +7,7 @@ import { useModals, withModal } from "@/modules/modals"; import { task, TaskGroup } from "@/modules/task"; import { useTableStyles } from "@/styles"; import { useArrayAction, useSelectorOptions } from "@/utilities"; +import FormUtils from "@/utilities/form"; import { useLanguageProfileBy, useProfileItemsToLanguages, @@ -126,14 +127,17 @@ const SeriesUploadForm: FunctionComponent = ({ })), }, validate: { - files: (values) => - values.find( - (v) => - v.language === null || - v.episode === null || - v.validateResult === undefined || - v.validateResult.state === "error" - ) === undefined, + files: FormUtils.validation( + (values) => + values.find( + (v) => + v.language === null || + v.episode === null || + v.validateResult === undefined || + v.validateResult.state === "error" + ) === undefined, + "Some files cannot be uploaded, please check" + ), }, }); diff --git a/frontend/src/components/forms/TimeOffsetForm.tsx b/frontend/src/components/forms/TimeOffsetForm.tsx index 38fad7b88..b02e75781 100644 --- a/frontend/src/components/forms/TimeOffsetForm.tsx +++ b/frontend/src/components/forms/TimeOffsetForm.tsx @@ -1,6 +1,7 @@ import { useSubtitleAction } from "@/apis/hooks"; import { useModals, withModal } from "@/modules/modals"; import { task } from "@/modules/task"; +import FormUtils from "@/utilities/form"; import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button, Divider, Group, NumberInput, Stack } from "@mantine/core"; @@ -31,10 +32,13 @@ const TimeOffsetForm: FunctionComponent = ({ selections, onSubmit }) => { ms: 0, }, validate: { - hour: (v) => v >= 0, - min: (v) => v >= 0, - sec: (v) => v >= 0, - ms: (v) => v >= 0, + hour: FormUtils.validation((v) => v >= 0, "Hour must be larger than 0"), + min: FormUtils.validation((v) => v >= 0, "Minute must be larger than 0"), + sec: FormUtils.validation((v) => v >= 0, "Second must be larger than 0"), + ms: FormUtils.validation( + (v) => v >= 0, + "Millisecond must be larger than 0" + ), }, }); diff --git a/frontend/src/components/forms/TranslationForm.tsx b/frontend/src/components/forms/TranslationForm.tsx index cb0ed1360..260d9b198 100644 --- a/frontend/src/components/forms/TranslationForm.tsx +++ b/frontend/src/components/forms/TranslationForm.tsx @@ -2,6 +2,7 @@ import { useSubtitleAction } from "@/apis/hooks"; import { useModals, withModal } from "@/modules/modals"; import { task } from "@/modules/task"; import { useSelectorOptions } from "@/utilities"; +import FormUtils from "@/utilities/form"; import { useEnabledLanguages } from "@/utilities/languages"; import { Alert, Button, Divider, Stack } from "@mantine/core"; import { useForm } from "@mantine/form"; @@ -139,7 +140,7 @@ const TranslationForm: FunctionComponent = ({ language: null as Language.Info | null, }, validate: { - language: isObject, + language: FormUtils.validation(isObject, "Please select a language"), }, }); diff --git a/frontend/src/pages/Settings/Notifications/components.tsx b/frontend/src/pages/Settings/Notifications/components.tsx index 3898b07c5..ba18ca658 100644 --- a/frontend/src/pages/Settings/Notifications/components.tsx +++ b/frontend/src/pages/Settings/Notifications/components.tsx @@ -3,6 +3,7 @@ import { Selector } from "@/components"; import MutateButton from "@/components/async/MutateButton"; import { useModals, withModal } from "@/modules/modals"; import { BuildKey, useSelectorOptions } from "@/utilities"; +import FormUtils from "@/utilities/form"; import { Button, Divider, @@ -44,8 +45,14 @@ const NotificationForm: FunctionComponent = ({ url: payload?.url ?? "", }, validate: { - selection: isObject, - url: (value) => value.trim() !== "", + selection: FormUtils.validation( + isObject, + "Please select a notification provider" + ), + url: FormUtils.validation( + (value) => value.trim().length !== 0, + "URL must not be empty" + ), }, }); diff --git a/frontend/src/utilities/form.ts b/frontend/src/utilities/form.ts new file mode 100644 index 000000000..bce72a530 --- /dev/null +++ b/frontend/src/utilities/form.ts @@ -0,0 +1,15 @@ +function validation(condition: (value: T) => boolean, message: string) { + return (value: T) => { + if (condition(value)) { + return null; + } else { + return message; + } + }; +} + +const FormUtils = { + validation, +}; + +export default FormUtils;