From ef209868bf11bc06d7d62f5d5e983266031e7b53 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Fri, 7 Feb 2025 20:45:32 +0300 Subject: [PATCH] F: Rework CstRename dialog --- rsconcept/frontend/src/backend/rsform/api.ts | 15 +++-- .../frontend/src/dialogs/DlgCreateVersion.tsx | 2 +- .../DlgEditVersions/DlgEditVersions.tsx | 17 +++-- .../frontend/src/dialogs/DlgRenameCst.tsx | 63 ++++++++++--------- .../EditorConstituenta/EditorControls.tsx | 16 +---- 5 files changed, 59 insertions(+), 54 deletions(-) diff --git a/rsconcept/frontend/src/backend/rsform/api.ts b/rsconcept/frontend/src/backend/rsform/api.ts index 001a9929..07f04e23 100644 --- a/rsconcept/frontend/src/backend/rsform/api.ts +++ b/rsconcept/frontend/src/backend/rsform/api.ts @@ -94,11 +94,16 @@ export type ICstUpdateDTO = z.infer; /** * Represents data, used in renaming {@link IConstituenta}. */ -export interface ICstRenameDTO { - alias: string; - cst_type: CstType; - target: ConstituentaID; -} +export const CstRenameSchema = z.object({ + target: z.number(), + alias: z.string(), + cst_type: z.nativeEnum(CstType) +}); + +/** + * Represents data, used in renaming {@link IConstituenta}. + */ +export type ICstRenameDTO = z.infer; /** * Represents data, used in ordering a list of {@link IConstituenta}. diff --git a/rsconcept/frontend/src/dialogs/DlgCreateVersion.tsx b/rsconcept/frontend/src/dialogs/DlgCreateVersion.tsx index f4a7b5c1..495bc6d8 100644 --- a/rsconcept/frontend/src/dialogs/DlgCreateVersion.tsx +++ b/rsconcept/frontend/src/dialogs/DlgCreateVersion.tsx @@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import clsx from 'clsx'; import { Controller, useForm, useWatch } from 'react-hook-form'; -import { VersionCreateSchema, IVersionCreateDTO } from '@/backend/library/api'; +import { IVersionCreateDTO, VersionCreateSchema } from '@/backend/library/api'; import { useVersionCreate } from '@/backend/library/useVersionCreate'; import { Checkbox, TextArea, TextInput } from '@/components/ui/Input'; import { ModalForm } from '@/components/ui/Modal'; diff --git a/rsconcept/frontend/src/dialogs/DlgEditVersions/DlgEditVersions.tsx b/rsconcept/frontend/src/dialogs/DlgEditVersions/DlgEditVersions.tsx index 2bf918ac..0bd81a3a 100644 --- a/rsconcept/frontend/src/dialogs/DlgEditVersions/DlgEditVersions.tsx +++ b/rsconcept/frontend/src/dialogs/DlgEditVersions/DlgEditVersions.tsx @@ -16,6 +16,7 @@ import { TextArea, TextInput } from '@/components/ui/Input'; import { ModalView } from '@/components/ui/Modal'; import { LibraryItemID, VersionID } from '@/models/library'; import { useDialogsStore } from '@/stores/dialogs'; +import { errors } from '@/utils/labels'; import TableVersions from './TableVersions'; @@ -37,14 +38,15 @@ function DlgEditVersions() { handleSubmit, control, reset, - formState: { isDirty } + formState: { isDirty, errors: formErrors } } = useForm({ resolver: zodResolver(VersionUpdateSchema), defaultValues: { id: schema.versions[0].id, version: schema.versions[0].version, description: schema.versions[0].description - } + }, + context: { schema: schema } }); const versionID = useWatch({ control, name: 'id' }); const versionName = useWatch({ control, name: 'version' }); @@ -92,11 +94,18 @@ function DlgEditVersions() { />
void handleSubmit(onUpdate)(event)}> - +
} /> diff --git a/rsconcept/frontend/src/dialogs/DlgRenameCst.tsx b/rsconcept/frontend/src/dialogs/DlgRenameCst.tsx index 87def155..4068cc3f 100644 --- a/rsconcept/frontend/src/dialogs/DlgRenameCst.tsx +++ b/rsconcept/frontend/src/dialogs/DlgRenameCst.tsx @@ -1,14 +1,15 @@ 'use client'; +import { zodResolver } from '@hookform/resolvers/zod'; import clsx from 'clsx'; -import { useEffect, useState } from 'react'; +import { useForm, useWatch } from 'react-hook-form'; -import { ICstRenameDTO } from '@/backend/rsform/api'; +import { CstRenameSchema, ICstRenameDTO } from '@/backend/rsform/api'; +import { useCstRename } from '@/backend/rsform/useCstRename'; import { SelectSingle, TextInput } from '@/components/ui/Input'; import { ModalForm } from '@/components/ui/Modal'; -import usePartialUpdate from '@/hooks/usePartialUpdate'; import { HelpTopic } from '@/models/miscellaneous'; -import { CstType, IRSForm } from '@/models/rsform'; +import { CstType, IConstituenta, IRSForm } from '@/models/rsform'; import { generateAlias, validateNewAlias } from '@/models/rsformAPI'; import { useDialogsStore } from '@/stores/dialogs'; import { labelCstType } from '@/utils/labels'; @@ -16,29 +17,35 @@ import { SelectorCstType } from '@/utils/selectors'; export interface DlgRenameCstProps { schema: IRSForm; - initial: ICstRenameDTO; - allowChangeType: boolean; - onRename: (data: ICstRenameDTO) => void; + target: IConstituenta; } function DlgRenameCst() { - const { schema, initial, allowChangeType, onRename } = useDialogsStore(state => state.props as DlgRenameCstProps); - const [validated, setValidated] = useState(false); - const [cstData, updateData] = usePartialUpdate(initial); + const { schema, target } = useDialogsStore(state => state.props as DlgRenameCstProps); + const { cstRename } = useCstRename(); - useEffect(() => { - if (initial && cstData.cst_type !== initial.cst_type) { - updateData({ alias: generateAlias(cstData.cst_type, schema) }); + const { register, setValue, handleSubmit, control } = useForm({ + resolver: zodResolver(CstRenameSchema), + defaultValues: { + target: target.id, + alias: target.alias, + cst_type: target.cst_type } - }, [initial, cstData.cst_type, updateData, schema]); + }); + const alias = useWatch({ control, name: 'alias' }); + const cst_type = useWatch({ control, name: 'cst_type' }); - useEffect(() => { - setValidated(cstData.alias !== initial.alias && validateNewAlias(cstData.alias, cstData.cst_type, schema)); - }, [cstData.cst_type, cstData.alias, initial, schema]); + // TODO: validate in ZOD + const validated = alias !== target.alias && validateNewAlias(alias, cst_type, schema); - function handleSubmit() { - onRename(cstData); - return true; + function onSubmit(data: ICstRenameDTO) { + console.log(data); + cstRename({ itemID: schema.id, data: data }); + } + + function handleChangeType(newType: CstType) { + setValue('alias', generateAlias(newType, schema)); + setValue('cst_type', newType); } return ( @@ -47,7 +54,7 @@ function DlgRenameCst() { submitText='Переименовать' submitInvalidTooltip='Введите незанятое имя, соответствующее типу' canSubmit={validated} - onSubmit={handleSubmit} + onSubmit={event => void handleSubmit(onSubmit)(event)} className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center ')} helpTopic={HelpTopic.CC_CONSTITUENTA} > @@ -55,22 +62,20 @@ function DlgRenameCst() { id='dlg_cst_type' placeholder='Выберите тип' className='min-w-[16rem]' - isDisabled={!allowChangeType} + isDisabled={target.is_inherited} options={SelectorCstType} value={{ - value: cstData.cst_type, - label: labelCstType(cstData.cst_type) + value: cst_type, + label: labelCstType(cst_type) }} - onChange={data => updateData({ cst_type: data?.value ?? CstType.BASE })} + onChange={data => handleChangeType(data?.value ?? CstType.BASE)} /> - updateData({ alias: event.target.value })} /> ); diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorControls.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorControls.tsx index f833e67c..f4c7e893 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorControls.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorControls.tsx @@ -1,7 +1,5 @@ import clsx from 'clsx'; -import { ICstRenameDTO } from '@/backend/rsform/api'; -import { useCstRename } from '@/backend/rsform/useCstRename'; import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm'; import { IconEdit } from '@/components/Icons'; import { Overlay } from '@/components/ui/Container'; @@ -16,7 +14,6 @@ import { useRSEdit } from '../RSEditContext'; interface EditorControlsProps { constituenta: IConstituenta; disabled: boolean; - onEditTerm: () => void; } @@ -26,20 +23,9 @@ function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsPr const isProcessing = useMutatingRSForm(); const showRenameCst = useDialogsStore(state => state.showRenameCst); - const { cstRename } = useCstRename(); function handleRenameCst() { - const initialData: ICstRenameDTO = { - target: constituenta.id, - alias: constituenta.alias, - cst_type: constituenta.cst_type - }; - showRenameCst({ - schema: schema, - initial: initialData, - allowChangeType: !constituenta.is_inherited, - onRename: data => cstRename({ itemID: schema.id, data }) - }); + showRenameCst({ schema: schema, target: constituenta }); } return (