mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
R: Move dialogs to form basis
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
This commit is contained in:
parent
05422df430
commit
bb33c1f212
|
@ -30,7 +30,7 @@ export interface IRenameLocationDTO {
|
||||||
/**
|
/**
|
||||||
* Represents data, used for cloning {@link IRSForm}.
|
* Represents data, used for cloning {@link IRSForm}.
|
||||||
*/
|
*/
|
||||||
export interface IRCloneLibraryItemDTO extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'owner'> {
|
export interface ICloneLibraryItemDTO extends Omit<ILibraryItem, 'time_create' | 'time_update' | 'owner'> {
|
||||||
items?: ConstituentaID[];
|
items?: ConstituentaID[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +90,16 @@ export type IUpdateLibraryItemDTO = z.infer<typeof UpdateLibraryItemSchema>;
|
||||||
/**
|
/**
|
||||||
* Create version metadata in persistent storage.
|
* Create version metadata in persistent storage.
|
||||||
*/
|
*/
|
||||||
export interface IVersionCreateDTO {
|
export const CreateVersionSchema = z.object({
|
||||||
version: string;
|
version: z.string(),
|
||||||
description: string;
|
description: z.string(),
|
||||||
items?: ConstituentaID[];
|
items: z.array(z.number()).optional()
|
||||||
}
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create version metadata in persistent storage.
|
||||||
|
*/
|
||||||
|
export type IVersionCreateDTO = z.infer<typeof CreateVersionSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents data response when creating {@link IVersionInfo}.
|
* Represents data response when creating {@link IVersionInfo}.
|
||||||
|
@ -197,8 +202,8 @@ export const libraryApi = {
|
||||||
successMessage: information.itemDestroyed
|
successMessage: information.itemDestroyed
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
cloneItem: (data: IRCloneLibraryItemDTO) =>
|
cloneItem: (data: ICloneLibraryItemDTO) =>
|
||||||
axiosPost<IRCloneLibraryItemDTO, IRSFormDTO>({
|
axiosPost<ICloneLibraryItemDTO, IRSFormDTO>({
|
||||||
endpoint: `/api/library/${data.id}/clone`,
|
endpoint: `/api/library/${data.id}/clone`,
|
||||||
request: {
|
request: {
|
||||||
data: data,
|
data: data,
|
||||||
|
@ -214,8 +219,8 @@ export const libraryApi = {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
versionCreate: ({ itemID, data }: { itemID: LibraryItemID; data: IVersionData }) =>
|
versionCreate: ({ itemID, data }: { itemID: LibraryItemID; data: IVersionCreateDTO }) =>
|
||||||
axiosPost<IVersionData, IVersionCreatedResponse>({
|
axiosPost<IVersionCreateDTO, IVersionCreatedResponse>({
|
||||||
endpoint: `/api/library/${itemID}/create-version`,
|
endpoint: `/api/library/${itemID}/create-version`,
|
||||||
request: {
|
request: {
|
||||||
data: data,
|
data: data,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
|
|
||||||
import { IRSFormDTO } from '../rsform/api';
|
import { IRSFormDTO } from '../rsform/api';
|
||||||
import { IRCloneLibraryItemDTO, libraryApi } from './api';
|
import { ICloneLibraryItemDTO, libraryApi } from './api';
|
||||||
|
|
||||||
export const useCloneItem = () => {
|
export const useCloneItem = () => {
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
|
@ -14,7 +14,7 @@ export const useCloneItem = () => {
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
cloneItem: (
|
cloneItem: (
|
||||||
data: IRCloneLibraryItemDTO, //
|
data: ICloneLibraryItemDTO, //
|
||||||
onSuccess?: DataCallback<IRSFormDTO>
|
onSuccess?: DataCallback<IRSFormDTO>
|
||||||
) => mutation.mutate(data, { onSuccess })
|
) => mutation.mutate(data, { onSuccess })
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { IVersionData, LibraryItemID, VersionID } from '@/models/library';
|
import { LibraryItemID, VersionID } from '@/models/library';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { IVersionCreateDTO, libraryApi } from './api';
|
||||||
|
|
||||||
export const useVersionCreate = () => {
|
export const useVersionCreate = () => {
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
|
@ -22,7 +22,7 @@ export const useVersionCreate = () => {
|
||||||
versionCreate: (
|
versionCreate: (
|
||||||
data: {
|
data: {
|
||||||
itemID: LibraryItemID; //
|
itemID: LibraryItemID; //
|
||||||
data: IVersionData;
|
data: IVersionCreateDTO;
|
||||||
},
|
},
|
||||||
onSuccess?: DataCallback<VersionID>
|
onSuccess?: DataCallback<VersionID>
|
||||||
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.version) })
|
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.version) })
|
||||||
|
|
|
@ -33,11 +33,14 @@ export interface ModalProps extends CProps.Styling {
|
||||||
/** Indicates that the modal window should be scrollable. */
|
/** Indicates that the modal window should be scrollable. */
|
||||||
overflowVisible?: boolean;
|
overflowVisible?: boolean;
|
||||||
|
|
||||||
|
/** ID of the form to be submitted. */
|
||||||
|
formID?: string;
|
||||||
|
|
||||||
/** Callback to be called before submit. */
|
/** Callback to be called before submit. */
|
||||||
beforeSubmit?: () => boolean;
|
beforeSubmit?: () => boolean;
|
||||||
|
|
||||||
/** Callback to be called after submit. */
|
/** Callback to be called after submit. */
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => boolean;
|
||||||
|
|
||||||
/** Callback to be called after cancel. */
|
/** Callback to be called after cancel. */
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
@ -64,6 +67,7 @@ function Modal({
|
||||||
overflowVisible,
|
overflowVisible,
|
||||||
|
|
||||||
beforeSubmit,
|
beforeSubmit,
|
||||||
|
formID,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
className,
|
className,
|
||||||
|
@ -84,7 +88,15 @@ function Modal({
|
||||||
if (beforeSubmit && !beforeSubmit()) {
|
if (beforeSubmit && !beforeSubmit()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onSubmit?.();
|
if (onSubmit && !onSubmit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (formID) {
|
||||||
|
const element = document.getElementById(formID) as HTMLFormElement;
|
||||||
|
if (element) {
|
||||||
|
element.requestSubmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
hideDialog();
|
hideDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,18 @@ function DlgChangeInputSchema() {
|
||||||
setSelected(newValue);
|
setSelected(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
onSubmit(target.id, selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
overflowVisible
|
overflowVisible
|
||||||
header='Выбор концептуальной схемы'
|
header='Выбор концептуальной схемы'
|
||||||
submitText='Подтвердить выбор'
|
submitText='Подтвердить выбор'
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onSubmit(target.id, selected)}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column')}
|
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column')}
|
||||||
>
|
>
|
||||||
<div className='flex justify-between gap-3 items-center'>
|
<div className='flex justify-between gap-3 items-center'>
|
||||||
|
|
|
@ -33,6 +33,11 @@ function DlgChangeLocation() {
|
||||||
setBody(newValue.length > 3 ? newValue.substring(3) : '');
|
setBody(newValue.length > 3 ? newValue.substring(3) : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
onChangeLocation(location);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
overflowVisible
|
overflowVisible
|
||||||
|
@ -40,7 +45,7 @@ function DlgChangeLocation() {
|
||||||
submitText='Переместить'
|
submitText='Переместить'
|
||||||
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
|
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onChangeLocation(location)}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3 h-[9rem]')}
|
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3 h-[9rem]')}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-2 min-w-[7rem] h-min'>
|
<div className='flex flex-col gap-2 min-w-[7rem] h-min'>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useState } from 'react';
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
||||||
import { IRCloneLibraryItemDTO } from '@/backend/library/api';
|
import { ICloneLibraryItemDTO } from '@/backend/library/api';
|
||||||
import { useCloneItem } from '@/backend/library/useCloneItem';
|
import { useCloneItem } from '@/backend/library/useCloneItem';
|
||||||
import { VisibilityIcon } from '@/components/DomainIcons';
|
import { VisibilityIcon } from '@/components/DomainIcons';
|
||||||
import SelectAccessPolicy from '@/components/select/SelectAccessPolicy';
|
import SelectAccessPolicy from '@/components/select/SelectAccessPolicy';
|
||||||
|
@ -59,7 +59,7 @@ function DlgCloneLibraryItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
const data: IRCloneLibraryItemDTO = {
|
const data: ICloneLibraryItemDTO = {
|
||||||
id: base.id,
|
id: base.id,
|
||||||
item_type: base.item_type,
|
item_type: base.item_type,
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -74,6 +74,7 @@ function DlgCloneLibraryItem() {
|
||||||
data.items = selected;
|
data.items = selected;
|
||||||
}
|
}
|
||||||
cloneItem(data, newSchema => router.push(urls.schema(newSchema.id)));
|
cloneItem(data, newSchema => router.push(urls.schema(newSchema.id)));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -19,6 +19,7 @@ export interface DlgCreateCstProps {
|
||||||
|
|
||||||
function DlgCreateCst() {
|
function DlgCreateCst() {
|
||||||
const { initial, schema, onCreate } = useDialogsStore(state => state.props as DlgCreateCstProps);
|
const { initial, schema, onCreate } = useDialogsStore(state => state.props as DlgCreateCstProps);
|
||||||
|
|
||||||
const [validated, setValidated] = useState(false);
|
const [validated, setValidated] = useState(false);
|
||||||
const [cstData, updateCstData] = usePartialUpdate(
|
const [cstData, updateCstData] = usePartialUpdate(
|
||||||
initial || {
|
initial || {
|
||||||
|
@ -33,7 +34,10 @@ function DlgCreateCst() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = () => onCreate(cstData);
|
const handleSubmit = () => {
|
||||||
|
onCreate(cstData);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|
|
@ -82,6 +82,7 @@ function DlgCreateOperation() {
|
||||||
arguments: activeTab === TabID.INPUT ? undefined : inputs.length > 0 ? inputs : undefined,
|
arguments: activeTab === TabID.INPUT ? undefined : inputs.length > 0 ? inputs : undefined,
|
||||||
create_schema: createSchema
|
create_schema: createSchema
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleSelectTab(newTab: TabID, last: TabID) {
|
function handleSelectTab(newTab: TabID, last: TabID) {
|
||||||
|
|
|
@ -1,71 +1,78 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { Controller, useForm, useWatch } from 'react-hook-form';
|
||||||
|
|
||||||
import { IVersionCreateDTO } from '@/backend/library/api';
|
import { CreateVersionSchema, IVersionCreateDTO } from '@/backend/library/api';
|
||||||
|
import { useVersionCreate } from '@/backend/library/useVersionCreate';
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Modal from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import TextArea from '@/components/ui/TextArea';
|
import TextArea from '@/components/ui/TextArea';
|
||||||
import TextInput from '@/components/ui/TextInput';
|
import TextInput from '@/components/ui/TextInput';
|
||||||
import { IVersionInfo } from '@/models/library';
|
import { IVersionInfo, LibraryItemID, VersionID } from '@/models/library';
|
||||||
import { nextVersion } from '@/models/libraryAPI';
|
import { nextVersion } from '@/models/libraryAPI';
|
||||||
import { ConstituentaID } from '@/models/rsform';
|
import { ConstituentaID } from '@/models/rsform';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
export interface DlgCreateVersionProps {
|
export interface DlgCreateVersionProps {
|
||||||
|
itemID: LibraryItemID;
|
||||||
versions: IVersionInfo[];
|
versions: IVersionInfo[];
|
||||||
onCreate: (data: IVersionCreateDTO) => void;
|
onCreate: (newVersion: VersionID) => void;
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCreateVersion() {
|
function DlgCreateVersion() {
|
||||||
const { versions, selected, totalCount, onCreate } = useDialogsStore(state => state.props as DlgCreateVersionProps);
|
const {
|
||||||
const [version, setVersion] = useState(versions.length > 0 ? nextVersion(versions[0].version) : '1.0.0');
|
itemID, //
|
||||||
const [description, setDescription] = useState('');
|
versions,
|
||||||
const [onlySelected, setOnlySelected] = useState(false);
|
selected,
|
||||||
|
totalCount,
|
||||||
|
onCreate
|
||||||
|
} = useDialogsStore(state => state.props as DlgCreateVersionProps);
|
||||||
|
const { versionCreate } = useVersionCreate();
|
||||||
|
|
||||||
|
const { register, handleSubmit, control } = useForm<IVersionCreateDTO>({
|
||||||
|
resolver: zodResolver(CreateVersionSchema),
|
||||||
|
defaultValues: {
|
||||||
|
version: versions.length > 0 ? nextVersion(versions[0].version) : '1.0.0',
|
||||||
|
description: '',
|
||||||
|
items: undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const version = useWatch({ control, name: 'version' });
|
||||||
const canSubmit = !versions.find(ver => ver.version === version);
|
const canSubmit = !versions.find(ver => ver.version === version);
|
||||||
|
|
||||||
function handleSubmit() {
|
function onSubmit(data: IVersionCreateDTO) {
|
||||||
onCreate({
|
versionCreate({ itemID, data }, onCreate);
|
||||||
version: version,
|
|
||||||
description: description,
|
|
||||||
items: onlySelected ? selected : undefined
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal header='Создание версии' canSubmit={canSubmit} submitText='Создать' formID={globals.dlg_create_version}>
|
||||||
header='Создание версии'
|
<form
|
||||||
canSubmit={canSubmit}
|
id={globals.dlg_create_version}
|
||||||
onSubmit={handleSubmit}
|
className={clsx('cc-column', 'w-[30rem]', 'py-2 px-6')}
|
||||||
submitText='Создать'
|
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||||
className={clsx('cc-column', 'w-[30rem]', 'py-2 px-6')}
|
>
|
||||||
>
|
<TextInput id='dlg_version' {...register('version')} dense label='Версия' className='w-[16rem]' />
|
||||||
<TextInput
|
<TextArea id='dlg_description' {...register('description')} spellCheck label='Описание' rows={3} />
|
||||||
id='dlg_version'
|
{selected.length > 0 ? (
|
||||||
dense
|
<Controller
|
||||||
label='Версия'
|
control={control}
|
||||||
className='w-[16rem]'
|
name='items'
|
||||||
value={version}
|
render={({ field }) => (
|
||||||
onChange={event => setVersion(event.target.value)}
|
<Checkbox
|
||||||
/>
|
id='dlg_only_selected'
|
||||||
<TextArea
|
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
||||||
id='dlg_description'
|
value={field.value !== undefined}
|
||||||
spellCheck
|
onChange={value => field.onChange(value ? selected : undefined)}
|
||||||
label='Описание'
|
/>
|
||||||
rows={3}
|
)}
|
||||||
value={description}
|
/>
|
||||||
onChange={event => setDescription(event.target.value)}
|
) : null}
|
||||||
/>
|
</form>
|
||||||
<Checkbox
|
|
||||||
id='dlg_only_selected'
|
|
||||||
label={`Только выбранные конституенты [${selected.length} из ${totalCount}]`}
|
|
||||||
value={onlySelected}
|
|
||||||
onChange={value => setOnlySelected(value)}
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ function DlgCstTemplate() {
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
onCreate(constituenta);
|
onCreate(constituenta);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrompt(): boolean {
|
function handlePrompt(): boolean {
|
||||||
|
|
|
@ -19,7 +19,6 @@ export interface DlgDeleteCstProps {
|
||||||
|
|
||||||
function DlgDeleteCst() {
|
function DlgDeleteCst() {
|
||||||
const { selected, schema, onDelete } = useDialogsStore(state => state.props as DlgDeleteCstProps);
|
const { selected, schema, onDelete } = useDialogsStore(state => state.props as DlgDeleteCstProps);
|
||||||
const hideDialog = useDialogsStore(state => state.hideDialog);
|
|
||||||
const [expandOut, setExpandOut] = useState(false);
|
const [expandOut, setExpandOut] = useState(false);
|
||||||
const expansion: ConstituentaID[] = schema.graph.expandAllOutputs(selected);
|
const expansion: ConstituentaID[] = schema.graph.expandAllOutputs(selected);
|
||||||
const hasInherited = selected.some(
|
const hasInherited = selected.some(
|
||||||
|
@ -28,12 +27,12 @@ function DlgDeleteCst() {
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
hideDialog();
|
|
||||||
if (expandOut) {
|
if (expandOut) {
|
||||||
onDelete(selected.concat(expansion));
|
onDelete(selected.concat(expansion));
|
||||||
} else {
|
} else {
|
||||||
onDelete(selected);
|
onDelete(selected);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -22,6 +22,7 @@ function DlgDeleteOperation() {
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
onSubmit(target.id, keepConstituents, deleteSchema);
|
onSubmit(target.id, keepConstituents, deleteSchema);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -26,6 +26,7 @@ function DlgEditEditors() {
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
onChangeEditors(selected);
|
onChangeEditors(selected);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDeleteEditor(target: UserID) {
|
function onDeleteEditor(target: UserID) {
|
||||||
|
|
|
@ -119,6 +119,7 @@ function DlgEditOperation() {
|
||||||
arguments: target.operation_type !== OperationType.SYNTHESIS ? undefined : inputs,
|
arguments: target.operation_type !== OperationType.SYNTHESIS ? undefined : inputs,
|
||||||
substitutions: target.operation_type !== OperationType.SYNTHESIS ? undefined : substitutions
|
substitutions: target.operation_type !== OperationType.SYNTHESIS ? undefined : substitutions
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -40,12 +40,17 @@ function DlgEditReference() {
|
||||||
const [reference, setReference] = useState('');
|
const [reference, setReference] = useState('');
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
onSave(reference);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Редактирование ссылки'
|
header='Редактирование ссылки'
|
||||||
submitText='Сохранить ссылку'
|
submitText='Сохранить ссылку'
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onSave(reference)}
|
onSubmit={handleSubmit}
|
||||||
className='w-[40rem] px-6 h-[32rem]'
|
className='w-[40rem] px-6 h-[32rem]'
|
||||||
helpTopic={HelpTopic.TERM_CONTROL}
|
helpTopic={HelpTopic.TERM_CONTROL}
|
||||||
>
|
>
|
||||||
|
|
|
@ -63,6 +63,7 @@ function DlgEditWordForms() {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
onSave(result);
|
onSave(result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAddForm() {
|
function handleAddForm() {
|
||||||
|
|
|
@ -17,11 +17,16 @@ function DlgGraphParams() {
|
||||||
const { initial, onConfirm } = useDialogsStore(state => state.props as DlgGraphParamsProps);
|
const { initial, onConfirm } = useDialogsStore(state => state.props as DlgGraphParamsProps);
|
||||||
const [params, updateParams] = usePartialUpdate(initial);
|
const [params, updateParams] = usePartialUpdate(initial);
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
onConfirm(params);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
canSubmit
|
canSubmit
|
||||||
header='Настройки графа термов'
|
header='Настройки графа термов'
|
||||||
onSubmit={() => onConfirm(params)}
|
onSubmit={handleSubmit}
|
||||||
submitText='Применить'
|
submitText='Применить'
|
||||||
className='flex gap-6 justify-between px-6 pb-3 w-[30rem]'
|
className='flex gap-6 justify-between px-6 pb-3 w-[30rem]'
|
||||||
>
|
>
|
||||||
|
|
|
@ -43,7 +43,7 @@ function DlgInlineSynthesis() {
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
if (!sourceID || selected.length === 0) {
|
if (!sourceID || selected.length === 0) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
onInlineSynthesis({
|
onInlineSynthesis({
|
||||||
source: sourceID,
|
source: sourceID,
|
||||||
|
@ -51,6 +51,7 @@ function DlgInlineSynthesis() {
|
||||||
items: selected,
|
items: selected,
|
||||||
substitutions: substitutions
|
substitutions: substitutions
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -76,13 +76,13 @@ function DlgRelocateConstituents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
if (!destination) {
|
if (destination) {
|
||||||
return;
|
onSubmit({
|
||||||
|
destination: destination.id,
|
||||||
|
items: selected
|
||||||
|
});
|
||||||
}
|
}
|
||||||
onSubmit({
|
return true;
|
||||||
destination: destination.id,
|
|
||||||
items: selected
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -37,13 +37,18 @@ function DlgRenameCst() {
|
||||||
setValidated(cstData.alias !== initial.alias && validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
setValidated(cstData.alias !== initial.alias && validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
||||||
}, [cstData.cst_type, cstData.alias, initial, schema]);
|
}, [cstData.cst_type, cstData.alias, initial, schema]);
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
onRename(cstData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Переименование конституенты'
|
header='Переименование конституенты'
|
||||||
submitText='Переименовать'
|
submitText='Переименовать'
|
||||||
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
onSubmit={() => onRename(cstData)}
|
onSubmit={handleSubmit}
|
||||||
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}
|
||||||
>
|
>
|
||||||
|
|
|
@ -21,10 +21,8 @@ function DlgSubstituteCst() {
|
||||||
const canSubmit = substitutions.length > 0;
|
const canSubmit = substitutions.length > 0;
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
const data: ICstSubstitutions = {
|
onSubstitute({ substitutions: substitutions });
|
||||||
substitutions: substitutions
|
return true;
|
||||||
};
|
|
||||||
onSubstitute(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -21,15 +21,15 @@ function DlgUploadRSForm() {
|
||||||
const [file, setFile] = useState<File | undefined>();
|
const [file, setFile] = useState<File | undefined>();
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (!file) {
|
if (file) {
|
||||||
return;
|
upload({
|
||||||
|
itemID: itemID,
|
||||||
|
load_metadata: loadMetadata,
|
||||||
|
file: file,
|
||||||
|
fileName: file.name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
upload({
|
return true;
|
||||||
itemID: itemID,
|
|
||||||
load_metadata: loadMetadata,
|
|
||||||
file: file,
|
|
||||||
fileName: file.name
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFile = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFile = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
|
|
@ -57,7 +57,10 @@ export interface IVersionInfo {
|
||||||
/**
|
/**
|
||||||
* Represents version data, intended to update version metadata in persistent storage.
|
* Represents version data, intended to update version metadata in persistent storage.
|
||||||
*/
|
*/
|
||||||
export interface IVersionData extends Omit<IVersionInfo, 'id' | 'time_create' | 'item'> {}
|
export interface IVersionData {
|
||||||
|
version: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents library item common data typical for all item types.
|
* Represents library item common data typical for all item types.
|
||||||
|
|
|
@ -45,7 +45,7 @@ function EditorOssCard() {
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<FlexColumn className='px-3'>
|
<FlexColumn className='px-3'>
|
||||||
<FormOSS id={globals.library_item_editor} />
|
<FormOSS />
|
||||||
<EditorLibraryItem controller={controller} />
|
<EditorLibraryItem controller={controller} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
'use no memo'; // TODO: remove when react hook forms are compliant with react compiler
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
|
|
||||||
import { IUpdateLibraryItemDTO } from '@/backend/library/api';
|
import { IUpdateLibraryItemDTO, UpdateLibraryItemSchema } from '@/backend/library/api';
|
||||||
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
||||||
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import { IconSave } from '@/components/Icons';
|
import { IconSave } from '@/components/Icons';
|
||||||
|
@ -13,112 +16,85 @@ import TextInput from '@/components/ui/TextInput';
|
||||||
import { LibraryItemType } from '@/models/library';
|
import { LibraryItemType } from '@/models/library';
|
||||||
import ToolbarItemAccess from '@/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess';
|
import ToolbarItemAccess from '@/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
import { useOssEdit } from '../OssEditContext';
|
import { useOssEdit } from '../OssEditContext';
|
||||||
|
|
||||||
interface FormOSSProps {
|
function FormOSS() {
|
||||||
id?: string;
|
const { updateItem: updateOss } = useUpdateItem();
|
||||||
}
|
|
||||||
|
|
||||||
function FormOSS({ id }: FormOSSProps) {
|
|
||||||
const { updateItem: update } = useUpdateItem();
|
|
||||||
const controller = useOssEdit();
|
const controller = useOssEdit();
|
||||||
const { isModified, setIsModified } = useModificationStore();
|
const { isModified, setIsModified } = useModificationStore();
|
||||||
const isProcessing = useMutatingOss();
|
const isProcessing = useMutatingOss();
|
||||||
const schema = controller.schema;
|
|
||||||
|
|
||||||
const [title, setTitle] = useState(schema.title);
|
const {
|
||||||
const [alias, setAlias] = useState(schema.alias);
|
register,
|
||||||
const [comment, setComment] = useState(schema.comment);
|
handleSubmit,
|
||||||
const [visible, setVisible] = useState(schema.visible);
|
control,
|
||||||
const [readOnly, setReadOnly] = useState(schema.read_only);
|
setValue,
|
||||||
|
reset,
|
||||||
useEffect(() => {
|
formState: { isDirty, errors }
|
||||||
if (schema) {
|
} = useForm<IUpdateLibraryItemDTO>({
|
||||||
setTitle(schema.title);
|
resolver: zodResolver(UpdateLibraryItemSchema),
|
||||||
setAlias(schema.alias);
|
defaultValues: {
|
||||||
setComment(schema.comment);
|
id: controller.schema.id,
|
||||||
setVisible(schema.visible);
|
|
||||||
setReadOnly(schema.read_only);
|
|
||||||
}
|
|
||||||
}, [schema]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsModified(
|
|
||||||
schema.title !== title ||
|
|
||||||
schema.alias !== alias ||
|
|
||||||
schema.comment !== comment ||
|
|
||||||
schema.visible !== visible ||
|
|
||||||
schema.read_only !== readOnly
|
|
||||||
);
|
|
||||||
return () => setIsModified(false);
|
|
||||||
}, [
|
|
||||||
schema.title,
|
|
||||||
schema.alias,
|
|
||||||
schema.comment,
|
|
||||||
schema.visible,
|
|
||||||
schema.read_only,
|
|
||||||
title,
|
|
||||||
alias,
|
|
||||||
comment,
|
|
||||||
visible,
|
|
||||||
readOnly,
|
|
||||||
setIsModified
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleSubmit = (event?: React.FormEvent<HTMLFormElement>) => {
|
|
||||||
if (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
const data: IUpdateLibraryItemDTO = {
|
|
||||||
id: schema.id,
|
|
||||||
item_type: LibraryItemType.RSFORM,
|
item_type: LibraryItemType.RSFORM,
|
||||||
title: title,
|
title: controller.schema.title,
|
||||||
alias: alias,
|
alias: controller.schema.alias,
|
||||||
comment: comment,
|
comment: controller.schema.comment,
|
||||||
visible: visible,
|
visible: controller.schema.visible,
|
||||||
read_only: readOnly
|
read_only: controller.schema.read_only
|
||||||
};
|
}
|
||||||
update(data);
|
});
|
||||||
};
|
const visible = useWatch({ control, name: 'visible' });
|
||||||
|
const readOnly = useWatch({ control, name: 'read_only' });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsModified(isDirty);
|
||||||
|
}, [isDirty, setIsModified]);
|
||||||
|
|
||||||
|
function onSubmit(data: IUpdateLibraryItemDTO) {
|
||||||
|
updateOss(data, () => reset({ ...data }));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form id={id} className={clsx('mt-1 min-w-[22rem] sm:w-[30rem]', 'flex flex-col pt-1')} onSubmit={handleSubmit}>
|
<form
|
||||||
|
id={globals.library_item_editor}
|
||||||
|
className={clsx('mt-1 min-w-[22rem] sm:w-[30rem]', 'flex flex-col pt-1')}
|
||||||
|
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||||
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
id='schema_title'
|
id='schema_title'
|
||||||
required
|
{...register('title')}
|
||||||
label='Полное название'
|
label='Полное название'
|
||||||
className='mb-3'
|
className='mb-3'
|
||||||
value={title}
|
|
||||||
disabled={!controller.isMutable}
|
disabled={!controller.isMutable}
|
||||||
onChange={event => setTitle(event.target.value)}
|
error={errors.title}
|
||||||
/>
|
/>
|
||||||
<div className='flex justify-between gap-3 mb-3'>
|
<div className='flex justify-between gap-3 mb-3'>
|
||||||
<TextInput
|
<TextInput
|
||||||
id='schema_alias'
|
id='schema_alias'
|
||||||
required
|
{...register('alias')}
|
||||||
label='Сокращение'
|
label='Сокращение'
|
||||||
className='w-[16rem]'
|
className='w-[16rem]'
|
||||||
disabled={!controller.isMutable}
|
disabled={!controller.isMutable}
|
||||||
value={alias}
|
error={errors.alias}
|
||||||
onChange={event => setAlias(event.target.value)}
|
|
||||||
/>
|
/>
|
||||||
<ToolbarItemAccess
|
<ToolbarItemAccess
|
||||||
visible={visible}
|
visible={visible}
|
||||||
toggleVisible={() => setVisible(prev => !prev)}
|
toggleVisible={() => setValue('visible', !visible, { shouldDirty: true })}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
toggleReadOnly={() => setReadOnly(prev => !prev)}
|
toggleReadOnly={() => setValue('read_only', !readOnly, { shouldDirty: true })}
|
||||||
controller={controller}
|
controller={controller}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TextArea
|
<TextArea
|
||||||
id='schema_comment'
|
id='schema_comment'
|
||||||
|
{...register('comment')}
|
||||||
label='Описание'
|
label='Описание'
|
||||||
rows={3}
|
rows={3}
|
||||||
value={comment}
|
|
||||||
disabled={!controller.isMutable || isProcessing}
|
disabled={!controller.isMutable || isProcessing}
|
||||||
onChange={event => setComment(event.target.value)}
|
error={errors.comment}
|
||||||
/>
|
/>
|
||||||
{controller.isMutable || isModified ? (
|
{controller.isMutable || isModified ? (
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
|
|
|
@ -44,7 +44,7 @@ function EditorRSFormCard() {
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<FlexColumn className='flex-shrink'>
|
<FlexColumn className='flex-shrink'>
|
||||||
<FormRSForm id={globals.library_item_editor} />
|
<FormRSForm />
|
||||||
<EditorLibraryItem controller={controller} />
|
<EditorLibraryItem controller={controller} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,13 @@ import TextArea from '@/components/ui/TextArea';
|
||||||
import TextInput from '@/components/ui/TextInput';
|
import TextInput from '@/components/ui/TextInput';
|
||||||
import { LibraryItemType, VersionID } from '@/models/library';
|
import { LibraryItemType, VersionID } from '@/models/library';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
import { useRSEdit } from '../RSEditContext';
|
import { useRSEdit } from '../RSEditContext';
|
||||||
import ToolbarItemAccess from './ToolbarItemAccess';
|
import ToolbarItemAccess from './ToolbarItemAccess';
|
||||||
import ToolbarVersioning from './ToolbarVersioning';
|
import ToolbarVersioning from './ToolbarVersioning';
|
||||||
|
|
||||||
interface FormRSFormProps {
|
function FormRSForm() {
|
||||||
id?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function FormRSForm({ id }: FormRSFormProps) {
|
|
||||||
const controller = useRSEdit();
|
const controller = useRSEdit();
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const { updateItem: updateSchema } = useUpdateItem();
|
const { updateItem: updateSchema } = useUpdateItem();
|
||||||
|
@ -59,7 +56,7 @@ function FormRSForm({ id }: FormRSFormProps) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsModified(isDirty);
|
setIsModified(isDirty);
|
||||||
}, [isDirty, controller.schema, setIsModified]);
|
}, [isDirty, setIsModified]);
|
||||||
|
|
||||||
function handleSelectVersion(version?: VersionID) {
|
function handleSelectVersion(version?: VersionID) {
|
||||||
router.push(urls.schema(controller.schema.id, version));
|
router.push(urls.schema(controller.schema.id, version));
|
||||||
|
@ -71,7 +68,7 @@ function FormRSForm({ id }: FormRSFormProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
id={id}
|
id={globals.library_item_editor}
|
||||||
className={clsx('mt-1 min-w-[22rem] sm:w-[30rem]', 'flex flex-col pt-1')}
|
className={clsx('mt-1 min-w-[22rem] sm:w-[30rem]', 'flex flex-col pt-1')}
|
||||||
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useVersionCreate } from '@/backend/library/useVersionCreate';
|
|
||||||
import { useVersionRestore } from '@/backend/library/useVersionRestore';
|
import { useVersionRestore } from '@/backend/library/useVersionRestore';
|
||||||
import { IconNewVersion, IconUpload, IconVersions } from '@/components/Icons';
|
import { IconNewVersion, IconUpload, IconVersions } from '@/components/Icons';
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
|
@ -23,7 +22,6 @@ function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
|
||||||
const controller = useRSEdit();
|
const controller = useRSEdit();
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const { versionRestore } = useVersionRestore();
|
const { versionRestore } = useVersionRestore();
|
||||||
const { versionCreate } = useVersionCreate();
|
|
||||||
|
|
||||||
const showCreateVersion = useDialogsStore(state => state.showCreateVersion);
|
const showCreateVersion = useDialogsStore(state => state.showCreateVersion);
|
||||||
const showEditVersions = useDialogsStore(state => state.showEditVersions);
|
const showEditVersions = useDialogsStore(state => state.showEditVersions);
|
||||||
|
@ -40,17 +38,11 @@ function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showCreateVersion({
|
showCreateVersion({
|
||||||
|
itemID: controller.schema.id,
|
||||||
versions: controller.schema.versions,
|
versions: controller.schema.versions,
|
||||||
selected: controller.selected,
|
selected: controller.selected,
|
||||||
totalCount: controller.schema.items.length,
|
totalCount: controller.schema.items.length,
|
||||||
onCreate: data =>
|
onCreate: newVersion => controller.navigateVersion(newVersion)
|
||||||
versionCreate(
|
|
||||||
{
|
|
||||||
itemID: controller.schema.id, //
|
|
||||||
data: data
|
|
||||||
},
|
|
||||||
newVersion => controller.navigateVersion(newVersion)
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { useRequestPasswordReset } from '@/backend/auth/useRequestPasswordReset';
|
import { useRequestPasswordReset } from '@/backend/auth/useRequestPasswordReset';
|
||||||
import { ErrorData } from '@/components/info/InfoError';
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
|
@ -23,10 +23,6 @@ export function Component() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
clearServerError();
|
|
||||||
}, [email, clearServerError]);
|
|
||||||
|
|
||||||
if (isCompleted) {
|
if (isCompleted) {
|
||||||
return (
|
return (
|
||||||
<div className='cc-fade-in flex flex-col items-center gap-1 mt-3'>
|
<div className='cc-fade-in flex flex-col items-center gap-1 mt-3'>
|
||||||
|
@ -37,7 +33,11 @@ export function Component() {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<form className={clsx('cc-fade-in cc-column', 'w-[24rem] mx-auto', 'px-6 mt-3')} onSubmit={handleSubmit}>
|
<form
|
||||||
|
className={clsx('cc-fade-in cc-column', 'w-[24rem] mx-auto', 'px-6 mt-3')}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
onChange={clearServerError}
|
||||||
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
id='email'
|
id='email'
|
||||||
autoComplete='email'
|
autoComplete='email'
|
||||||
|
|
|
@ -114,7 +114,8 @@ export const globals = {
|
||||||
main_scroll: 'main_scroll',
|
main_scroll: 'main_scroll',
|
||||||
library_item_editor: 'library_item_editor',
|
library_item_editor: 'library_item_editor',
|
||||||
constituenta_editor: 'constituenta_editor',
|
constituenta_editor: 'constituenta_editor',
|
||||||
graph_schemas: 'graph_schemas_tooltip'
|
graph_schemas: 'graph_schemas_tooltip',
|
||||||
|
dlg_create_version: 'dlg_create_version'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user