+
- Выбраны {selected.length} из {data.length}
+ {data.length > 0 ? `Выбраны ${selected.length} из ${data.length}` : 'Конституенты'}
{
oss: IOperationSchema;
- target: IOperation;
+ initialTarget?: IOperation;
onSubmit: (data: ICstRelocateData) => void;
}
-function DlgRelocateConstituents({ oss, hideWindow, target, onSubmit }: DlgRelocateConstituentsProps) {
+function DlgRelocateConstituents({ oss, hideWindow, initialTarget, 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, target.id]);
+ const [directionUp, setDirectionUp] = useState(true);
const [destination, setDestination] = useState(undefined);
const [selected, setSelected] = useState([]);
+ const [source, setSource] = useState(
+ library.items.find(item => item.id === initialTarget?.result)
+ );
- const source = useRSFormDetails({ target: String(target.result!) });
- const filtered = useMemo(() => {
- if (!source.schema || !destination) {
+ const operation = useMemo(() => oss.items.find(item => item.result === source?.id), [oss, source]);
+ const sourceSchemas = useMemo(() => library.items.filter(item => oss.schemas.includes(item.id)), [library, oss]);
+ const destinationSchemas = useMemo(() => {
+ if (!operation) {
+ return [];
+ }
+ const node = oss.graph.at(operation.id)!;
+ const ids: LibraryItemID[] = directionUp
+ ? 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, operation, directionUp]);
+
+ const sourceData = useRSFormDetails({ target: source ? String(source.id) : undefined });
+ const filteredConstituents = useMemo(() => {
+ if (!sourceData.schema || !destination || !operation) {
return [];
}
const destinationOperation = oss.items.find(item => item.result === destination.id);
- return getRelocateCandidates(target.id, destinationOperation!.id, source.schema, oss);
- }, [destination, target.id, source.schema, oss]);
+ return getRelocateCandidates(operation.id, destinationOperation!.id, sourceData.schema, oss);
+ }, [destination, operation, sourceData.schema, oss]);
const isValid = useMemo(() => !!destination && selected.length > 0, [destination, selected]);
+ const toggleDirection = useCallback(() => {
+ setDirectionUp(prev => !prev);
+ setDestination(undefined);
+ }, []);
- useLayoutEffect(() => {
+ const handleSelectSource = useCallback((newValue: ILibraryItem | undefined) => {
+ setSource(newValue);
+ setDestination(undefined);
setSelected([]);
- }, [destination]);
+ }, []);
const handleSelectDestination = useCallback((newValue: ILibraryItem | undefined) => {
setDestination(newValue);
+ setSelected([]);
}, []);
const handleSubmit = useCallback(() => {
@@ -74,24 +92,44 @@ function DlgRelocateConstituents({ oss, hideWindow, target, onSubmit }: DlgReloc
onSubmit={handleSubmit}
className={clsx('w-[40rem] h-[33rem]', 'py-3 px-6')}
>
-
-
- {source.schema ? (
-
+
+
- ) : null}
-
+ }
+ onClick={toggleDirection}
+ />
+
+
+
+ {sourceData.schema ? (
+
+ ) : null}
+
+
);
}
diff --git a/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx b/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
index 38215c4c..056416df 100644
--- a/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
@@ -4,6 +4,7 @@ import { urls } from '@/app/urls';
import {
IconAdmin,
IconAlert,
+ IconChild,
IconDestroy,
IconEdit2,
IconEditor,
@@ -67,6 +68,11 @@ function MenuOssTabs({ onDestroy }: MenuOssTabsProps) {
router.push(urls.login);
}
+ function handleRelocate() {
+ editMenu.hide();
+ controller.promptRelocateConstituents(undefined, []);
+ }
+
return (
@@ -128,9 +134,11 @@ function MenuOssTabs({ onDestroy }: MenuOssTabsProps) {
/>
}
+ disabled={controller.isProcessing}
+ onClick={handleRelocate}
/>
diff --git a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
index 2f23e672..3d82786c 100644
--- a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
@@ -76,7 +76,7 @@ export interface IOssEditContext extends ILibraryItemEditor {
promptEditInput: (target: OperationID, positions: IOperationPosition[]) => void;
promptEditOperation: (target: OperationID, positions: IOperationPosition[]) => void;
executeOperation: (target: OperationID, positions: IOperationPosition[]) => void;
- promptRelocateConstituents: (target: OperationID, positions: IOperationPosition[]) => void;
+ promptRelocateConstituents: (target: OperationID | undefined, positions: IOperationPosition[]) => void;
}
const OssEditContext = createContext
(null);
@@ -360,7 +360,7 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
[model]
);
- const promptRelocateConstituents = useCallback((target: OperationID, positions: IOperationPosition[]) => {
+ const promptRelocateConstituents = useCallback((target: OperationID | undefined, positions: IOperationPosition[]) => {
setPositions(positions);
setTargetOperationID(target);
setShowRelocateConstituents(true);
@@ -368,9 +368,18 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
const handleRelocateConstituents = useCallback(
(data: ICstRelocateData) => {
- model.savePositions({ positions: positions }, () =>
- model.relocateConstituents(data, () => toast.success(information.changesSaved))
- );
+ if (
+ positions.every(item => {
+ const operation = model.schema!.operationByID.get(item.id)!;
+ return operation.position_x === item.position_x && operation.position_y === item.position_y;
+ })
+ ) {
+ model.relocateConstituents(data, () => toast.success(information.changesSaved));
+ } else {
+ model.savePositions({ positions: positions }, () =>
+ model.relocateConstituents(data, () => toast.success(information.changesSaved))
+ );
+ }
},
[model, positions]
);
@@ -458,7 +467,7 @@ export const OssEditState = ({ selected, setSelected, children }: React.PropsWit
{showRelocateConstituents ? (
setShowRelocateConstituents(false)}
- target={targetOperation!}
+ initialTarget={targetOperation}
oss={model.schema}
onSubmit={handleRelocateConstituents}
/>