mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-08-14 12:50:37 +03:00
R: Improve dialogs persistence when data is invalidated
This commit is contained in:
parent
2ecdbd1719
commit
9420729a96
|
@ -10,18 +10,20 @@ import { ModalForm } from '@/components/modal';
|
|||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateBlockDTO, schemaCreateBlock } from '../../backend/types';
|
||||
import { type ICreateBlockDTO, type IOssLayout, schemaCreateBlock } from '../../backend/types';
|
||||
import { useCreateBlock } from '../../backend/use-create-block';
|
||||
import { type IOssItem, NodeType } from '../../models/oss';
|
||||
import { type LayoutManager } from '../../models/oss-layout-api';
|
||||
import { useOssSuspense } from '../../backend/use-oss';
|
||||
import { LayoutManager } from '../../models/oss-layout-api';
|
||||
import { BLOCK_NODE_MIN_HEIGHT, BLOCK_NODE_MIN_WIDTH } from '../../pages/oss-page/editor-oss-graph/graph/block-node';
|
||||
|
||||
import { TabBlockCard } from './tab-block-card';
|
||||
import { TabBlockChildren } from './tab-block-children';
|
||||
|
||||
export interface DlgCreateBlockProps {
|
||||
manager: LayoutManager;
|
||||
initialChildren: IOssItem[];
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
childrenBlocks: number[];
|
||||
childrenOperations: number[];
|
||||
initialParent: number | null;
|
||||
defaultX: number;
|
||||
defaultY: number;
|
||||
|
@ -37,9 +39,19 @@ export type TabID = (typeof TabID)[keyof typeof TabID];
|
|||
export function DlgCreateBlock() {
|
||||
const { createBlock } = useCreateBlock();
|
||||
|
||||
const { manager, initialChildren, initialParent, onCreate, defaultX, defaultY } = useDialogsStore(
|
||||
state => state.props as DlgCreateBlockProps
|
||||
);
|
||||
const {
|
||||
ossID, //
|
||||
layout,
|
||||
childrenBlocks,
|
||||
childrenOperations,
|
||||
initialParent,
|
||||
onCreate,
|
||||
defaultX,
|
||||
defaultY
|
||||
} = useDialogsStore(state => state.props as DlgCreateBlockProps);
|
||||
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
|
||||
const methods = useForm<ICreateBlockDTO>({
|
||||
resolver: zodResolver(schemaCreateBlock),
|
||||
|
@ -55,8 +67,8 @@ export function DlgCreateBlock() {
|
|||
width: BLOCK_NODE_MIN_WIDTH,
|
||||
height: BLOCK_NODE_MIN_HEIGHT
|
||||
},
|
||||
children_blocks: initialChildren.filter(item => item.nodeType === NodeType.BLOCK).map(item => item.id),
|
||||
children_operations: initialChildren.filter(item => item.nodeType === NodeType.OPERATION).map(item => item.id),
|
||||
children_blocks: childrenBlocks,
|
||||
children_operations: childrenOperations,
|
||||
layout: manager.layout
|
||||
},
|
||||
mode: 'onChange'
|
||||
|
@ -93,11 +105,11 @@ export function DlgCreateBlock() {
|
|||
|
||||
<FormProvider {...methods}>
|
||||
<TabPanel>
|
||||
<TabBlockCard />
|
||||
<TabBlockCard oss={schema} />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
<TabBlockChildren />
|
||||
<TabBlockChildren oss={schema} />
|
||||
</TabPanel>
|
||||
</FormProvider>
|
||||
</Tabs>
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
import { TextArea, TextInput } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateBlockDTO } from '../../backend/types';
|
||||
import { SelectParent } from '../../components/select-parent';
|
||||
import { NodeType } from '../../models/oss';
|
||||
import { type IOperationSchema, NodeType } from '../../models/oss';
|
||||
import { constructNodeID } from '../../models/oss-api';
|
||||
|
||||
import { type DlgCreateBlockProps } from './dlg-create-block';
|
||||
interface TabBlockCardProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabBlockCard() {
|
||||
const { manager } = useDialogsStore(state => state.props as DlgCreateBlockProps);
|
||||
export function TabBlockCard({ oss }: TabBlockCardProps) {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
|
@ -21,7 +21,7 @@ export function TabBlockCard() {
|
|||
} = useFormContext<ICreateBlockDTO>();
|
||||
const children_blocks = useWatch({ control, name: 'children_blocks' });
|
||||
const block_ids = children_blocks.map(id => constructNodeID(NodeType.BLOCK, id));
|
||||
const all_children = [...block_ids, ...manager.oss.hierarchy.expandAllOutputs(block_ids)];
|
||||
const all_children = [...block_ids, ...oss.hierarchy.expandAllOutputs(block_ids)];
|
||||
|
||||
return (
|
||||
<div className='cc-fade-in cc-column'>
|
||||
|
@ -36,8 +36,8 @@ export function TabBlockCard() {
|
|||
control={control}
|
||||
render={({ field }) => (
|
||||
<SelectParent
|
||||
items={manager.oss.blocks.filter(block => !all_children.includes(block.nodeID))}
|
||||
value={field.value ? manager.oss.blockByID.get(field.value) ?? null : null}
|
||||
items={oss.blocks.filter(block => !all_children.includes(block.nodeID))}
|
||||
value={field.value ? oss.blockByID.get(field.value) ?? null : null}
|
||||
placeholder='Родительский блок'
|
||||
onChange={value => field.onChange(value ? value.id : null)}
|
||||
/>
|
||||
|
|
|
@ -3,34 +3,34 @@
|
|||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
import { Label } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateBlockDTO } from '../../backend/types';
|
||||
import { PickContents } from '../../components/pick-contents';
|
||||
import { type IOssItem, NodeType } from '../../models/oss';
|
||||
import { type IOperationSchema, type IOssItem, NodeType } from '../../models/oss';
|
||||
|
||||
import { type DlgCreateBlockProps } from './dlg-create-block';
|
||||
interface TabBlockChildrenProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabBlockChildren() {
|
||||
export function TabBlockChildren({ oss }: TabBlockChildrenProps) {
|
||||
const { setValue, control } = useFormContext<ICreateBlockDTO>();
|
||||
const { manager } = useDialogsStore(state => state.props as DlgCreateBlockProps);
|
||||
const parent = useWatch({ control, name: 'item_data.parent' });
|
||||
const children_blocks = useWatch({ control, name: 'children_blocks' });
|
||||
const children_operations = useWatch({ control, name: 'children_operations' });
|
||||
|
||||
const parentItem = parent ? manager.oss.blockByID.get(parent) : null;
|
||||
const parentItem = parent ? oss.blockByID.get(parent) : null;
|
||||
const internalBlocks = parentItem
|
||||
? manager.oss.hierarchy
|
||||
? oss.hierarchy
|
||||
.expandAllInputs([parentItem.nodeID])
|
||||
.map(id => manager.oss.itemByNodeID.get(id))
|
||||
.map(id => oss.itemByNodeID.get(id))
|
||||
.filter(item => item !== null && item?.nodeType === NodeType.BLOCK)
|
||||
: [];
|
||||
|
||||
const exclude = parentItem ? [parentItem, ...internalBlocks] : [];
|
||||
|
||||
const value = [
|
||||
...children_blocks.map(id => manager.oss.blockByID.get(id)!),
|
||||
...children_operations.map(id => manager.oss.operationByID.get(id)!)
|
||||
...children_blocks.map(id => oss.blockByID.get(id)!),
|
||||
...children_operations.map(id => oss.operationByID.get(id)!)
|
||||
];
|
||||
|
||||
function handleChangeSelected(newValue: IOssItem[]) {
|
||||
|
@ -50,7 +50,7 @@ export function TabBlockChildren() {
|
|||
<div className='cc-fade-in cc-column'>
|
||||
<Label text={`Выбор содержания: [ ${value.length} ]`} />
|
||||
<PickContents
|
||||
schema={manager.oss}
|
||||
schema={oss}
|
||||
exclude={exclude}
|
||||
value={value}
|
||||
onChange={newValue => handleChangeSelected(newValue)}
|
||||
|
|
|
@ -9,13 +9,15 @@ import { TextArea, TextInput } from '@/components/input';
|
|||
import { ModalForm } from '@/components/modal';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateSchemaDTO, schemaCreateSchema } from '../backend/types';
|
||||
import { type ICreateSchemaDTO, type IOssLayout, schemaCreateSchema } from '../backend/types';
|
||||
import { useCreateSchema } from '../backend/use-create-schema';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
import { SelectParent } from '../components/select-parent';
|
||||
import { type LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../models/oss-layout-api';
|
||||
import { LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../models/oss-layout-api';
|
||||
|
||||
export interface DlgCreateSchemaProps {
|
||||
manager: LayoutManager;
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
defaultX: number;
|
||||
defaultY: number;
|
||||
initialParent: number | null;
|
||||
|
@ -25,9 +27,17 @@ export interface DlgCreateSchemaProps {
|
|||
export function DlgCreateSchema() {
|
||||
const { createSchema } = useCreateSchema();
|
||||
|
||||
const { manager, initialParent, onCreate, defaultX, defaultY } = useDialogsStore(
|
||||
state => state.props as DlgCreateSchemaProps
|
||||
);
|
||||
const {
|
||||
ossID, //
|
||||
layout,
|
||||
initialParent,
|
||||
onCreate,
|
||||
defaultX,
|
||||
defaultY
|
||||
} = useDialogsStore(state => state.props as DlgCreateSchemaProps);
|
||||
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -11,15 +11,17 @@ import { ModalForm } from '@/components/modal';
|
|||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateSynthesisDTO, schemaCreateSynthesis } from '../../backend/types';
|
||||
import { type ICreateSynthesisDTO, type IOssLayout, schemaCreateSynthesis } from '../../backend/types';
|
||||
import { useCreateSynthesis } from '../../backend/use-create-synthesis';
|
||||
import { type LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../../models/oss-layout-api';
|
||||
import { useOssSuspense } from '../../backend/use-oss';
|
||||
import { LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../../models/oss-layout-api';
|
||||
|
||||
import { TabArguments } from './tab-arguments';
|
||||
import { TabSubstitutions } from './tab-substitutions';
|
||||
|
||||
export interface DlgCreateSynthesisProps {
|
||||
manager: LayoutManager;
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
initialParent: number | null;
|
||||
initialInputs: number[];
|
||||
defaultX: number;
|
||||
|
@ -36,9 +38,17 @@ export type TabID = (typeof TabID)[keyof typeof TabID];
|
|||
export function DlgCreateSynthesis() {
|
||||
const { createSynthesis } = useCreateSynthesis();
|
||||
|
||||
const { manager, initialInputs, initialParent, onCreate, defaultX, defaultY } = useDialogsStore(
|
||||
state => state.props as DlgCreateSynthesisProps
|
||||
);
|
||||
const {
|
||||
ossID, //
|
||||
layout,
|
||||
initialInputs,
|
||||
initialParent,
|
||||
onCreate,
|
||||
defaultX,
|
||||
defaultY
|
||||
} = useDialogsStore(state => state.props as DlgCreateSynthesisProps);
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
|
||||
const methods = useForm<ICreateSynthesisDTO>({
|
||||
resolver: zodResolver(schemaCreateSynthesis),
|
||||
|
@ -87,7 +97,7 @@ export function DlgCreateSynthesis() {
|
|||
</TabList>
|
||||
<FormProvider {...methods}>
|
||||
<TabPanel>
|
||||
<TabArguments />
|
||||
<TabArguments oss={schema} />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<Suspense
|
||||
|
@ -97,7 +107,7 @@ export function DlgCreateSynthesis() {
|
|||
</div>
|
||||
}
|
||||
>
|
||||
<TabSubstitutions />
|
||||
<TabSubstitutions oss={schema} />
|
||||
</Suspense>
|
||||
</TabPanel>
|
||||
</FormProvider>
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
import { Label, TextArea, TextInput } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateSynthesisDTO } from '../../backend/types';
|
||||
import { PickMultiOperation } from '../../components/pick-multi-operation';
|
||||
import { SelectParent } from '../../components/select-parent';
|
||||
import { type IOperationSchema } from '../../models/oss';
|
||||
|
||||
import { type DlgCreateSynthesisProps } from './dlg-create-synthesis';
|
||||
interface TabArgumentsProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabArguments() {
|
||||
const { manager } = useDialogsStore(state => state.props as DlgCreateSynthesisProps);
|
||||
export function TabArguments({ oss }: TabArgumentsProps) {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
|
@ -20,11 +21,11 @@ export function TabArguments() {
|
|||
} = useFormContext<ICreateSynthesisDTO>();
|
||||
const inputs = useWatch({ control, name: 'arguments' });
|
||||
|
||||
const replicas = manager.oss.replicas
|
||||
const replicas = oss.replicas
|
||||
.filter(item => inputs.includes(item.original))
|
||||
.map(item => item.replica)
|
||||
.concat(manager.oss.replicas.filter(item => inputs.includes(item.replica)).map(item => item.original));
|
||||
const filtered = manager.oss.operations.filter(item => !replicas.includes(item.id));
|
||||
.concat(oss.replicas.filter(item => inputs.includes(item.replica)).map(item => item.original));
|
||||
const filtered = oss.operations.filter(item => !replicas.includes(item.id));
|
||||
|
||||
return (
|
||||
<div className='cc-fade-in cc-column'>
|
||||
|
@ -48,8 +49,8 @@ export function TabArguments() {
|
|||
control={control}
|
||||
render={({ field }) => (
|
||||
<SelectParent
|
||||
items={manager.oss.blocks}
|
||||
value={field.value ? manager.oss.blockByID.get(field.value) ?? null : null}
|
||||
items={oss.blocks}
|
||||
value={field.value ? oss.blockByID.get(field.value) ?? null : null}
|
||||
placeholder='Родительский блок'
|
||||
onChange={value => field.onChange(value ? value.id : null)}
|
||||
/>
|
||||
|
|
|
@ -6,21 +6,22 @@ import { useRSForms } from '@/features/rsform/backend/use-rsforms';
|
|||
import { PickSubstitutions } from '@/features/rsform/components/pick-substitutions';
|
||||
|
||||
import { TextArea } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type ICreateSynthesisDTO } from '../../backend/types';
|
||||
import { type IOperationSchema } from '../../models/oss';
|
||||
import { SubstitutionValidator } from '../../models/oss-api';
|
||||
|
||||
import { type DlgCreateSynthesisProps } from './dlg-create-synthesis';
|
||||
interface TabSubstitutionsProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabSubstitutions() {
|
||||
const { manager } = useDialogsStore(state => state.props as DlgCreateSynthesisProps);
|
||||
export function TabSubstitutions({ oss }: TabSubstitutionsProps) {
|
||||
const { control } = useFormContext<ICreateSynthesisDTO>();
|
||||
const inputs = useWatch({ control, name: 'arguments' });
|
||||
const substitutions = useWatch({ control, name: 'substitutions' });
|
||||
|
||||
const schemasIDs = inputs
|
||||
.map(id => manager.oss.operationByID.get(id)!)
|
||||
.map(id => oss.operationByID.get(id)!)
|
||||
.map(operation => operation.result)
|
||||
.filter(id => id !== null);
|
||||
const schemas = useRSForms(schemasIDs);
|
||||
|
|
|
@ -11,23 +11,26 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
|
||||
import { type IDeleteOperationDTO, type IOssLayout, OperationType, schemaDeleteOperation } from '../backend/types';
|
||||
import { useDeleteOperation } from '../backend/use-delete-operation';
|
||||
import { type IOperationInput, type IOperationSchema, type IOperationSynthesis } from '../models/oss';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
|
||||
export interface DlgDeleteOperationProps {
|
||||
oss: IOperationSchema;
|
||||
target: IOperationInput | IOperationSynthesis;
|
||||
ossID: number;
|
||||
targetID: number;
|
||||
layout: IOssLayout;
|
||||
beforeDelete?: () => void;
|
||||
}
|
||||
|
||||
export function DlgDeleteOperation() {
|
||||
const { oss, target, layout, beforeDelete } = useDialogsStore(state => state.props as DlgDeleteOperationProps);
|
||||
const { ossID, targetID, layout, beforeDelete } = useDialogsStore(state => state.props as DlgDeleteOperationProps);
|
||||
const { deleteOperation } = useDeleteOperation();
|
||||
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const target = schema.operationByID.get(targetID)!;
|
||||
|
||||
const { handleSubmit, control } = useForm<IDeleteOperationDTO>({
|
||||
resolver: zodResolver(schemaDeleteOperation),
|
||||
defaultValues: {
|
||||
target: target.id,
|
||||
target: targetID,
|
||||
layout: layout,
|
||||
keep_constituents: false,
|
||||
delete_schema: true
|
||||
|
@ -35,7 +38,7 @@ export function DlgDeleteOperation() {
|
|||
});
|
||||
|
||||
function onSubmit(data: IDeleteOperationDTO) {
|
||||
return deleteOperation({ itemID: oss.id, data: data, beforeUpdate: beforeDelete });
|
||||
return deleteOperation({ itemID: ossID, data: data, beforeUpdate: beforeDelete });
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -11,23 +11,26 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
|
||||
import { type IDeleteReplicaDTO, type IOssLayout, schemaDeleteReplica } from '../backend/types';
|
||||
import { useDeleteReplica } from '../backend/use-delete-replica';
|
||||
import { type IOperationReplica, type IOperationSchema } from '../models/oss';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
|
||||
export interface DlgDeleteReplicaProps {
|
||||
oss: IOperationSchema;
|
||||
target: IOperationReplica;
|
||||
ossID: number;
|
||||
targetID: number;
|
||||
layout: IOssLayout;
|
||||
beforeDelete?: () => void;
|
||||
}
|
||||
|
||||
export function DlgDeleteReplica() {
|
||||
const { oss, target, layout, beforeDelete } = useDialogsStore(state => state.props as DlgDeleteReplicaProps);
|
||||
const { ossID, targetID, layout, beforeDelete } = useDialogsStore(state => state.props as DlgDeleteReplicaProps);
|
||||
const { deleteReplica: deleteReference } = useDeleteReplica();
|
||||
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const target = schema.operationByID.get(targetID)!;
|
||||
|
||||
const { handleSubmit, control } = useForm<IDeleteReplicaDTO>({
|
||||
resolver: zodResolver(schemaDeleteReplica),
|
||||
defaultValues: {
|
||||
target: target.id,
|
||||
target: targetID,
|
||||
layout: layout,
|
||||
keep_constituents: false,
|
||||
keep_connections: false
|
||||
|
@ -36,7 +39,7 @@ export function DlgDeleteReplica() {
|
|||
const keep_connections = useWatch({ control, name: 'keep_connections' });
|
||||
|
||||
function onSubmit(data: IDeleteReplicaDTO) {
|
||||
return deleteReference({ itemID: oss.id, data: data, beforeUpdate: beforeDelete });
|
||||
return deleteReference({ itemID: ossID, data: data, beforeUpdate: beforeDelete });
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -9,20 +9,24 @@ import { TextArea, TextInput } from '@/components/input';
|
|||
import { ModalForm } from '@/components/modal';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IUpdateBlockDTO, schemaUpdateBlock } from '../backend/types';
|
||||
import { type IOssLayout, type IUpdateBlockDTO, schemaUpdateBlock } from '../backend/types';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
import { useUpdateBlock } from '../backend/use-update-block';
|
||||
import { SelectParent } from '../components/select-parent';
|
||||
import { type IBlock } from '../models/oss';
|
||||
import { type LayoutManager } from '../models/oss-layout-api';
|
||||
import { LayoutManager } from '../models/oss-layout-api';
|
||||
|
||||
export interface DlgEditBlockProps {
|
||||
manager: LayoutManager;
|
||||
target: IBlock;
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
targetID: number;
|
||||
}
|
||||
|
||||
export function DlgEditBlock() {
|
||||
const { manager, target } = useDialogsStore(state => state.props as DlgEditBlockProps);
|
||||
const { ossID, targetID, layout } = useDialogsStore(state => state.props as DlgEditBlockProps);
|
||||
const { updateBlock } = useUpdateBlock();
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
const target = manager.oss.blockByID.get(targetID)!;
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
|
|
|
@ -11,18 +11,19 @@ import { ModalForm } from '@/components/modal';
|
|||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IUpdateOperationDTO, OperationType, schemaUpdateOperation } from '../../backend/types';
|
||||
import { type IOssLayout, type IUpdateOperationDTO, OperationType, schemaUpdateOperation } from '../../backend/types';
|
||||
import { useOssSuspense } from '../../backend/use-oss';
|
||||
import { useUpdateOperation } from '../../backend/use-update-operation';
|
||||
import { type IOperationInput, type IOperationSynthesis } from '../../models/oss';
|
||||
import { type LayoutManager } from '../../models/oss-layout-api';
|
||||
import { LayoutManager } from '../../models/oss-layout-api';
|
||||
|
||||
import { TabArguments } from './tab-arguments';
|
||||
import { TabOperation } from './tab-operation';
|
||||
import { TabSubstitutions } from './tab-substitutions';
|
||||
|
||||
export interface DlgEditOperationProps {
|
||||
manager: LayoutManager;
|
||||
target: IOperationInput | IOperationSynthesis;
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
targetID: number;
|
||||
}
|
||||
|
||||
export const TabID = {
|
||||
|
@ -33,13 +34,17 @@ export const TabID = {
|
|||
export type TabID = (typeof TabID)[keyof typeof TabID];
|
||||
|
||||
export function DlgEditOperation() {
|
||||
const { manager, target } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||
const { ossID, layout, targetID } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||
const { updateOperation } = useUpdateOperation();
|
||||
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
const target = manager.oss.operationByID.get(targetID)!;
|
||||
|
||||
const methods = useForm<IUpdateOperationDTO>({
|
||||
resolver: zodResolver(schemaUpdateOperation),
|
||||
defaultValues: {
|
||||
target: target.id,
|
||||
target: targetID,
|
||||
item_data: {
|
||||
alias: target.alias,
|
||||
title: target.title,
|
||||
|
@ -101,15 +106,17 @@ export function DlgEditOperation() {
|
|||
|
||||
<FormProvider {...methods}>
|
||||
<TabPanel>
|
||||
<TabOperation />
|
||||
<TabOperation oss={schema} />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>{target.operation_type === OperationType.SYNTHESIS ? <TabArguments /> : null}</TabPanel>
|
||||
<TabPanel>
|
||||
{target.operation_type === OperationType.SYNTHESIS ? <TabArguments oss={schema} target={target} /> : null}
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel>
|
||||
{target.operation_type === OperationType.SYNTHESIS ? (
|
||||
<Suspense fallback={<Loader />}>
|
||||
<TabSubstitutions />
|
||||
<TabSubstitutions oss={schema} />
|
||||
</Suspense>
|
||||
) : null}
|
||||
</TabPanel>
|
||||
|
|
|
@ -3,24 +3,26 @@
|
|||
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
import { Label } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IUpdateOperationDTO } from '../../backend/types';
|
||||
import { PickMultiOperation } from '../../components/pick-multi-operation';
|
||||
import { type IOperationInput, type IOperationSchema, type IOperationSynthesis } from '../../models/oss';
|
||||
|
||||
import { type DlgEditOperationProps } from './dlg-edit-operation';
|
||||
interface TabArgumentsProps {
|
||||
oss: IOperationSchema;
|
||||
target: IOperationInput | IOperationSynthesis;
|
||||
}
|
||||
|
||||
export function TabArguments() {
|
||||
export function TabArguments({ oss, target }: TabArgumentsProps) {
|
||||
const { control, setValue } = useFormContext<IUpdateOperationDTO>();
|
||||
const { manager, target } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||
const args = useWatch({ control, name: 'arguments' });
|
||||
|
||||
const replicas = manager.oss.replicas
|
||||
const replicas = oss.replicas
|
||||
.filter(item => args.includes(item.original) || item.original === target.id)
|
||||
.map(item => item.replica)
|
||||
.concat(manager.oss.replicas.filter(item => args.includes(item.replica)).map(item => item.original));
|
||||
const potentialCycle = [target.id, ...replicas, ...manager.oss.graph.expandAllOutputs([target.id])];
|
||||
const filtered = manager.oss.operations.filter(item => !potentialCycle.includes(item.id));
|
||||
.concat(oss.replicas.filter(item => args.includes(item.replica)).map(item => item.original));
|
||||
const potentialCycle = [target.id, ...replicas, ...oss.graph.expandAllOutputs([target.id])];
|
||||
const filtered = oss.operations.filter(item => !potentialCycle.includes(item.id));
|
||||
|
||||
function handleChangeArguments(prev: number[], newValue: number[]) {
|
||||
setValue('arguments', newValue, { shouldValidate: true });
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
|
||||
import { TextArea, TextInput } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IUpdateOperationDTO } from '../../backend/types';
|
||||
import { SelectParent } from '../../components/select-parent';
|
||||
import { type IOperationSchema } from '../../models/oss';
|
||||
|
||||
import { type DlgEditOperationProps } from './dlg-edit-operation';
|
||||
interface TabOperationProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabOperation() {
|
||||
const { manager } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||
export function TabOperation({ oss }: TabOperationProps) {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
|
@ -37,8 +38,8 @@ export function TabOperation() {
|
|||
control={control}
|
||||
render={({ field }) => (
|
||||
<SelectParent
|
||||
items={manager.oss.blocks}
|
||||
value={field.value ? manager.oss.blockByID.get(field.value) ?? null : null}
|
||||
items={oss.blocks}
|
||||
value={field.value ? oss.blockByID.get(field.value) ?? null : null}
|
||||
placeholder='Родительский блок'
|
||||
onChange={value => field.onChange(value ? value.id : null)}
|
||||
/>
|
||||
|
|
|
@ -6,21 +6,22 @@ import { useRSForms } from '@/features/rsform/backend/use-rsforms';
|
|||
import { PickSubstitutions } from '@/features/rsform/components/pick-substitutions';
|
||||
|
||||
import { TextArea } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IUpdateOperationDTO } from '../../backend/types';
|
||||
import { type IOperationSchema } from '../../models/oss';
|
||||
import { SubstitutionValidator } from '../../models/oss-api';
|
||||
|
||||
import { type DlgEditOperationProps } from './dlg-edit-operation';
|
||||
interface TabSubstitutionsProps {
|
||||
oss: IOperationSchema;
|
||||
}
|
||||
|
||||
export function TabSubstitutions() {
|
||||
const { manager } = useDialogsStore(state => state.props as DlgEditOperationProps);
|
||||
export function TabSubstitutions({ oss }: TabSubstitutionsProps) {
|
||||
const { control } = useFormContext<IUpdateOperationDTO>();
|
||||
const inputs = useWatch({ control, name: 'arguments' });
|
||||
const substitutions = useWatch({ control, name: 'substitutions' });
|
||||
|
||||
const schemasIDs = inputs
|
||||
.map(id => manager.oss.operationByID.get(id)!)
|
||||
.map(id => oss.operationByID.get(id)!)
|
||||
.map(operation => operation.result)
|
||||
.filter(id => id !== null);
|
||||
const schemas = useRSForms(schemasIDs);
|
||||
|
|
|
@ -12,14 +12,16 @@ import { Checkbox, TextArea, TextInput } from '@/components/input';
|
|||
import { ModalForm } from '@/components/modal';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IImportSchemaDTO, schemaImportSchema } from '../backend/types';
|
||||
import { type IImportSchemaDTO, type IOssLayout, schemaImportSchema } from '../backend/types';
|
||||
import { useImportSchema } from '../backend/use-import-schema';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
import { SelectParent } from '../components/select-parent';
|
||||
import { sortItemsForOSS } from '../models/oss-api';
|
||||
import { type LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../models/oss-layout-api';
|
||||
import { LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH } from '../models/oss-layout-api';
|
||||
|
||||
export interface DlgImportSchemaProps {
|
||||
manager: LayoutManager;
|
||||
ossID: number;
|
||||
layout: IOssLayout;
|
||||
defaultX: number;
|
||||
defaultY: number;
|
||||
initialParent: number | null;
|
||||
|
@ -29,9 +31,16 @@ export interface DlgImportSchemaProps {
|
|||
export function DlgImportSchema() {
|
||||
const { importSchema } = useImportSchema();
|
||||
|
||||
const { manager, initialParent, onCreate, defaultX, defaultY } = useDialogsStore(
|
||||
state => state.props as DlgImportSchemaProps
|
||||
);
|
||||
const {
|
||||
ossID, //
|
||||
layout,
|
||||
initialParent,
|
||||
onCreate,
|
||||
defaultX,
|
||||
defaultY
|
||||
} = useDialogsStore(state => state.props as DlgImportSchemaProps);
|
||||
const { schema } = useOssSuspense({ itemID: ossID });
|
||||
const manager = new LayoutManager(schema, layout);
|
||||
const { items: libraryItems } = useLibrary();
|
||||
const sortedItems = sortItemsForOSS(manager.oss, libraryItems);
|
||||
|
||||
|
|
|
@ -17,24 +17,27 @@ import { ModalForm } from '@/components/modal';
|
|||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { type IOssLayout, type IRelocateConstituentsDTO, schemaRelocateConstituents } from '../backend/types';
|
||||
import { useOssSuspense } from '../backend/use-oss';
|
||||
import { useRelocateConstituents } from '../backend/use-relocate-constituents';
|
||||
import { useUpdateLayout } from '../backend/use-update-layout';
|
||||
import { IconRelocationUp } from '../components/icon-relocation-up';
|
||||
import { type IOperation, type IOperationSchema } from '../models/oss';
|
||||
import { getRelocateCandidates } from '../models/oss-api';
|
||||
|
||||
export interface DlgRelocateConstituentsProps {
|
||||
oss: IOperationSchema;
|
||||
initialTarget?: IOperation;
|
||||
ossID: number;
|
||||
targetID?: number;
|
||||
layout?: IOssLayout;
|
||||
}
|
||||
|
||||
export function DlgRelocateConstituents() {
|
||||
const { oss, initialTarget, layout } = useDialogsStore(state => state.props as DlgRelocateConstituentsProps);
|
||||
const { ossID, targetID, layout } = useDialogsStore(state => state.props as DlgRelocateConstituentsProps);
|
||||
const { items: libraryItems } = useLibrary();
|
||||
const { updateLayout: updatePositions } = useUpdateLayout();
|
||||
const { relocateConstituents } = useRelocateConstituents();
|
||||
|
||||
const { schema: oss } = useOssSuspense({ itemID: ossID });
|
||||
const initialTarget = targetID ? oss.operationByID.get(targetID)! : undefined;
|
||||
|
||||
const { handleSubmit, control, setValue } = useForm<IRelocateConstituentsDTO>({
|
||||
resolver: zodResolver(schemaRelocateConstituents),
|
||||
defaultValues: {
|
||||
|
|
|
@ -7,7 +7,6 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { useDeleteBlock } from '../../../../backend/use-delete-block';
|
||||
import { useMutatingOss } from '../../../../backend/use-mutating-oss';
|
||||
import { type IBlock } from '../../../../models/oss';
|
||||
import { LayoutManager } from '../../../../models/oss-layout-api';
|
||||
import { useOssEdit } from '../../oss-edit-context';
|
||||
import { useGetLayout } from '../use-get-layout';
|
||||
|
||||
|
@ -30,8 +29,9 @@ export function MenuBlock({ block, onHide }: MenuBlockProps) {
|
|||
}
|
||||
onHide();
|
||||
showEditBlock({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
target: block
|
||||
layout: getLayout(),
|
||||
ossID: schema.id,
|
||||
targetID: block.id
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -101,8 +101,9 @@ export function MenuOperation({ operation, onHide }: MenuOperationProps) {
|
|||
}
|
||||
onHide();
|
||||
showEditOperation({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
target: operation
|
||||
layout: getLayout(),
|
||||
ossID: schema.id,
|
||||
targetID: operation.id
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -114,8 +115,8 @@ export function MenuOperation({ operation, onHide }: MenuOperationProps) {
|
|||
switch (operation.operation_type) {
|
||||
case OperationType.REPLICA:
|
||||
showDeleteReference({
|
||||
oss: schema,
|
||||
target: operation,
|
||||
ossID: schema.id,
|
||||
targetID: operation.id,
|
||||
layout: getLayout(),
|
||||
beforeDelete: deselectAll
|
||||
});
|
||||
|
@ -123,8 +124,8 @@ export function MenuOperation({ operation, onHide }: MenuOperationProps) {
|
|||
case OperationType.INPUT:
|
||||
case OperationType.SYNTHESIS:
|
||||
showDeleteOperation({
|
||||
oss: schema,
|
||||
target: operation,
|
||||
ossID: schema.id,
|
||||
targetID: operation.id,
|
||||
layout: getLayout(),
|
||||
beforeDelete: deselectAll
|
||||
});
|
||||
|
@ -163,8 +164,8 @@ export function MenuOperation({ operation, onHide }: MenuOperationProps) {
|
|||
}
|
||||
onHide();
|
||||
showRelocateConstituents({
|
||||
oss: schema,
|
||||
initialTarget: operation,
|
||||
ossID: schema.id,
|
||||
targetID: operation.id,
|
||||
layout: getLayout()
|
||||
});
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ export function OssFlow() {
|
|||
|
||||
const [mouseCoords, setMouseCoords] = useState<Position2D>({ x: 0, y: 0 });
|
||||
|
||||
const showCreateOperation = useDialogsStore(state => state.showCreateOperation);
|
||||
const showCreateOperation = useDialogsStore(state => state.showCreateSynthesis);
|
||||
const showCreateBlock = useDialogsStore(state => state.showCreateBlock);
|
||||
const showCreateSchema = useDialogsStore(state => state.showCreateSchema);
|
||||
const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation);
|
||||
|
@ -91,7 +91,8 @@ export function OssFlow() {
|
|||
function handleCreateSynthesis() {
|
||||
const targetPosition = screenToFlowPosition({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
showCreateOperation({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
ossID: schema.id,
|
||||
layout: getLayout(),
|
||||
defaultX: targetPosition.x,
|
||||
defaultY: targetPosition.y,
|
||||
initialInputs: selectedItems.filter(item => item?.nodeType === NodeType.OPERATION).map(item => item.id),
|
||||
|
@ -106,12 +107,18 @@ export function OssFlow() {
|
|||
function handleCreateBlock() {
|
||||
const targetPosition = screenToFlowPosition({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
const parent = extractBlockParent(selectedItems);
|
||||
const needChildren = parent === null || selectedItems.length !== 1 || parent !== selectedItems[0].id;
|
||||
showCreateBlock({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
ossID: schema.id,
|
||||
layout: getLayout(),
|
||||
defaultX: targetPosition.x,
|
||||
defaultY: targetPosition.y,
|
||||
initialChildren:
|
||||
parent !== null && selectedItems.length === 1 && parent === selectedItems[0].id ? [] : selectedItems,
|
||||
childrenBlocks: !needChildren
|
||||
? []
|
||||
: selectedItems.filter(item => item.nodeType === NodeType.BLOCK).map(item => item.id),
|
||||
childrenOperations: !needChildren
|
||||
? []
|
||||
: selectedItems.filter(item => item.nodeType === NodeType.OPERATION).map(item => item.id),
|
||||
initialParent: parent,
|
||||
onCreate: newID => {
|
||||
resetView();
|
||||
|
@ -123,7 +130,8 @@ export function OssFlow() {
|
|||
function handleCreateSchema() {
|
||||
const targetPosition = screenToFlowPosition({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
showCreateSchema({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
ossID: schema.id,
|
||||
layout: getLayout(),
|
||||
defaultX: targetPosition.x,
|
||||
defaultY: targetPosition.y,
|
||||
initialParent: extractBlockParent(selectedItems),
|
||||
|
@ -137,7 +145,8 @@ export function OssFlow() {
|
|||
function handleImportSchema() {
|
||||
const targetPosition = screenToFlowPosition({ x: window.innerWidth / 2, y: window.innerHeight / 2 });
|
||||
showImportSchema({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
ossID: schema.id,
|
||||
layout: getLayout(),
|
||||
defaultX: targetPosition.x,
|
||||
defaultY: targetPosition.y,
|
||||
initialParent: extractBlockParent(selectedItems),
|
||||
|
@ -163,8 +172,8 @@ export function OssFlow() {
|
|||
switch (item.operation_type) {
|
||||
case OperationType.REPLICA:
|
||||
showDeleteReference({
|
||||
oss: schema,
|
||||
target: item,
|
||||
ossID: schema.id,
|
||||
targetID: item.id,
|
||||
layout: getLayout(),
|
||||
beforeDelete: deselectAll
|
||||
});
|
||||
|
@ -172,8 +181,8 @@ export function OssFlow() {
|
|||
case OperationType.INPUT:
|
||||
case OperationType.SYNTHESIS:
|
||||
showDeleteOperation({
|
||||
oss: schema,
|
||||
target: item,
|
||||
ossID: schema.id,
|
||||
targetID: item.id,
|
||||
layout: getLayout(),
|
||||
beforeDelete: deselectAll
|
||||
});
|
||||
|
@ -198,8 +207,9 @@ export function OssFlow() {
|
|||
const block = schema.blockByID.get(-Number(node.id));
|
||||
if (block) {
|
||||
showEditBlock({
|
||||
manager: new LayoutManager(schema, getLayout()),
|
||||
target: block
|
||||
ossID: schema.id,
|
||||
layout: getLayout(),
|
||||
targetID: block.id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -93,7 +93,7 @@ interface DialogsStore {
|
|||
showCstTemplate: (props: DlgCstTemplateProps) => void;
|
||||
showCreateCst: (props: DlgCreateCstProps) => void;
|
||||
showCreateBlock: (props: DlgCreateBlockProps) => void;
|
||||
showCreateOperation: (props: DlgCreateSynthesisProps) => void;
|
||||
showCreateSynthesis: (props: DlgCreateSynthesisProps) => void;
|
||||
showDeleteCst: (props: DlgDeleteCstProps) => void;
|
||||
showEditEditors: (props: DlgEditEditorsProps) => void;
|
||||
showEditOperation: (props: DlgEditOperationProps) => void;
|
||||
|
@ -138,7 +138,7 @@ export const useDialogsStore = create<DialogsStore>()(set => ({
|
|||
showVideo: props => set({ active: DialogType.SHOW_VIDEO, props: props }),
|
||||
showCstTemplate: props => set({ active: DialogType.CONSTITUENTA_TEMPLATE, props: props }),
|
||||
showCreateCst: props => set({ active: DialogType.CREATE_CONSTITUENTA, props: props }),
|
||||
showCreateOperation: props => set({ active: DialogType.CREATE_SYNTHESIS, props: props }),
|
||||
showCreateSynthesis: props => set({ active: DialogType.CREATE_SYNTHESIS, props: props }),
|
||||
showCreateBlock: props => set({ active: DialogType.CREATE_BLOCK, props: props }),
|
||||
showDeleteCst: props => set({ active: DialogType.DELETE_CONSTITUENTA, props: props }),
|
||||
showEditEditors: props => set({ active: DialogType.EDIT_EDITORS, props: props }),
|
||||
|
|
Loading…
Reference in New Issue
Block a user