Refactor dialogs

This commit is contained in:
IRBorisov 2023-07-29 15:37:49 +03:00
parent 4f45b9978e
commit 44cc9371e4
3 changed files with 93 additions and 72 deletions

View File

@ -7,25 +7,24 @@ import SubmitButton from '../../components/Common/SubmitButton';
import TextArea from '../../components/Common/TextArea';
import { DumpBinIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
import { type CstType, EditMode, type ICstCreateData, ICstUpdateData, SyntaxTree } from '../../utils/models';
import { createAliasFor, getCstTypeLabel } from '../../utils/staticUI';
import DlgCreateCst from './DlgCreateCst';
import { type CstType, EditMode, ICstUpdateData, SyntaxTree } from '../../utils/models';
import { getCstTypeLabel } from '../../utils/staticUI';
import EditorRSExpression from './EditorRSExpression';
import ViewSideConstituents from './elements/ViewSideConstituents';
import { RSTabsList } from './RSTabs';
interface EditorConstituentaProps {
onShowAST: (ast: SyntaxTree) => void
onShowCreateCst: (position: number | undefined, type: CstType | undefined) => void
}
function EditorConstituenta({onShowAST}: EditorConstituentaProps) {
function EditorConstituenta({ onShowAST, onShowCreateCst }: EditorConstituentaProps) {
const navigate = useNavigate();
const {
activeCst, activeID, schema, setActiveID, processing, isEditable,
cstDelete, cstUpdate, cstCreate
cstDelete, cstUpdate
} = useRSForm();
const [showCstModal, setShowCstModal] = useState(false);
const [isModified, setIsModified] = useState(false);
const [editMode, setEditMode] = useState(EditMode.TEXT);
@ -107,24 +106,12 @@ function EditorConstituenta({onShowAST}: EditorConstituentaProps) {
}, [activeID, schema, cstDelete, navigate]);
const handleAddNew = useCallback(
(type?: CstType) => {
if (!activeID || !schema?.items) {
() => {
if (!activeID || !schema) {
return;
}
if (!type) {
setShowCstModal(true);
} else {
const data: ICstCreateData = {
cst_type: type,
alias: createAliasFor(type, schema),
insert_after: activeID
}
cstCreate(data, newCst => {
navigate(`/rsforms/${schema.id}?tab=${RSTabsList.CST_EDIT}&active=${newCst.id}`);
toast.success(`Конституента добавлена: ${newCst.alias}`);
});
}
}, [activeID, schema, cstCreate, navigate]);
onShowCreateCst(activeID, activeCst?.cstType);
}, [activeID, activeCst?.cstType, schema, onShowCreateCst]);
const handleRename = useCallback(() => {
toast.info('Переименование в разработке');
@ -136,11 +123,6 @@ function EditorConstituenta({onShowAST}: EditorConstituentaProps) {
return (
<div className='flex items-start w-full gap-2'>
{showCstModal && <DlgCreateCst
hideWindow={() => { setShowCstModal(false); }}
onCreate={handleAddNew}
defaultType={activeCst?.cstType as CstType}
/>}
<form onSubmit={handleSubmit} className='flex-grow min-w-[50rem] max-w-min px-4 py-2 border'>
<div className='flex items-start justify-between'>
<button type='submit'
@ -176,7 +158,7 @@ function EditorConstituenta({onShowAST}: EditorConstituentaProps) {
<MiniButton
tooltip='Создать конституенты после данной'
disabled={!isEnabled}
onClick={() => { handleAddNew(); }}
onClick={handleAddNew}
icon={<SmallPlusIcon size={5} color={isEnabled ? 'text-green' : ''} />}
/>
<MiniButton

View File

@ -7,24 +7,23 @@ import Divider from '../../components/Common/Divider';
import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext';
import { CstType, type IConstituenta, type ICstCreateData, ICstMovetoData,inferStatus, ParsingStatus, ValueClass } from '../../utils/models'
import { createAliasFor, getCstTypePrefix, getCstTypeShortcut, getStatusInfo, getTypeLabel } from '../../utils/staticUI';
import DlgCreateCst from './DlgCreateCst';
import { CstType, type IConstituenta, ICstMovetoData, inferStatus, ParsingStatus, ValueClass } from '../../utils/models'
import { getCstTypePrefix, getCstTypeShortcut, getStatusInfo, getTypeLabel } from '../../utils/staticUI';
interface EditorItemsProps {
onOpenEdit: (cst: IConstituenta) => void
onShowCreateCst: (position: number | undefined, type: CstType | undefined, skipDialog?: boolean) => void
}
function EditorItems({ onOpenEdit }: EditorItemsProps) {
function EditorItems({ onOpenEdit, onShowCreateCst }: EditorItemsProps) {
const {
schema, isEditable,
cstCreate, cstDelete, cstMoveTo, resetAliases
cstDelete, cstMoveTo, resetAliases
} = useRSForm();
const { noNavigation } = useConceptTheme();
const [selected, setSelected] = useState<number[]>([]);
const nothingSelected = useMemo(() => selected.length === 0, [selected]);
const [showCstModal, setShowCstModal] = useState(false);
const [toggledClearRows, setToggledClearRows] = useState(false);
const handleRowClicked = useCallback(
@ -112,25 +111,18 @@ function EditorItems({ onOpenEdit }: EditorItemsProps) {
}, [resetAliases]);
// Add new constituent
const handleAddNew = useCallback((type?: CstType) => {
const handleAddNew = useCallback(
(type?: CstType) => {
if (!schema) {
return;
}
if (!type) {
setShowCstModal(true);
} else {
const selectedPosition = selected.reduce((prev, cstID) => {
const position = schema.items.findIndex(cst => cst.id === cstID);
return Math.max(position, prev);
}, -1) + 1;
const data: ICstCreateData = {
cst_type: type,
alias: createAliasFor(type, schema),
insert_after: selectedPosition > 0 ? selectedPosition : null
}
cstCreate(data, new_cst => toast.success(`Добавлена конституента ${new_cst.alias}`));
}
}, [schema, selected, cstCreate]);
const insert_where = selectedPosition > 0 ? selectedPosition : undefined;
onShowCreateCst(insert_where, type, type !== undefined);
}, [schema, onShowCreateCst, selected]);
// Implement hotkeys for working with constituents table
function handleTableKey(event: React.KeyboardEvent<HTMLDivElement>) {
@ -283,11 +275,7 @@ function EditorItems({ onOpenEdit }: EditorItemsProps) {
], []
);
return (<>
{showCstModal && <DlgCreateCst
hideWindow={() => { setShowCstModal(false); }}
onCreate={handleAddNew}
/>}
return (
<div className='w-full'>
<div
className={'flex justify-start w-full gap-1 px-2 py-1 border-y items-center h-[2.2rem] clr-app' +
@ -376,7 +364,7 @@ function EditorItems({ onOpenEdit }: EditorItemsProps) {
/>
</div>
</div>
</>);
);
}
export default EditorItems;

View File

@ -1,13 +1,17 @@
import { useCallback, useEffect, useLayoutEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { TabList, TabPanel, Tabs } from 'react-tabs';
import { toast } from 'react-toastify';
import BackendError from '../../components/BackendError';
import ConceptTab from '../../components/Common/ConceptTab';
import { Loader } from '../../components/Common/Loader';
import { useRSForm } from '../../context/RSFormContext';
import useLocalStorage from '../../hooks/useLocalStorage';
import { type IConstituenta,SyntaxTree } from '../../utils/models';
import { CstType,type IConstituenta, ICstCreateData, SyntaxTree } from '../../utils/models';
import { createAliasFor } from '../../utils/staticUI';
import DlgCloneRSForm from './DlgCloneRSForm';
import DlgCreateCst from './DlgCreateCst';
import DlgShowAST from './DlgShowAST';
import DlgUploadRSForm from './DlgUploadRSForm';
import EditorConstituenta from './EditorConstituenta';
@ -23,28 +27,64 @@ export enum RSTabsList {
}
function RSTabs() {
const { setActiveID, activeID, error, schema, loading } = useRSForm();
const [tabIndex, setTabIndex] = useLocalStorage('rsform_edit_tab', RSTabsList.CARD);
const navigate = useNavigate();
const { setActiveID, activeID, error, schema, loading, cstCreate } = useRSForm();
const [activeTab, setActiveTab] = useLocalStorage('rsform_edit_tab', RSTabsList.CARD);
const [init, setInit] = useState(false);
const [showUpload, setShowUpload] = useState(false);
const [showClone, setShowClone] = useState(false);
const [syntaxTree, setSyntaxTree] = useState<SyntaxTree>([]);
const [showAST, setShowAST] = useState(false);
const [defaultType, setDefaultType] = useState<CstType | undefined>(undefined);
const [insertPosition, setInsertPosition] = useState<number | undefined>(undefined);
const [showCreateCst, setShowCreateCst] = useState(false);
const handleAddNew = useCallback(
(type: CstType) => {
if (!schema?.items) {
return;
}
const data: ICstCreateData = {
cst_type: type,
alias: createAliasFor(type, schema),
insert_after: insertPosition ?? null
}
cstCreate(data, newCst => {
toast.success(`Конституента добавлена: ${newCst.alias}`);
if (activeTab === RSTabsList.CST_EDIT) {
navigate(`/rsforms/${schema.id}?tab=${RSTabsList.CST_EDIT}&active=${newCst.id}`);
}
});
}, [schema, cstCreate, insertPosition, navigate, activeTab]);
const onShowCreateCst = useCallback(
(position: number | undefined, type: CstType | undefined, skipDialog?: boolean) => {
if (skipDialog && type) {
handleAddNew(type);
} else {
setDefaultType(type);
setInsertPosition(position);
setShowCreateCst(true);
}
}, [handleAddNew]);
const onShowAST = useCallback(
(ast: SyntaxTree) => {
setSyntaxTree(ast);
setShowAST(true);
}, [])
}, []);
const onEditCst = (cst: IConstituenta) => {
setActiveID(cst.id);
setTabIndex(RSTabsList.CST_EDIT)
setActiveTab(RSTabsList.CST_EDIT)
};
const onSelectTab = (index: number) => {
setTabIndex(index);
setActiveTab(index);
};
useLayoutEffect(() => {
@ -66,17 +106,17 @@ function RSTabs() {
useEffect(() => {
const url = new URL(window.location.href);
const tabQuery = url.searchParams.get('tab');
setTabIndex(Number(tabQuery) || RSTabsList.CARD);
}, [setTabIndex]);
setActiveTab(Number(tabQuery) || RSTabsList.CARD);
}, [setActiveTab]);
useEffect(() => {
if (init) {
const url = new URL(window.location.href);
const currentActive = url.searchParams.get('active');
const currentTab = url.searchParams.get('tab');
const saveHistory = tabIndex === RSTabsList.CST_EDIT && currentActive !== String(activeID);
if (currentTab !== String(tabIndex)) {
url.searchParams.set('tab', String(tabIndex));
const saveHistory = activeTab === RSTabsList.CST_EDIT && currentActive !== String(activeID);
if (currentTab !== String(activeTab)) {
url.searchParams.set('tab', String(activeTab));
}
if (activeID) {
if (currentActive !== String(activeID)) {
@ -91,7 +131,7 @@ function RSTabs() {
window.history.replaceState(null, '', url.toString());
}
}
}, [tabIndex, activeID, init]);
}, [activeTab, activeID, init]);
return (
<div className='w-full'>
@ -101,9 +141,19 @@ function RSTabs() {
<>
{showUpload && <DlgUploadRSForm hideWindow={() => { setShowUpload(false); }}/>}
{showClone && <DlgCloneRSForm hideWindow={() => { setShowClone(false); }}/>}
{showAST && <DlgShowAST syntaxTree={syntaxTree} hideWindow={() => { setShowAST(false); }}/>}
{showAST &&
<DlgShowAST
syntaxTree={syntaxTree}
hideWindow={() => { setShowAST(false); }}
/>}
{showCreateCst &&
<DlgCreateCst
hideWindow={() => { setShowCreateCst(false); }}
onCreate={handleAddNew}
defaultType={defaultType}
/>}
<Tabs
selectedIndex={tabIndex}
selectedIndex={activeTab}
onSelect={onSelectTab}
defaultFocus={true}
selectedTabClassName='font-bold'
@ -127,13 +177,14 @@ function RSTabs() {
</TabPanel>
<TabPanel className='w-full'>
<EditorItems onOpenEdit={onEditCst} />
<EditorItems onOpenEdit={onEditCst} onShowCreateCst={onShowCreateCst} />
</TabPanel>
<TabPanel>
<EditorConstituenta onShowAST={onShowAST} />
<EditorConstituenta onShowAST={onShowAST} onShowCreateCst={onShowCreateCst} />
</TabPanel>
</Tabs></>
</Tabs>
</>
}
</div>);
}