+
{data.type}
diff --git a/src/features/connection/ConnectionDetailInfo/components/ConnectionData/utils/getDescriptionItems/index.ts b/src/features/connection/ConnectionDetailInfo/components/ConnectionData/utils/getDescriptionItems/index.ts
index 4194300b..53f0c461 100644
--- a/src/features/connection/ConnectionDetailInfo/components/ConnectionData/utils/getDescriptionItems/index.ts
+++ b/src/features/connection/ConnectionDetailInfo/components/ConnectionData/utils/getDescriptionItems/index.ts
@@ -1,11 +1,11 @@
-import { DescriptionItem } from '@shared/types';
+import { ConnectionType, DescriptionItem } from '@shared/types';
import { GetDescriptionItemsProps } from './types';
/** Util for mapping data for Description component depends on connection type */
export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): DescriptionItem[] => {
switch (data.type) {
- case 'oracle':
+ case ConnectionType.ORACLE:
return [
{
label: 'Host',
@@ -24,7 +24,7 @@ export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): Descrip
content: data.sid || '',
},
];
- case 'postgres':
+ case ConnectionType.POSTGRES:
return [
{
label: 'Host',
@@ -39,7 +39,7 @@ export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): Descrip
content: data.database_name,
},
];
- case 's3':
+ case ConnectionType.S3:
return [
{
label: 'Host',
@@ -66,7 +66,8 @@ export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): Descrip
content: data.region || '',
},
];
- default:
+ case ConnectionType.HIVE:
+ case ConnectionType.HDFS:
return [
{
label: 'Cluster',
diff --git a/src/features/connection/ConnectionDetailInfo/index.tsx b/src/features/connection/ConnectionDetailInfo/index.tsx
index bc102cbf..679c53bc 100644
--- a/src/features/connection/ConnectionDetailInfo/index.tsx
+++ b/src/features/connection/ConnectionDetailInfo/index.tsx
@@ -22,10 +22,13 @@ export const ConnectionDetailInfo = ({ connection, group, ...props }: Connection
{group.name}
+
+
+
+
+
+
-
-
-
);
};
diff --git a/src/features/connection/ConnectionDetailInfo/styles.module.less b/src/features/connection/ConnectionDetailInfo/styles.module.less
index 0f0fc6a0..43e4522c 100644
--- a/src/features/connection/ConnectionDetailInfo/styles.module.less
+++ b/src/features/connection/ConnectionDetailInfo/styles.module.less
@@ -2,4 +2,18 @@
display: flex;
flex-direction: column;
gap: 24px;
+
+ .subDescription {
+ :global(+ .ant-descriptions-item-content) {
+ padding: 0;
+ }
+
+ :global(.ant-descriptions-item) {
+ padding: 0;
+ }
+
+ :global(.ant-descriptions-view) {
+ border: 0;
+ }
+ }
}
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/index.tsx b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/index.tsx
new file mode 100644
index 00000000..ea13f87e
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/index.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { Descriptions } from 'antd';
+
+import { TransferFileFormatDataProps } from './types';
+import { getDescriptionItems } from './utils';
+
+export const TransferFileFormatData = ({ data, ...props }: TransferFileFormatDataProps) => {
+ return (
+
+
+ {data.type}
+
+ {getDescriptionItems({ data }).map((item, index) => (
+
+ {item.content}
+
+ ))}
+
+ );
+};
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/types.ts b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/types.ts
new file mode 100644
index 00000000..6284ba3e
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/types.ts
@@ -0,0 +1,6 @@
+import { FileFormat } from '@shared/types';
+import { DescriptionsProps } from 'antd';
+
+export interface TransferFileFormatDataProps extends DescriptionsProps {
+ data: FileFormat;
+}
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/index.ts b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/index.ts
new file mode 100644
index 00000000..2eb37227
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/index.ts
@@ -0,0 +1,48 @@
+import { DescriptionItem, FileFormatType } from '@shared/types';
+
+import { GetDescriptionItemsProps } from './types';
+
+/** Util for mapping data for Description component depends on file format type */
+export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): DescriptionItem[] => {
+ switch (data.type) {
+ case FileFormatType.CSV:
+ return [
+ {
+ label: 'Delimiter',
+ content: data.delimiter,
+ },
+ {
+ label: 'Encoding',
+ content: data.encoding,
+ },
+ {
+ label: 'Quote',
+ content: data.quote,
+ },
+ {
+ label: 'Escape',
+ content: data.escape,
+ },
+ {
+ label: 'Header',
+ content: data.header,
+ },
+ {
+ label: 'Line Sep',
+ content: data.line_sep,
+ },
+ ];
+ case FileFormatType.JSON:
+ case FileFormatType.JSON_LINE:
+ return [
+ {
+ label: 'Encoding',
+ content: data.encoding,
+ },
+ {
+ label: 'Line Sep',
+ content: data.line_sep,
+ },
+ ];
+ }
+};
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/types.ts b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/types.ts
new file mode 100644
index 00000000..f8c1737c
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/getDescriptionItems/types.ts
@@ -0,0 +1,5 @@
+import { FileFormat } from '@shared/types';
+
+export interface GetDescriptionItemsProps {
+ data: FileFormat;
+}
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/index.ts b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/index.ts
new file mode 100644
index 00000000..0519775c
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferFileFormatData/utils/index.ts
@@ -0,0 +1 @@
+export * from './getDescriptionItems';
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferParams/index.tsx b/src/features/transfer/TransferDetailInfo/components/TransferParams/index.tsx
new file mode 100644
index 00000000..e4e0d9ff
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferParams/index.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { Descriptions } from 'antd';
+
+import { TransferParamsProps } from './types';
+import { getDescriptionItems } from './utils';
+
+export const TransferParams = ({ data, ...props }: TransferParamsProps) => {
+ return (
+
+
+ {data.type}
+
+ {getDescriptionItems({ data }).map((item, index) => (
+
+ {item.content}
+
+ ))}
+
+ );
+};
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferParams/types.ts b/src/features/transfer/TransferDetailInfo/components/TransferParams/types.ts
new file mode 100644
index 00000000..5699d794
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferParams/types.ts
@@ -0,0 +1,6 @@
+import { Transfer } from '@entities/transfer';
+import { DescriptionsProps } from 'antd';
+
+export interface TransferParamsProps extends DescriptionsProps {
+ data: Transfer['source_params'] | Transfer['target_params'];
+}
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/index.tsx b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/index.tsx
new file mode 100644
index 00000000..6bac868b
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/index.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { ConnectionType, DescriptionItem } from '@shared/types';
+
+import { TransferFileFormatData } from '../../../TransferFileFormatData';
+
+import { GetDescriptionItemsProps } from './types';
+
+/** Util for mapping data for Description component depends on connection type */
+export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): DescriptionItem[] => {
+ switch (data.type) {
+ case ConnectionType.HDFS:
+ case ConnectionType.S3:
+ return [
+ {
+ label: 'Directory path',
+ content: data.directory_path,
+ },
+ {
+ label: 'File format',
+ content: ,
+ },
+ ];
+ case ConnectionType.HIVE:
+ case ConnectionType.ORACLE:
+ case ConnectionType.POSTGRES:
+ return [
+ {
+ label: 'Table name',
+ content: data.table_name,
+ },
+ ];
+ }
+};
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/types.ts b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/types.ts
new file mode 100644
index 00000000..ce28b695
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/types.ts
@@ -0,0 +1,5 @@
+import { Transfer } from '@entities/transfer';
+
+export interface GetDescriptionItemsProps {
+ data: Transfer['source_params'];
+}
diff --git a/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/index.ts b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/index.ts
new file mode 100644
index 00000000..0519775c
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/TransferParams/utils/index.ts
@@ -0,0 +1 @@
+export * from './getDescriptionItems';
diff --git a/src/features/transfer/TransferDetailInfo/components/index.ts b/src/features/transfer/TransferDetailInfo/components/index.ts
new file mode 100644
index 00000000..b71fed24
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/components/index.ts
@@ -0,0 +1,2 @@
+export * from './TransferParams';
+export * from './TransferFileFormatData';
diff --git a/src/features/transfer/TransferDetailInfo/index.tsx b/src/features/transfer/TransferDetailInfo/index.tsx
new file mode 100644
index 00000000..b4b167db
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/index.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import { Descriptions } from 'antd';
+import { Link } from 'react-router-dom';
+
+import { TransferDetailInfoProps } from './types';
+import classes from './styles.module.less';
+import { TransferParams } from './components';
+
+export const TransferDetailInfo = ({
+ transfer,
+ group,
+ connectionSource,
+ connectionTarget,
+ queue,
+ ...props
+}: TransferDetailInfoProps) => {
+ return (
+
+
+
+ {transfer.id}
+
+
+ {transfer.name}
+
+
+ {transfer.description}
+
+
+ {group.name}
+
+
+ {connectionSource.name}
+
+
+ {connectionTarget.name}
+
+
+ {queue.name}
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/features/transfer/TransferDetailInfo/styles.module.less b/src/features/transfer/TransferDetailInfo/styles.module.less
new file mode 100644
index 00000000..1ac6d167
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/styles.module.less
@@ -0,0 +1,23 @@
+.root {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+
+ .subDescription {
+ :global(:has(.ant-descriptions-item-content)) {
+ padding: 0;
+ }
+
+ :global(+ .ant-descriptions-item-content) {
+ padding: 0;
+ }
+
+ :global(.ant-descriptions-item) {
+ padding: 0;
+ }
+
+ :global(.ant-descriptions-view) {
+ border: 0;
+ }
+ }
+}
diff --git a/src/features/transfer/TransferDetailInfo/types.ts b/src/features/transfer/TransferDetailInfo/types.ts
new file mode 100644
index 00000000..e4b515bb
--- /dev/null
+++ b/src/features/transfer/TransferDetailInfo/types.ts
@@ -0,0 +1,13 @@
+import { Transfer } from '@entities/transfer';
+import { GroupData } from '@entities/group';
+import { DescriptionsProps } from 'antd';
+import { Connection } from '@entities/connection';
+import { Queue } from '@entities/queue';
+
+export interface TransferDetailInfoProps extends DescriptionsProps {
+ transfer: Transfer;
+ group: GroupData;
+ connectionSource: Connection;
+ connectionTarget: Connection;
+ queue: Queue;
+}
diff --git a/src/features/transfer/TransferList/constants.tsx b/src/features/transfer/TransferList/constants.tsx
new file mode 100644
index 00000000..82efb934
--- /dev/null
+++ b/src/features/transfer/TransferList/constants.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { PaginationResponse } from '@shared/types';
+import { TableColumns } from '@shared/ui';
+import { Link } from 'react-router-dom';
+import { Transfer } from '@entities/transfer';
+
+export const TRANSFER_LIST_COLUMNS: TableColumns> = [
+ {
+ title: 'Id',
+ dataIndex: 'id',
+ width: 150,
+ },
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ render: (name, record) => {name},
+ width: 400,
+ },
+ {
+ title: 'Description',
+ dataIndex: 'description',
+ },
+];
diff --git a/src/features/transfer/TransferList/index.tsx b/src/features/transfer/TransferList/index.tsx
new file mode 100644
index 00000000..8459cebd
--- /dev/null
+++ b/src/features/transfer/TransferList/index.tsx
@@ -0,0 +1,21 @@
+import React, { memo } from 'react';
+import { ManagedTable } from '@shared/ui';
+import { hasAccessByUserRole } from '@shared/utils';
+import { UserRole } from '@shared/types';
+import { TransferQueryKey, transferService } from '@entities/transfer';
+
+import { TRANSFER_LIST_COLUMNS } from './constants';
+import { TransferListProps } from './types';
+
+export const TransferList = memo(({ group }: TransferListProps) => {
+ return (
+ transferService.getTransfers({ ...params, group_id: group.data.id })}
+ columns={TRANSFER_LIST_COLUMNS}
+ isRenderUpdateRowAction={() => hasAccessByUserRole(UserRole.Developer, group.role)}
+ isRenderDeleteRowAction={() => hasAccessByUserRole(UserRole.Maintainer, group.role)}
+ rowKey="id"
+ />
+ );
+});
diff --git a/src/features/transfer/TransferList/types.ts b/src/features/transfer/TransferList/types.ts
new file mode 100644
index 00000000..b7a1f643
--- /dev/null
+++ b/src/features/transfer/TransferList/types.ts
@@ -0,0 +1,5 @@
+import { Group } from '@entities/group';
+
+export interface TransferListProps {
+ group: Group;
+}
diff --git a/src/features/transfer/index.ts b/src/features/transfer/index.ts
new file mode 100644
index 00000000..ead941e9
--- /dev/null
+++ b/src/features/transfer/index.ts
@@ -0,0 +1,2 @@
+export * from './TransferList';
+export * from './TransferDetailInfo';
diff --git a/src/pages/transfer/TransferDetailPage/index.tsx b/src/pages/transfer/TransferDetailPage/index.tsx
new file mode 100644
index 00000000..30ebaaaf
--- /dev/null
+++ b/src/pages/transfer/TransferDetailPage/index.tsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import { PageDetailParams } from '@shared/types';
+import { PageContentWrapper } from '@shared/ui';
+import { Typography } from 'antd';
+import { useParams } from 'react-router-dom';
+import { useGetGroup } from '@entities/group';
+import { useGetTransfer } from '@entities/transfer';
+import { TransferDetail } from '@widgets/transfer';
+import { useGetConnection } from '@entities/connection';
+import { useGetQueue } from '@entities/queue';
+
+const { Title } = Typography;
+
+export const TransferDetailPage = () => {
+ const params = useParams();
+ const { data: transfer } = useGetTransfer({ id: Number(params.id) });
+ const { data: group } = useGetGroup({ id: transfer.group_id });
+ const { data: connectionSource } = useGetConnection({ id: transfer.source_connection_id });
+ const { data: connectionTarget } = useGetConnection({ id: transfer.target_connection_id });
+ const { data: queue } = useGetQueue({ id: transfer.queue_id });
+
+ if (!transfer || !group || !connectionSource || !connectionTarget || !queue) {
+ return null;
+ }
+
+ return (
+
+ {transfer.name}
+
+
+ );
+};
diff --git a/src/pages/transfer/TransferListPage/index.tsx b/src/pages/transfer/TransferListPage/index.tsx
new file mode 100644
index 00000000..fc82cea3
--- /dev/null
+++ b/src/pages/transfer/TransferListPage/index.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import { PageContentWrapper } from '@shared/ui';
+import { Typography } from 'antd';
+import { GroupWarningAlert, useSelectedGroup } from '@entities/group';
+import { TransferListWrapper } from '@widgets/transfer';
+
+const { Title } = Typography;
+
+export const TransferListPage = () => {
+ const { group } = useSelectedGroup();
+
+ const renderContent = () => {
+ if (!group?.data.id) {
+ return ;
+ }
+
+ return (
+
+
+
+ );
+ };
+
+ return (
+
+ Transfers
+ {renderContent()}
+
+ );
+};
diff --git a/src/pages/transfer/index.ts b/src/pages/transfer/index.ts
new file mode 100644
index 00000000..fbb5c1c1
--- /dev/null
+++ b/src/pages/transfer/index.ts
@@ -0,0 +1,2 @@
+export * from './TransferListPage';
+export * from './TransferDetailPage';
diff --git a/src/shared/types/connection.ts b/src/shared/types/connection.ts
new file mode 100644
index 00000000..17b6c4c0
--- /dev/null
+++ b/src/shared/types/connection.ts
@@ -0,0 +1,7 @@
+export enum ConnectionType {
+ HIVE = 'hive',
+ HDFS = 'hdfs',
+ ORACLE = 'oracle',
+ POSTGRES = 'postgres',
+ S3 = 's3',
+}
diff --git a/src/shared/types/file.ts b/src/shared/types/file.ts
new file mode 100644
index 00000000..874ba010
--- /dev/null
+++ b/src/shared/types/file.ts
@@ -0,0 +1,29 @@
+export enum FileFormatType {
+ CSV = 'csv',
+ JSON = 'json',
+ JSON_LINE = 'jsonline',
+}
+
+export type FileFormat = FileFormatCsv | FileFormatJson | FileFormatJsonLine;
+
+export interface FileFormatCsv {
+ type: FileFormatType.CSV;
+ delimiter: string;
+ encoding: string;
+ quote: string;
+ escape: string;
+ header: boolean;
+ line_sep: string;
+}
+
+export interface FileFormatJson {
+ type: FileFormatType.JSON;
+ encoding: string;
+ line_sep: string;
+}
+
+export interface FileFormatJsonLine {
+ type: FileFormatType.JSON_LINE;
+ encoding: string;
+ line_sep: string;
+}
diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts
index 61f51d34..c0095715 100644
--- a/src/shared/types/index.ts
+++ b/src/shared/types/index.ts
@@ -1,4 +1,6 @@
export * from './api';
-export * from './pages';
-export * from './roles';
+export * from './page';
+export * from './role';
export * from './antd';
+export * from './connection';
+export * from './file';
diff --git a/src/shared/types/pages.ts b/src/shared/types/page.ts
similarity index 100%
rename from src/shared/types/pages.ts
rename to src/shared/types/page.ts
diff --git a/src/shared/types/roles.ts b/src/shared/types/role.ts
similarity index 100%
rename from src/shared/types/roles.ts
rename to src/shared/types/role.ts
diff --git a/src/widgets/transfer/TransferDetail/index.tsx b/src/widgets/transfer/TransferDetail/index.tsx
new file mode 100644
index 00000000..292e59d4
--- /dev/null
+++ b/src/widgets/transfer/TransferDetail/index.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { PageContentWrapper } from '@shared/ui';
+import { TransferDetailInfo } from '@features/transfer';
+
+import { TransferDetailProps } from './types';
+
+export const TransferDetail = ({ transfer, group, connectionSource, connectionTarget, queue }: TransferDetailProps) => {
+ return (
+
+ {/* //TODO: [DOP-20065] add update and delete actions for transfer */}
+
+
+ );
+};
diff --git a/src/widgets/transfer/TransferDetail/types.ts b/src/widgets/transfer/TransferDetail/types.ts
new file mode 100644
index 00000000..3cd7a069
--- /dev/null
+++ b/src/widgets/transfer/TransferDetail/types.ts
@@ -0,0 +1,12 @@
+import { Connection } from '@entities/connection';
+import { Group } from '@entities/group';
+import { Queue } from '@entities/queue';
+import { Transfer } from '@entities/transfer';
+
+export interface TransferDetailProps {
+ transfer: Transfer;
+ group: Group;
+ connectionSource: Connection;
+ connectionTarget: Connection;
+ queue: Queue;
+}
diff --git a/src/widgets/transfer/TransferListWrapper/index.tsx b/src/widgets/transfer/TransferListWrapper/index.tsx
new file mode 100644
index 00000000..a6a051a5
--- /dev/null
+++ b/src/widgets/transfer/TransferListWrapper/index.tsx
@@ -0,0 +1,9 @@
+import React from 'react';
+import { TransferList } from '@features/transfer';
+
+import { TransferListWrapperProps } from './types';
+
+export const TransferListWrapper = ({ group }: TransferListWrapperProps) => {
+ //TODO: [DOP-20065] add update and delete actions for transfer
+ return ;
+};
diff --git a/src/widgets/transfer/TransferListWrapper/types.ts b/src/widgets/transfer/TransferListWrapper/types.ts
new file mode 100644
index 00000000..142f1af5
--- /dev/null
+++ b/src/widgets/transfer/TransferListWrapper/types.ts
@@ -0,0 +1,5 @@
+import { Group } from '@entities/group';
+
+export interface TransferListWrapperProps {
+ group: Group;
+}
diff --git a/src/widgets/transfer/index.ts b/src/widgets/transfer/index.ts
new file mode 100644
index 00000000..6e384940
--- /dev/null
+++ b/src/widgets/transfer/index.ts
@@ -0,0 +1,2 @@
+export * from './TransferListWrapper';
+export * from './TransferDetail';