mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
R: Refactor dialogs using zustand store
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
b260640ebf
commit
33ad3c6b95
|
@ -9,6 +9,7 @@ import { NavigationState } from '@/context/NavigationContext';
|
||||||
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
|
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
|
||||||
import { globals } from '@/utils/constants';
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
|
import { GlobalDialogs } from './GlobalDialogs';
|
||||||
import { GlobalTooltips } from './GlobalTooltips';
|
import { GlobalTooltips } from './GlobalTooltips';
|
||||||
|
|
||||||
function ApplicationLayout() {
|
function ApplicationLayout() {
|
||||||
|
@ -29,6 +30,7 @@ function ApplicationLayout() {
|
||||||
pauseOnFocusLoss={false}
|
pauseOnFocusLoss={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<GlobalDialogs />
|
||||||
<GlobalTooltips />
|
<GlobalTooltips />
|
||||||
|
|
||||||
<Navigation />
|
<Navigation />
|
||||||
|
|
83
rsconcept/frontend/src/app/GlobalDialogs.tsx
Normal file
83
rsconcept/frontend/src/app/GlobalDialogs.tsx
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import DlgChangeInputSchema from '@/dialogs/DlgChangeInputSchema';
|
||||||
|
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
|
||||||
|
import DlgCloneLibraryItem from '@/dialogs/DlgCloneLibraryItem';
|
||||||
|
import DlgCreateCst from '@/dialogs/DlgCreateCst';
|
||||||
|
import DlgCreateOperation from '@/dialogs/DlgCreateOperation';
|
||||||
|
import DlgCreateVersion from '@/dialogs/DlgCreateVersion';
|
||||||
|
import DlgCstTemplate from '@/dialogs/DlgCstTemplate';
|
||||||
|
import DlgDeleteCst from '@/dialogs/DlgDeleteCst';
|
||||||
|
import DlgDeleteOperation from '@/dialogs/DlgDeleteOperation';
|
||||||
|
import DlgEditEditors from '@/dialogs/DlgEditEditors';
|
||||||
|
import DlgEditOperation from '@/dialogs/DlgEditOperation';
|
||||||
|
import DlgEditReference from '@/dialogs/DlgEditReference';
|
||||||
|
import DlgEditVersions from '@/dialogs/DlgEditVersions';
|
||||||
|
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
||||||
|
import DlgGraphParams from '@/dialogs/DlgGraphParams';
|
||||||
|
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
||||||
|
import DlgRelocateConstituents from '@/dialogs/DlgRelocateConstituents';
|
||||||
|
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
||||||
|
import DlgShowAST from '@/dialogs/DlgShowAST';
|
||||||
|
import DlgShowQR from '@/dialogs/DlgShowQR';
|
||||||
|
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||||
|
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
||||||
|
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
||||||
|
import { DialogType } from '@/models/miscellaneous';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
|
export const GlobalDialogs = () => {
|
||||||
|
const active = useDialogsStore(state => state.active);
|
||||||
|
|
||||||
|
if (active === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (active) {
|
||||||
|
case DialogType.CONSTITUENTA_TEMPLATE:
|
||||||
|
return <DlgCstTemplate />;
|
||||||
|
case DialogType.CREATE_CONSTITUENTA:
|
||||||
|
return <DlgCreateCst />;
|
||||||
|
case DialogType.CREATE_OPERATION:
|
||||||
|
return <DlgCreateOperation />;
|
||||||
|
case DialogType.DELETE_CONSTITUENTA:
|
||||||
|
return <DlgDeleteCst />;
|
||||||
|
case DialogType.EDIT_EDITORS:
|
||||||
|
return <DlgEditEditors />;
|
||||||
|
case DialogType.EDIT_OPERATION:
|
||||||
|
return <DlgEditOperation />;
|
||||||
|
case DialogType.EDIT_REFERENCE:
|
||||||
|
return <DlgEditReference />;
|
||||||
|
case DialogType.EDIT_VERSIONS:
|
||||||
|
return <DlgEditVersions />;
|
||||||
|
case DialogType.EDIT_WORD_FORMS:
|
||||||
|
return <DlgEditWordForms />;
|
||||||
|
case DialogType.INLINE_SYNTHESIS:
|
||||||
|
return <DlgInlineSynthesis />;
|
||||||
|
case DialogType.SHOW_AST:
|
||||||
|
return <DlgShowAST />;
|
||||||
|
case DialogType.SHOW_TYPE_GRAPH:
|
||||||
|
return <DlgShowTypeGraph />;
|
||||||
|
case DialogType.CHANGE_INPUT_SCHEMA:
|
||||||
|
return <DlgChangeInputSchema />;
|
||||||
|
case DialogType.CHANGE_LOCATION:
|
||||||
|
return <DlgChangeLocation />;
|
||||||
|
case DialogType.CLONE_LIBRARY_ITEM:
|
||||||
|
return <DlgCloneLibraryItem />;
|
||||||
|
case DialogType.CREATE_VERSION:
|
||||||
|
return <DlgCreateVersion />;
|
||||||
|
case DialogType.DELETE_OPERATION:
|
||||||
|
return <DlgDeleteOperation />;
|
||||||
|
case DialogType.GRAPH_PARAMETERS:
|
||||||
|
return <DlgGraphParams />;
|
||||||
|
case DialogType.RELOCATE_CONSTITUENTS:
|
||||||
|
return <DlgRelocateConstituents />;
|
||||||
|
case DialogType.RENAME_CONSTITUENTA:
|
||||||
|
return <DlgRenameCst />;
|
||||||
|
case DialogType.SHOW_QR_CODE:
|
||||||
|
return <DlgShowQR />;
|
||||||
|
case DialogType.SUBSTITUTE_CONSTITUENTS:
|
||||||
|
return <DlgSubstituteCst />;
|
||||||
|
case DialogType.UPLOAD_RSFORM:
|
||||||
|
return <DlgUploadRSForm />;
|
||||||
|
}
|
||||||
|
};
|
|
@ -9,13 +9,13 @@ import { EditorView } from 'codemirror';
|
||||||
import { forwardRef, useRef, useState } from 'react';
|
import { forwardRef, useRef, useState } from 'react';
|
||||||
|
|
||||||
import Label from '@/components/ui/Label';
|
import Label from '@/components/ui/Label';
|
||||||
import DlgEditReference from '@/dialogs/DlgEditReference';
|
|
||||||
import { ReferenceType } from '@/models/language';
|
import { ReferenceType } from '@/models/language';
|
||||||
|
import { DialogType } from '@/models/miscellaneous';
|
||||||
import { ConstituentaID, IRSForm } from '@/models/rsform';
|
import { ConstituentaID, IRSForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { APP_COLORS } from '@/styling/color';
|
import { APP_COLORS } from '@/styling/color';
|
||||||
import { CodeMirrorWrapper } from '@/utils/codemirror';
|
import { CodeMirrorWrapper } from '@/utils/codemirror';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
|
||||||
|
|
||||||
import { refsNavigation } from './clickNavigation';
|
import { refsNavigation } from './clickNavigation';
|
||||||
import { NaturalLanguage, ReferenceTokens } from './parse';
|
import { NaturalLanguage, ReferenceTokens } from './parse';
|
||||||
|
@ -96,7 +96,10 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
|
||||||
|
|
||||||
const [isFocused, setIsFocused] = useState(false);
|
const [isFocused, setIsFocused] = useState(false);
|
||||||
|
|
||||||
const [showEditor, setShowEditor] = useState(false);
|
const showEditReference = useDialogsStore(state => state.showEditReference);
|
||||||
|
const activeDialog = useDialogsStore(state => state.active);
|
||||||
|
const isActive = activeDialog === DialogType.EDIT_REFERENCE;
|
||||||
|
|
||||||
const [currentType, setCurrentType] = useState<ReferenceType>(ReferenceType.ENTITY);
|
const [currentType, setCurrentType] = useState<ReferenceType>(ReferenceType.ENTITY);
|
||||||
const [refText, setRefText] = useState('');
|
const [refText, setRefText] = useState('');
|
||||||
const [hintText, setHintText] = useState('');
|
const [hintText, setHintText] = useState('');
|
||||||
|
@ -146,7 +149,7 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInput(event: React.KeyboardEvent<HTMLDivElement>) {
|
function handleInput(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||||
if (!thisRef.current?.view) {
|
if (!thisRef.current?.view || !schema) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return;
|
return;
|
||||||
|
@ -174,7 +177,17 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
|
||||||
setMainRefs(mainNodes.map(node => wrap.getText(node.from, node.to)));
|
setMainRefs(mainNodes.map(node => wrap.getText(node.from, node.to)));
|
||||||
setBasePosition(mainNodes.filter(node => node.to <= selection.from).length);
|
setBasePosition(mainNodes.filter(node => node.to <= selection.from).length);
|
||||||
|
|
||||||
setShowEditor(true);
|
showEditReference({
|
||||||
|
schema: schema,
|
||||||
|
initial: {
|
||||||
|
type: currentType,
|
||||||
|
refRaw: refText,
|
||||||
|
text: hintText,
|
||||||
|
basePosition: basePosition,
|
||||||
|
mainRefs: mainRefs
|
||||||
|
},
|
||||||
|
onSave: handleInputReference
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,27 +200,8 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
|
||||||
wrap.replaceWith(referenceText);
|
wrap.replaceWith(referenceText);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideEditReference() {
|
|
||||||
setShowEditor(false);
|
|
||||||
setTimeout(() => thisRef.current?.view?.focus(), PARAMETER.refreshTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx('flex flex-col gap-2', cursor)}>
|
<div className={clsx('flex flex-col gap-2', cursor)}>
|
||||||
{showEditor && schema ? (
|
|
||||||
<DlgEditReference
|
|
||||||
hideWindow={hideEditReference}
|
|
||||||
schema={schema}
|
|
||||||
initial={{
|
|
||||||
type: currentType,
|
|
||||||
refRaw: refText,
|
|
||||||
text: hintText,
|
|
||||||
basePosition: basePosition,
|
|
||||||
mainRefs: mainRefs
|
|
||||||
}}
|
|
||||||
onSave={handleInputReference}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<Label text={label} />
|
<Label text={label} />
|
||||||
<CodeMirror
|
<CodeMirror
|
||||||
id={id}
|
id={id}
|
||||||
|
@ -215,10 +209,10 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
|
||||||
basicSetup={editorSetup}
|
basicSetup={editorSetup}
|
||||||
theme={customTheme}
|
theme={customTheme}
|
||||||
extensions={editorExtensions}
|
extensions={editorExtensions}
|
||||||
value={isFocused ? value : value !== initialValue || showEditor ? value : resolved}
|
value={isFocused ? value : value !== initialValue || isActive ? value : resolved}
|
||||||
indentWithTab={false}
|
indentWithTab={false}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
editable={!disabled && !showEditor}
|
editable={!disabled && !isActive}
|
||||||
onKeyDown={handleInput}
|
onKeyDown={handleInput}
|
||||||
onFocus={handleFocusIn}
|
onFocus={handleFocusIn}
|
||||||
onBlur={handleFocusOut}
|
onBlur={handleFocusOut}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import useEscapeKey from '@/hooks/useEscapeKey';
|
import useEscapeKey from '@/hooks/useEscapeKey';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
import { prepareTooltip } from '@/utils/labels';
|
import { prepareTooltip } from '@/utils/labels';
|
||||||
|
|
||||||
|
@ -32,9 +33,6 @@ 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;
|
||||||
|
|
||||||
/** Callback to be called when the modal window is closed. */
|
|
||||||
hideWindow: () => void;
|
|
||||||
|
|
||||||
/** Callback to be called before submit. */
|
/** Callback to be called before submit. */
|
||||||
beforeSubmit?: () => boolean;
|
beforeSubmit?: () => boolean;
|
||||||
|
|
||||||
|
@ -65,7 +63,6 @@ function Modal({
|
||||||
canSubmit,
|
canSubmit,
|
||||||
overflowVisible,
|
overflowVisible,
|
||||||
|
|
||||||
hideWindow,
|
|
||||||
beforeSubmit,
|
beforeSubmit,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
|
@ -75,10 +72,11 @@ function Modal({
|
||||||
hideHelpWhen,
|
hideHelpWhen,
|
||||||
...restProps
|
...restProps
|
||||||
}: React.PropsWithChildren<ModalProps>) {
|
}: React.PropsWithChildren<ModalProps>) {
|
||||||
useEscapeKey(hideWindow);
|
const hideDialog = useDialogsStore(state => state.hideDialog);
|
||||||
|
useEscapeKey(hideDialog);
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
hideWindow();
|
hideDialog();
|
||||||
onCancel?.();
|
onCancel?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +85,7 @@ function Modal({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onSubmit?.();
|
onSubmit?.();
|
||||||
hideWindow();
|
hideDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -95,7 +93,7 @@ function Modal({
|
||||||
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
|
||||||
<div
|
<div
|
||||||
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
|
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
|
||||||
onClick={hideWindow}
|
onClick={hideDialog}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
|
|
@ -7,19 +7,21 @@ import { IconReset } from '@/components/Icons';
|
||||||
import PickSchema from '@/components/select/PickSchema';
|
import PickSchema from '@/components/select/PickSchema';
|
||||||
import Label from '@/components/ui/Label';
|
import Label from '@/components/ui/Label';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
|
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
|
||||||
import { IOperation, IOperationSchema } from '@/models/oss';
|
import { IOperation, IOperationSchema, OperationID } from '@/models/oss';
|
||||||
import { sortItemsForOSS } from '@/models/ossAPI';
|
import { sortItemsForOSS } from '@/models/ossAPI';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
interface DlgChangeInputSchemaProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgChangeInputSchemaProps {
|
||||||
oss: IOperationSchema;
|
oss: IOperationSchema;
|
||||||
target: IOperation;
|
target: IOperation;
|
||||||
onSubmit: (newSchema: LibraryItemID | undefined) => void;
|
onSubmit: (target: OperationID, newSchema: LibraryItemID | undefined) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgChangeInputSchema({ oss, hideWindow, target, onSubmit }: DlgChangeInputSchemaProps) {
|
function DlgChangeInputSchema() {
|
||||||
|
const { oss, target, onSubmit } = useDialogsStore(state => state.props as DlgChangeInputSchemaProps);
|
||||||
const [selected, setSelected] = useState<LibraryItemID | undefined>(target.result ?? undefined);
|
const [selected, setSelected] = useState<LibraryItemID | undefined>(target.result ?? undefined);
|
||||||
const library = useLibrary();
|
const library = useLibrary();
|
||||||
const sortedItems = sortItemsForOSS(oss, library.items);
|
const sortedItems = sortItemsForOSS(oss, library.items);
|
||||||
|
@ -38,9 +40,8 @@ function DlgChangeInputSchema({ oss, hideWindow, target, onSubmit }: DlgChangeIn
|
||||||
overflowVisible
|
overflowVisible
|
||||||
header='Выбор концептуальной схемы'
|
header='Выбор концептуальной схемы'
|
||||||
submitText='Подтвердить выбор'
|
submitText='Подтвердить выбор'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onSubmit(selected)}
|
onSubmit={() => onSubmit(target.id, selected)}
|
||||||
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'>
|
||||||
|
|
|
@ -6,20 +6,22 @@ import { useState } from 'react';
|
||||||
import SelectLocationContext from '@/components/select/SelectLocationContext';
|
import SelectLocationContext from '@/components/select/SelectLocationContext';
|
||||||
import SelectLocationHead from '@/components/select/SelectLocationHead';
|
import SelectLocationHead from '@/components/select/SelectLocationHead';
|
||||||
import Label from '@/components/ui/Label';
|
import Label from '@/components/ui/Label';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import TextArea from '@/components/ui/TextArea';
|
import TextArea from '@/components/ui/TextArea';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import { LocationHead } from '@/models/library';
|
import { LocationHead } from '@/models/library';
|
||||||
import { combineLocation, validateLocation } from '@/models/libraryAPI';
|
import { combineLocation, validateLocation } from '@/models/libraryAPI';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { limits } from '@/utils/constants';
|
import { limits } from '@/utils/constants';
|
||||||
|
|
||||||
interface DlgChangeLocationProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgChangeLocationProps {
|
||||||
initial: string;
|
initial: string;
|
||||||
onChangeLocation: (newLocation: string) => void;
|
onChangeLocation: (newLocation: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgChangeLocation({ hideWindow, initial, onChangeLocation }: DlgChangeLocationProps) {
|
function DlgChangeLocation() {
|
||||||
|
const { initial, onChangeLocation } = useDialogsStore(state => state.props as DlgChangeLocationProps);
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [head, setHead] = useState<LocationHead>(initial.substring(0, 2) as LocationHead);
|
const [head, setHead] = useState<LocationHead>(initial.substring(0, 2) as LocationHead);
|
||||||
const [body, setBody] = useState<string>(initial.substring(3));
|
const [body, setBody] = useState<string>(initial.substring(3));
|
||||||
|
@ -40,7 +42,6 @@ function DlgChangeLocation({ hideWindow, initial, onChangeLocation }: DlgChangeL
|
||||||
header='Изменение расположения'
|
header='Изменение расположения'
|
||||||
submitText='Переместить'
|
submitText='Переместить'
|
||||||
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
|
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onChangeLocation(location)}
|
onSubmit={() => onChangeLocation(location)}
|
||||||
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]')}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SelectLocationHead from '@/components/select/SelectLocationHead';
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Label from '@/components/ui/Label';
|
import Label from '@/components/ui/Label';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Modal, { ModalProps } 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 { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
|
@ -21,18 +21,23 @@ import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { AccessPolicy, ILibraryItem, LocationHead } from '@/models/library';
|
import { AccessPolicy, ILibraryItem, LocationHead } from '@/models/library';
|
||||||
import { cloneTitle, combineLocation, validateLocation } from '@/models/libraryAPI';
|
import { cloneTitle, combineLocation, validateLocation } from '@/models/libraryAPI';
|
||||||
import { ConstituentaID, IRSFormCloneData } from '@/models/rsform';
|
import { ConstituentaID, IRSFormCloneData } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { information } from '@/utils/labels';
|
import { information } from '@/utils/labels';
|
||||||
|
|
||||||
interface DlgCloneLibraryItemProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgCloneLibraryItemProps {
|
||||||
base: ILibraryItem;
|
base: ILibraryItem;
|
||||||
initialLocation: string;
|
initialLocation: string;
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCloneLibraryItem({ hideWindow, base, initialLocation, selected, totalCount }: DlgCloneLibraryItemProps) {
|
function DlgCloneLibraryItem() {
|
||||||
|
const { base, initialLocation, selected, totalCount } = useDialogsStore(
|
||||||
|
state => state.props as DlgCloneLibraryItemProps
|
||||||
|
);
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const [title, setTitle] = useState(cloneTitle(base));
|
const [title, setTitle] = useState(cloneTitle(base));
|
||||||
const [alias, setAlias] = useState(base.alias);
|
const [alias, setAlias] = useState(base.alias);
|
||||||
const [comment, setComment] = useState(base.comment);
|
const [comment, setComment] = useState(base.comment);
|
||||||
|
@ -77,7 +82,6 @@ function DlgCloneLibraryItem({ hideWindow, base, initialLocation, selected, tota
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Создание копии концептуальной схемы'
|
header='Создание копии концептуальной схемы'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={canSubmit}
|
canSubmit={canSubmit}
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
export { default } from './DlgConstituentaTemplate';
|
|
|
@ -2,20 +2,22 @@
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||||
import { generateAlias } from '@/models/rsformAPI';
|
import { generateAlias } from '@/models/rsformAPI';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import FormCreateCst from './FormCreateCst';
|
import FormCreateCst from './FormCreateCst';
|
||||||
|
|
||||||
interface DlgCreateCstProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgCreateCstProps {
|
||||||
initial?: ICstCreateData;
|
initial?: ICstCreateData;
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
onCreate: (data: ICstCreateData) => void;
|
onCreate: (data: ICstCreateData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) {
|
function DlgCreateCst() {
|
||||||
|
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 || {
|
||||||
|
@ -35,7 +37,6 @@ function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstPro
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Создание конституенты'
|
header='Создание конституенты'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
|
|
|
@ -10,13 +10,13 @@ import { useLibrary } from '@/context/LibraryContext';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { IOperationCreateData, IOperationSchema, OperationID, OperationType } from '@/models/oss';
|
import { IOperationCreateData, IOperationSchema, OperationID, OperationType } from '@/models/oss';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { describeOperationType, labelOperationType } from '@/utils/labels';
|
import { describeOperationType, labelOperationType } from '@/utils/labels';
|
||||||
|
|
||||||
import TabInputOperation from './TabInputOperation';
|
import TabInputOperation from './TabInputOperation';
|
||||||
import TabSynthesisOperation from './TabSynthesisOperation';
|
import TabSynthesisOperation from './TabSynthesisOperation';
|
||||||
|
|
||||||
interface DlgCreateOperationProps {
|
export interface DlgCreateOperationProps {
|
||||||
hideWindow: () => void;
|
|
||||||
oss: IOperationSchema;
|
oss: IOperationSchema;
|
||||||
onCreate: (data: IOperationCreateData) => void;
|
onCreate: (data: IOperationCreateData) => void;
|
||||||
initialInputs: OperationID[];
|
initialInputs: OperationID[];
|
||||||
|
@ -27,7 +27,8 @@ export enum TabID {
|
||||||
SYNTHESIS = 1
|
SYNTHESIS = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCreateOperation({ hideWindow, oss, onCreate, initialInputs }: DlgCreateOperationProps) {
|
function DlgCreateOperation() {
|
||||||
|
const { oss, onCreate, initialInputs } = useDialogsStore(state => state.props as DlgCreateOperationProps);
|
||||||
const library = useLibrary();
|
const library = useLibrary();
|
||||||
const [activeTab, setActiveTab] = useState(initialInputs.length > 0 ? TabID.SYNTHESIS : TabID.INPUT);
|
const [activeTab, setActiveTab] = useState(initialInputs.length > 0 ? TabID.SYNTHESIS : TabID.INPUT);
|
||||||
|
|
||||||
|
@ -98,7 +99,6 @@ function DlgCreateOperation({ hideWindow, oss, onCreate, initialInputs }: DlgCre
|
||||||
<Modal
|
<Modal
|
||||||
header='Создание операции'
|
header='Создание операции'
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className='w-[40rem] px-6 h-[32rem]'
|
className='w-[40rem] px-6 h-[32rem]'
|
||||||
|
|
|
@ -4,21 +4,23 @@ import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Modal, { ModalProps } 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 { IVersionCreateData, IVersionInfo } from '@/models/library';
|
import { IVersionCreateData, IVersionInfo } 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';
|
||||||
|
|
||||||
interface DlgCreateVersionProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgCreateVersionProps {
|
||||||
versions: IVersionInfo[];
|
versions: IVersionInfo[];
|
||||||
onCreate: (data: IVersionCreateData) => void;
|
onCreate: (data: IVersionCreateData) => void;
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCreateVersion({ hideWindow, versions, selected, totalCount, onCreate }: DlgCreateVersionProps) {
|
function DlgCreateVersion() {
|
||||||
|
const { versions, selected, totalCount, onCreate } = useDialogsStore(state => state.props as DlgCreateVersionProps);
|
||||||
const [version, setVersion] = useState(versions.length > 0 ? nextVersion(versions[0].version) : '1.0.0');
|
const [version, setVersion] = useState(versions.length > 0 ? nextVersion(versions[0].version) : '1.0.0');
|
||||||
const [description, setDescription] = useState('');
|
const [description, setDescription] = useState('');
|
||||||
const [onlySelected, setOnlySelected] = useState(false);
|
const [onlySelected, setOnlySelected] = useState(false);
|
||||||
|
@ -39,7 +41,6 @@ function DlgCreateVersion({ hideWindow, versions, selected, totalCount, onCreate
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Создание версии'
|
header='Создание версии'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={canSubmit}
|
canSubmit={canSubmit}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
|
|
|
@ -4,7 +4,7 @@ import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import TabLabel from '@/components/ui/TabLabel';
|
import TabLabel from '@/components/ui/TabLabel';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
|
@ -12,13 +12,14 @@ import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||||
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { prompts } from '@/utils/labels';
|
import { prompts } from '@/utils/labels';
|
||||||
|
|
||||||
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
||||||
import TabArguments, { IArgumentsState } from './TabArguments';
|
import TabArguments, { IArgumentsState } from './TabArguments';
|
||||||
import TabTemplate, { ITemplateState } from './TabTemplate';
|
import TabTemplate, { ITemplateState } from './TabTemplate';
|
||||||
|
|
||||||
interface DlgConstituentaTemplateProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgCstTemplateProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
onCreate: (data: ICstCreateData) => void;
|
onCreate: (data: ICstCreateData) => void;
|
||||||
insertAfter?: number;
|
insertAfter?: number;
|
||||||
|
@ -30,7 +31,8 @@ export enum TabID {
|
||||||
CONSTITUENTA = 2
|
CONSTITUENTA = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }: DlgConstituentaTemplateProps) {
|
function DlgCstTemplate() {
|
||||||
|
const { schema, onCreate, insertAfter } = useDialogsStore(state => state.props as DlgCstTemplateProps);
|
||||||
const { retrieveTemplate } = useLibrary();
|
const { retrieveTemplate } = useLibrary();
|
||||||
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
|
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
|
||||||
|
|
||||||
|
@ -128,7 +130,6 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
|
||||||
header='Создание конституенты из шаблона'
|
header='Создание конституенты из шаблона'
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
className='w-[43rem] h-[35rem] px-6'
|
className='w-[43rem] h-[35rem] px-6'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
beforeSubmit={handlePrompt}
|
beforeSubmit={handlePrompt}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
@ -164,4 +165,4 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DlgConstituentaTemplate;
|
export default DlgCstTemplate;
|
1
rsconcept/frontend/src/dialogs/DlgCstTemplate/index.tsx
Normal file
1
rsconcept/frontend/src/dialogs/DlgCstTemplate/index.tsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './DlgCstTemplate';
|
|
@ -4,19 +4,22 @@ import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { ConstituentaID, IRSForm } from '@/models/rsform';
|
import { ConstituentaID, IRSForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
import ListConstituents from './ListConstituents';
|
import ListConstituents from './ListConstituents';
|
||||||
|
|
||||||
interface DlgDeleteCstProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgDeleteCstProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
onDelete: (items: ConstituentaID[]) => void;
|
onDelete: (items: ConstituentaID[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstProps) {
|
function DlgDeleteCst() {
|
||||||
|
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(
|
||||||
|
@ -25,7 +28,7 @@ function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstPr
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
hideWindow();
|
hideDialog();
|
||||||
if (expandOut) {
|
if (expandOut) {
|
||||||
onDelete(selected.concat(expansion));
|
onDelete(selected.concat(expansion));
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +41,6 @@ function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstPr
|
||||||
canSubmit
|
canSubmit
|
||||||
header='Удаление конституент'
|
header='Удаление конституент'
|
||||||
submitText={expandOut ? 'Удалить с зависимыми' : 'Удалить'}
|
submitText={expandOut ? 'Удалить с зависимыми' : 'Удалить'}
|
||||||
hideWindow={hideWindow}
|
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('cc-column', 'max-w-[60vw] min-w-[30rem]', 'px-6')}
|
className={clsx('cc-column', 'max-w-[60vw] min-w-[30rem]', 'px-6')}
|
||||||
>
|
>
|
||||||
|
|
|
@ -4,22 +4,24 @@ import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import TextInput from '@/components/ui/TextInput';
|
import TextInput from '@/components/ui/TextInput';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { IOperation } from '@/models/oss';
|
import { IOperation, OperationID } from '@/models/oss';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
interface DlgDeleteOperationProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgDeleteOperationProps {
|
||||||
target: IOperation;
|
target: IOperation;
|
||||||
onSubmit: (keepConstituents: boolean, deleteSchema: boolean) => void;
|
onSubmit: (targetID: OperationID, keepConstituents: boolean, deleteSchema: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgDeleteOperation({ hideWindow, target, onSubmit }: DlgDeleteOperationProps) {
|
function DlgDeleteOperation() {
|
||||||
|
const { target, onSubmit } = useDialogsStore(state => state.props as DlgDeleteOperationProps);
|
||||||
const [keepConstituents, setKeepConstituents] = useState(false);
|
const [keepConstituents, setKeepConstituents] = useState(false);
|
||||||
const [deleteSchema, setDeleteSchema] = useState(false);
|
const [deleteSchema, setDeleteSchema] = useState(false);
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
onSubmit(keepConstituents, deleteSchema);
|
onSubmit(target.id, keepConstituents, deleteSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -27,7 +29,6 @@ function DlgDeleteOperation({ hideWindow, target, onSubmit }: DlgDeleteOperation
|
||||||
overflowVisible
|
overflowVisible
|
||||||
header='Удаление операции'
|
header='Удаление операции'
|
||||||
submitText='Подтвердить удаление'
|
submitText='Подтвердить удаление'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={true}
|
canSubmit={true}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column', 'select-none')}
|
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column', 'select-none')}
|
||||||
|
|
|
@ -10,16 +10,17 @@ import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Modal from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { useUsers } from '@/context/UsersContext';
|
import { useUsers } from '@/context/UsersContext';
|
||||||
import { UserID } from '@/models/user';
|
import { UserID } from '@/models/user';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import TableUsers from './TableUsers';
|
import TableUsers from './TableUsers';
|
||||||
|
|
||||||
interface DlgEditEditorsProps {
|
export interface DlgEditEditorsProps {
|
||||||
editors: UserID[];
|
editors: UserID[];
|
||||||
setEditors: (newValue: UserID[]) => void;
|
setEditors: (newValue: UserID[]) => void;
|
||||||
hideWindow: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgEditEditors({ hideWindow, editors, setEditors }: DlgEditEditorsProps) {
|
function DlgEditEditors() {
|
||||||
|
const { editors, setEditors } = useDialogsStore(state => state.props as DlgEditEditorsProps);
|
||||||
const [selected, setSelected] = useState<UserID[]>(editors);
|
const [selected, setSelected] = useState<UserID[]>(editors);
|
||||||
const { users } = useUsers();
|
const { users } = useUsers();
|
||||||
const filtered = users.filter(user => !selected.includes(user.id));
|
const filtered = users.filter(user => !selected.includes(user.id));
|
||||||
|
@ -41,7 +42,6 @@ function DlgEditEditors({ hideWindow, editors, setEditors }: DlgEditEditorsProps
|
||||||
canSubmit
|
canSubmit
|
||||||
header='Список редакторов'
|
header='Список редакторов'
|
||||||
submitText='Сохранить список'
|
submitText='Сохранить список'
|
||||||
hideWindow={hideWindow}
|
|
||||||
className='flex flex-col w-[35rem] px-6 gap-3 pb-6'
|
className='flex flex-col w-[35rem] px-6 gap-3 pb-6'
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
|
|
@ -19,13 +19,13 @@ import {
|
||||||
} from '@/models/oss';
|
} from '@/models/oss';
|
||||||
import { SubstitutionValidator } from '@/models/ossAPI';
|
import { SubstitutionValidator } from '@/models/ossAPI';
|
||||||
import { ConstituentaID } from '@/models/rsform';
|
import { ConstituentaID } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import TabArguments from './TabArguments';
|
import TabArguments from './TabArguments';
|
||||||
import TabOperation from './TabOperation';
|
import TabOperation from './TabOperation';
|
||||||
import TabSynthesis from './TabSynthesis';
|
import TabSynthesis from './TabSynthesis';
|
||||||
|
|
||||||
interface DlgEditOperationProps {
|
export interface DlgEditOperationProps {
|
||||||
hideWindow: () => void;
|
|
||||||
oss: IOperationSchema;
|
oss: IOperationSchema;
|
||||||
target: IOperation;
|
target: IOperation;
|
||||||
onSubmit: (data: IOperationUpdateData) => void;
|
onSubmit: (data: IOperationUpdateData) => void;
|
||||||
|
@ -37,7 +37,8 @@ export enum TabID {
|
||||||
SUBSTITUTION = 2
|
SUBSTITUTION = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperationProps) {
|
function DlgEditOperation() {
|
||||||
|
const { oss, target, onSubmit } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||||
const [activeTab, setActiveTab] = useState(TabID.CARD);
|
const [activeTab, setActiveTab] = useState(TabID.CARD);
|
||||||
|
|
||||||
const [alias, setAlias] = useState(target.alias);
|
const [alias, setAlias] = useState(target.alias);
|
||||||
|
@ -142,7 +143,6 @@ function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperatio
|
||||||
<Modal
|
<Modal
|
||||||
header='Редактирование операции'
|
header='Редактирование операции'
|
||||||
submitText='Сохранить'
|
submitText='Сохранить'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={canSubmit}
|
canSubmit={canSubmit}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className='w-[40rem] px-6 h-[32rem]'
|
className='w-[40rem] px-6 h-[32rem]'
|
||||||
|
|
|
@ -9,6 +9,7 @@ import TabLabel from '@/components/ui/TabLabel';
|
||||||
import { ReferenceType } from '@/models/language';
|
import { ReferenceType } from '@/models/language';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { IRSForm } from '@/models/rsform';
|
import { IRSForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { labelReferenceType } from '@/utils/labels';
|
import { labelReferenceType } from '@/utils/labels';
|
||||||
|
|
||||||
import TabEntityReference from './TabEntityReference';
|
import TabEntityReference from './TabEntityReference';
|
||||||
|
@ -22,8 +23,7 @@ export interface IReferenceInputState {
|
||||||
basePosition: number;
|
basePosition: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DlgEditReferenceProps {
|
export interface DlgEditReferenceProps {
|
||||||
hideWindow: () => void;
|
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
initial: IReferenceInputState;
|
initial: IReferenceInputState;
|
||||||
onSave: (newRef: string) => void;
|
onSave: (newRef: string) => void;
|
||||||
|
@ -34,7 +34,8 @@ export enum TabID {
|
||||||
SYNTACTIC = 1
|
SYNTACTIC = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgEditReference({ hideWindow, schema, initial, onSave }: DlgEditReferenceProps) {
|
function DlgEditReference() {
|
||||||
|
const { schema, initial, onSave } = useDialogsStore(state => state.props as DlgEditReferenceProps);
|
||||||
const [activeTab, setActiveTab] = useState(initial.type === ReferenceType.ENTITY ? TabID.ENTITY : TabID.SYNTACTIC);
|
const [activeTab, setActiveTab] = useState(initial.type === ReferenceType.ENTITY ? TabID.ENTITY : TabID.SYNTACTIC);
|
||||||
const [reference, setReference] = useState('');
|
const [reference, setReference] = useState('');
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
|
@ -43,7 +44,6 @@ function DlgEditReference({ hideWindow, schema, initial, onSave }: DlgEditRefere
|
||||||
<Modal
|
<Modal
|
||||||
header='Редактирование ссылки'
|
header='Редактирование ссылки'
|
||||||
submitText='Сохранить ссылку'
|
submitText='Сохранить ссылку'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={() => onSave(reference)}
|
onSubmit={() => onSave(reference)}
|
||||||
className='w-[40rem] px-6 h-[32rem]'
|
className='w-[40rem] px-6 h-[32rem]'
|
||||||
|
|
|
@ -7,21 +7,21 @@ import MiniButton from '@/components/ui/MiniButton';
|
||||||
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 { useRSForm } from '@/context/RSFormContext';
|
|
||||||
import { IVersionData, IVersionInfo, VersionID } from '@/models/library';
|
import { IVersionData, IVersionInfo, VersionID } from '@/models/library';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import TableVersions from './TableVersions';
|
import TableVersions from './TableVersions';
|
||||||
|
|
||||||
interface DlgEditVersionsProps {
|
export interface DlgEditVersionsProps {
|
||||||
hideWindow: () => void;
|
|
||||||
versions: IVersionInfo[];
|
versions: IVersionInfo[];
|
||||||
onDelete: (versionID: VersionID) => void;
|
onDelete: (versionID: VersionID) => void;
|
||||||
onUpdate: (versionID: VersionID, data: IVersionData) => void;
|
onUpdate: (versionID: VersionID, data: IVersionData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgEditVersions({ hideWindow, versions, onDelete, onUpdate }: DlgEditVersionsProps) {
|
function DlgEditVersions() {
|
||||||
const { processing } = useRSForm();
|
const { versions, onDelete, onUpdate } = useDialogsStore(state => state.props as DlgEditVersionsProps);
|
||||||
const [selected, setSelected] = useState<IVersionInfo | undefined>(undefined);
|
const [selected, setSelected] = useState<IVersionInfo | undefined>(undefined);
|
||||||
|
const processing = false; // TODO: fix processing hook and versions update
|
||||||
|
|
||||||
const [version, setVersion] = useState('');
|
const [version, setVersion] = useState('');
|
||||||
const [description, setDescription] = useState('');
|
const [description, setDescription] = useState('');
|
||||||
|
@ -54,12 +54,7 @@ function DlgEditVersions({ hideWindow, versions, onDelete, onUpdate }: DlgEditVe
|
||||||
}, [selected]);
|
}, [selected]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal readonly header='Редактирование версий' className='flex flex-col w-[40rem] px-6 gap-3 pb-6'>
|
||||||
readonly
|
|
||||||
header='Редактирование версий'
|
|
||||||
hideWindow={hideWindow}
|
|
||||||
className='flex flex-col w-[40rem] px-6 gap-3 pb-6'
|
|
||||||
>
|
|
||||||
<TableVersions
|
<TableVersions
|
||||||
processing={processing}
|
processing={processing}
|
||||||
items={versions}
|
items={versions}
|
||||||
|
|
|
@ -14,18 +14,19 @@ import { Grammeme, ITextRequest, IWordForm, IWordFormPlain } from '@/models/lang
|
||||||
import { parseGrammemes, wordFormEquals } from '@/models/languageAPI';
|
import { parseGrammemes, wordFormEquals } from '@/models/languageAPI';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { IConstituenta, TermForm } from '@/models/rsform';
|
import { IConstituenta, TermForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { prompts } from '@/utils/labels';
|
import { prompts } from '@/utils/labels';
|
||||||
import { IGrammemeOption, SelectorGrammemes, SelectorGrammemesList } from '@/utils/selectors';
|
import { IGrammemeOption, SelectorGrammemes, SelectorGrammemesList } from '@/utils/selectors';
|
||||||
|
|
||||||
import TableWordForms from './TableWordForms';
|
import TableWordForms from './TableWordForms';
|
||||||
|
|
||||||
interface DlgEditWordFormsProps {
|
export interface DlgEditWordFormsProps {
|
||||||
hideWindow: () => void;
|
|
||||||
target: IConstituenta;
|
target: IConstituenta;
|
||||||
onSave: (data: TermForm[]) => void;
|
onSave: (data: TermForm[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps) {
|
function DlgEditWordForms() {
|
||||||
|
const { target, onSave } = useDialogsStore(state => state.props as DlgEditWordFormsProps);
|
||||||
const textProcessor = useConceptText();
|
const textProcessor = useConceptText();
|
||||||
|
|
||||||
const [term, setTerm] = useState('');
|
const [term, setTerm] = useState('');
|
||||||
|
@ -123,7 +124,6 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
<Modal
|
<Modal
|
||||||
canSubmit
|
canSubmit
|
||||||
header='Редактирование словоформ'
|
header='Редактирование словоформ'
|
||||||
hideWindow={hideWindow}
|
|
||||||
submitText='Сохранить'
|
submitText='Сохранить'
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className='flex flex-col w-[40rem] px-6'
|
className='flex flex-col w-[40rem] px-6'
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
import { GraphFilterParams } from '@/models/miscellaneous';
|
import { GraphFilterParams } from '@/models/miscellaneous';
|
||||||
import { CstType } from '@/models/rsform';
|
import { CstType } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { labelCstType } from '@/utils/labels';
|
import { labelCstType } from '@/utils/labels';
|
||||||
|
|
||||||
interface DlgGraphParamsProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgGraphParamsProps {
|
||||||
initial: GraphFilterParams;
|
initial: GraphFilterParams;
|
||||||
onConfirm: (params: GraphFilterParams) => void;
|
onConfirm: (params: GraphFilterParams) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgGraphParams({ hideWindow, initial, onConfirm }: DlgGraphParamsProps) {
|
function DlgGraphParams() {
|
||||||
|
const { initial, onConfirm } = useDialogsStore(state => state.props as DlgGraphParamsProps);
|
||||||
const [params, updateParams] = usePartialUpdate(initial);
|
const [params, updateParams] = usePartialUpdate(initial);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
canSubmit
|
canSubmit
|
||||||
hideWindow={hideWindow}
|
|
||||||
header='Настройки графа термов'
|
header='Настройки графа термов'
|
||||||
onSubmit={() => onConfirm(params)}
|
onSubmit={() => onConfirm(params)}
|
||||||
submitText='Применить'
|
submitText='Применить'
|
||||||
|
|
|
@ -4,18 +4,19 @@ import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import TabLabel from '@/components/ui/TabLabel';
|
import TabLabel from '@/components/ui/TabLabel';
|
||||||
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { ICstSubstitute } from '@/models/oss';
|
import { ICstSubstitute } from '@/models/oss';
|
||||||
import { ConstituentaID, IInlineSynthesisData, IRSForm } from '@/models/rsform';
|
import { ConstituentaID, IInlineSynthesisData, IRSForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import TabConstituents from './TabConstituents';
|
import TabConstituents from './TabConstituents';
|
||||||
import TabSchema from './TabSchema';
|
import TabSchema from './TabSchema';
|
||||||
import TabSubstitutions from './TabSubstitutions';
|
import TabSubstitutions from './TabSubstitutions';
|
||||||
|
|
||||||
interface DlgInlineSynthesisProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgInlineSynthesisProps {
|
||||||
receiver: IRSForm;
|
receiver: IRSForm;
|
||||||
onInlineSynthesis: (data: IInlineSynthesisData) => void;
|
onInlineSynthesis: (data: IInlineSynthesisData) => void;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +27,8 @@ export enum TabID {
|
||||||
SUBSTITUTIONS = 2
|
SUBSTITUTIONS = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgInlineSynthesis({ hideWindow, receiver, onInlineSynthesis }: DlgInlineSynthesisProps) {
|
function DlgInlineSynthesis() {
|
||||||
|
const { receiver, onInlineSynthesis } = useDialogsStore(state => state.props as DlgInlineSynthesisProps);
|
||||||
const [activeTab, setActiveTab] = useState(TabID.SCHEMA);
|
const [activeTab, setActiveTab] = useState(TabID.SCHEMA);
|
||||||
|
|
||||||
const [donorID, setDonorID] = useState<LibraryItemID | undefined>(undefined);
|
const [donorID, setDonorID] = useState<LibraryItemID | undefined>(undefined);
|
||||||
|
@ -60,7 +62,6 @@ function DlgInlineSynthesis({ hideWindow, receiver, onInlineSynthesis }: DlgInli
|
||||||
header='Импорт концептуальной схем'
|
header='Импорт концептуальной схем'
|
||||||
submitText='Добавить конституенты'
|
submitText='Добавить конституенты'
|
||||||
className='w-[40rem] h-[33rem] px-6'
|
className='w-[40rem] h-[33rem] px-6'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { RelocateUpIcon } from '@/components/DomainIcons';
|
||||||
import PickMultiConstituenta from '@/components/select/PickMultiConstituenta';
|
import PickMultiConstituenta from '@/components/select/PickMultiConstituenta';
|
||||||
import SelectLibraryItem from '@/components/select/SelectLibraryItem';
|
import SelectLibraryItem from '@/components/select/SelectLibraryItem';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import DataLoader from '@/components/wrap/DataLoader';
|
import DataLoader from '@/components/wrap/DataLoader';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
||||||
|
@ -16,15 +16,17 @@ import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { ICstRelocateData, IOperation, IOperationSchema } from '@/models/oss';
|
import { ICstRelocateData, IOperation, IOperationSchema } from '@/models/oss';
|
||||||
import { getRelocateCandidates } from '@/models/ossAPI';
|
import { getRelocateCandidates } from '@/models/ossAPI';
|
||||||
import { ConstituentaID } from '@/models/rsform';
|
import { ConstituentaID } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
interface DlgRelocateConstituentsProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgRelocateConstituentsProps {
|
||||||
oss: IOperationSchema;
|
oss: IOperationSchema;
|
||||||
initialTarget?: IOperation;
|
initialTarget?: IOperation;
|
||||||
onSubmit: (data: ICstRelocateData) => void;
|
onSubmit: (data: ICstRelocateData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgRelocateConstituents({ oss, hideWindow, initialTarget, onSubmit }: DlgRelocateConstituentsProps) {
|
function DlgRelocateConstituents() {
|
||||||
|
const { oss, initialTarget, onSubmit } = useDialogsStore(state => state.props as DlgRelocateConstituentsProps);
|
||||||
const library = useLibrary();
|
const library = useLibrary();
|
||||||
|
|
||||||
const [directionUp, setDirectionUp] = useState(true);
|
const [directionUp, setDirectionUp] = useState(true);
|
||||||
|
@ -88,7 +90,6 @@ function DlgRelocateConstituents({ oss, hideWindow, initialTarget, onSubmit }: D
|
||||||
<Modal
|
<Modal
|
||||||
header='Перенос конституент'
|
header='Перенос конституент'
|
||||||
submitText='Переместить'
|
submitText='Переместить'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={isValid}
|
canSubmit={isValid}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('w-[40rem] h-[33rem]', 'py-3 px-6')}
|
className={clsx('w-[40rem] h-[33rem]', 'py-3 px-6')}
|
||||||
|
|
|
@ -3,25 +3,26 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import SelectSingle from '@/components/ui/SelectSingle';
|
import SelectSingle from '@/components/ui/SelectSingle';
|
||||||
import TextInput from '@/components/ui/TextInput';
|
import TextInput from '@/components/ui/TextInput';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { CstType, ICstRenameData } from '@/models/rsform';
|
import { CstType, ICstRenameData, IRSForm } from '@/models/rsform';
|
||||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { labelCstType } from '@/utils/labels';
|
import { labelCstType } from '@/utils/labels';
|
||||||
import { SelectorCstType } from '@/utils/selectors';
|
import { SelectorCstType } from '@/utils/selectors';
|
||||||
|
|
||||||
interface DlgRenameCstProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgRenameCstProps {
|
||||||
|
schema: IRSForm;
|
||||||
initial: ICstRenameData;
|
initial: ICstRenameData;
|
||||||
allowChangeType: boolean;
|
allowChangeType: boolean;
|
||||||
onRename: (data: ICstRenameData) => void;
|
onRename: (data: ICstRenameData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgRenameCst({ hideWindow, initial, allowChangeType, onRename }: DlgRenameCstProps) {
|
function DlgRenameCst() {
|
||||||
const { schema } = useRSForm();
|
const { schema, initial, allowChangeType, onRename } = useDialogsStore(state => state.props as DlgRenameCstProps);
|
||||||
const [validated, setValidated] = useState(false);
|
const [validated, setValidated] = useState(false);
|
||||||
const [cstData, updateData] = usePartialUpdate(initial);
|
const [cstData, updateData] = usePartialUpdate(initial);
|
||||||
|
|
||||||
|
@ -42,7 +43,6 @@ function DlgRenameCst({ hideWindow, initial, allowChangeType, onRename }: DlgRen
|
||||||
header='Переименование конституенты'
|
header='Переименование конституенты'
|
||||||
submitText='Переименовать'
|
submitText='Переименовать'
|
||||||
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
onSubmit={() => onRename(cstData)}
|
onSubmit={() => onRename(cstData)}
|
||||||
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 ')}
|
||||||
|
|
|
@ -3,19 +3,21 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ReactFlowProvider } from 'reactflow';
|
import { ReactFlowProvider } from 'reactflow';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { SyntaxTree } from '@/models/rslang';
|
import { SyntaxTree } from '@/models/rslang';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
import ASTFlow from './ASTFlow';
|
import ASTFlow from './ASTFlow';
|
||||||
|
|
||||||
interface DlgShowASTProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgShowASTProps {
|
||||||
syntaxTree: SyntaxTree;
|
syntaxTree: SyntaxTree;
|
||||||
expression: string;
|
expression: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
function DlgShowAST() {
|
||||||
|
const { syntaxTree, expression } = useDialogsStore(state => state.props as DlgShowASTProps);
|
||||||
const [hoverID, setHoverID] = useState<number | undefined>(undefined);
|
const [hoverID, setHoverID] = useState<number | undefined>(undefined);
|
||||||
const hoverNode = syntaxTree.find(node => node.uid === hoverID);
|
const hoverNode = syntaxTree.find(node => node.uid === hoverID);
|
||||||
|
|
||||||
|
@ -24,7 +26,6 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
readonly
|
readonly
|
||||||
hideWindow={hideWindow}
|
|
||||||
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
||||||
helpTopic={HelpTopic.UI_FORMULA_TREE}
|
helpTopic={HelpTopic.UI_FORMULA_TREE}
|
||||||
>
|
>
|
||||||
|
|
|
@ -3,19 +3,17 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { QRCodeSVG } from 'qrcode.react';
|
import { QRCodeSVG } from 'qrcode.react';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
interface DlgShowQRProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgShowQRProps {
|
||||||
target: string;
|
target: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgShowQR({ hideWindow, target }: DlgShowQRProps) {
|
function DlgShowQR() {
|
||||||
|
const { target } = useDialogsStore(state => state.props as DlgShowQRProps);
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal readonly className={clsx('w-[30rem]', 'py-12 pr-3 pl-6 flex gap-3 justify-center items-center')}>
|
||||||
readonly
|
|
||||||
hideWindow={hideWindow}
|
|
||||||
className={clsx('w-[30rem]', 'py-12 pr-3 pl-6 flex gap-3 justify-center items-center')}
|
|
||||||
>
|
|
||||||
<div className='bg-[#ffffff] p-4 border'>
|
<div className='bg-[#ffffff] p-4 border'>
|
||||||
<QRCodeSVG value={target} size={256} />
|
<QRCodeSVG value={target} size={256} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,19 +3,22 @@
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import { ReactFlowProvider } from 'reactflow';
|
import { ReactFlowProvider } from 'reactflow';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { ITypeInfo } from '@/models/rslang';
|
import { ITypeInfo } from '@/models/rslang';
|
||||||
import { TMGraph } from '@/models/TMGraph';
|
import { TMGraph } from '@/models/TMGraph';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { errors } from '@/utils/labels';
|
import { errors } from '@/utils/labels';
|
||||||
|
|
||||||
import MGraphFlow from './MGraphFlow';
|
import MGraphFlow from './MGraphFlow';
|
||||||
|
|
||||||
interface DlgShowTypeGraphProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgShowTypeGraphProps {
|
||||||
items: ITypeInfo[];
|
items: ITypeInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
|
function DlgShowTypeGraph() {
|
||||||
|
const { items } = useDialogsStore(state => state.props as DlgShowTypeGraphProps);
|
||||||
|
const hideDialog = useDialogsStore(state => state.hideDialog);
|
||||||
const graph = (() => {
|
const graph = (() => {
|
||||||
const result = new TMGraph();
|
const result = new TMGraph();
|
||||||
items.forEach(item => result.addConstituenta(item.alias, item.result, item.args));
|
items.forEach(item => result.addConstituenta(item.alias, item.result, item.args));
|
||||||
|
@ -24,7 +27,7 @@ function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
|
||||||
|
|
||||||
if (graph.nodes.length === 0) {
|
if (graph.nodes.length === 0) {
|
||||||
toast.error(errors.typeStructureFailed);
|
toast.error(errors.typeStructureFailed);
|
||||||
hideWindow();
|
hideDialog();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +35,6 @@ function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
|
||||||
<Modal
|
<Modal
|
||||||
header='Граф ступеней'
|
header='Граф ступеней'
|
||||||
readonly
|
readonly
|
||||||
hideWindow={hideWindow}
|
|
||||||
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
||||||
helpTopic={HelpTopic.UI_TYPE_GRAPH}
|
helpTopic={HelpTopic.UI_TYPE_GRAPH}
|
||||||
>
|
>
|
||||||
|
|
|
@ -4,18 +4,20 @@ import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import PickSubstitutions from '@/components/select/PickSubstitutions';
|
import PickSubstitutions from '@/components/select/PickSubstitutions';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { ICstSubstitute, ICstSubstituteData } from '@/models/oss';
|
import { ICstSubstitute, ICstSubstituteData } from '@/models/oss';
|
||||||
import { IRSForm } from '@/models/rsform';
|
import { IRSForm } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
interface DlgSubstituteCstProps extends Pick<ModalProps, 'hideWindow'> {
|
export interface DlgSubstituteCstProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
onSubstitute: (data: ICstSubstituteData) => void;
|
onSubstitute: (data: ICstSubstituteData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgSubstituteCst({ hideWindow, onSubstitute, schema }: DlgSubstituteCstProps) {
|
function DlgSubstituteCst() {
|
||||||
|
const { onSubstitute, schema } = useDialogsStore(state => state.props as DlgSubstituteCstProps);
|
||||||
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>([]);
|
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>([]);
|
||||||
const canSubmit = substitutions.length > 0;
|
const canSubmit = substitutions.length > 0;
|
||||||
|
|
||||||
|
@ -31,7 +33,6 @@ function DlgSubstituteCst({ hideWindow, onSubstitute, schema }: DlgSubstituteCst
|
||||||
header='Отождествление'
|
header='Отождествление'
|
||||||
submitText='Отождествить'
|
submitText='Отождествить'
|
||||||
submitInvalidTooltip='Выберите две различные конституенты'
|
submitInvalidTooltip='Выберите две различные конституенты'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={canSubmit}
|
canSubmit={canSubmit}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className={clsx('w-[40rem]', 'px-6 pb-3')}
|
className={clsx('w-[40rem]', 'px-6 pb-3')}
|
||||||
|
|
|
@ -6,16 +6,16 @@ import { toast } from 'react-toastify';
|
||||||
import Checkbox from '@/components/ui/Checkbox';
|
import Checkbox from '@/components/ui/Checkbox';
|
||||||
import FileInput from '@/components/ui/FileInput';
|
import FileInput from '@/components/ui/FileInput';
|
||||||
import Modal from '@/components/ui/Modal';
|
import Modal from '@/components/ui/Modal';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
|
||||||
import { IRSFormUploadData } from '@/models/rsform';
|
import { IRSFormUploadData } from '@/models/rsform';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
||||||
|
|
||||||
interface DlgUploadRSFormProps {
|
export interface DlgUploadRSFormProps {
|
||||||
hideWindow: () => void;
|
upload: (data: IRSFormUploadData, callback: () => void) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgUploadRSForm({ hideWindow }: DlgUploadRSFormProps) {
|
function DlgUploadRSForm() {
|
||||||
const { upload } = useRSForm();
|
const { upload } = useDialogsStore(state => state.props as DlgUploadRSFormProps);
|
||||||
const [loadMetadata, setLoadMetadata] = useState(false);
|
const [loadMetadata, setLoadMetadata] = useState(false);
|
||||||
const [file, setFile] = useState<File | undefined>();
|
const [file, setFile] = useState<File | undefined>();
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ function DlgUploadRSForm({ hideWindow }: DlgUploadRSFormProps) {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Импорт схемы из Экстеора'
|
header='Импорт схемы из Экстеора'
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={!!file}
|
canSubmit={!!file}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
submitText='Загрузить'
|
submitText='Загрузить'
|
||||||
|
|
|
@ -224,3 +224,32 @@ export interface Position2D {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents global dialog.
|
||||||
|
*/
|
||||||
|
export enum DialogType {
|
||||||
|
CONSTITUENTA_TEMPLATE = 1,
|
||||||
|
CREATE_CONSTITUENTA,
|
||||||
|
CREATE_OPERATION,
|
||||||
|
DELETE_CONSTITUENTA,
|
||||||
|
EDIT_EDITORS,
|
||||||
|
EDIT_OPERATION,
|
||||||
|
EDIT_REFERENCE,
|
||||||
|
EDIT_VERSIONS,
|
||||||
|
EDIT_WORD_FORMS,
|
||||||
|
INLINE_SYNTHESIS,
|
||||||
|
SHOW_AST,
|
||||||
|
SHOW_TYPE_GRAPH,
|
||||||
|
CHANGE_INPUT_SCHEMA,
|
||||||
|
CHANGE_LOCATION,
|
||||||
|
CLONE_LIBRARY_ITEM,
|
||||||
|
CREATE_VERSION,
|
||||||
|
DELETE_OPERATION,
|
||||||
|
GRAPH_PARAMETERS,
|
||||||
|
RELOCATE_CONSTITUENTS,
|
||||||
|
RENAME_CONSTITUENTA,
|
||||||
|
SHOW_QR_CODE,
|
||||||
|
SUBSTITUTE_CONSTITUENTS,
|
||||||
|
UPLOAD_RSFORM
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import fileDownload from 'js-file-download';
|
import fileDownload from 'js-file-download';
|
||||||
import { useCallback, useState } from 'react';
|
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { IconCSV } from '@/components/Icons';
|
import { IconCSV } from '@/components/Icons';
|
||||||
|
@ -9,9 +8,9 @@ import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import DataLoader from '@/components/wrap/DataLoader';
|
import DataLoader from '@/components/wrap/DataLoader';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
|
|
||||||
import { IRenameLocationData } from '@/models/library';
|
import { IRenameLocationData } from '@/models/library';
|
||||||
import { useAppLayoutStore } from '@/stores/appLayout';
|
import { useAppLayoutStore } from '@/stores/appLayout';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { useLibraryFilter, useLibrarySearchStore } from '@/stores/librarySearch';
|
import { useLibraryFilter, useLibrarySearchStore } from '@/stores/librarySearch';
|
||||||
import { information } from '@/utils/labels';
|
import { information } from '@/utils/labels';
|
||||||
import { convertToCSV } from '@/utils/utils';
|
import { convertToCSV } from '@/utils/utils';
|
||||||
|
@ -31,23 +30,20 @@ function LibraryPage() {
|
||||||
const filter = useLibraryFilter();
|
const filter = useLibraryFilter();
|
||||||
const items = library.applyFilter(filter);
|
const items = library.applyFilter(filter);
|
||||||
|
|
||||||
const [showRenameLocation, setShowRenameLocation] = useState(false);
|
const showChangeLocation = useDialogsStore(state => state.showChangeLocation);
|
||||||
|
|
||||||
const handleRenameLocation = useCallback(
|
function handleRenameLocation(newLocation: string) {
|
||||||
(newLocation: string) => {
|
const data: IRenameLocationData = {
|
||||||
const data: IRenameLocationData = {
|
target: location,
|
||||||
target: location,
|
new_location: newLocation
|
||||||
new_location: newLocation
|
};
|
||||||
};
|
library.renameLocation(data, () => {
|
||||||
library.renameLocation(data, () => {
|
setLocation(newLocation);
|
||||||
setLocation(newLocation);
|
toast.success(information.locationRenamed);
|
||||||
toast.success(information.locationRenamed);
|
});
|
||||||
});
|
}
|
||||||
},
|
|
||||||
[location, setLocation, library]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDownloadCSV = useCallback(() => {
|
function handleDownloadCSV() {
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
toast.error(information.noDataToExport);
|
toast.error(information.noDataToExport);
|
||||||
return;
|
return;
|
||||||
|
@ -58,17 +54,10 @@ function LibraryPage() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}, [items]);
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataLoader isLoading={library.loading} error={library.loadingError} hasNoData={library.items.length === 0}>
|
<DataLoader isLoading={library.loading} error={library.loadingError} hasNoData={library.items.length === 0}>
|
||||||
{showRenameLocation ? (
|
|
||||||
<DlgChangeLocation
|
|
||||||
initial={location}
|
|
||||||
onChangeLocation={handleRenameLocation}
|
|
||||||
hideWindow={() => setShowRenameLocation(false)}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<Overlay
|
<Overlay
|
||||||
position={noNavigation ? 'top-[0.25rem] right-[3rem]' : 'top-[0.25rem] right-0'}
|
position={noNavigation ? 'top-[0.25rem] right-[3rem]' : 'top-[0.25rem] right-0'}
|
||||||
layer='z-tooltip'
|
layer='z-tooltip'
|
||||||
|
@ -86,7 +75,7 @@ function LibraryPage() {
|
||||||
<ViewSideLocation
|
<ViewSideLocation
|
||||||
isVisible={folderMode}
|
isVisible={folderMode}
|
||||||
folderTree={library.folders}
|
folderTree={library.folders}
|
||||||
onRenameLocation={() => setShowRenameLocation(true)}
|
onRenameLocation={() => showChangeLocation({ initial: location, onChangeLocation: handleRenameLocation })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TableLibraryItems items={items} />
|
<TableLibraryItems items={items} />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
|
@ -8,13 +8,6 @@ import { useAuth } from '@/context/AuthContext';
|
||||||
import { useLibrary } from '@/context/LibraryContext';
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { useOSS } from '@/context/OssContext';
|
import { useOSS } from '@/context/OssContext';
|
||||||
import DlgChangeInputSchema from '@/dialogs/DlgChangeInputSchema';
|
|
||||||
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
|
|
||||||
import DlgCreateOperation from '@/dialogs/DlgCreateOperation';
|
|
||||||
import DlgDeleteOperation from '@/dialogs/DlgDeleteOperation';
|
|
||||||
import DlgEditEditors from '@/dialogs/DlgEditEditors';
|
|
||||||
import DlgEditOperation from '@/dialogs/DlgEditOperation';
|
|
||||||
import DlgRelocateConstituents from '@/dialogs/DlgRelocateConstituents';
|
|
||||||
import { AccessPolicy, ILibraryItemEditor, LibraryItemID } from '@/models/library';
|
import { AccessPolicy, ILibraryItemEditor, LibraryItemID } from '@/models/library';
|
||||||
import { Position2D } from '@/models/miscellaneous';
|
import { Position2D } from '@/models/miscellaneous';
|
||||||
import { calculateInsertPosition } from '@/models/miscellaneousAPI';
|
import { calculateInsertPosition } from '@/models/miscellaneousAPI';
|
||||||
|
@ -30,6 +23,7 @@ import {
|
||||||
OperationType
|
OperationType
|
||||||
} from '@/models/oss';
|
} from '@/models/oss';
|
||||||
import { UserID, UserRole } from '@/models/user';
|
import { UserID, UserRole } from '@/models/user';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { useRoleStore } from '@/stores/role';
|
import { useRoleStore } from '@/stores/role';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
@ -106,24 +100,18 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
|
|
||||||
const [showTooltip, setShowTooltip] = useState(true);
|
const [showTooltip, setShowTooltip] = useState(true);
|
||||||
|
|
||||||
const [showEditEditors, setShowEditEditors] = useState(false);
|
|
||||||
const [showEditLocation, setShowEditLocation] = useState(false);
|
|
||||||
const [showEditInput, setShowEditInput] = useState(false);
|
|
||||||
const [showEditOperation, setShowEditOperation] = useState(false);
|
|
||||||
const [showDeleteOperation, setShowDeleteOperation] = useState(false);
|
|
||||||
const [showRelocateConstituents, setShowRelocateConstituents] = useState(false);
|
|
||||||
|
|
||||||
const [showCreateOperation, setShowCreateOperation] = useState(false);
|
|
||||||
const [insertPosition, setInsertPosition] = useState<Position2D>({ x: 0, y: 0 });
|
const [insertPosition, setInsertPosition] = useState<Position2D>({ x: 0, y: 0 });
|
||||||
const [initialInputs, setInitialInputs] = useState<OperationID[]>([]);
|
|
||||||
const [createCallback, setCreateCallback] = useState<((newID: OperationID) => void) | undefined>(undefined);
|
const [createCallback, setCreateCallback] = useState<((newID: OperationID) => void) | undefined>(undefined);
|
||||||
|
|
||||||
|
const showEditEditors = useDialogsStore(state => state.showEditEditors);
|
||||||
|
const showEditLocation = useDialogsStore(state => state.showChangeLocation);
|
||||||
|
const showEditInput = useDialogsStore(state => state.showChangeInputSchema);
|
||||||
|
const showEditOperation = useDialogsStore(state => state.showEditOperation);
|
||||||
|
const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation);
|
||||||
|
const showRelocateConstituents = useDialogsStore(state => state.showRelocateConstituents);
|
||||||
|
const showCreateOperation = useDialogsStore(state => state.showCreateOperation);
|
||||||
|
|
||||||
const [positions, setPositions] = useState<IOperationPosition[]>([]);
|
const [positions, setPositions] = useState<IOperationPosition[]>([]);
|
||||||
const [targetOperationID, setTargetOperationID] = useState<OperationID | undefined>(undefined);
|
|
||||||
const targetOperation = useMemo(
|
|
||||||
() => (targetOperationID ? model.schema?.operationByID.get(targetOperationID) : undefined),
|
|
||||||
[model, targetOperationID]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() =>
|
() =>
|
||||||
|
@ -146,14 +134,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
const promptEditors = useCallback(() => {
|
|
||||||
setShowEditEditors(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const promptLocation = useCallback(() => {
|
|
||||||
setShowEditLocation(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const share = useCallback(() => {
|
const share = useCallback(() => {
|
||||||
const currentRef = window.location.href;
|
const currentRef = window.location.href;
|
||||||
const url = currentRef.includes('?') ? currentRef + '&share' : currentRef + '?share';
|
const url = currentRef.includes('?') ? currentRef + '&share' : currentRef + '?share';
|
||||||
|
@ -177,7 +157,7 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setEditors = useCallback(
|
const handleSetEditors = useCallback(
|
||||||
(newEditors: UserID[]) => {
|
(newEditors: UserID[]) => {
|
||||||
model.setEditors(newEditors, () => toast.success(information.changesSaved));
|
model.setEditors(newEditors, () => toast.success(information.changesSaved));
|
||||||
},
|
},
|
||||||
|
@ -212,17 +192,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
const promptCreateOperation = useCallback(
|
|
||||||
({ defaultX, defaultY, inputs, positions, callback }: ICreateOperationPrompt) => {
|
|
||||||
setInsertPosition({ x: defaultX, y: defaultY });
|
|
||||||
setInitialInputs(inputs);
|
|
||||||
setPositions(positions);
|
|
||||||
setCreateCallback(() => callback);
|
|
||||||
setShowCreateOperation(true);
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleCreateOperation = useCallback(
|
const handleCreateOperation = useCallback(
|
||||||
(data: IOperationCreateData) => {
|
(data: IOperationCreateData) => {
|
||||||
const target = calculateInsertPosition(
|
const target = calculateInsertPosition(
|
||||||
|
@ -245,12 +214,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model, positions, insertPosition, createCallback]
|
[model, positions, insertPosition, createCallback]
|
||||||
);
|
);
|
||||||
|
|
||||||
const promptEditOperation = useCallback((target: OperationID, positions: IOperationPosition[]) => {
|
|
||||||
setPositions(positions);
|
|
||||||
setTargetOperationID(target);
|
|
||||||
setShowEditOperation(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleEditOperation = useCallback(
|
const handleEditOperation = useCallback(
|
||||||
(data: IOperationUpdateData) => {
|
(data: IOperationUpdateData) => {
|
||||||
data.positions = positions;
|
data.positions = positions;
|
||||||
|
@ -276,26 +239,17 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
const promptDeleteOperation = useCallback((target: OperationID, positions: IOperationPosition[]) => {
|
const handleDeleteOperation = useCallback(
|
||||||
setPositions(positions);
|
(targetID: OperationID, keepConstituents: boolean, deleteSchema: boolean) => {
|
||||||
setTargetOperationID(target);
|
|
||||||
setShowDeleteOperation(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const deleteOperation = useCallback(
|
|
||||||
(keepConstituents: boolean, deleteSchema: boolean) => {
|
|
||||||
if (!targetOperationID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const data: IOperationDeleteData = {
|
const data: IOperationDeleteData = {
|
||||||
target: targetOperationID,
|
target: targetID,
|
||||||
positions: positions,
|
positions: positions,
|
||||||
keep_constituents: keepConstituents,
|
keep_constituents: keepConstituents,
|
||||||
delete_schema: deleteSchema
|
delete_schema: deleteSchema
|
||||||
};
|
};
|
||||||
model.deleteOperation(data, () => toast.success(information.operationDestroyed));
|
model.deleteOperation(data, () => toast.success(information.operationDestroyed));
|
||||||
},
|
},
|
||||||
[model, targetOperationID, positions]
|
[model, positions]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createInput = useCallback(
|
const createInput = useCallback(
|
||||||
|
@ -316,44 +270,18 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model, library.items, router]
|
[model, library.items, router]
|
||||||
);
|
);
|
||||||
|
|
||||||
const promptEditInput = useCallback((target: OperationID, positions: IOperationPosition[]) => {
|
|
||||||
setPositions(positions);
|
|
||||||
setTargetOperationID(target);
|
|
||||||
setShowEditInput(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const setTargetInput = useCallback(
|
const setTargetInput = useCallback(
|
||||||
(newInput: LibraryItemID | undefined) => {
|
(target: OperationID, newInput: LibraryItemID | undefined) => {
|
||||||
if (!targetOperationID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const data: IOperationSetInputData = {
|
const data: IOperationSetInputData = {
|
||||||
target: targetOperationID,
|
target: target,
|
||||||
positions: positions,
|
positions: positions,
|
||||||
input: newInput ?? null
|
input: newInput ?? null
|
||||||
};
|
};
|
||||||
model.setInput(data, () => toast.success(information.changesSaved));
|
model.setInput(data, () => toast.success(information.changesSaved));
|
||||||
},
|
},
|
||||||
[model, targetOperationID, positions]
|
[model, positions]
|
||||||
);
|
);
|
||||||
|
|
||||||
const executeOperation = useCallback(
|
|
||||||
(target: OperationID, positions: IOperationPosition[]) => {
|
|
||||||
const data = {
|
|
||||||
target: target,
|
|
||||||
positions: positions
|
|
||||||
};
|
|
||||||
model.executeOperation(data, () => toast.success(information.operationExecuted));
|
|
||||||
},
|
|
||||||
[model]
|
|
||||||
);
|
|
||||||
|
|
||||||
const promptRelocateConstituents = useCallback((target: OperationID | undefined, positions: IOperationPosition[]) => {
|
|
||||||
setPositions(positions);
|
|
||||||
setTargetOperationID(target);
|
|
||||||
setShowRelocateConstituents(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleRelocateConstituents = useCallback(
|
const handleRelocateConstituents = useCallback(
|
||||||
(data: ICstRelocateData) => {
|
(data: ICstRelocateData) => {
|
||||||
if (
|
if (
|
||||||
|
@ -372,6 +300,92 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
[model, positions]
|
[model, positions]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const executeOperation = useCallback(
|
||||||
|
(target: OperationID, positions: IOperationPosition[]) => {
|
||||||
|
const data = {
|
||||||
|
target: target,
|
||||||
|
positions: positions
|
||||||
|
};
|
||||||
|
model.executeOperation(data, () => toast.success(information.operationExecuted));
|
||||||
|
},
|
||||||
|
[model]
|
||||||
|
);
|
||||||
|
|
||||||
|
const promptEditors = useCallback(() => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showEditEditors({ editors: model.schema.editors, setEditors: handleSetEditors });
|
||||||
|
}, [model.schema, showEditEditors, handleSetEditors]);
|
||||||
|
|
||||||
|
const promptLocation = useCallback(() => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showEditLocation({ initial: model.schema.location, onChangeLocation: handleSetLocation });
|
||||||
|
}, [model.schema, showEditLocation, handleSetLocation]);
|
||||||
|
|
||||||
|
const promptCreateOperation = useCallback(
|
||||||
|
({ defaultX, defaultY, inputs, positions, callback }: ICreateOperationPrompt) => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setInsertPosition({ x: defaultX, y: defaultY });
|
||||||
|
setPositions(positions);
|
||||||
|
setCreateCallback(() => callback);
|
||||||
|
showCreateOperation({ oss: model.schema, onCreate: handleCreateOperation, initialInputs: inputs });
|
||||||
|
},
|
||||||
|
[model.schema, showCreateOperation, handleCreateOperation]
|
||||||
|
);
|
||||||
|
|
||||||
|
const promptEditOperation = useCallback(
|
||||||
|
(target: OperationID, positions: IOperationPosition[]) => {
|
||||||
|
const operation = model.schema?.operationByID.get(target);
|
||||||
|
if (!model.schema || !operation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPositions(positions);
|
||||||
|
showEditOperation({ oss: model.schema, target: operation, onSubmit: handleEditOperation });
|
||||||
|
},
|
||||||
|
[model.schema, showEditOperation, handleEditOperation]
|
||||||
|
);
|
||||||
|
|
||||||
|
const promptDeleteOperation = useCallback(
|
||||||
|
(target: OperationID, positions: IOperationPosition[]) => {
|
||||||
|
const operation = model.schema?.operationByID.get(target);
|
||||||
|
if (!model.schema || !operation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPositions(positions);
|
||||||
|
showDeleteOperation({ target: operation, onSubmit: handleDeleteOperation });
|
||||||
|
},
|
||||||
|
[model.schema, showDeleteOperation, handleDeleteOperation]
|
||||||
|
);
|
||||||
|
|
||||||
|
const promptEditInput = useCallback(
|
||||||
|
(target: OperationID, positions: IOperationPosition[]) => {
|
||||||
|
const operation = model.schema?.operationByID.get(target);
|
||||||
|
if (!model.schema || !operation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPositions(positions);
|
||||||
|
showEditInput({ oss: model.schema, target: operation, onSubmit: setTargetInput });
|
||||||
|
},
|
||||||
|
[model.schema, showEditInput, setTargetInput]
|
||||||
|
);
|
||||||
|
|
||||||
|
const promptRelocateConstituents = useCallback(
|
||||||
|
(target: OperationID | undefined, positions: IOperationPosition[]) => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const operation = target ? model.schema?.operationByID.get(target) : undefined;
|
||||||
|
setPositions(positions);
|
||||||
|
showRelocateConstituents({ oss: model.schema, initialTarget: operation, onSubmit: handleRelocateConstituents });
|
||||||
|
},
|
||||||
|
[model.schema, showRelocateConstituents, handleRelocateConstituents]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OssEditContext
|
<OssEditContext
|
||||||
value={{
|
value={{
|
||||||
|
@ -405,64 +419,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
|
||||||
promptRelocateConstituents
|
promptRelocateConstituents
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{model.schema ? (
|
|
||||||
<>
|
|
||||||
{showEditEditors ? (
|
|
||||||
<DlgEditEditors
|
|
||||||
hideWindow={() => setShowEditEditors(false)}
|
|
||||||
editors={model.schema.editors}
|
|
||||||
setEditors={setEditors}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditLocation ? (
|
|
||||||
<DlgChangeLocation
|
|
||||||
hideWindow={() => setShowEditLocation(false)}
|
|
||||||
initial={model.schema.location}
|
|
||||||
onChangeLocation={handleSetLocation}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showCreateOperation ? (
|
|
||||||
<DlgCreateOperation
|
|
||||||
hideWindow={() => setShowCreateOperation(false)}
|
|
||||||
oss={model.schema}
|
|
||||||
onCreate={handleCreateOperation}
|
|
||||||
initialInputs={initialInputs}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditInput ? (
|
|
||||||
<DlgChangeInputSchema
|
|
||||||
hideWindow={() => setShowEditInput(false)}
|
|
||||||
oss={model.schema}
|
|
||||||
target={targetOperation!}
|
|
||||||
onSubmit={setTargetInput}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditOperation ? (
|
|
||||||
<DlgEditOperation
|
|
||||||
hideWindow={() => setShowEditOperation(false)}
|
|
||||||
oss={model.schema}
|
|
||||||
target={targetOperation!}
|
|
||||||
onSubmit={handleEditOperation}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showDeleteOperation ? (
|
|
||||||
<DlgDeleteOperation
|
|
||||||
hideWindow={() => setShowDeleteOperation(false)}
|
|
||||||
target={targetOperation!}
|
|
||||||
onSubmit={deleteOperation}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showRelocateConstituents ? (
|
|
||||||
<DlgRelocateConstituents
|
|
||||||
hideWindow={() => setShowRelocateConstituents(false)}
|
|
||||||
initialTarget={targetOperation}
|
|
||||||
oss={model.schema}
|
|
||||||
onSubmit={handleRelocateConstituents}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</OssEditContext>
|
</OssEditContext>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,10 +12,10 @@ import Overlay from '@/components/ui/Overlay';
|
||||||
import SubmitButton from '@/components/ui/SubmitButton';
|
import SubmitButton from '@/components/ui/SubmitButton';
|
||||||
import TextArea from '@/components/ui/TextArea';
|
import TextArea from '@/components/ui/TextArea';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
|
||||||
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
|
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
|
||||||
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
|
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
|
||||||
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { errors, information, labelCstTypification } from '@/utils/labels';
|
import { errors, information, labelCstTypification } from '@/utils/labels';
|
||||||
|
|
||||||
import EditorRSExpression from '../EditorRSExpression';
|
import EditorRSExpression from '../EditorRSExpression';
|
||||||
|
@ -56,7 +56,6 @@ function FormConstituenta({
|
||||||
const [expression, setExpression] = useState(state?.definition_formal ?? '');
|
const [expression, setExpression] = useState(state?.definition_formal ?? '');
|
||||||
const [convention, setConvention] = useState(state?.convention ?? '');
|
const [convention, setConvention] = useState(state?.convention ?? '');
|
||||||
const [typification, setTypification] = useState('N/A');
|
const [typification, setTypification] = useState('N/A');
|
||||||
const [showTypification, setShowTypification] = useState(false);
|
|
||||||
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
||||||
const typeInfo = state
|
const typeInfo = state
|
||||||
? {
|
? {
|
||||||
|
@ -72,6 +71,8 @@ function FormConstituenta({
|
||||||
const isElementary = !!state && isBaseSet(state.cst_type);
|
const isElementary = !!state && isBaseSet(state.cst_type);
|
||||||
const showConvention = !state || !!state.convention || forceComment || isBasic;
|
const showConvention = !state || !!state.convention || forceComment || isBasic;
|
||||||
|
|
||||||
|
const showTypification = useDialogsStore(state => state.showShowTypeGraph);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state) {
|
if (state) {
|
||||||
setConvention(state.convention);
|
setConvention(state.convention);
|
||||||
|
@ -142,14 +143,11 @@ function FormConstituenta({
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setShowTypification(true);
|
showTypification({ items: typeInfo ? [typeInfo] : [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
|
<div className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
|
||||||
{showTypification && state ? (
|
|
||||||
<DlgShowTypeGraph items={typeInfo ? [typeInfo] : []} hideWindow={() => setShowTypification(false)} />
|
|
||||||
) : null}
|
|
||||||
{state ? (
|
{state ? (
|
||||||
<ControlsOverlay
|
<ControlsOverlay
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
|
@ -11,13 +11,13 @@ import { parser as rslangParser } from '@/components/RSInput/rslang/parserAST';
|
||||||
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
import DlgShowAST from '@/dialogs/DlgShowAST';
|
|
||||||
import useCheckConstituenta from '@/hooks/useCheckConstituenta';
|
import useCheckConstituenta from '@/hooks/useCheckConstituenta';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
||||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||||
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '@/models/rslang';
|
import { IExpressionParse, IRSErrorDescription } from '@/models/rslang';
|
||||||
import { TokenID } from '@/models/rslang';
|
import { TokenID } from '@/models/rslang';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { transformAST } from '@/utils/codemirror';
|
import { transformAST } from '@/utils/codemirror';
|
||||||
import { errors, labelTypification } from '@/utils/labels';
|
import { errors, labelTypification } from '@/utils/labels';
|
||||||
|
@ -64,9 +64,7 @@ function EditorRSExpression({
|
||||||
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
||||||
|
|
||||||
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
||||||
const [syntaxTree, setSyntaxTree] = useState<SyntaxTree>([]);
|
const showAST = useDialogsStore(state => state.showShowAST);
|
||||||
const [expression, setExpression] = useState('');
|
|
||||||
const [showAST, setShowAST] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsModified(false);
|
setIsModified(false);
|
||||||
|
@ -131,17 +129,13 @@ function EditorRSExpression({
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const tree = rslangParser.parse(value);
|
const tree = rslangParser.parse(value);
|
||||||
const ast = transformAST(tree);
|
const ast = transformAST(tree);
|
||||||
setSyntaxTree(ast);
|
showAST({ syntaxTree: ast, expression: value });
|
||||||
setExpression(value);
|
|
||||||
setShowAST(true);
|
|
||||||
} else {
|
} else {
|
||||||
handleCheckExpression(parse => {
|
handleCheckExpression(parse => {
|
||||||
if (!parse.astText) {
|
if (!parse.astText) {
|
||||||
toast.error(errors.astFailed);
|
toast.error(errors.astFailed);
|
||||||
} else {
|
} else {
|
||||||
setSyntaxTree(parse.ast);
|
showAST({ syntaxTree: parse.ast, expression: getDefinitionPrefix(activeCst) + value });
|
||||||
setExpression(getDefinitionPrefix(activeCst) + value);
|
|
||||||
setShowAST(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -149,10 +143,6 @@ function EditorRSExpression({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='cc-fade-in'>
|
<div className='cc-fade-in'>
|
||||||
{showAST ? (
|
|
||||||
<DlgShowAST expression={expression} syntaxTree={syntaxTree} hideWindow={() => setShowAST(false)} />
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<ToolbarRSExpression disabled={disabled} showAST={handleShowAST} showTypeGraph={onShowTypeGraph} />
|
<ToolbarRSExpression disabled={disabled} showAST={handleShowAST} showTypeGraph={onShowTypeGraph} />
|
||||||
|
|
||||||
<Overlay
|
<Overlay
|
||||||
|
|
|
@ -24,10 +24,10 @@ import SelectedCounter from '@/components/info/SelectedCounter';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
import ToolbarGraphSelection from '@/components/select/ToolbarGraphSelection';
|
import ToolbarGraphSelection from '@/components/select/ToolbarGraphSelection';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import DlgGraphParams from '@/dialogs/DlgGraphParams';
|
|
||||||
import { ConstituentaID, CstType, IConstituenta } from '@/models/rsform';
|
import { ConstituentaID, CstType, IConstituenta } from '@/models/rsform';
|
||||||
import { isBasicConcept } from '@/models/rsformAPI';
|
import { isBasicConcept } from '@/models/rsformAPI';
|
||||||
import { useMainHeight } from '@/stores/appLayout';
|
import { useMainHeight } from '@/stores/appLayout';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { useTermGraphStore } from '@/stores/termGraph';
|
import { useTermGraphStore } from '@/stores/termGraph';
|
||||||
import { APP_COLORS, colorBgGraphNode } from '@/styling/color';
|
import { APP_COLORS, colorBgGraphNode } from '@/styling/color';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
@ -60,7 +60,7 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const { addSelectedNodes } = store.getState();
|
const { addSelectedNodes } = store.getState();
|
||||||
|
|
||||||
const [showParamsDialog, setShowParamsDialog] = useState(false);
|
const showParams = useDialogsStore(state => state.showGraphParams);
|
||||||
|
|
||||||
const filter = useTermGraphStore(state => state.filter);
|
const filter = useTermGraphStore(state => state.filter);
|
||||||
const setFilter = useTermGraphStore(state => state.setFilter);
|
const setFilter = useTermGraphStore(state => state.setFilter);
|
||||||
|
@ -295,15 +295,11 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showParamsDialog ? (
|
|
||||||
<DlgGraphParams hideWindow={() => setShowParamsDialog(false)} initial={filter} onConfirm={setFilter} />
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<Overlay position='cc-tab-tools' className='flex flex-col items-center rounded-b-2xl cc-blur'>
|
<Overlay position='cc-tab-tools' className='flex flex-col items-center rounded-b-2xl cc-blur'>
|
||||||
<ToolbarTermGraph
|
<ToolbarTermGraph
|
||||||
noText={filter.noText}
|
noText={filter.noText}
|
||||||
foldDerived={filter.foldDerived}
|
foldDerived={filter.foldDerived}
|
||||||
showParamsDialog={() => setShowParamsDialog(true)}
|
showParamsDialog={() => showParams({ initial: filter, onConfirm: setFilter })}
|
||||||
onCreate={handleCreateCst}
|
onCreate={handleCreateCst}
|
||||||
onDelete={handleDeleteCst}
|
onDelete={handleDeleteCst}
|
||||||
onFitView={() => setToggleResetView(prev => !prev)}
|
onFitView={() => setToggleResetView(prev => !prev)}
|
||||||
|
|
|
@ -8,21 +8,6 @@ import { urls } from '@/app/urls';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
|
|
||||||
import DlgCloneLibraryItem from '@/dialogs/DlgCloneLibraryItem';
|
|
||||||
import DlgConstituentaTemplate from '@/dialogs/DlgConstituentaTemplate';
|
|
||||||
import DlgCreateCst from '@/dialogs/DlgCreateCst';
|
|
||||||
import DlgCreateVersion from '@/dialogs/DlgCreateVersion';
|
|
||||||
import DlgDeleteCst from '@/dialogs/DlgDeleteCst';
|
|
||||||
import DlgEditEditors from '@/dialogs/DlgEditEditors';
|
|
||||||
import DlgEditVersions from '@/dialogs/DlgEditVersions';
|
|
||||||
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
|
||||||
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
|
||||||
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
|
||||||
import DlgShowQR from '@/dialogs/DlgShowQR';
|
|
||||||
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
|
||||||
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
|
||||||
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
|
||||||
import {
|
import {
|
||||||
AccessPolicy,
|
AccessPolicy,
|
||||||
ILibraryItemEditor,
|
ILibraryItemEditor,
|
||||||
|
@ -49,6 +34,7 @@ import {
|
||||||
} from '@/models/rsform';
|
} from '@/models/rsform';
|
||||||
import { generateAlias } from '@/models/rsformAPI';
|
import { generateAlias } from '@/models/rsformAPI';
|
||||||
import { UserID, UserRole } from '@/models/user';
|
import { UserID, UserRole } from '@/models/user';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { usePreferencesStore } from '@/stores/preferences';
|
import { usePreferencesStore } from '@/stores/preferences';
|
||||||
import { useRoleStore } from '@/stores/role';
|
import { useRoleStore } from '@/stores/role';
|
||||||
import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
||||||
|
@ -161,27 +147,26 @@ export const RSEditState = ({
|
||||||
[model.schema]
|
[model.schema]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [showUpload, setShowUpload] = useState(false);
|
|
||||||
const [showClone, setShowClone] = useState(false);
|
|
||||||
const [showDeleteCst, setShowDeleteCst] = useState(false);
|
|
||||||
const [showEditEditors, setShowEditEditors] = useState(false);
|
|
||||||
const [showEditLocation, setShowEditLocation] = useState(false);
|
|
||||||
const [showEditTerm, setShowEditTerm] = useState(false);
|
|
||||||
const [showSubstitute, setShowSubstitute] = useState(false);
|
|
||||||
const [showCreateVersion, setShowCreateVersion] = useState(false);
|
|
||||||
const [showEditVersions, setShowEditVersions] = useState(false);
|
|
||||||
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
|
||||||
const [showTypeGraph, setShowTypeGraph] = useState(false);
|
|
||||||
const [showQR, setShowQR] = useState(false);
|
|
||||||
|
|
||||||
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
|
||||||
const [showCreateCst, setShowCreateCst] = useState(false);
|
|
||||||
|
|
||||||
const [renameInitialData, setRenameInitialData] = useState<ICstRenameData>();
|
const [renameInitialData, setRenameInitialData] = useState<ICstRenameData>();
|
||||||
const [showRenameCst, setShowRenameCst] = useState(false);
|
|
||||||
|
|
||||||
const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined);
|
const showClone = useDialogsStore(state => state.showCloneLibraryItem);
|
||||||
const [showTemplates, setShowTemplates] = useState(false);
|
const showCreateVersion = useDialogsStore(state => state.showCreateVersion);
|
||||||
|
const showEditVersions = useDialogsStore(state => state.showEditVersions);
|
||||||
|
const showEditEditors = useDialogsStore(state => state.showEditEditors);
|
||||||
|
const showEditLocation = useDialogsStore(state => state.showChangeLocation);
|
||||||
|
|
||||||
|
const showCreateCst = useDialogsStore(state => state.showCreateCst);
|
||||||
|
const showDeleteCst = useDialogsStore(state => state.showDeleteCst);
|
||||||
|
|
||||||
|
const showRenameCst = useDialogsStore(state => state.showRenameCst);
|
||||||
|
const showEditTerm = useDialogsStore(state => state.showEditWordForms);
|
||||||
|
|
||||||
|
const showSubstituteCst = useDialogsStore(state => state.showSubstituteCst);
|
||||||
|
const showCstTemplate = useDialogsStore(state => state.showCstTemplate);
|
||||||
|
const showInlineSynthesis = useDialogsStore(state => state.showInlineSynthesis);
|
||||||
|
const showTypeGraph = useDialogsStore(state => state.showShowTypeGraph);
|
||||||
|
const showUpload = useDialogsStore(state => state.showUploadRSForm);
|
||||||
|
const showQR = useDialogsStore(state => state.showQR);
|
||||||
|
|
||||||
const typeInfo = useMemo(
|
const typeInfo = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
@ -235,13 +220,6 @@ export const RSEditState = ({
|
||||||
[router]
|
[router]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createVersion = useCallback(() => {
|
|
||||||
if (isModified && !promptUnsaved()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setShowCreateVersion(true);
|
|
||||||
}, [isModified]);
|
|
||||||
|
|
||||||
const restoreVersion = useCallback(() => {
|
const restoreVersion = useCallback(() => {
|
||||||
if (!model.versionID || !window.confirm(prompts.restoreArchive)) {
|
if (!model.versionID || !window.confirm(prompts.restoreArchive)) {
|
||||||
return;
|
return;
|
||||||
|
@ -252,7 +230,7 @@ export const RSEditState = ({
|
||||||
});
|
});
|
||||||
}, [model, viewVersion]);
|
}, [model, viewVersion]);
|
||||||
|
|
||||||
function calculateCloneLocation(): string {
|
const calculateCloneLocation = useCallback(() => {
|
||||||
if (!model.schema) {
|
if (!model.schema) {
|
||||||
return LocationHead.USER;
|
return LocationHead.USER;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +243,7 @@ export const RSEditState = ({
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
return head === LocationHead.USER ? LocationHead.USER : location;
|
return head === LocationHead.USER ? LocationHead.USER : location;
|
||||||
}
|
}, [model.schema, user]);
|
||||||
|
|
||||||
const handleCreateCst = useCallback(
|
const handleCreateCst = useCallback(
|
||||||
(data: ICstCreateData) => {
|
(data: ICstCreateData) => {
|
||||||
|
@ -397,6 +375,29 @@ export const RSEditState = ({
|
||||||
[model, setSelected]
|
[model, setSelected]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const createVersion = useCallback(() => {
|
||||||
|
if (!model.schema || (isModified && !promptUnsaved())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showCreateVersion({
|
||||||
|
versions: model.schema.versions,
|
||||||
|
onCreate: handleCreateVersion,
|
||||||
|
selected: selected,
|
||||||
|
totalCount: model.schema.items.length
|
||||||
|
});
|
||||||
|
}, [isModified, model.schema, selected, handleCreateVersion, showCreateVersion]);
|
||||||
|
|
||||||
|
const promptEditVersions = useCallback(() => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showEditVersions({
|
||||||
|
versions: model.schema.versions,
|
||||||
|
onDelete: handleDeleteVersion,
|
||||||
|
onUpdate: handleUpdateVersion
|
||||||
|
});
|
||||||
|
}, [model.schema, handleDeleteVersion, handleUpdateVersion, showEditVersions]);
|
||||||
|
|
||||||
const moveUp = useCallback(() => {
|
const moveUp = useCallback(() => {
|
||||||
if (!model.schema?.items || selected.length === 0) {
|
if (!model.schema?.items || selected.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -460,11 +461,10 @@ export const RSEditState = ({
|
||||||
if (skipDialog) {
|
if (skipDialog) {
|
||||||
handleCreateCst(data);
|
handleCreateCst(data);
|
||||||
} else {
|
} else {
|
||||||
setCreateInitialData(data);
|
showCreateCst({ schema: model.schema, onCreate: handleCreateCst, initial: data });
|
||||||
setShowCreateCst(true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeCst, handleCreateCst, model.schema]
|
[activeCst, handleCreateCst, model.schema, showCreateCst]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cloneCst = useCallback(() => {
|
const cloneCst = useCallback(() => {
|
||||||
|
@ -485,7 +485,7 @@ export const RSEditState = ({
|
||||||
}, [activeCst, handleCreateCst, model.schema]);
|
}, [activeCst, handleCreateCst, model.schema]);
|
||||||
|
|
||||||
const renameCst = useCallback(() => {
|
const renameCst = useCallback(() => {
|
||||||
if (!activeCst) {
|
if (!activeCst || !model.schema) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ICstRenameData = {
|
const data: ICstRenameData = {
|
||||||
|
@ -494,22 +494,34 @@ export const RSEditState = ({
|
||||||
cst_type: activeCst.cst_type
|
cst_type: activeCst.cst_type
|
||||||
};
|
};
|
||||||
setRenameInitialData(data);
|
setRenameInitialData(data);
|
||||||
setShowRenameCst(true);
|
showRenameCst({
|
||||||
}, [activeCst]);
|
schema: model.schema,
|
||||||
|
initial: data,
|
||||||
|
allowChangeType: !activeCst.is_inherited,
|
||||||
|
onRename: handleRenameCst
|
||||||
|
});
|
||||||
|
}, [activeCst, model.schema, handleRenameCst, showRenameCst]);
|
||||||
|
|
||||||
const substitute = useCallback(() => {
|
const substitute = useCallback(() => {
|
||||||
if (isModified && !promptUnsaved()) {
|
if (!model.schema || (isModified && !promptUnsaved())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setShowSubstitute(true);
|
showSubstituteCst({ schema: model.schema, onSubstitute: handleSubstituteCst });
|
||||||
}, [isModified]);
|
}, [isModified, model.schema, handleSubstituteCst, showSubstituteCst]);
|
||||||
|
|
||||||
const inlineSynthesis = useCallback(() => {
|
const inlineSynthesis = useCallback(() => {
|
||||||
if (isModified && !promptUnsaved()) {
|
if (!model.schema || (isModified && !promptUnsaved())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setShowInlineSynthesis(true);
|
showInlineSynthesis({ receiver: model.schema, onInlineSynthesis: handleInlineSynthesis });
|
||||||
}, [isModified]);
|
}, [isModified, model.schema, handleInlineSynthesis, showInlineSynthesis]);
|
||||||
|
|
||||||
|
const promptDeleteCst = useCallback(() => {
|
||||||
|
if (!model.schema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showDeleteCst({ schema: model.schema, selected: selected, onDelete: handleDeleteCst });
|
||||||
|
}, [model.schema, selected, handleDeleteCst, showDeleteCst]);
|
||||||
|
|
||||||
const editTermForms = useCallback(() => {
|
const editTermForms = useCallback(() => {
|
||||||
if (!activeCst) {
|
if (!activeCst) {
|
||||||
|
@ -518,8 +530,8 @@ export const RSEditState = ({
|
||||||
if (isModified && !promptUnsaved()) {
|
if (isModified && !promptUnsaved()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setShowEditTerm(true);
|
showEditTerm({ target: activeCst, onSave: handleSaveWordforms });
|
||||||
}, [isModified, activeCst]);
|
}, [isModified, activeCst, handleSaveWordforms, showEditTerm]);
|
||||||
|
|
||||||
const reindex = useCallback(() => model.resetAliases(() => toast.success(information.reindexComplete)), [model]);
|
const reindex = useCallback(() => model.resetAliases(() => toast.success(information.reindexComplete)), [model]);
|
||||||
const reorder = useCallback(() => model.restoreOrder(() => toast.success(information.reorderComplete)), [model]);
|
const reorder = useCallback(() => model.restoreOrder(() => toast.success(information.reorderComplete)), [model]);
|
||||||
|
@ -551,28 +563,45 @@ export const RSEditState = ({
|
||||||
});
|
});
|
||||||
}, [activeCst, setSelected, model, isModified]);
|
}, [activeCst, setSelected, model, isModified]);
|
||||||
|
|
||||||
|
const setEditors = useCallback(
|
||||||
|
(newEditors: UserID[]) => {
|
||||||
|
model.setEditors(newEditors, () => toast.success(information.changesSaved));
|
||||||
|
},
|
||||||
|
[model]
|
||||||
|
);
|
||||||
|
|
||||||
const promptTemplate = useCallback(() => {
|
const promptTemplate = useCallback(() => {
|
||||||
if (isModified && !promptUnsaved()) {
|
if ((isModified && !promptUnsaved()) || !model.schema) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setInsertCstID(activeCst?.id);
|
showCstTemplate({ schema: model.schema, onCreate: handleCreateCst, insertAfter: activeCst?.id });
|
||||||
setShowTemplates(true);
|
}, [activeCst, isModified, handleCreateCst, model.schema, showCstTemplate]);
|
||||||
}, [activeCst, isModified]);
|
|
||||||
|
|
||||||
const promptClone = useCallback(() => {
|
const promptClone = useCallback(() => {
|
||||||
if (isModified && !promptUnsaved()) {
|
if (!model.schema || (isModified && !promptUnsaved())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setShowClone(true);
|
showClone({
|
||||||
}, [isModified]);
|
base: model.schema,
|
||||||
|
initialLocation: calculateCloneLocation(),
|
||||||
|
selected: selected,
|
||||||
|
totalCount: model.schema.items.length
|
||||||
|
});
|
||||||
|
}, [isModified, model.schema, selected, showClone, calculateCloneLocation]);
|
||||||
|
|
||||||
const promptEditors = useCallback(() => {
|
const promptEditors = useCallback(() => {
|
||||||
setShowEditEditors(true);
|
if (!model.schema) {
|
||||||
}, []);
|
return;
|
||||||
|
}
|
||||||
|
showEditEditors({ editors: model.schema.editors, setEditors: setEditors });
|
||||||
|
}, [model.schema, showEditEditors, setEditors]);
|
||||||
|
|
||||||
const promptLocation = useCallback(() => {
|
const promptLocation = useCallback(() => {
|
||||||
setShowEditLocation(true);
|
if (!model.schema) {
|
||||||
}, []);
|
return;
|
||||||
|
}
|
||||||
|
showEditLocation({ initial: model.schema.location, onChangeLocation: handleSetLocation });
|
||||||
|
}, [model.schema, showEditLocation, handleSetLocation]);
|
||||||
|
|
||||||
const download = useCallback(() => {
|
const download = useCallback(() => {
|
||||||
if (isModified && !promptUnsaved()) {
|
if (isModified && !promptUnsaved()) {
|
||||||
|
@ -611,13 +640,6 @@ export const RSEditState = ({
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setEditors = useCallback(
|
|
||||||
(newEditors: UserID[]) => {
|
|
||||||
model.setEditors(newEditors, () => toast.success(information.changesSaved));
|
|
||||||
},
|
|
||||||
[model]
|
|
||||||
);
|
|
||||||
|
|
||||||
function generateQR(): string {
|
function generateQR(): string {
|
||||||
const currentRef = window.location.href;
|
const currentRef = window.location.href;
|
||||||
return currentRef.includes('?') ? currentRef + '&qr' : currentRef + '?qr';
|
return currentRef.includes('?') ? currentRef + '&qr' : currentRef + '?qr';
|
||||||
|
@ -653,19 +675,19 @@ export const RSEditState = ({
|
||||||
viewPredecessor,
|
viewPredecessor,
|
||||||
createVersion,
|
createVersion,
|
||||||
restoreVersion,
|
restoreVersion,
|
||||||
promptEditVersions: () => setShowEditVersions(true),
|
promptEditVersions,
|
||||||
|
|
||||||
moveUp,
|
moveUp,
|
||||||
moveDown,
|
moveDown,
|
||||||
createCst,
|
createCst,
|
||||||
cloneCst,
|
cloneCst,
|
||||||
renameCst,
|
renameCst,
|
||||||
promptDeleteCst: () => setShowDeleteCst(true),
|
promptDeleteCst,
|
||||||
editTermForms,
|
editTermForms,
|
||||||
|
|
||||||
promptTemplate,
|
promptTemplate,
|
||||||
promptClone,
|
promptClone,
|
||||||
promptUpload: () => setShowUpload(true),
|
promptUpload: () => showUpload({ upload: model.upload }),
|
||||||
download,
|
download,
|
||||||
share,
|
share,
|
||||||
|
|
||||||
|
@ -675,113 +697,10 @@ export const RSEditState = ({
|
||||||
produceStructure,
|
produceStructure,
|
||||||
substitute,
|
substitute,
|
||||||
|
|
||||||
showTypeGraph: () => setShowTypeGraph(true),
|
showTypeGraph: () => showTypeGraph({ items: typeInfo }),
|
||||||
showQR: () => setShowQR(true)
|
showQR: () => showQR({ target: generateQR() })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{model.schema ? (
|
|
||||||
<>
|
|
||||||
{showQR ? <DlgShowQR hideWindow={() => setShowQR(false)} target={generateQR()} /> : null}
|
|
||||||
{showUpload ? <DlgUploadRSForm hideWindow={() => setShowUpload(false)} /> : null}
|
|
||||||
{showClone ? (
|
|
||||||
<DlgCloneLibraryItem
|
|
||||||
base={model.schema}
|
|
||||||
initialLocation={calculateCloneLocation()}
|
|
||||||
hideWindow={() => setShowClone(false)}
|
|
||||||
selected={selected}
|
|
||||||
totalCount={model.schema.items.length}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showCreateCst ? (
|
|
||||||
<DlgCreateCst
|
|
||||||
hideWindow={() => setShowCreateCst(false)}
|
|
||||||
onCreate={handleCreateCst}
|
|
||||||
schema={model.schema}
|
|
||||||
initial={createInitialData}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{activeCst && showRenameCst && renameInitialData ? (
|
|
||||||
<DlgRenameCst
|
|
||||||
hideWindow={() => setShowRenameCst(false)}
|
|
||||||
onRename={handleRenameCst}
|
|
||||||
allowChangeType={!activeCst.is_inherited}
|
|
||||||
initial={renameInitialData}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showSubstitute ? (
|
|
||||||
<DlgSubstituteCst
|
|
||||||
schema={model.schema}
|
|
||||||
hideWindow={() => setShowSubstitute(false)} // prettier: split lines
|
|
||||||
onSubstitute={handleSubstituteCst}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showDeleteCst ? (
|
|
||||||
<DlgDeleteCst
|
|
||||||
schema={model.schema}
|
|
||||||
hideWindow={() => setShowDeleteCst(false)}
|
|
||||||
onDelete={handleDeleteCst}
|
|
||||||
selected={selected}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditTerm && activeCst ? (
|
|
||||||
<DlgEditWordForms
|
|
||||||
hideWindow={() => setShowEditTerm(false)}
|
|
||||||
onSave={handleSaveWordforms}
|
|
||||||
target={activeCst}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showTemplates ? (
|
|
||||||
<DlgConstituentaTemplate
|
|
||||||
schema={model.schema}
|
|
||||||
hideWindow={() => setShowTemplates(false)}
|
|
||||||
insertAfter={insertCstID}
|
|
||||||
onCreate={handleCreateCst}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showCreateVersion ? (
|
|
||||||
<DlgCreateVersion
|
|
||||||
versions={model.schema.versions}
|
|
||||||
hideWindow={() => setShowCreateVersion(false)}
|
|
||||||
onCreate={handleCreateVersion}
|
|
||||||
selected={selected}
|
|
||||||
totalCount={model.schema.items.length}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditVersions ? (
|
|
||||||
<DlgEditVersions
|
|
||||||
versions={model.schema.versions}
|
|
||||||
hideWindow={() => setShowEditVersions(false)}
|
|
||||||
onDelete={handleDeleteVersion}
|
|
||||||
onUpdate={handleUpdateVersion}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditEditors ? (
|
|
||||||
<DlgEditEditors
|
|
||||||
hideWindow={() => setShowEditEditors(false)}
|
|
||||||
editors={model.schema.editors}
|
|
||||||
setEditors={setEditors}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{showEditLocation ? (
|
|
||||||
<DlgChangeLocation
|
|
||||||
hideWindow={() => setShowEditLocation(false)}
|
|
||||||
initial={model.schema.location}
|
|
||||||
onChangeLocation={handleSetLocation}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{showInlineSynthesis ? (
|
|
||||||
<DlgInlineSynthesis
|
|
||||||
receiver={model.schema}
|
|
||||||
hideWindow={() => setShowInlineSynthesis(false)}
|
|
||||||
onInlineSynthesis={handleInlineSynthesis}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{showTypeGraph ? <DlgShowTypeGraph items={typeInfo} hideWindow={() => setShowTypeGraph(false)} /> : null}
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</RSEditContext>
|
</RSEditContext>
|
||||||
);
|
);
|
||||||
|
|
86
rsconcept/frontend/src/stores/dialogs.ts
Normal file
86
rsconcept/frontend/src/stores/dialogs.ts
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import { DlgChangeInputSchemaProps } from '@/dialogs/DlgChangeInputSchema';
|
||||||
|
import { DlgChangeLocationProps } from '@/dialogs/DlgChangeLocation';
|
||||||
|
import { DlgCloneLibraryItemProps } from '@/dialogs/DlgCloneLibraryItem';
|
||||||
|
import { DlgCreateCstProps } from '@/dialogs/DlgCreateCst/DlgCreateCst';
|
||||||
|
import { DlgCreateOperationProps } from '@/dialogs/DlgCreateOperation/DlgCreateOperation';
|
||||||
|
import { DlgCreateVersionProps } from '@/dialogs/DlgCreateVersion';
|
||||||
|
import { DlgCstTemplateProps } from '@/dialogs/DlgCstTemplate/DlgCstTemplate';
|
||||||
|
import { DlgDeleteCstProps } from '@/dialogs/DlgDeleteCst/DlgDeleteCst';
|
||||||
|
import { DlgDeleteOperationProps } from '@/dialogs/DlgDeleteOperation';
|
||||||
|
import { DlgEditEditorsProps } from '@/dialogs/DlgEditEditors/DlgEditEditors';
|
||||||
|
import { DlgEditOperationProps } from '@/dialogs/DlgEditOperation/DlgEditOperation';
|
||||||
|
import { DlgEditReferenceProps } from '@/dialogs/DlgEditReference/DlgEditReference';
|
||||||
|
import { DlgEditVersionsProps } from '@/dialogs/DlgEditVersions/DlgEditVersions';
|
||||||
|
import { DlgEditWordFormsProps } from '@/dialogs/DlgEditWordForms/DlgEditWordForms';
|
||||||
|
import { DlgGraphParamsProps } from '@/dialogs/DlgGraphParams';
|
||||||
|
import { DlgInlineSynthesisProps } from '@/dialogs/DlgInlineSynthesis/DlgInlineSynthesis';
|
||||||
|
import { DlgRelocateConstituentsProps } from '@/dialogs/DlgRelocateConstituents';
|
||||||
|
import { DlgRenameCstProps } from '@/dialogs/DlgRenameCst';
|
||||||
|
import { DlgShowASTProps } from '@/dialogs/DlgShowAST/DlgShowAST';
|
||||||
|
import { DlgShowQRProps } from '@/dialogs/DlgShowQR';
|
||||||
|
import { DlgShowTypeGraphProps } from '@/dialogs/DlgShowTypeGraph/DlgShowTypeGraph';
|
||||||
|
import { DlgSubstituteCstProps } from '@/dialogs/DlgSubstituteCst';
|
||||||
|
import { DlgUploadRSFormProps } from '@/dialogs/DlgUploadRSForm';
|
||||||
|
import { DialogType } from '@/models/miscellaneous';
|
||||||
|
|
||||||
|
interface DialogsStore {
|
||||||
|
active: DialogType | undefined;
|
||||||
|
props: unknown;
|
||||||
|
hideDialog: () => void;
|
||||||
|
|
||||||
|
showCstTemplate: (props: DlgCstTemplateProps) => void;
|
||||||
|
showCreateCst: (props: DlgCreateCstProps) => void;
|
||||||
|
showCreateOperation: (props: DlgCreateOperationProps) => void;
|
||||||
|
showDeleteCst: (props: DlgDeleteCstProps) => void;
|
||||||
|
showEditEditors: (props: DlgEditEditorsProps) => void;
|
||||||
|
showEditOperation: (props: DlgEditOperationProps) => void;
|
||||||
|
showEditReference: (props: DlgEditReferenceProps) => void;
|
||||||
|
showEditVersions: (props: DlgEditVersionsProps) => void;
|
||||||
|
showEditWordForms: (props: DlgEditWordFormsProps) => void;
|
||||||
|
showInlineSynthesis: (props: DlgInlineSynthesisProps) => void;
|
||||||
|
showShowAST: (props: DlgShowASTProps) => void;
|
||||||
|
showShowTypeGraph: (props: DlgShowTypeGraphProps) => void;
|
||||||
|
showChangeInputSchema: (props: DlgChangeInputSchemaProps) => void;
|
||||||
|
showChangeLocation: (props: DlgChangeLocationProps) => void;
|
||||||
|
showCloneLibraryItem: (props: DlgCloneLibraryItemProps) => void;
|
||||||
|
showCreateVersion: (props: DlgCreateVersionProps) => void;
|
||||||
|
showDeleteOperation: (props: DlgDeleteOperationProps) => void;
|
||||||
|
showGraphParams: (props: DlgGraphParamsProps) => void;
|
||||||
|
showRelocateConstituents: (props: DlgRelocateConstituentsProps) => void;
|
||||||
|
showRenameCst: (props: DlgRenameCstProps) => void;
|
||||||
|
showQR: (props: DlgShowQRProps) => void;
|
||||||
|
showSubstituteCst: (props: DlgSubstituteCstProps) => void;
|
||||||
|
showUploadRSForm: (props: DlgUploadRSFormProps) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDialogsStore = create<DialogsStore>()(set => ({
|
||||||
|
active: undefined,
|
||||||
|
props: undefined,
|
||||||
|
hideDialog: () => set({ active: undefined, props: undefined }),
|
||||||
|
|
||||||
|
showCstTemplate: props => set({ active: DialogType.CONSTITUENTA_TEMPLATE, props: props }),
|
||||||
|
showCreateCst: props => set({ active: DialogType.CREATE_CONSTITUENTA, props: props }),
|
||||||
|
showCreateOperation: props => set({ active: DialogType.CREATE_OPERATION, props: props }),
|
||||||
|
showDeleteCst: props => set({ active: DialogType.DELETE_CONSTITUENTA, props: props }),
|
||||||
|
showEditEditors: props => set({ active: DialogType.EDIT_EDITORS, props: props }),
|
||||||
|
showEditOperation: props => set({ active: DialogType.EDIT_OPERATION, props: props }),
|
||||||
|
showEditReference: props => set({ active: DialogType.EDIT_REFERENCE, props: props }),
|
||||||
|
showEditVersions: props => set({ active: DialogType.EDIT_VERSIONS, props: props }),
|
||||||
|
showEditWordForms: props => set({ active: DialogType.EDIT_WORD_FORMS, props: props }),
|
||||||
|
showInlineSynthesis: props => set({ active: DialogType.INLINE_SYNTHESIS, props: props }),
|
||||||
|
showShowAST: props => set({ active: DialogType.SHOW_AST, props: props }),
|
||||||
|
showShowTypeGraph: props => set({ active: DialogType.SHOW_TYPE_GRAPH, props: props }),
|
||||||
|
showChangeInputSchema: props => set({ active: DialogType.CHANGE_INPUT_SCHEMA, props: props }),
|
||||||
|
showChangeLocation: props => set({ active: DialogType.CHANGE_LOCATION, props: props }),
|
||||||
|
showCloneLibraryItem: props => set({ active: DialogType.CLONE_LIBRARY_ITEM, props: props }),
|
||||||
|
showCreateVersion: props => set({ active: DialogType.CREATE_VERSION, props: props }),
|
||||||
|
showDeleteOperation: props => set({ active: DialogType.DELETE_OPERATION, props: props }),
|
||||||
|
showGraphParams: props => set({ active: DialogType.GRAPH_PARAMETERS, props: props }),
|
||||||
|
showRelocateConstituents: props => set({ active: DialogType.RELOCATE_CONSTITUENTS, props: props }),
|
||||||
|
showRenameCst: props => set({ active: DialogType.RENAME_CONSTITUENTA, props: props }),
|
||||||
|
showQR: props => set({ active: DialogType.SHOW_QR_CODE, props: props }),
|
||||||
|
showSubstituteCst: props => set({ active: DialogType.SUBSTITUTE_CONSTITUENTS, props: props }),
|
||||||
|
showUploadRSForm: props => set({ active: DialogType.UPLOAD_RSFORM, props: props })
|
||||||
|
}));
|
Loading…
Reference in New Issue
Block a user