Skip to content

Commit e23e58c

Browse files
ZabilsyaZabilsya
authored andcommitted
[DOP-22299] add file name template field
1 parent 6b1ad3f commit e23e58c

File tree

14 files changed

+120
-17
lines changed

14 files changed

+120
-17
lines changed

src/app/styles/variables.less

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@
2020
@input-bg: #f1f3f5;
2121
@select-background: #f1f3f5;
2222
@picker-bg: #f1f3f5;
23+
24+
@tooltip-bg: #000000;

src/entities/file/@x/transfer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/** Cross-import entities using public API in FSD https://feature-sliced.design/ru/docs/reference/public-api#public-api-for-cross-imports */
22
export type { FileFormat, Json } from '../types';
3-
export { FileFormatParams } from '../ui';
3+
export { FileFormatParams, FileNameTemplate } from '../ui';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
3+
/** Regexp to filename template, which must include `{extension}` and `{index}` placeholder (e.g. qwerty_{index}.{extension}) */
4+
export const FILE_NAME_TEMPLATE_REGEXP =
5+
/^(?=.*\{index\})(?=.*\{extension\})([a-zA-Z0-9._\-]*\{(?:index|extension|run_created_at|run_id)\}[a-zA-Z0-9._\-]*)*$/;
6+
7+
export const fileNameTemplateTooltipText = (
8+
<>
9+
You can use the following placeholders (with brackets {'{}'}): <br />
10+
<ul>
11+
<li>{`{index}`} - required</li>
12+
<li>{`{extension}`} - required</li>
13+
<li>{`{run_created_at}`}</li>
14+
<li>{`{run_id}`}</li>
15+
</ul>
16+
And letters, numbers, and symbols &quot;.&quot;, &quot;_&quot;, &quot;-&quot; <br />
17+
</>
18+
);
19+
20+
export const fileNamePlaceholder = '{run_created_at}_{index}.{extension}';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Form, Input } from 'antd';
2+
import React from 'react';
3+
import { validateFormFieldByPattern } from '@shared/utils';
4+
5+
import { FILE_NAME_TEMPLATE_REGEXP, fileNamePlaceholder, fileNameTemplateTooltipText } from './constants';
6+
7+
export const FileNameTemplate = () => {
8+
return (
9+
<Form.Item
10+
label="Filename template"
11+
normalize={(value) => (value.trim() === '' ? undefined : value)}
12+
tooltip={fileNameTemplateTooltipText}
13+
name={['target_params', 'file_name_template']}
14+
rules={[
15+
{
16+
pattern: FILE_NAME_TEMPLATE_REGEXP,
17+
validator: validateFormFieldByPattern,
18+
},
19+
]}
20+
>
21+
<Input className="nodrag" size="large" placeholder={fileNamePlaceholder} />
22+
</Form.Item>
23+
);
24+
};

src/entities/file/ui/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './FileFormatParams';
2+
export * from './FileNameTemplate';

src/entities/transfer/api/types.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,25 +75,27 @@ interface TransferParamsHdfs {
7575
directory_path: string;
7676
}
7777

78-
interface TransferSourceParamsHdfs extends TransferParamsHdfs {
78+
export interface TransferSourceParamsHdfs extends TransferParamsHdfs {
7979
file_format: FileFormat;
8080
}
8181

82-
interface TransferTargetParamsHdfs extends TransferParamsHdfs {
82+
export interface TransferTargetParamsHdfs extends TransferParamsHdfs {
8383
file_format: Exclude<FileFormat, Json>;
84+
file_name_template: string;
8485
}
8586

8687
interface TransferParamsS3 {
8788
type: ConnectionType.S3;
8889
directory_path: string;
8990
}
9091

91-
interface TransferSourceParamsS3 extends TransferParamsS3 {
92+
export interface TransferSourceParamsS3 extends TransferParamsS3 {
9293
file_format: FileFormat;
9394
}
9495

95-
interface TransferTargetParamsS3 extends TransferParamsS3 {
96+
export interface TransferTargetParamsS3 extends TransferParamsS3 {
9697
file_format: Exclude<FileFormat, Json>;
98+
file_name_template: string;
9799
}
98100

99101
export interface GetTransfersRequest extends PaginationRequest {

src/entities/transfer/ui/TransferConnectionHdfs/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { Divider, Form, Input } from 'antd';
33
import { ABSOLUTE_PATH_REGEXP } from '@shared/constants';
4-
import { FileFormatParams } from '@entities/file/@x/transfer';
4+
import { FileFormatParams, FileNameTemplate } from '@entities/file/@x/transfer';
55

66
import { TransferConnectionHdfsProps } from './types';
77

@@ -15,6 +15,7 @@ export const TransferConnectionHdfs = ({ name }: TransferConnectionHdfsProps) =>
1515
>
1616
<Input className="nodrag" size="large" />
1717
</Form.Item>
18+
{name === 'target_params' && <FileNameTemplate />}
1819
<Divider>File format settings</Divider>
1920
<FileFormatParams name={name} />
2021
</>

src/entities/transfer/ui/TransferConnectionS3/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { Divider, Form, Input } from 'antd';
33
import { ABSOLUTE_PATH_REGEXP } from '@shared/constants';
4-
import { FileFormatParams } from '@entities/file/@x/transfer';
4+
import { FileFormatParams, FileNameTemplate } from '@entities/file/@x/transfer';
55

66
import { TransferConnectionS3Props } from './types';
77

@@ -15,6 +15,7 @@ export const TransferConnectionS3 = ({ name }: TransferConnectionS3Props) => {
1515
>
1616
<Input className="nodrag" size="large" />
1717
</Form.Item>
18+
{name === 'target_params' && <FileNameTemplate />}
1819
<Divider>File format settings</Divider>
1920
<FileFormatParams name={name} />
2021
</>

src/features/transfer/TransferDetailInfo/components/TransferParams/utils/getDescriptionItems/index.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
import React from 'react';
22
import { ConnectionType, DescriptionItem } from '@shared/types';
3+
import { Transfer } from '@entities/transfer';
34

45
import { TransferFileFormatData } from '../../../TransferFileFormatData';
6+
import { isTargetParamsFileConnectionType } from '../isTargetParamsFileConnectionType';
57

68
import { GetDescriptionItemsProps } from './types';
79

810
/** Util for mapping data for Description component depends on connection type */
9-
export const getDescriptionItems = ({ data }: GetDescriptionItemsProps): DescriptionItem[] => {
11+
export const getDescriptionItems = <T extends Transfer['source_params'] | Transfer['target_params']>({
12+
data,
13+
}: GetDescriptionItemsProps<T>): DescriptionItem[] => {
1014
switch (data.type) {
1115
case ConnectionType.HDFS:
1216
case ConnectionType.S3:
13-
return [
17+
const items: DescriptionItem[] = [
1418
{
1519
label: 'Directory path',
1620
content: data.directory_path,
1721
},
18-
{
19-
label: 'File format',
20-
content: <TransferFileFormatData data={data.file_format} />,
21-
},
2222
];
23+
if (isTargetParamsFileConnectionType(data)) {
24+
items.push({
25+
label: 'Filename template',
26+
content: data.file_name_template,
27+
});
28+
}
29+
items.push({
30+
label: 'File format',
31+
content: <TransferFileFormatData data={data.file_format} />,
32+
});
33+
34+
return items;
2335
case ConnectionType.HIVE:
2436
case ConnectionType.ORACLE:
2537
case ConnectionType.POSTGRES:
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Transfer } from '@entities/transfer';
2-
3-
export interface GetDescriptionItemsProps {
4-
data: Transfer['source_params'];
1+
export interface GetDescriptionItemsProps<T> {
2+
data: T;
53
}

0 commit comments

Comments
 (0)