Skip to content

Commit

Permalink
refactor(ui): replace existing validation logic with validateString
Browse files Browse the repository at this point in the history
… utility
  • Loading branch information
hdinia committed Feb 28, 2024
1 parent 631956e commit 61834f6
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { getUsers } from "../../../../../../services/api/user";
import { getAuthUser } from "../../../../../../redux/selectors";
import useAppSelector from "../../../../../../redux/hooks/useAppSelector";
import { UseFormReturnPlus } from "../../../../../common/Form/types";
import { validateString } from "../../../../../../utils/validationUtils";

function GroupForm(props: UseFormReturnPlus) {
const {
Expand Down Expand Up @@ -101,12 +102,9 @@ function GroupForm(props: UseFormReturnPlus) {
}
fullWidth
{...register("name", {
required: t("form.field.required") as string,
validate: (value) => {
if (RESERVED_GROUP_NAMES.includes(value)) {
return t("form.field.notAllowedValue") as string;
}
},
validate: (v) =>
validateString(v, { excludedEntries: RESERVED_GROUP_NAMES }) ||
undefined,
})}
/>
{/* Permissions */}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router";
import { useTranslation } from "react-i18next";
import AddCircleIcon from "@mui/icons-material/AddCircle";
Expand All @@ -10,6 +10,7 @@ import StringFE from "../../../../common/fieldEditors/StringFE";
import Fieldset from "../../../../common/Fieldset";
import SelectFE from "../../../../common/fieldEditors/SelectFE";
import { SubmitHandlerPlus } from "../../../../common/Form/types";
import { validateString } from "../../../../../utils/validationUtils";

interface Props {
parentId: string;
Expand All @@ -25,6 +26,11 @@ function CreateVariantDialog(props: Props) {
const [sourceList, setSourceList] = useState<GenericInfo[]>([]);
const defaultValues = { name: "", sourceId: parentId };

const existingVariants = useMemo(
() => sourceList.map((variant) => variant.name),
[sourceList],
);

useEffect(() => {
setSourceList(createListFromTree(tree));
}, [tree]);
Expand Down Expand Up @@ -67,8 +73,8 @@ function CreateVariantDialog(props: Props) {
name="name"
control={control}
rules={{
required: true,
validate: (val) => val.trim().length > 0,
validate: (v) =>
validateString(v, { existingEntries: existingVariants }),
}}
/>
<SelectFE
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/components/App/Singlestudy/PropertiesDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Fieldset from "../../common/Fieldset";
import { SubmitHandlerPlus } from "../../common/Form/types";
import useAppDispatch from "../../../redux/hooks/useAppDispatch";
import { updateStudy } from "../../../redux/ducks/studies";
import { validateString } from "../../../utils/validationUtils";

const logErr = debug("antares:createstudyform:error");

Expand Down Expand Up @@ -137,7 +138,7 @@ function PropertiesDialog(props: Props) {
label={t("studies.studyName")}
name="name"
control={control}
rules={{ required: true, validate: (val) => val.trim().length > 0 }}
rules={{ validate: (v) => validateString(v) }}
sx={{ mx: 0 }}
fullWidth
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SelectFE from "../../../../../common/fieldEditors/SelectFE";
import StringFE from "../../../../../common/fieldEditors/StringFE";
import SwitchFE from "../../../../../common/fieldEditors/SwitchFE";
import { StudyMetadata } from "../../../../../../common/types";
import { validateString } from "../../../../../../utils/validationUtils";

interface Props {
studyId: StudyMetadata["id"];
Expand Down Expand Up @@ -102,14 +103,8 @@ function AddDialog({ studyId, existingConstraints, open, onClose }: Props) {
label={t("global.name")}
control={control}
rules={{
validate: (v) => {
if (v.trim().length <= 0) {
return t("form.field.required");
}
if (existingConstraints.includes(v.trim().toLowerCase())) {
return t("form.field.duplicate", { 0: v });
}
},
validate: (v) =>
validateString(v, { existingEntries: existingConstraints }),
}}
/>
<StringFE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import useAppDispatch from "../../../../../../../../redux/hooks/useAppDispatch";
import { createStudyMapDistrict } from "../../../../../../../../redux/ducks/studyMaps";
import useAppSelector from "../../../../../../../../redux/hooks/useAppSelector";
import { getStudyMapDistrictsById } from "../../../../../../../../redux/selectors";
import { validateString } from "../../../../../../../../utils/validationUtils";

interface Props {
open: boolean;
Expand Down Expand Up @@ -81,15 +82,8 @@ function CreateDistrictDialog(props: Props) {
control={control}
fullWidth
rules={{
required: { value: true, message: t("form.field.required") },
validate: (v) => {
if (v.trim().length <= 0) {
return false;
}
if (existingDistricts.includes(v.toLowerCase())) {
return `The District "${v}" already exists`;
}
},
validate: (v) =>
validateString(v, { existingEntries: existingDistricts }),
}}
sx={{ m: 0 }}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import useAppDispatch from "../../../../../../../../redux/hooks/useAppDispatch";
import useEnqueueErrorSnackbar from "../../../../../../../../hooks/useEnqueueErrorSnackbar";
import useAppSelector from "../../../../../../../../redux/hooks/useAppSelector";
import { getStudyMapLayersById } from "../../../../../../../../redux/selectors";
import { validateString } from "../../../../../../../../utils/validationUtils";

interface Props {
open: boolean;
Expand Down Expand Up @@ -73,15 +74,8 @@ function CreateLayerDialog(props: Props) {
control={control}
fullWidth
rules={{
required: { value: true, message: t("form.field.required") },
validate: (v) => {
if (v.trim().length <= 0) {
return false;
}
if (existingLayers.includes(v.toLowerCase())) {
return `The layer "${v}" already exists`;
}
},
validate: (v) =>
validateString(v, { existingEntries: existingLayers }),
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
updateStudyMapLayer,
} from "../../../../../../../../redux/ducks/studyMaps";
import useAppDispatch from "../../../../../../../../redux/hooks/useAppDispatch";
import { validateString } from "../../../../../../../../utils/validationUtils";

interface Props {
open: boolean;
Expand Down Expand Up @@ -104,15 +105,8 @@ function UpdateLayerDialog(props: Props) {
control={control}
fullWidth
rules={{
required: { value: true, message: t("form.field.required") },
validate: (v) => {
if (v.trim().length <= 0) {
return false;
}
if (existingLayers.includes(v.toLowerCase())) {
return `The Layer "${v}" already exists`;
}
},
validate: (v) =>
validateString(v, { existingEntries: existingLayers }),
}}
disabled={getValues("layerId") === ""}
sx={{ mx: 0 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import SelectFE from "../../../../../common/fieldEditors/SelectFE";
import StringFE from "../../../../../common/fieldEditors/StringFE";
import { getTableColumnsForType, type TableTemplate } from "../utils";
import { TABLE_MODE_TYPES } from "../../../../../../services/api/studies/tableMode/constants";
import { validateString } from "../../../../../../utils/validationUtils";
import { useMemo } from "react";

export interface TableTemplateFormDialogProps
extends Pick<
Expand All @@ -23,6 +25,15 @@ function TableTemplateFormDialog(props: TableTemplateFormDialogProps) {
props;
const { t } = useTranslation();

const existingTables = useMemo(
() => templates.map((table) => table.name),
[templates],
);

////////////////////////////////////////////////////////////////
// JSX
////////////////////////////////////////////////////////////////

return (
<FormDialog
open={open}
Expand All @@ -47,16 +58,8 @@ function TableTemplateFormDialog(props: TableTemplateFormDialogProps) {
autoFocus
control={control}
rules={{
validate: (value) => {
const id = getValues("id");
const hasDuplicate = templates.find(
(tp) => tp.id !== id && tp.name.trim() === value.trim(),
);
if (hasDuplicate) {
return t("form.field.notAllowedValue") as string;
}
},
required: true,
validate: (v) =>
validateString(v, { existingEntries: existingTables }),
}}
/>
<SelectFE
Expand Down
16 changes: 3 additions & 13 deletions webapp/src/components/common/GroupedDataTable/CreateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SubmitHandlerPlus } from "../Form/types";
import SelectFE from "../fieldEditors/SelectFE";
import { nameToId } from "../../../services/utils";
import { TRow } from "./utils";
import { validateString } from "../../../utils/validationUtils";

interface Props<TData extends TRow> {
open: boolean;
Expand Down Expand Up @@ -65,19 +66,8 @@ function CreateDialog<TData extends TRow>({
control={control}
fullWidth
rules={{
required: { value: true, message: t("form.field.required") },
validate: (v) => {
const regex = /^[a-zA-Z0-9_\-() &]+$/;
if (!regex.test(v.trim())) {
return t("form.field.specialChars", { 0: "&()_-" });
}
if (v.trim().length <= 0) {
return t("form.field.required");
}
if (existingNames.includes(v.trim().toLowerCase())) {
return t("form.field.duplicate", { 0: v });
}
},
validate: (v) =>
validateString(v, { existingEntries: existingNames }),
}}
sx={{ m: 0 }}
/>
Expand Down
16 changes: 3 additions & 13 deletions webapp/src/components/common/GroupedDataTable/DuplicateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Fieldset from "../Fieldset";
import FormDialog from "../dialogs/FormDialog";
import { SubmitHandlerPlus } from "../Form/types";
import StringFE from "../fieldEditors/StringFE";
import { validateString } from "../../../utils/validationUtils";

interface Props {
open: boolean;
Expand Down Expand Up @@ -51,19 +52,8 @@ function DuplicateDialog(props: Props) {
control={control}
fullWidth
rules={{
required: { value: true, message: t("form.field.required") },
validate: (v) => {
const regex = /^[a-zA-Z0-9_\-() &]+$/;
if (!regex.test(v.trim())) {
return t("form.field.specialChars", { 0: "&()_-" });
}
if (v.trim().length <= 0) {
return t("form.field.required");
}
if (existingNames.includes(v.trim().toLowerCase())) {
return t("form.field.duplicate", { 0: v });
}
},
validate: (v) =>
validateString(v, { existingEntries: existingNames }),
}}
sx={{ m: 0 }}
/>
Expand Down

0 comments on commit 61834f6

Please sign in to comment.