Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/entities/transformation/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConnectionType } from '@shared/types';
import { createContext } from 'react';

import {
Expand All @@ -17,9 +18,9 @@ const SHOW_BUTTONS_CONTEXT_INITIAL_VALUE: ShowButtonsContextProps = {
export const ShowButtonsContext = createContext<ShowButtonsContextProps>(SHOW_BUTTONS_CONTEXT_INITIAL_VALUE);

export const TRANSFORMATIONS_FORM_DEFAULT_VALUE: TransformationsForm = {
[TransformationType.FILTER_FILE]: [],
[TransformationType.FILTER_ROWS]: [],
[TransformationType.FILTER_COLUMNS]: [],
[TransformationType.FILTER_FILE]: [],
};

export const TRANSFORMATIONS_REQUEST_DEFAULT_VALUE: Transformations = [
Expand Down Expand Up @@ -65,3 +66,24 @@ export const TRANSFORMATION_FILTER_FILE_TYPE_DISPLAY = {
[TransformationFilterFileType.FILE_SIZE_MIN]: 'fileSizeMin',
[TransformationFilterFileType.FILE_SIZE_MAX]: 'fileSizeMax',
} as const;

const FILE_TRANSFORMATION_TYPES = Object.values(TransformationType);

const DB_TRANSFORMATION_TYPES = FILE_TRANSFORMATION_TYPES.filter((type) => type !== TransformationType.FILTER_FILE);

export const CONNECTION_TYPE_SUPPORT_TRANSFORMATION_TYPES: Record<ConnectionType, TransformationType[]> = {
[ConnectionType.CLICKHOUSE]: DB_TRANSFORMATION_TYPES,
[ConnectionType.FTP]: FILE_TRANSFORMATION_TYPES,
[ConnectionType.FTPS]: FILE_TRANSFORMATION_TYPES,
[ConnectionType.HDFS]: DB_TRANSFORMATION_TYPES,
[ConnectionType.HIVE]: DB_TRANSFORMATION_TYPES,
[ConnectionType.ICEBERG]: DB_TRANSFORMATION_TYPES,
[ConnectionType.MSSQL]: DB_TRANSFORMATION_TYPES,
[ConnectionType.MYSQL]: DB_TRANSFORMATION_TYPES,
[ConnectionType.ORACLE]: DB_TRANSFORMATION_TYPES,
[ConnectionType.POSTGRES]: DB_TRANSFORMATION_TYPES,
[ConnectionType.S3]: DB_TRANSFORMATION_TYPES,
[ConnectionType.SAMBA]: FILE_TRANSFORMATION_TYPES,
[ConnectionType.SFTP]: FILE_TRANSFORMATION_TYPES,
[ConnectionType.WEBDAV]: FILE_TRANSFORMATION_TYPES,
};
2 changes: 1 addition & 1 deletion src/entities/transformation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ export interface TransformationFilterFileForm {
export type Transformations = Array<TransformationFilterRows | TransformationFilterColumns | TransformationFilterFile>;

export interface TransformationsForm {
[TransformationType.FILTER_FILE]?: TransformationFilterFileForm['filters'];
[TransformationType.FILTER_ROWS]?: TransformationFilterRows['filters'];
[TransformationType.FILTER_COLUMNS]?: TransformationFilterColumns['filters'];
[TransformationType.FILTER_FILE]?: TransformationFilterFileForm['filters'];
}

export type TransformationsFormNestedType<T extends keyof TransformationsForm> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export const useGetNestedTypesSelectOptions = (transformationType: Transformatio
TransformationType,
OptionItem<TransformationFilterRowsType | TransformationFilterColumnsType | TransformationFilterFileType>[]
> = {
[TransformationType.FILTER_FILE]: filterFileTypeSelectOptions,
[TransformationType.FILTER_ROWS]: filterRowsTypeSelectOptions,
[TransformationType.FILTER_COLUMNS]: filterColumnsTypeSelectOptions,
[TransformationType.FILTER_FILE]: filterFileTypeSelectOptions,
};

return filterOptions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useMemo } from 'react';
import { useMemo } from 'react';
import { Canvas } from '@shared/ui';
import { ReactFlowProvider } from '@xyflow/react';
import { Form } from 'antd';
import { ShowButtonsContext, TransformationsForm, TransformationType } from '@entities/transformation';

import { TransformButtons } from '../TransformButtons';
import { useSupportedTransformationTypes } from '../../hooks';

import { TransferCanvasProps } from './types';
import { getInitialEdges, getInitialNodes } from './utils';
Expand All @@ -15,6 +16,7 @@ import '@xyflow/react/dist/style.css';

export const TransferConnectionsCanvas = ({ groupId, isDisplayedButtons = true }: TransferCanvasProps) => {
const formInstance = Form.useFormInstance();
const { supportedTransformationTypes } = useSupportedTransformationTypes();

const initialTransformations = useMemo(() => {
return formInstance.getFieldValue('transformations') as TransformationsForm;
Expand All @@ -23,11 +25,17 @@ export const TransferConnectionsCanvas = ({ groupId, isDisplayedButtons = true }
const initialNodes = useMemo(() => {
return getInitialNodes({
groupId,
hasFilterRows: !!initialTransformations[TransformationType.FILTER_ROWS]?.length,
hasFilterColumns: !!initialTransformations[TransformationType.FILTER_COLUMNS]?.length,
hasFilterFile: !!initialTransformations[TransformationType.FILTER_FILE]?.length,
hasFilterFile:
supportedTransformationTypes.includes(TransformationType.FILTER_FILE) &&
!!initialTransformations[TransformationType.FILTER_FILE]?.length,
hasFilterRows:
supportedTransformationTypes.includes(TransformationType.FILTER_ROWS) &&
!!initialTransformations[TransformationType.FILTER_ROWS]?.length,
hasFilterColumns:
supportedTransformationTypes.includes(TransformationType.FILTER_COLUMNS) &&
!!initialTransformations[TransformationType.FILTER_COLUMNS]?.length,
});
}, [groupId, initialTransformations]);
}, [groupId, supportedTransformationTypes, initialTransformations]);

const initialEdges = useMemo(() => {
return getInitialEdges(initialNodes);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NodeTypes } from '@xyflow/react';
import { TransformationType } from '@entities/transformation';

import { SourceParamsNode } from '../SourceParamsNode';
import { TargetParamsNode } from '../TargetParamsNode';
Expand All @@ -11,32 +12,54 @@ import { TransferCanvasDefaultNodeType, TransferCanvasEdgeType, TransferCanvasTr
export const NODE_TYPES: NodeTypes = {
[TransferCanvasDefaultNodeType.SOURCE]: SourceParamsNode,
[TransferCanvasDefaultNodeType.TARGET]: TargetParamsNode,
[TransferCanvasTransformNodeType.FILTER_FILE]: FilterFileNode,
[TransferCanvasTransformNodeType.FILTER_ROWS]: FilterRowsNode,
[TransferCanvasTransformNodeType.FILTER_COLUMNS]: FilterColumnsNode,
[TransferCanvasTransformNodeType.FILTER_FILE]: FilterFileNode,
};

export const NODE_TYPES_ID = {
[TransferCanvasDefaultNodeType.SOURCE]: '1',
[TransferCanvasTransformNodeType.FILTER_ROWS]: '2',
[TransferCanvasTransformNodeType.FILTER_COLUMNS]: '3',
[TransferCanvasTransformNodeType.FILTER_FILE]: '4',
[TransferCanvasTransformNodeType.FILTER_FILE]: '2',
[TransferCanvasTransformNodeType.FILTER_ROWS]: '3',
[TransferCanvasTransformNodeType.FILTER_COLUMNS]: '4',
[TransferCanvasDefaultNodeType.TARGET]: '5',
};

export const EDGE_TYPES_ID = {
[TransferCanvasEdgeType.SOURCE]: '1',
[TransferCanvasEdgeType.FILTER_ROWS]: '2',
[TransferCanvasEdgeType.FILTER_COLUMNS]: '3',
[TransferCanvasEdgeType.FILTER_FILE]: '4',
[TransferCanvasEdgeType.FILTER_FILE]: '2',
[TransferCanvasEdgeType.FILTER_ROWS]: '3',
[TransferCanvasEdgeType.FILTER_COLUMNS]: '4',
[TransferCanvasEdgeType.TARGET]: '5',
};

export const NODE_POSITION_X_GAP_DEFAULT = 500;
export const NODE_POSITION_X_GAP_LARGE = 1000;

export const TRANSFER_CANVAS_TRANSFORM_NODE_TYPE_NAME_DISPLAY = {
[TransferCanvasTransformNodeType.FILTER_FILE]: 'filterFile',
[TransferCanvasTransformNodeType.FILTER_ROWS]: 'filterRows',
[TransferCanvasTransformNodeType.FILTER_COLUMNS]: 'filterColumns',
[TransferCanvasTransformNodeType.FILTER_FILE]: 'filterFile',
} as const;

export const TRANSFER_CANVAS_NODE_TYPE_TO_TRANSFORM_TYPE_MAP: Record<
TransferCanvasTransformNodeType,
TransformationType
> = {
[TransferCanvasTransformNodeType.FILTER_FILE]: TransformationType.FILTER_FILE,
[TransferCanvasTransformNodeType.FILTER_ROWS]: TransformationType.FILTER_ROWS,
[TransferCanvasTransformNodeType.FILTER_COLUMNS]: TransformationType.FILTER_COLUMNS,
} as const;

export const TRANSFER_TRANSFORM_TYPE_TO_CANVAS_NODE_TYPE_MAP: Record<
TransformationType,
TransferCanvasTransformNodeType
> = {
[TransformationType.FILTER_FILE]: TransferCanvasTransformNodeType.FILTER_FILE,
[TransformationType.FILTER_ROWS]: TransferCanvasTransformNodeType.FILTER_ROWS,
[TransformationType.FILTER_COLUMNS]: TransferCanvasTransformNodeType.FILTER_COLUMNS,
} as const;

export const TRANSFER_CANVAS_FILTER_NODES = Object.values(
TransferCanvasTransformNodeType,
) as TransferCanvasTransformNodeType[];
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ export enum TransferCanvasDefaultNodeType {
}

export enum TransferCanvasTransformNodeType {
FILTER_FILE = 'FILTER_FILE',
FILTER_ROWS = 'FILTER_ROWS',
FILTER_COLUMNS = 'FILTER_COLUMNS',
FILTER_FILE = 'FILTER_FILE',
}

export enum TransferCanvasEdgeType {
SOURCE = 'SOURCE',
FILTER_FILE = 'FILTER_FILE',
FILTER_ROWS = 'FILTER_ROWS',
FILTER_COLUMNS = 'FILTER_COLUMNS',
FILTER_FILE = 'FILTER_FILE',
TARGET = 'TARGET',
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,30 @@ export const getInitialNodes = ({

let nodeIndex = 1;

if (hasFilterRows) {
if (hasFilterFile) {
nodes.push({
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_ROWS],
type: TransferCanvasTransformNodeType.FILTER_ROWS,
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_FILE],
type: TransferCanvasTransformNodeType.FILTER_FILE,
data: {},
position: setNodePosition(nodeIndex),
});
nodeIndex++;
}

if (hasFilterColumns) {
if (hasFilterRows) {
nodes.push({
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_COLUMNS],
type: TransferCanvasTransformNodeType.FILTER_COLUMNS,
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_ROWS],
type: TransferCanvasTransformNodeType.FILTER_ROWS,
data: {},
position: setNodePosition(nodeIndex),
});
nodeIndex++;
}

if (hasFilterFile) {
if (hasFilterColumns) {
nodes.push({
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_FILE],
type: TransferCanvasTransformNodeType.FILTER_FILE,
id: NODE_TYPES_ID[TransferCanvasTransformNodeType.FILTER_COLUMNS],
type: TransferCanvasTransformNodeType.FILTER_COLUMNS,
data: {},
position: setNodePosition(nodeIndex),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { FilterRowsFormItem } from '../FilterRowsFormItem';
import { FilterTypeConfig } from './types';

export const FILTER_TYPES_CONFIG: Record<TransformationType, FilterTypeConfig> = {
[TransformationType.FILTER_FILE]: {
title: 'filterFile',
filter: <FilterFileFormItem canHaveEmptyRecordsList />,
},
[TransformationType.FILTER_ROWS]: {
title: 'filterRows',
filter: <FilterRowsFormItem canHaveEmptyRecordsList />,
Expand All @@ -16,8 +20,4 @@ export const FILTER_TYPES_CONFIG: Record<TransformationType, FilterTypeConfig> =
title: 'filterColumns',
filter: <FilterColumnsFormItem canHaveEmptyRecordsList />,
},
[TransformationType.FILTER_FILE]: {
title: 'filterFile',
filter: <FilterFileFormItem canHaveEmptyRecordsList />,
},
} as const;
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import React, { useMemo } from 'react';
import { useMemo } from 'react';
import { Fieldset } from '@shared/ui';
import { useTranslation } from 'react-i18next';
import { TransformationType } from '@entities/transformation';

import { SourceParams } from '../SourceParams';
import { TargetParams } from '../TargetParams';
import { useSupportedTransformationTypes } from '../../hooks';

import { TransferConnectionsDefaultProps } from './types';
import { FILTER_TYPES_CONFIG } from './constants';

export const TransferConnectionsDefault = ({ groupId }: TransferConnectionsDefaultProps) => {
const { t } = useTranslation('transfer');
const { supportedTransformationTypes } = useSupportedTransformationTypes();

const filters = useMemo(
() =>
Object.entries(FILTER_TYPES_CONFIG).map(([key, { title, filter }]) => (
<Fieldset key={key} title={t(title, { ns: 'transformation' })}>
{filter}
</Fieldset>
)),
[t],
Object.entries(FILTER_TYPES_CONFIG)
.filter(([key]) => supportedTransformationTypes.includes(key as TransformationType))
.map(([key, { title, filter }]) => (
<Fieldset key={key} title={t(title, { ns: 'transformation' })}>
{filter}
</Fieldset>
)),
[supportedTransformationTypes, t],
);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { memo, useState } from 'react';
import { memo, useState } from 'react';
import { Typography } from 'antd';
import { useModalState } from '@shared/hooks';
import { ModalWrapper } from '@shared/ui';
Expand All @@ -8,7 +8,9 @@ import { useTranslation } from 'react-i18next';
import {
TransferCanvasTransformNodeType,
TRANSFER_CANVAS_TRANSFORM_NODE_TYPE_NAME_DISPLAY,
TRANSFER_CANVAS_NODE_TYPE_TO_TRANSFORM_TYPE_MAP,
} from '../TransferConnectionsCanvas';
import { useSupportedTransformationTypes } from '../../hooks';

import { useHandleNodes } from './hooks';
import { DeleteNode, TransformButtonItem } from './components';
Expand All @@ -20,6 +22,8 @@ export const TransformButtons = memo(() => {
const { t } = useTranslation('transformation');
const { transformNodeTypes, handleAddTransformNode, handleDeleteTransformNode } = useHandleNodes();

const { supportedTransformationTypes } = useSupportedTransformationTypes();

const [nodeTypeForDeleting, setNodeTypeForDeleting] = useState<TransferCanvasTransformNodeType | null>(null);

const { isOpened: isOpenedModal, handleOpen: openModal, handleClose: handleCloseModal } = useModalState();
Expand All @@ -38,15 +42,19 @@ export const TransformButtons = memo(() => {
<div className={classes.root}>
<Text strong>{t('transformations')}</Text>
<div className={classes.buttons}>
{Object.values(TransferCanvasTransformNodeType).map((item, index) => (
<TransformButtonItem
nodeType={item}
isExist={transformNodeTypes ? !!transformNodeTypes[item] : false}
onAddNode={handleAddTransformNode}
onDeleteNode={handleOpenDeleteNodeModal}
key={index}
/>
))}
{Object.values(TransferCanvasTransformNodeType)
.filter((item) =>
supportedTransformationTypes.includes(TRANSFER_CANVAS_NODE_TYPE_TO_TRANSFORM_TYPE_MAP[item]),
)
.map((item) => (
<TransformButtonItem
nodeType={item}
isExist={transformNodeTypes ? !!transformNodeTypes[item] : false}
onAddNode={handleAddTransformNode}
onDeleteNode={handleOpenDeleteNodeModal}
key={item}
/>
))}
</div>
{nodeTypeForDeleting && (
<ModalWrapper
Expand Down
Loading