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
6 changes: 5 additions & 1 deletion src/app/config/router/instance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
CreateConnectionPage,
UpdateConnectionPage,
} from '@pages/connection';
import { TransferDetailPage, TransferListPage } from '@pages/transfer';
import { CreateTransferPage, TransferDetailPage, TransferListPage } from '@pages/transfer';
import { RunDetailPage } from '@pages/run';

import { ErrorBoundary, NotFoundError } from '../errorBoundary';
Expand Down Expand Up @@ -117,6 +117,10 @@ export const router = createBrowserRouter([
path: '/transfers/runs/:id',
element: <RunDetailPage />,
},
{
path: '/transfers/create',
element: <CreateTransferPage />,
},
],
},
{
Expand Down
12 changes: 11 additions & 1 deletion src/entities/transfer/api/transferService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { axiosInstance } from '@shared/config';
import { PaginationResponse } from '@shared/types';

import { DeleteTransferRequest, GetTransferRequest, GetTransfersRequest, Transfer } from './types';
import {
CreateTransferRequest,
DeleteTransferRequest,
GetTransferRequest,
GetTransfersRequest,
Transfer,
} from './types';

export const transferService = {
getTransfers: (params: GetTransfersRequest): Promise<PaginationResponse<Transfer>> => {
Expand All @@ -12,6 +18,10 @@ export const transferService = {
return axiosInstance.get(`transfers/${id}`);
},

createTransfer: (data: CreateTransferRequest): Promise<Transfer> => {
return axiosInstance.post(`transfers`, data);
},

deleteTransfer: ({ id }: DeleteTransferRequest): Promise<null> => {
return axiosInstance.delete(`transfers/${id}`);
},
Expand Down
12 changes: 7 additions & 5 deletions src/entities/transfer/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ export interface Transfer {
source_connection_id: number;
target_connection_id: number;
description: string;
is_scheduled: boolean;
schedule: string;
queue_id: number;
source_params:
| TransferParamsHive
Expand All @@ -23,9 +21,13 @@ export interface Transfer {
| TransferTargetParamsHdfs
| TransferTargetParamsS3;
strategy_params: TransferStrategyParams;
is_scheduled: boolean;
schedule: string;
}

interface TransferStrategyParams {
export type TransferConnectionParamFieldName = 'source_params' | 'target_params';

export interface TransferStrategyParams {
type: 'full' | 'incremental';
}

Expand All @@ -47,7 +49,6 @@ interface TransferParamsPostgres {
interface TransferParamsHdfs {
type: ConnectionType.HDFS;
directory_path: string;
options: object;
}

interface TransferSourceParamsHdfs extends TransferParamsHdfs {
Expand All @@ -61,7 +62,6 @@ interface TransferTargetParamsHdfs extends TransferParamsHdfs {
interface TransferParamsS3 {
type: ConnectionType.S3;
directory_path: string;
options: object;
}

interface TransferSourceParamsS3 extends TransferParamsS3 {
Expand All @@ -80,6 +80,8 @@ export interface GetTransferRequest {
id: number;
}

export interface CreateTransferRequest extends Omit<Transfer, 'id'> {}

export interface DeleteTransferRequest {
id: number;
}
24 changes: 24 additions & 0 deletions src/entities/transfer/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { prepareOptionsForSelect } from '@shared/ui';
import { FileFormatType } from '@shared/types';

import { TransferStrategyParams } from './api';

export const TRANSFER_STRATEGY_PARAMS_SELECT_OPTIONS = prepareOptionsForSelect<TransferStrategyParams['type']>({
data: ['full', 'incremental'],
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const TRANSFER_SOURCE_CONNECTION_FILE_FORMAT_SELECT_OPTIONS = prepareOptionsForSelect<FileFormatType>({
data: Object.values(FileFormatType),
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const TRANSFER_TARGET_CONNECTION_FILE_FORMAT_SELECT_OPTIONS = prepareOptionsForSelect<
Exclude<FileFormatType, 'json'>
>({
data: [FileFormatType.CSV, FileFormatType.JSON_LINE],
renderLabel: (data) => data,
renderValue: (data) => data,
});
1 change: 1 addition & 0 deletions src/entities/transfer/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './api';
export * from './constants';
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { ConnectionQueryKey, connectionService } from '@entities/connection';
import { ManagedSelect } from '@shared/ui';
import { Divider, Form, Input } from 'antd';

import { useSelectConnectionType } from '../../hooks';

import { SourceParamsProps } from './types';
import { TRANSFER_SOURCE_CONNECTION_TYPE_COMPONENT } from './constants';

export const SourceParams = ({ groupId, initialSourceConnectionType }: SourceParamsProps) => {
const { selectedConnectionType, handleSelectConnection } = useSelectConnectionType({
connectionParamFieldName: 'source_params',
initialConnectionType: initialSourceConnectionType,
});

return (
<>
<Divider>Source params</Divider>
<Form.Item label="Source connection" name="source_connection_id" rules={[{ required: true }]}>
<ManagedSelect
size="large"
queryKey={[ConnectionQueryKey.GET_CONNECTIONS, groupId]}
queryFunction={(params) => connectionService.getConnections({ group_id: groupId, ...params })}
renderOptionValue={(connection) => connection.id}
renderOptionLabel={(connection) => connection.name}
onSelect={handleSelectConnection}
placeholder="Select source connection"
/>
</Form.Item>
<Form.Item name={['source_params', 'type']} style={{ display: 'none' }}>
<Input />
</Form.Item>
{TRANSFER_SOURCE_CONNECTION_TYPE_COMPONENT[selectedConnectionType!]}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { ConnectionType } from '@shared/types';

import { TransferConnectionHdfs } from '../TransferConnectionHdfs';
import { TransferConnectionHive } from '../TransferConnectionHive';
import { TransferConnectionOracle } from '../TransferConnectionOracle';
import { TransferConnectionPostgres } from '../TransferConnectionPostgres';
import { TransferConnectionS3 } from '../TransferConnectionS3';

export const TRANSFER_SOURCE_CONNECTION_TYPE_COMPONENT = {
[ConnectionType.HDFS]: <TransferConnectionHdfs name="source_params" />,
[ConnectionType.HIVE]: <TransferConnectionHive name="source_params" />,
[ConnectionType.ORACLE]: <TransferConnectionOracle name="source_params" />,
[ConnectionType.POSTGRES]: <TransferConnectionPostgres name="source_params" />,
[ConnectionType.S3]: <TransferConnectionS3 name="source_params" />,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './SourceParams';
export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ConnectionType } from '@shared/types';

export interface SourceParamsProps {
groupId: number;
initialSourceConnectionType?: ConnectionType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { ConnectionQueryKey, connectionService } from '@entities/connection';
import { ManagedSelect } from '@shared/ui';
import { Divider, Form, Input } from 'antd';

import { useSelectConnectionType } from '../../hooks';

import { TargetParamsProps } from './types';
import { TRANSFER_TARGET_CONNECTION_TYPE_COMPONENT } from './constants';

export const TargetParams = ({ groupId, initialTargetConnectionType }: TargetParamsProps) => {
const { selectedConnectionType, handleSelectConnection } = useSelectConnectionType({
connectionParamFieldName: 'target_params',
initialConnectionType: initialTargetConnectionType,
});

return (
<>
<Divider>Target params</Divider>
<Form.Item label="Target connection" name="target_connection_id" rules={[{ required: true }]}>
<ManagedSelect
size="large"
queryKey={[ConnectionQueryKey.GET_CONNECTIONS, groupId]}
queryFunction={(params) => connectionService.getConnections({ group_id: groupId, ...params })}
renderOptionValue={(connection) => connection.id}
renderOptionLabel={(connection) => connection.name}
onSelect={handleSelectConnection}
placeholder="Select target connection"
/>
</Form.Item>
<Form.Item name={['target_params', 'type']} style={{ display: 'none' }}>
<Input />
</Form.Item>
{TRANSFER_TARGET_CONNECTION_TYPE_COMPONENT[selectedConnectionType!]}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { ConnectionType } from '@shared/types';

import { TransferConnectionHdfs } from '../TransferConnectionHdfs';
import { TransferConnectionHive } from '../TransferConnectionHive';
import { TransferConnectionOracle } from '../TransferConnectionOracle';
import { TransferConnectionPostgres } from '../TransferConnectionPostgres';
import { TransferConnectionS3 } from '../TransferConnectionS3';

export const TRANSFER_TARGET_CONNECTION_TYPE_COMPONENT = {
[ConnectionType.HDFS]: <TransferConnectionHdfs name="target_params" />,
[ConnectionType.HIVE]: <TransferConnectionHive name="target_params" />,
[ConnectionType.ORACLE]: <TransferConnectionOracle name="target_params" />,
[ConnectionType.POSTGRES]: <TransferConnectionPostgres name="target_params" />,
[ConnectionType.S3]: <TransferConnectionS3 name="target_params" />,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './TargetParams';
export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ConnectionType } from '@shared/types';

export interface TargetParamsProps {
groupId: number;
initialTargetConnectionType?: ConnectionType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { Form, Input, Select } from 'antd';
import {
TRANSFER_SOURCE_CONNECTION_FILE_FORMAT_SELECT_OPTIONS,
TRANSFER_TARGET_CONNECTION_FILE_FORMAT_SELECT_OPTIONS,
} from '@entities/transfer';
import { ABSOLUTE_PATH_REGEXP } from '@shared/constants';

import { TransferConnectionHdfsProps } from './types';

export const TransferConnectionHdfs = ({ name }: TransferConnectionHdfsProps) => {
return (
<>
<Form.Item
label="Directory path"
name={[name, 'directory_path']}
rules={[{ required: true, pattern: ABSOLUTE_PATH_REGEXP }]}
>
<Input size="large" />
</Form.Item>
<Form.Item label="File format" name={[name, 'file_format', 'type']} rules={[{ required: true }]}>
<Select
size="large"
options={
name === 'source_params'
? TRANSFER_SOURCE_CONNECTION_FILE_FORMAT_SELECT_OPTIONS
: TRANSFER_TARGET_CONNECTION_FILE_FORMAT_SELECT_OPTIONS
}
placeholder="Select file format"
/>
</Form.Item>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ConnectionParamFieldName } from '../../types';

export interface TransferConnectionHdfsProps extends ConnectionParamFieldName {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Form, Input } from 'antd';

import { TransferConnectionHiveProps } from './types';

export const TransferConnectionHive = ({ name }: TransferConnectionHiveProps) => {
return (
<Form.Item label="Table name" name={[name, 'table_name']} rules={[{ required: true }]}>
<Input size="large" />
</Form.Item>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ConnectionParamFieldName } from '../../types';

export interface TransferConnectionHiveProps extends ConnectionParamFieldName {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Form, Input } from 'antd';

import { TransferConnectionOracleProps } from './types';

export const TransferConnectionOracle = ({ name }: TransferConnectionOracleProps) => {
return (
<Form.Item label="Table name" name={[name, 'table_name']} rules={[{ required: true }]}>
<Input size="large" />
</Form.Item>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ConnectionParamFieldName } from '../../types';

export interface TransferConnectionOracleProps extends ConnectionParamFieldName {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Form, Input } from 'antd';

import { TransferConnectionPostgresProps } from './types';

export const TransferConnectionPostgres = ({ name }: TransferConnectionPostgresProps) => {
return (
<Form.Item label="Table name" name={[name, 'table_name']} rules={[{ required: true }]}>
<Input size="large" />
</Form.Item>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ConnectionParamFieldName } from '../../types';

export interface TransferConnectionPostgresProps extends ConnectionParamFieldName {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { Form, Input, Select } from 'antd';
import {
TRANSFER_SOURCE_CONNECTION_FILE_FORMAT_SELECT_OPTIONS,
TRANSFER_TARGET_CONNECTION_FILE_FORMAT_SELECT_OPTIONS,
} from '@entities/transfer';
import { ABSOLUTE_PATH_REGEXP } from '@shared/constants';

import { TransferConnectionS3Props } from './types';

export const TransferConnectionS3 = ({ name }: TransferConnectionS3Props) => {
return (
<>
<Form.Item
label="Directory path"
name={[name, 'directory_path']}
rules={[{ required: true, pattern: ABSOLUTE_PATH_REGEXP }]}
>
<Input size="large" />
</Form.Item>
<Form.Item label="File format" name={[name, 'file_format', 'type']} rules={[{ required: true }]}>
<Select
size="large"
options={
name === 'source_params'
? TRANSFER_SOURCE_CONNECTION_FILE_FORMAT_SELECT_OPTIONS
: TRANSFER_TARGET_CONNECTION_FILE_FORMAT_SELECT_OPTIONS
}
placeholder="Select file format"
/>
</Form.Item>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ConnectionParamFieldName } from '../../types';

export interface TransferConnectionS3Props extends ConnectionParamFieldName {}
Loading
Loading