Compare commits

..

No commits in common. "3b036f2c9d8b3d19b64cf70caada502f3e52858e" and "5cda15b9611c25d740f03a753c2612af222047e0" have entirely different histories.

14 changed files with 52 additions and 297 deletions

View File

@ -88,8 +88,6 @@ This readme file is used mostly to document project dependencies and conventions
- Rubik - Rubik
- Alegreya Sans SC - Alegreya Sans SC
- Noto Sans Math - Noto Sans Math
- Noto Sans Symbol
- Noto Color Emoji
</pre> </pre>
</details> </details>

View File

@ -4,7 +4,6 @@ import { IConstituenta } from '@/models/rsform';
import { isBasicConcept } from '@/models/rsformAPI'; import { isBasicConcept } from '@/models/rsformAPI';
import { labelCstTypification } from '@/utils/labels'; import { labelCstTypification } from '@/utils/labels';
import { IconChild } from '../Icons';
import { CProps } from '../props'; import { CProps } from '../props';
interface InfoConstituentaProps extends CProps.Div { interface InfoConstituentaProps extends CProps.Div {
@ -14,11 +13,9 @@ interface InfoConstituentaProps extends CProps.Div {
function InfoConstituenta({ data, className, ...restProps }: InfoConstituentaProps) { function InfoConstituenta({ data, className, ...restProps }: InfoConstituentaProps) {
return ( return (
<div className={clsx('dense min-w-[15rem] break-words', className)} {...restProps}> <div className={clsx('dense min-w-[15rem] break-words', className)} {...restProps}>
<h2 className='cursor-default' title={data.is_inherited ? ' наследник' : undefined}> <h2>
{data.alias} {data.alias}
{data.is_inherited ? ( {data.is_inherited ? ' (наследуется)' : ''}
<IconChild size='1rem' className='inline-icon translate-y-[-0.1rem] translate-x-[0.125rem]' />
) : null}
</h2> </h2>
{data.term_resolved ? ( {data.term_resolved ? (
<p> <p>

View File

@ -5,7 +5,6 @@ import { useLayoutEffect, useMemo, useState } from 'react';
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { Graph } from '@/models/Graph';
import { CstMatchMode } from '@/models/miscellaneous'; import { CstMatchMode } from '@/models/miscellaneous';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { isBasicConcept, matchConstituenta } from '@/models/rsformAPI'; import { isBasicConcept, matchConstituenta } from '@/models/rsformAPI';
@ -18,9 +17,7 @@ import ToolbarGraphSelection from './ToolbarGraphSelection';
interface PickMultiConstituentaProps { interface PickMultiConstituentaProps {
id?: string; id?: string;
schema: IRSForm; schema?: IRSForm;
data: IConstituenta[];
prefixID: string; prefixID: string;
rows?: number; rows?: number;
@ -30,39 +27,12 @@ interface PickMultiConstituentaProps {
const columnHelper = createColumnHelper<IConstituenta>(); const columnHelper = createColumnHelper<IConstituenta>();
function PickMultiConstituenta({ function PickMultiConstituenta({ id, schema, prefixID, rows, selected, setSelected }: PickMultiConstituentaProps) {
id,
schema,
data,
prefixID,
rows,
selected,
setSelected
}: PickMultiConstituentaProps) {
const { colors } = useConceptOptions(); const { colors } = useConceptOptions();
const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
const [filtered, setFiltered] = useState<IConstituenta[]>(data); const [filtered, setFiltered] = useState<IConstituenta[]>(schema?.items ?? []);
const [filterText, setFilterText] = useState(''); const [filterText, setFilterText] = useState('');
const foldedGraph = useMemo(() => {
if (data.length === schema.items.length) {
return schema.graph;
}
const newGraph = new Graph();
schema.graph.nodes.forEach(node => {
newGraph.addNode(node.id);
node.outputs.forEach(output => {
newGraph.addEdge(node.id, output);
});
});
schema.items
.filter(item => data.find(cst => cst.id === item.id) === undefined)
.forEach(item => {
newGraph.foldNode(item.id);
});
return newGraph;
}, [schema.graph, data]);
useLayoutEffect(() => { useLayoutEffect(() => {
if (filtered.length === 0) { if (filtered.length === 0) {
setRowSelection({}); setRowSelection({});
@ -76,17 +46,17 @@ function PickMultiConstituenta({
}, [filtered, setRowSelection, selected]); }, [filtered, setRowSelection, selected]);
useLayoutEffect(() => { useLayoutEffect(() => {
if (data.length === 0) { if (!schema || schema.items.length === 0) {
setFiltered([]); setFiltered([]);
} else if (filterText) { } else if (filterText) {
setFiltered(data.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL))); setFiltered(schema.items.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL)));
} else { } else {
setFiltered(data); setFiltered(schema.items);
} }
}, [filterText, data]); }, [filterText, schema?.items, schema]);
function handleRowSelection(updater: React.SetStateAction<RowSelectionState>) { function handleRowSelection(updater: React.SetStateAction<RowSelectionState>) {
if (!data) { if (!schema) {
setSelected([]); setSelected([]);
} else { } else {
const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater; const newRowSelection = typeof updater === 'function' ? updater(rowSelection) : updater;
@ -121,7 +91,7 @@ function PickMultiConstituenta({
<div> <div>
<div className='flex justify-between items-center clr-input px-3 border-x border-t rounded-t-md'> <div className='flex justify-between items-center clr-input px-3 border-x border-t rounded-t-md'>
<div className='w-[24ch] select-none whitespace-nowrap'> <div className='w-[24ch] select-none whitespace-nowrap'>
Выбраны {selected.length} из {data.length} Выбраны {selected.length} из {schema?.items.length ?? 0}
</div> </div>
<SearchBar <SearchBar
id='dlg_constituents_search' id='dlg_constituents_search'
@ -130,14 +100,16 @@ function PickMultiConstituenta({
value={filterText} value={filterText}
onChange={setFilterText} onChange={setFilterText}
/> />
<ToolbarGraphSelection {schema ? (
graph={foldedGraph} <ToolbarGraphSelection
isCore={cstID => isBasicConcept(schema.cstByID.get(cstID)?.cst_type)} graph={schema.graph}
isOwned={cstID => !schema.cstByID.get(cstID)?.is_inherited} isCore={cstID => isBasicConcept(schema.cstByID.get(cstID)?.cst_type)}
setSelected={setSelected} isOwned={cstID => !schema.cstByID.get(cstID)?.is_inherited}
emptySelection={selected.length === 0} setSelected={setSelected}
className='w-fit' emptySelection={selected.length === 0}
/> className='w-fit'
/>
) : null}
</div> </div>
<DataTable <DataTable
id={id} id={id}

View File

@ -9,7 +9,7 @@ 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 { IInlineSynthesisData, IRSForm } from '@/models/rsform';
import TabConstituents from './TabConstituents'; import TabConstituents from './TabConstituents';
import TabSchema from './TabSchema'; import TabSchema from './TabSchema';
@ -30,7 +30,7 @@ function DlgInlineSynthesis({ hideWindow, receiver, onInlineSynthesis }: DlgInli
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);
const [selected, setSelected] = useState<ConstituentaID[]>([]); const [selected, setSelected] = useState<LibraryItemID[]>([]);
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>([]); const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>([]);
const source = useRSFormDetails({ target: donorID ? String(donorID) : undefined }); const source = useRSFormDetails({ target: donorID ? String(donorID) : undefined });

View File

@ -17,16 +17,13 @@ interface TabConstituentsProps {
function TabConstituents({ schema, error, loading, selected, setSelected }: TabConstituentsProps) { function TabConstituents({ schema, error, loading, selected, setSelected }: TabConstituentsProps) {
return ( return (
<DataLoader id='dlg-constituents-tab' isLoading={loading} error={error} hasNoData={!schema}> <DataLoader id='dlg-constituents-tab' isLoading={loading} error={error} hasNoData={!schema}>
{schema ? ( <PickMultiConstituenta
<PickMultiConstituenta schema={schema}
schema={schema} rows={13}
data={schema.items} prefixID={prefixes.cst_inline_synth_list}
rows={13} selected={selected}
prefixID={prefixes.cst_inline_synth_list} setSelected={setSelected}
selected={selected} />
setSelected={setSelected}
/>
) : null}
</DataLoader> </DataLoader>
); );
} }

View File

@ -1,96 +0,0 @@
'use client';
import clsx from 'clsx';
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import PickMultiConstituenta from '@/components/select/PickMultiConstituenta';
import SelectLibraryItem from '@/components/select/SelectLibraryItem';
import Modal, { ModalProps } from '@/components/ui/Modal';
import DataLoader from '@/components/wrap/DataLoader';
import { useLibrary } from '@/context/LibraryContext';
import useRSFormDetails from '@/hooks/useRSFormDetails';
import { ILibraryItem, LibraryItemID } from '@/models/library';
import { ICstRelocateData, IOperation, IOperationSchema } from '@/models/oss';
import { getRelocateCandidates } from '@/models/ossAPI';
import { ConstituentaID } from '@/models/rsform';
import { prefixes } from '@/utils/constants';
interface DlgRelocateConstituentsProps extends Pick<ModalProps, 'hideWindow'> {
oss: IOperationSchema;
target: IOperation;
onSubmit: (data: ICstRelocateData) => void;
}
function DlgRelocateConstituents({ oss, hideWindow, target, onSubmit }: DlgRelocateConstituentsProps) {
const library = useLibrary();
const schemas = useMemo(() => {
const node = oss.graph.at(target.id)!;
const ids: LibraryItemID[] = [
...node.inputs.map(id => oss.operationByID.get(id)!.result).filter(id => id !== null),
...node.outputs.map(id => oss.operationByID.get(id)!.result).filter(id => id !== null)
];
return ids.map(id => library.items.find(item => item.id === id)).filter(item => item !== undefined);
}, [oss, library.items]);
const [destination, setDestination] = useState<ILibraryItem | undefined>(undefined);
const [selected, setSelected] = useState<ConstituentaID[]>([]);
const source = useRSFormDetails({ target: String(target.result!) });
const filtered = useMemo(() => {
if (!source.schema || !destination) {
return [];
}
const destinationOperation = oss.items.find(item => item.result === destination.id);
return getRelocateCandidates(target.id, destinationOperation!.id, source.schema, oss);
}, [destination, source.schema?.items]);
const isValid = useMemo(() => !!destination && selected.length > 0, [destination, selected]);
useLayoutEffect(() => {
setSelected([]);
}, [destination]);
const handleSelectDestination = useCallback((newValue: ILibraryItem | undefined) => {
setDestination(newValue);
}, []);
const handleSubmit = useCallback(() => {
const data: ICstRelocateData = {
destination: target.result ?? 0,
items: []
};
onSubmit(data);
}, [target, onSubmit]);
return (
<Modal
header='Перемещение конституент'
submitText='Переместить'
hideWindow={hideWindow}
canSubmit={isValid}
onSubmit={handleSubmit}
className={clsx('w-[40rem] h-[33rem]', 'py-3 px-6')}
>
<DataLoader id='dlg-relocate-constituents' className='cc-column' isLoading={source.loading} error={source.error}>
<SelectLibraryItem
placeholder='Выберите целевую схему'
items={schemas}
value={destination}
onSelectValue={handleSelectDestination}
/>
{source.schema ? (
<PickMultiConstituenta
schema={source.schema}
data={filtered}
rows={12}
prefixID={prefixes.dlg_cst_constituents_list}
selected={selected}
setSelected={setSelected}
/>
) : null}
</DataLoader>
</Modal>
);
}
export default DlgRelocateConstituents;

View File

@ -86,25 +86,30 @@ export class Graph {
return !!this.nodes.get(target); return !!this.nodes.get(target);
} }
removeNode(target: number): void { removeNode(target: number): GraphNode | null {
this.nodes.forEach(node => {
node.removeInput(target);
node.removeOutput(target);
});
this.nodes.delete(target);
}
foldNode(target: number): void {
const nodeToRemove = this.nodes.get(target); const nodeToRemove = this.nodes.get(target);
if (!nodeToRemove) { if (!nodeToRemove) {
return; return null;
}
this.nodes.forEach(node => {
node.removeInput(nodeToRemove.id);
node.removeOutput(nodeToRemove.id);
});
this.nodes.delete(target);
return nodeToRemove;
}
foldNode(target: number): GraphNode | null {
const nodeToRemove = this.nodes.get(target);
if (!nodeToRemove) {
return null;
} }
nodeToRemove.inputs.forEach(input => { nodeToRemove.inputs.forEach(input => {
nodeToRemove.outputs.forEach(output => { nodeToRemove.outputs.forEach(output => {
this.addEdge(input, output); this.addEdge(input, output);
}); });
}); });
this.removeNode(target); return this.removeNode(target);
} }
removeIsolated(): GraphNode[] { removeIsolated(): GraphNode[] {
@ -119,9 +124,6 @@ export class Graph {
} }
addEdge(source: number, destination: number): void { addEdge(source: number, destination: number): void {
if (this.hasEdge(source, destination)) {
return;
}
const sourceNode = this.addNode(source); const sourceNode = this.addNode(source);
const destinationNode = this.addNode(destination); const destinationNode = this.addNode(destination);
sourceNode.addOutput(destinationNode.id); sourceNode.addOutput(destinationNode.id);

View File

@ -125,14 +125,6 @@ export interface ICstSubstituteData {
substitutions: ICstSubstitute[]; substitutions: ICstSubstitute[];
} }
/**
* Represents data, used relocating {@link IConstituenta}s between {@link ILibraryItem}s.
*/
export interface ICstRelocateData {
destination: LibraryItemID;
items: ConstituentaID[];
}
/** /**
* Represents substitution for multi synthesis table. * Represents substitution for multi synthesis table.
*/ */

View File

@ -8,7 +8,7 @@ import { TextMatcher } from '@/utils/utils';
import { Graph } from './Graph'; import { Graph } from './Graph';
import { ILibraryItem, LibraryItemID } from './library'; import { ILibraryItem, LibraryItemID } from './library';
import { ICstSubstitute, IOperation, IOperationSchema, OperationID, SubstitutionErrorType } from './oss'; import { ICstSubstitute, IOperation, IOperationSchema, SubstitutionErrorType } from './oss';
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from './rsform'; import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from './rsform';
import { AliasMapping, ParsingStatus } from './rslang'; import { AliasMapping, ParsingStatus } from './rslang';
import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI'; import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI';
@ -424,45 +424,3 @@ export class SubstitutionValidator {
return false; return false;
} }
} }
/**
* Filter relocate candidates from gives schema.
*/
export function getRelocateCandidates(
source: OperationID,
destination: OperationID,
schema: IRSForm,
oss: IOperationSchema
): IConstituenta[] {
const destinationSchema = oss.operationByID.get(destination)?.result;
if (!destinationSchema) {
return [];
}
const node = oss.graph.at(source);
if (!node) {
return [];
}
const addedCst = schema.items.filter(item => !item.is_inherited);
if (node.outputs.includes(destination)) {
return addedCst;
}
const unreachableBases: ConstituentaID[] = [];
for (const cst of schema.items.filter(item => item.is_inherited)) {
if (cst.parent_schema == destinationSchema) {
continue;
}
const parent = schema.inheritance.find(item => item.child === cst.id && item.child_source === cst.schema)?.parent;
if (parent) {
const original = oss.substitutions.find(sub => sub.substitution === parent)?.original;
if (original) {
continue;
// TODO: test if original schema is destination schema
}
}
unreachableBases.push(cst.id);
}
const unreachable = schema.graph.expandAllOutputs(unreachableBases);
return addedCst.filter(cst => !unreachable.includes(cst.id));
}

View File

@ -2,15 +2,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { import { IconConnect, IconDestroy, IconEdit2, IconExecute, IconNewRSForm, IconRSForm } from '@/components/Icons';
IconChild,
IconConnect,
IconDestroy,
IconEdit2,
IconExecute,
IconNewRSForm,
IconRSForm
} from '@/components/Icons';
import Dropdown from '@/components/ui/Dropdown'; import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton'; import DropdownButton from '@/components/ui/DropdownButton';
import useClickedOutside from '@/hooks/useClickedOutside'; import useClickedOutside from '@/hooks/useClickedOutside';
@ -33,7 +25,6 @@ interface NodeContextMenuProps extends ContextMenuData {
onEditSchema: (target: OperationID) => void; onEditSchema: (target: OperationID) => void;
onEditOperation: (target: OperationID) => void; onEditOperation: (target: OperationID) => void;
onExecuteOperation: (target: OperationID) => void; onExecuteOperation: (target: OperationID) => void;
onRelocateConstituents: (target: OperationID) => void;
} }
function NodeContextMenu({ function NodeContextMenu({
@ -45,8 +36,7 @@ function NodeContextMenu({
onCreateInput, onCreateInput,
onEditSchema, onEditSchema,
onEditOperation, onEditOperation,
onExecuteOperation, onExecuteOperation
onRelocateConstituents
}: NodeContextMenuProps) { }: NodeContextMenuProps) {
const controller = useOssEdit(); const controller = useOssEdit();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@ -110,11 +100,6 @@ function NodeContextMenu({
onExecuteOperation(operation.id); onExecuteOperation(operation.id);
}; };
const handleRelocateConstituents = () => {
handleHide();
onRelocateConstituents(operation.id);
};
return ( return (
<div ref={ref} className='absolute select-none' style={{ top: cursorY, left: cursorX }}> <div ref={ref} className='absolute select-none' style={{ top: cursorY, left: cursorX }}>
<Dropdown <Dropdown
@ -171,16 +156,6 @@ function NodeContextMenu({
/> />
) : null} ) : null}
{controller.isMutable && operation.result ? (
<DropdownButton
text='Конституенты'
titleHtml='Перемещение конституент</br>между схемами'
icon={<IconChild size='1rem' className='icon-green' />}
disabled={controller.isProcessing}
onClick={handleRelocateConstituents}
/>
) : null}
<DropdownButton <DropdownButton
text='Удалить операцию' text='Удалить операцию'
icon={<IconDestroy size='1rem' className='icon-red' />} icon={<IconDestroy size='1rem' className='icon-red' />}

View File

@ -197,13 +197,6 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
handleExecuteOperation(controller.selected[0]); handleExecuteOperation(controller.selected[0]);
}, [controller, handleExecuteOperation]); }, [controller, handleExecuteOperation]);
const handleRelocateConstituents = useCallback(
(target: OperationID) => {
controller.promptRelocateConstituents(target);
},
[controller]
);
const handleFitView = useCallback(() => { const handleFitView = useCallback(() => {
flow.fitView({ duration: PARAMETER.zoomDuration }); flow.fitView({ duration: PARAMETER.zoomDuration });
}, [flow]); }, [flow]);
@ -383,7 +376,6 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
onEditSchema={handleEditSchema} onEditSchema={handleEditSchema}
onEditOperation={handleEditOperation} onEditOperation={handleEditOperation}
onExecuteOperation={handleExecuteOperation} onExecuteOperation={handleExecuteOperation}
onRelocateConstituents={handleRelocateConstituents}
{...menuProps} {...menuProps}
/> />
) : null} ) : null}

View File

@ -17,12 +17,10 @@ import DlgCreateOperation from '@/dialogs/DlgCreateOperation';
import DlgDeleteOperation from '@/dialogs/DlgDeleteOperation'; import DlgDeleteOperation from '@/dialogs/DlgDeleteOperation';
import DlgEditEditors from '@/dialogs/DlgEditEditors'; import DlgEditEditors from '@/dialogs/DlgEditEditors';
import DlgEditOperation from '@/dialogs/DlgEditOperation'; 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';
import { import {
ICstRelocateData,
IOperationCreateData, IOperationCreateData,
IOperationDeleteData, IOperationDeleteData,
IOperationPosition, IOperationPosition,
@ -76,7 +74,6 @@ export interface IOssEditContext extends ILibraryItemEditor {
promptEditInput: (target: OperationID, positions: IOperationPosition[]) => void; promptEditInput: (target: OperationID, positions: IOperationPosition[]) => void;
promptEditOperation: (target: OperationID, positions: IOperationPosition[]) => void; promptEditOperation: (target: OperationID, positions: IOperationPosition[]) => void;
executeOperation: (target: OperationID, positions: IOperationPosition[]) => void; executeOperation: (target: OperationID, positions: IOperationPosition[]) => void;
promptRelocateConstituents: (target: OperationID) => void;
} }
const OssEditContext = createContext<IOssEditContext | null>(null); const OssEditContext = createContext<IOssEditContext | null>(null);
@ -113,7 +110,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
const [showEditInput, setShowEditInput] = useState(false); const [showEditInput, setShowEditInput] = useState(false);
const [showEditOperation, setShowEditOperation] = useState(false); const [showEditOperation, setShowEditOperation] = useState(false);
const [showDeleteOperation, setShowDeleteOperation] = useState(false); const [showDeleteOperation, setShowDeleteOperation] = useState(false);
const [showRelocateConstituents, setShowRelocateConstituents] = useState(false);
const [showCreateOperation, setShowCreateOperation] = 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 });
@ -363,23 +359,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
[model] [model]
); );
const promptRelocateConstituents = useCallback(
(target: OperationID) => {
setTargetOperationID(target);
setShowRelocateConstituents(true);
},
[model]
);
const handleRelocateConstituents = useCallback(
(data: ICstRelocateData) => {
// TODO: implement backed call
console.log(data);
toast.success('В разработке');
},
[model]
);
return ( return (
<OssEditContext.Provider <OssEditContext.Provider
value={{ value={{
@ -409,8 +388,7 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
createInput, createInput,
promptEditInput, promptEditInput,
promptEditOperation, promptEditOperation,
executeOperation, executeOperation
promptRelocateConstituents
}} }}
> >
{model.schema ? ( {model.schema ? (
@ -460,15 +438,6 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
onSubmit={deleteOperation} onSubmit={deleteOperation}
/> />
) : null} ) : null}
{showRelocateConstituents ? (
<DlgRelocateConstituents
hideWindow={() => setShowRelocateConstituents(false)}
target={targetOperation!}
oss={model.schema}
onSubmit={handleRelocateConstituents}
/>
) : null}
)
</AnimatePresence> </AnimatePresence>
) : null} ) : null}

View File

@ -69,7 +69,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFilt
); );
return ( return (
<div className='flex border-b clr-input rounded-t-md'> <div className='flex border-b clr-input'>
<SearchBar <SearchBar
id='constituents_search' id='constituents_search'
noBorder noBorder

View File

@ -182,6 +182,5 @@ export const prefixes = {
user_editors: 'user_editors_', user_editors: 'user_editors_',
wordform_list: 'wordform_list_', wordform_list: 'wordform_list_',
rsedit_btn: 'rsedit_btn_', rsedit_btn: 'rsedit_btn_',
dlg_cst_substitutes_list: 'dlg_cst_substitutes_list_', dlg_cst_substitutes_list: 'dlg_cst_substitutes_list_'
dlg_cst_constituents_list: 'dlg_cst_constituents_list_'
}; };