mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
This commit is contained in:
parent
a44c1cd170
commit
ef209868bf
|
@ -94,11 +94,16 @@ export type ICstUpdateDTO = z.infer<typeof CstUpdateSchema>;
|
||||||
/**
|
/**
|
||||||
* Represents data, used in renaming {@link IConstituenta}.
|
* Represents data, used in renaming {@link IConstituenta}.
|
||||||
*/
|
*/
|
||||||
export interface ICstRenameDTO {
|
export const CstRenameSchema = z.object({
|
||||||
alias: string;
|
target: z.number(),
|
||||||
cst_type: CstType;
|
alias: z.string(),
|
||||||
target: ConstituentaID;
|
cst_type: z.nativeEnum(CstType)
|
||||||
}
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents data, used in renaming {@link IConstituenta}.
|
||||||
|
*/
|
||||||
|
export type ICstRenameDTO = z.infer<typeof CstRenameSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents data, used in ordering a list of {@link IConstituenta}.
|
* Represents data, used in ordering a list of {@link IConstituenta}.
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { Controller, useForm, useWatch } from 'react-hook-form';
|
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 { useVersionCreate } from '@/backend/library/useVersionCreate';
|
||||||
import { Checkbox, TextArea, TextInput } from '@/components/ui/Input';
|
import { Checkbox, TextArea, TextInput } from '@/components/ui/Input';
|
||||||
import { ModalForm } from '@/components/ui/Modal';
|
import { ModalForm } from '@/components/ui/Modal';
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { TextArea, TextInput } from '@/components/ui/Input';
|
||||||
import { ModalView } from '@/components/ui/Modal';
|
import { ModalView } from '@/components/ui/Modal';
|
||||||
import { LibraryItemID, VersionID } from '@/models/library';
|
import { LibraryItemID, VersionID } from '@/models/library';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
import { errors } from '@/utils/labels';
|
||||||
|
|
||||||
import TableVersions from './TableVersions';
|
import TableVersions from './TableVersions';
|
||||||
|
|
||||||
|
@ -37,14 +38,15 @@ function DlgEditVersions() {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
reset,
|
reset,
|
||||||
formState: { isDirty }
|
formState: { isDirty, errors: formErrors }
|
||||||
} = useForm<IVersionUpdateDTO>({
|
} = useForm<IVersionUpdateDTO>({
|
||||||
resolver: zodResolver(VersionUpdateSchema),
|
resolver: zodResolver(VersionUpdateSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
id: schema.versions[0].id,
|
id: schema.versions[0].id,
|
||||||
version: schema.versions[0].version,
|
version: schema.versions[0].version,
|
||||||
description: schema.versions[0].description
|
description: schema.versions[0].description
|
||||||
}
|
},
|
||||||
|
context: { schema: schema }
|
||||||
});
|
});
|
||||||
const versionID = useWatch({ control, name: 'id' });
|
const versionID = useWatch({ control, name: 'id' });
|
||||||
const versionName = useWatch({ control, name: 'version' });
|
const versionName = useWatch({ control, name: 'version' });
|
||||||
|
@ -92,11 +94,18 @@ function DlgEditVersions() {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<form className='flex' onSubmit={event => void handleSubmit(onUpdate)(event)}>
|
<form className='flex' onSubmit={event => void handleSubmit(onUpdate)(event)}>
|
||||||
<TextInput id='dlg_version' {...register('version')} dense label='Версия' className='w-[16rem] mr-3' />
|
<TextInput
|
||||||
|
id='dlg_version'
|
||||||
|
{...register('version')}
|
||||||
|
dense
|
||||||
|
label='Версия'
|
||||||
|
className='w-[16rem] mr-3'
|
||||||
|
error={formErrors.version}
|
||||||
|
/>
|
||||||
<div className='cc-icons'>
|
<div className='cc-icons'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
type='submit'
|
type='submit'
|
||||||
title='Сохранить изменения'
|
title={isValid ? 'Сохранить изменения' : errors.versionTaken}
|
||||||
disabled={!isDirty || !isValid || isProcessing}
|
disabled={!isDirty || !isValid || isProcessing}
|
||||||
icon={<IconSave size='1.25rem' className='icon-primary' />}
|
icon={<IconSave size='1.25rem' className='icon-primary' />}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import clsx from 'clsx';
|
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 { SelectSingle, TextInput } from '@/components/ui/Input';
|
||||||
import { ModalForm } from '@/components/ui/Modal';
|
import { ModalForm } from '@/components/ui/Modal';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
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 { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { labelCstType } from '@/utils/labels';
|
import { labelCstType } from '@/utils/labels';
|
||||||
|
@ -16,29 +17,35 @@ import { SelectorCstType } from '@/utils/selectors';
|
||||||
|
|
||||||
export interface DlgRenameCstProps {
|
export interface DlgRenameCstProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
initial: ICstRenameDTO;
|
target: IConstituenta;
|
||||||
allowChangeType: boolean;
|
|
||||||
onRename: (data: ICstRenameDTO) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgRenameCst() {
|
function DlgRenameCst() {
|
||||||
const { schema, initial, allowChangeType, onRename } = useDialogsStore(state => state.props as DlgRenameCstProps);
|
const { schema, target } = useDialogsStore(state => state.props as DlgRenameCstProps);
|
||||||
const [validated, setValidated] = useState(false);
|
const { cstRename } = useCstRename();
|
||||||
const [cstData, updateData] = usePartialUpdate(initial);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const { register, setValue, handleSubmit, control } = useForm<ICstRenameDTO>({
|
||||||
if (initial && cstData.cst_type !== initial.cst_type) {
|
resolver: zodResolver(CstRenameSchema),
|
||||||
updateData({ alias: generateAlias(cstData.cst_type, schema) });
|
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(() => {
|
// TODO: validate in ZOD
|
||||||
setValidated(cstData.alias !== initial.alias && validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
const validated = alias !== target.alias && validateNewAlias(alias, cst_type, schema);
|
||||||
}, [cstData.cst_type, cstData.alias, initial, schema]);
|
|
||||||
|
|
||||||
function handleSubmit() {
|
function onSubmit(data: ICstRenameDTO) {
|
||||||
onRename(cstData);
|
console.log(data);
|
||||||
return true;
|
cstRename({ itemID: schema.id, data: data });
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChangeType(newType: CstType) {
|
||||||
|
setValue('alias', generateAlias(newType, schema));
|
||||||
|
setValue('cst_type', newType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -47,7 +54,7 @@ function DlgRenameCst() {
|
||||||
submitText='Переименовать'
|
submitText='Переименовать'
|
||||||
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
||||||
canSubmit={validated}
|
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 ')}
|
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center ')}
|
||||||
helpTopic={HelpTopic.CC_CONSTITUENTA}
|
helpTopic={HelpTopic.CC_CONSTITUENTA}
|
||||||
>
|
>
|
||||||
|
@ -55,22 +62,20 @@ function DlgRenameCst() {
|
||||||
id='dlg_cst_type'
|
id='dlg_cst_type'
|
||||||
placeholder='Выберите тип'
|
placeholder='Выберите тип'
|
||||||
className='min-w-[16rem]'
|
className='min-w-[16rem]'
|
||||||
isDisabled={!allowChangeType}
|
isDisabled={target.is_inherited}
|
||||||
options={SelectorCstType}
|
options={SelectorCstType}
|
||||||
value={{
|
value={{
|
||||||
value: cstData.cst_type,
|
value: cst_type,
|
||||||
label: labelCstType(cstData.cst_type)
|
label: labelCstType(cst_type)
|
||||||
}}
|
}}
|
||||||
onChange={data => updateData({ cst_type: data?.value ?? CstType.BASE })}
|
onChange={data => handleChangeType(data?.value ?? CstType.BASE)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
id='dlg_cst_alias'
|
id='dlg_cst_alias' //
|
||||||
|
{...register('alias')}
|
||||||
dense
|
dense
|
||||||
label='Имя'
|
label='Имя'
|
||||||
className='w-[7rem]'
|
className='w-[7rem]'
|
||||||
value={cstData.alias}
|
|
||||||
onChange={event => updateData({ alias: event.target.value })}
|
|
||||||
/>
|
/>
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { ICstRenameDTO } from '@/backend/rsform/api';
|
|
||||||
import { useCstRename } from '@/backend/rsform/useCstRename';
|
|
||||||
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconEdit } from '@/components/Icons';
|
import { IconEdit } from '@/components/Icons';
|
||||||
import { Overlay } from '@/components/ui/Container';
|
import { Overlay } from '@/components/ui/Container';
|
||||||
|
@ -16,7 +14,6 @@ import { useRSEdit } from '../RSEditContext';
|
||||||
interface EditorControlsProps {
|
interface EditorControlsProps {
|
||||||
constituenta: IConstituenta;
|
constituenta: IConstituenta;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
|
||||||
onEditTerm: () => void;
|
onEditTerm: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,20 +23,9 @@ function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsPr
|
||||||
const isProcessing = useMutatingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const showRenameCst = useDialogsStore(state => state.showRenameCst);
|
const showRenameCst = useDialogsStore(state => state.showRenameCst);
|
||||||
const { cstRename } = useCstRename();
|
|
||||||
|
|
||||||
function handleRenameCst() {
|
function handleRenameCst() {
|
||||||
const initialData: ICstRenameDTO = {
|
showRenameCst({ schema: schema, target: constituenta });
|
||||||
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 })
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user