diff --git a/src/features/transfer/MutateTransferForm/components/FilterRows/index.tsx b/src/features/transfer/MutateTransferForm/components/FilterRows/index.tsx
new file mode 100644
index 00000000..c6725e80
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/FilterRows/index.tsx
@@ -0,0 +1,6 @@
+import React, { memo } from 'react';
+
+/** TODO: [DOP-22361] Add component content */
+export const FilterRows = memo(() => {
+ return
FilterRowsNode
;
+});
diff --git a/src/features/transfer/MutateTransferForm/components/FilterRowsNode/FilterRowsNode.tsx b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/FilterRowsNode.tsx
new file mode 100644
index 00000000..d6f5d156
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/FilterRowsNode.tsx
@@ -0,0 +1,31 @@
+import React, { useMemo } from 'react';
+import { CanvasNode } from '@shared/ui';
+import { Handle, Position } from '@xyflow/react';
+import { FilterOutlined } from '@ant-design/icons';
+
+import { FilterRows } from '../FilterRows';
+import { TransferCanvasEdge } from '../TransferConnectionsCanvas';
+
+import { FilterRowsNodeProps } from './types';
+
+export const FilterRowsNode = ({}: FilterRowsNodeProps) => {
+ const icon = useMemo(() => {
+ return ;
+ }, []);
+
+ const children = useMemo(() => {
+ return (
+ <>
+
+
+
+ >
+ );
+ }, []);
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/features/transfer/MutateTransferForm/components/FilterRowsNode/index.ts b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/index.ts
new file mode 100644
index 00000000..7a06d705
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/index.ts
@@ -0,0 +1,2 @@
+export * from './FilterRowsNode';
+export * from './types';
diff --git a/src/features/transfer/MutateTransferForm/components/FilterRowsNode/types.ts b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/types.ts
new file mode 100644
index 00000000..5101e834
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/FilterRowsNode/types.ts
@@ -0,0 +1,8 @@
+import { Node, NodeProps } from '@xyflow/react';
+
+import { TransferCanvasTransformNodeType } from '../TransferConnectionsCanvas';
+
+export interface FilterRowsNodeData
+ extends Node, TransferCanvasTransformNodeType.FILTER_ROWS> {}
+
+export interface FilterRowsNodeProps extends NodeProps {}
diff --git a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/SourceParamsNode.tsx b/src/features/transfer/MutateTransferForm/components/SourceParamsNode/SourceParamsNode.tsx
index ade8579c..e717aca1 100644
--- a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/SourceParamsNode.tsx
+++ b/src/features/transfer/MutateTransferForm/components/SourceParamsNode/SourceParamsNode.tsx
@@ -9,7 +9,6 @@ import { SourceParams } from '../SourceParams';
import { TransferCanvasEdge } from '../TransferConnectionsCanvas';
import { SourceParamsNodeProps } from './types';
-import classes from './styles.module.less';
export const SourceParamsNode = ({ data }: SourceParamsNodeProps) => {
const connectionType = Form.useWatch(['source_params', 'type']);
@@ -28,7 +27,7 @@ export const SourceParamsNode = ({ data }: SourceParamsNodeProps) => {
}, [data.groupId, data.initialSourceConnectionType]);
return (
-
+
{children}
);
diff --git a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/styles.module.less b/src/features/transfer/MutateTransferForm/components/SourceParamsNode/styles.module.less
deleted file mode 100644
index c6b6dd45..00000000
--- a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/styles.module.less
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- width: 300px;
-}
diff --git a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/types.ts b/src/features/transfer/MutateTransferForm/components/SourceParamsNode/types.ts
index a7c959ce..5d38a69c 100644
--- a/src/features/transfer/MutateTransferForm/components/SourceParamsNode/types.ts
+++ b/src/features/transfer/MutateTransferForm/components/SourceParamsNode/types.ts
@@ -1,8 +1,8 @@
import { Node, NodeProps } from '@xyflow/react';
import { SourceParamsProps } from '../SourceParams';
-import { TransferCanvasNode } from '../TransferConnectionsCanvas';
+import { TransferCanvasDefaultNodeType } from '../TransferConnectionsCanvas';
-export interface SourceParamsNodeData extends Node {}
+export interface SourceParamsNodeData extends Node {}
export interface SourceParamsNodeProps extends NodeProps {}
diff --git a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/TargetParamsNode.tsx b/src/features/transfer/MutateTransferForm/components/TargetParamsNode/TargetParamsNode.tsx
index db66eb4c..9827c3bd 100644
--- a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/TargetParamsNode.tsx
+++ b/src/features/transfer/MutateTransferForm/components/TargetParamsNode/TargetParamsNode.tsx
@@ -9,7 +9,6 @@ import { TargetParams } from '../TargetParams';
import { TransferCanvasEdge } from '../TransferConnectionsCanvas';
import { TargetParamsNodeProps } from './types';
-import classes from './styles.module.less';
export const TargetParamsNode = ({ data }: TargetParamsNodeProps) => {
const connectionType = Form.useWatch(['target_params', 'type']);
@@ -28,7 +27,7 @@ export const TargetParamsNode = ({ data }: TargetParamsNodeProps) => {
}, [data.groupId, data.initialTargetConnectionType]);
return (
-
+
{children}
);
diff --git a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/styles.module.less b/src/features/transfer/MutateTransferForm/components/TargetParamsNode/styles.module.less
deleted file mode 100644
index c6b6dd45..00000000
--- a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/styles.module.less
+++ /dev/null
@@ -1,3 +0,0 @@
-.root {
- width: 300px;
-}
diff --git a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/types.ts b/src/features/transfer/MutateTransferForm/components/TargetParamsNode/types.ts
index 0be51b22..2073f923 100644
--- a/src/features/transfer/MutateTransferForm/components/TargetParamsNode/types.ts
+++ b/src/features/transfer/MutateTransferForm/components/TargetParamsNode/types.ts
@@ -1,8 +1,8 @@
import { Node, NodeProps } from '@xyflow/react';
import { TargetParamsProps } from '../TargetParams';
-import { TransferCanvasNode } from '../TransferConnectionsCanvas';
+import { TransferCanvasDefaultNodeType } from '../TransferConnectionsCanvas';
-export interface TargetParamsNodeData extends Node {}
+export interface TargetParamsNodeData extends Node {}
export interface TargetParamsNodeProps extends NodeProps {}
diff --git a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/TransferConnectionsCanvas.tsx b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/TransferConnectionsCanvas.tsx
index 3d871f12..7d92f4d5 100644
--- a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/TransferConnectionsCanvas.tsx
+++ b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/TransferConnectionsCanvas.tsx
@@ -2,10 +2,13 @@ import React, { useMemo } from 'react';
import { Canvas, Fieldset } from '@shared/ui';
import { ReactFlowProvider, useEdgesState, useNodesState } from '@xyflow/react';
+import { TransformButtons } from '../TransformButtons';
+
import { TransferCanvasProps } from './types';
import { getInitialNodes } from './utils';
import { INITIAL_EDGES, NODE_TYPES } from './constants';
import classes from './styles.module.less';
+
import '@xyflow/react/dist/style.css';
export const TransferConnectionsCanvas = (props: TransferCanvasProps) => {
@@ -29,7 +32,9 @@ export const TransferConnectionsCanvas = (props: TransferCanvasProps) => {
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
- />
+ >
+
+
diff --git a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/constants.ts b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/constants.ts
index fc5c9896..e3b9a488 100644
--- a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/constants.ts
+++ b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/constants.ts
@@ -2,19 +2,21 @@ import { Edge, NodeTypes } from '@xyflow/react';
import { SourceParamsNode } from '../SourceParamsNode';
import { TargetParamsNode } from '../TargetParamsNode';
+import { FilterRowsNode } from '../FilterRowsNode';
-import { TransferCanvasNode } from './types';
+import { TransferCanvasDefaultNodeType, TransferCanvasTransformNodeType } from './types';
export const INITIAL_EDGES: Edge[] = [
{
id: 'edge-1',
- source: TransferCanvasNode.SOURCE,
- target: TransferCanvasNode.TARGET,
+ source: TransferCanvasDefaultNodeType.SOURCE,
+ target: TransferCanvasDefaultNodeType.TARGET,
animated: true,
},
];
export const NODE_TYPES: NodeTypes = {
- [TransferCanvasNode.SOURCE]: SourceParamsNode,
- [TransferCanvasNode.TARGET]: TargetParamsNode,
+ [TransferCanvasDefaultNodeType.SOURCE]: SourceParamsNode,
+ [TransferCanvasDefaultNodeType.TARGET]: TargetParamsNode,
+ [TransferCanvasTransformNodeType.FILTER_ROWS]: FilterRowsNode,
};
diff --git a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/types.ts b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/types.ts
index efc71617..f119895f 100644
--- a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/types.ts
+++ b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/types.ts
@@ -1,18 +1,26 @@
+import { FilterRowsNodeData } from '../FilterRowsNode';
import { SourceParamsNodeData } from '../SourceParamsNode';
import { TargetParamsNodeData } from '../TargetParamsNode';
import { GetInitialNodesProps } from './utils';
-export interface TransferCanvasProps extends GetInitialNodesProps {}
+export interface TransferCanvasProps
+ extends Pick {}
-export type TransferCanvasNodeData = SourceParamsNodeData | TargetParamsNodeData;
+export type TransferCanvasNodeData = SourceParamsNodeData | TargetParamsNodeData | FilterRowsNodeData;
-export enum TransferCanvasNode {
+export enum TransferCanvasDefaultNodeType {
SOURCE = 'SOURCE',
TARGET = 'TARGET',
}
+export enum TransferCanvasTransformNodeType {
+ FILTER_ROWS = 'FILTER_ROWS',
+}
+
export enum TransferCanvasEdge {
SOURCE = 'SOURCE',
TARGET = 'TARGET',
+ FILTER_ROWS_SOURCE = 'FILTER_ROWS_SOURCE',
+ FILTER_ROWS_TARGET = 'FILTER_ROWS_TARGET',
}
diff --git a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/utils/getInitialNodes/getInitialNodes.ts b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/utils/getInitialNodes/getInitialNodes.ts
index 909e00c5..5523598a 100644
--- a/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/utils/getInitialNodes/getInitialNodes.ts
+++ b/src/features/transfer/MutateTransferForm/components/TransferConnectionsCanvas/utils/getInitialNodes/getInitialNodes.ts
@@ -1,4 +1,4 @@
-import { TransferCanvasNodeData, TransferCanvasNode } from '../../types';
+import { TransferCanvasNodeData, TransferCanvasDefaultNodeType } from '../../types';
import { GetInitialNodesProps } from './types';
@@ -8,15 +8,15 @@ export const getInitialNodes = ({
initialTargetConnectionType,
}: GetInitialNodesProps): TransferCanvasNodeData[] => [
{
- id: TransferCanvasNode.SOURCE,
- type: TransferCanvasNode.SOURCE,
+ id: TransferCanvasDefaultNodeType.SOURCE,
+ type: TransferCanvasDefaultNodeType.SOURCE,
data: { groupId, initialSourceConnectionType },
position: { x: 0, y: 0 },
},
{
- id: TransferCanvasNode.TARGET,
- type: TransferCanvasNode.TARGET,
+ id: TransferCanvasDefaultNodeType.TARGET,
+ type: TransferCanvasDefaultNodeType.TARGET,
data: { groupId, initialTargetConnectionType },
- position: { x: 600, y: 0 },
+ position: { x: 500, y: 0 },
},
];
diff --git a/src/features/transfer/MutateTransferForm/components/TransformButtons/TransformButtons.tsx b/src/features/transfer/MutateTransferForm/components/TransformButtons/TransformButtons.tsx
new file mode 100644
index 00000000..e6e9bcd2
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/TransformButtons/TransformButtons.tsx
@@ -0,0 +1,28 @@
+import React, { memo } from 'react';
+import { Button, Typography } from 'antd';
+
+import { TransferCanvasTransformNodeType } from '../TransferConnectionsCanvas';
+
+import classes from './styles.module.less';
+import { useHandleNodes } from './hooks';
+
+const { Text } = Typography;
+
+export const TransformButtons = memo(() => {
+ const { transformNodeTypes, handleAddTransformNode } = useHandleNodes();
+
+ return (
+
+
You can add some data transforms:
+
+
+
+
+ );
+});
diff --git a/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/index.ts b/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/index.ts
new file mode 100644
index 00000000..0d21cc47
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useHandleNodes';
diff --git a/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/useHandleNodes/index.ts b/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/useHandleNodes/index.ts
new file mode 100644
index 00000000..69467511
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/TransformButtons/hooks/useHandleNodes/index.ts
@@ -0,0 +1,52 @@
+import { useReactFlow } from '@xyflow/react';
+import { useState } from 'react';
+
+import { TransferCanvasDefaultNodeType, TransferCanvasTransformNodeType } from '../../../TransferConnectionsCanvas';
+
+/** Hook for handling nodes and edges data (add, delete) */
+export const useHandleNodes = () => {
+ const [transformNodeTypes, setTransformNodeTypes] = useState>();
+ const { getNodes, getEdges, setNodes, setEdges } = useReactFlow();
+
+ const addNewNode = (nodeType: TransferCanvasTransformNodeType) => {
+ const newNode = {
+ id: nodeType,
+ type: nodeType,
+ position: { x: 0, y: 0 },
+ data: {},
+ };
+
+ const nodes = getNodes();
+
+ const firstNodes = nodes.slice(0, nodes.length - 1);
+ const lastNode = nodes[nodes.length - 1];
+ const newNodes = firstNodes.concat(newNode).concat(lastNode);
+
+ setNodes(newNodes.map((node, index) => ({ ...node, position: { x: index * 500, y: 0 } })));
+ };
+
+ const addNewEdge = (nodeType: TransferCanvasTransformNodeType) => {
+ const edges = getEdges();
+
+ const newEdge = {
+ id: `edge-${edges.length + 1}`,
+ source: nodeType,
+ target: TransferCanvasDefaultNodeType.TARGET,
+ animated: true,
+ };
+
+ const firstEdges = edges.slice(0, edges.length - 1);
+ const lastEdge = { ...edges[edges.length - 1], target: nodeType };
+ const newEdges = firstEdges.concat(lastEdge).concat(newEdge);
+
+ setEdges(newEdges);
+ };
+
+ const handleAddTransformNode = (nodeType: TransferCanvasTransformNodeType) => {
+ setTransformNodeTypes((state) => ({ ...state, [nodeType]: true }));
+ addNewNode(nodeType);
+ addNewEdge(nodeType);
+ };
+
+ return { transformNodeTypes, handleAddTransformNode };
+};
diff --git a/src/features/transfer/MutateTransferForm/components/TransformButtons/index.ts b/src/features/transfer/MutateTransferForm/components/TransformButtons/index.ts
new file mode 100644
index 00000000..cd35d2b9
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/TransformButtons/index.ts
@@ -0,0 +1 @@
+export * from './TransformButtons';
diff --git a/src/features/transfer/MutateTransferForm/components/TransformButtons/styles.module.less b/src/features/transfer/MutateTransferForm/components/TransformButtons/styles.module.less
new file mode 100644
index 00000000..d825a71c
--- /dev/null
+++ b/src/features/transfer/MutateTransferForm/components/TransformButtons/styles.module.less
@@ -0,0 +1,20 @@
+.root {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: @white;
+ margin-bottom: 15px;
+ border-radius: 16px;
+ padding: 16px;
+ z-index: 5;
+
+ .buttons {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ }
+}
diff --git a/src/shared/ui/Canvas/index.tsx b/src/shared/ui/Canvas/index.tsx
index 794a0feb..4aae0865 100644
--- a/src/shared/ui/Canvas/index.tsx
+++ b/src/shared/ui/Canvas/index.tsx
@@ -1,10 +1,17 @@
-import { Background, BackgroundVariant, Controls, Edge, MiniMap, Node, ReactFlow } from '@xyflow/react';
-import React from 'react';
+import { Background, BackgroundVariant, Controls, Edge, MiniMap, Node, ReactFlow, useReactFlow } from '@xyflow/react';
+import React, { useEffect } from 'react';
import classes from './styles.module.less';
import { CanvasProps } from './types';
-export const Canvas = (props: CanvasProps) => {
+export const Canvas = ({ children, nodes, ...props }: CanvasProps) => {
+ const { fitView } = useReactFlow();
+
+ /** Set appropriate zoom of canvas when nodes count has changed */
+ useEffect(() => {
+ fitView({ duration: 200 });
+ }, [nodes?.length, fitView]);
+
return (
(props: CanvasProps)
nodesFocusable
elementsSelectable
nodesConnectable={false}
+ nodes={nodes}
nodesDraggable
panOnScroll={false}
panOnDrag
zoomOnScroll
zoomOnPinch
zoomOnDoubleClick={false}
- fitViewOptions={{ duration: 200, padding: 1 }}
+ fitViewOptions={{ duration: 200, padding: 0.5 }}
fitView
{...props}
>
+ {children}
);
};
diff --git a/src/shared/ui/Canvas/styles.module.less b/src/shared/ui/Canvas/styles.module.less
index 75413e6c..46d14d57 100644
--- a/src/shared/ui/Canvas/styles.module.less
+++ b/src/shared/ui/Canvas/styles.module.less
@@ -1,10 +1,13 @@
.root {
:global(.react-flow__minimap) {
- transform: scale(70%);
+ svg {
+ width: 140px;
+ height: 105px;
+ }
}
:global(.react-flow__node) {
- width: fit-content;
+ width: 300px;
background-color: @white;
border: 1px solid fade(@black, 25%);
border-radius: 16px;