Skip to content

Commit 6b0977a

Browse files
authored
[DOP-31558] Rework input for escape/lineSep/delimiter
1 parent 8bcf06f commit 6b0977a

File tree

16 files changed

+225
-115
lines changed

16 files changed

+225
-115
lines changed

src/entities/file/constants.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
import { FileSizeUnit } from './types';
1+
import { FileColumnDelimiter, FileLineSeparator, FileSizeUnit } from './types';
22

33
export const FILE_SIZE_UNIT_DISPLAY = {
44
[FileSizeUnit.B]: 'b',
55
[FileSizeUnit.KiB]: 'kib',
66
[FileSizeUnit.MiB]: 'mib',
77
[FileSizeUnit.GiB]: 'gib',
88
} as const;
9+
10+
export const FILE_LINE_SEPARATOR_VALUES: Record<FileLineSeparator, string> = {
11+
[FileLineSeparator.WIN]: '\r\n',
12+
[FileLineSeparator.UNIX]: '\n',
13+
[FileLineSeparator.MAC]: '\r',
14+
} as const;
15+
16+
export const FILE_COLUMN_DELIMITER_VALUES: Record<FileColumnDelimiter, string> = {
17+
[FileColumnDelimiter.TAB]: '\t',
18+
[FileColumnDelimiter.SPACE]: ' ',
19+
[FileColumnDelimiter.COMMA]: ',',
20+
[FileColumnDelimiter.SEMICOLON]: ';',
21+
[FileColumnDelimiter.PIPE]: '|',
22+
} as const;

src/entities/file/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ export enum FileCompression {
2222
DEFLATE = 'deflate',
2323
}
2424

25+
export enum FileLineSeparator {
26+
WIN = 'win',
27+
UNIX = 'unix',
28+
MAC = 'mac',
29+
}
30+
31+
export enum FileColumnDelimiter {
32+
TAB = 'tab',
33+
SPACE = 'space',
34+
COMMA = 'comma',
35+
SEMICOLON = 'semicolon',
36+
PIPE = 'pipe',
37+
}
38+
2539
export enum FileFormatType {
2640
CSV = 'csv',
2741
EXCEL = 'excel',
Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,23 @@
1-
import React from 'react';
2-
import { Form, Switch } from 'antd';
3-
import { Select } from '@shared/ui';
4-
import { Typography } from 'antd';
5-
import clsx from 'clsx';
1+
import { Form, Radio } from 'antd';
62
import { useTranslation } from 'react-i18next';
3+
import { FileCompression as FileCompressionType } from '@entities/file/types';
74

85
import { FileCompressionProps } from './types';
9-
import classes from './styles.module.less';
10-
11-
const { Text } = Typography;
126

137
export const FileCompression = <T,>({ name, options }: FileCompressionProps<T>) => {
148
const { t } = useTranslation('file');
159
const fieldName = [...name, 'compression'];
1610

17-
/* useWatch takes a value from Form.Item, but useFormInstance takes one from general form state
18-
* useWatch returns undefined when Form.Item has not rendered yet
19-
* https://github.com/ant-design/ant-design/issues/49010
20-
*/
21-
Form.useWatch(fieldName);
22-
const formInstance = Form.useFormInstance();
23-
24-
const toggleCompression = (value: boolean) => {
25-
if (value) {
26-
formInstance.setFieldValue(fieldName, undefined);
27-
} else {
28-
formInstance.setFieldValue(fieldName, 'none');
29-
}
30-
};
31-
32-
const switchChecked = formInstance.getFieldValue(fieldName) !== 'none';
33-
34-
const selectClassNames = clsx({
35-
nodrag: true,
36-
[classes.hidden]: !switchChecked,
37-
});
38-
3911
return (
40-
<div className={classes.wrapper}>
41-
<div className={classes.switch}>
42-
<Text className={classes.label}>{t('compression')}</Text>
43-
<Switch className="nodrag" checked={switchChecked} onChange={toggleCompression} />
44-
</div>
45-
<Form.Item className={classes.formItem} name={fieldName}>
46-
<Select
47-
/** className "nodrag" and "nowheel" for select in custom node React Flow https://reactflow.dev/api-reference/react-flow#no-drag-class-name */
48-
className={selectClassNames}
49-
popupClassName="nowheel"
50-
size="large"
51-
options={options}
52-
placeholder={t('selectCompression')}
53-
showSearch
54-
/>
55-
</Form.Item>
56-
</div>
12+
<Form.Item label={t('compression')} name={fieldName} initialValue="none">
13+
<Radio.Group>
14+
<Radio.Button value="none">{t('no', { ns: 'shared' })}</Radio.Button>
15+
{options.map((option) => (
16+
<Radio.Button key={option.value} value={option.value}>
17+
{t(`compressions.${option.label as FileCompressionType}`)}
18+
</Radio.Button>
19+
))}
20+
</Radio.Group>
21+
</Form.Item>
5722
);
5823
};

src/entities/file/ui/FileFormatParams/components/FileCompression/styles.module.less

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/entities/file/ui/FileFormatParams/components/FileFormatCsv/constants.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { prepareOptionsForSelect } from '@shared/ui';
2-
3-
import { Csv, FileCompression } from '../../../../types';
2+
import { FILE_COLUMN_DELIMITER_VALUES, FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';
3+
import { Csv, FileColumnDelimiter, FileCompression, FileLineSeparator } from '@entities/file/types';
44

55
export const CSV_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Csv['compression']>({
66
data: [
@@ -13,3 +13,33 @@ export const CSV_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Csv['compr
1313
renderLabel: (data) => data,
1414
renderValue: (data) => data,
1515
});
16+
17+
export const CSV_DELIMITER_SELECT_OPTIONS = prepareOptionsForSelect<Csv['delimiter']>({
18+
data: [
19+
FileColumnDelimiter.TAB,
20+
FileColumnDelimiter.SPACE,
21+
FileColumnDelimiter.COMMA,
22+
FileColumnDelimiter.SEMICOLON,
23+
FileColumnDelimiter.PIPE,
24+
],
25+
renderLabel: (data) => data,
26+
renderValue: (data) => FILE_COLUMN_DELIMITER_VALUES[data as FileColumnDelimiter],
27+
});
28+
29+
export const CSV_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
30+
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
31+
renderLabel: (data) => data,
32+
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
33+
});
34+
35+
export const CSV_QUOTE_SELECT_OPTIONS = prepareOptionsForSelect<Csv['quote']>({
36+
data: ['"', "'"],
37+
renderLabel: (data) => data,
38+
renderValue: (data) => data,
39+
});
40+
41+
export const CSV_ESCAPE_SELECT_OPTIONS = prepareOptionsForSelect<Csv['escape']>({
42+
data: ['\\', '"', "'"],
43+
renderLabel: (data) => data,
44+
renderValue: (data) => data,
45+
});

src/entities/file/ui/FileFormatParams/components/FileFormatCsv/index.tsx

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,69 @@
1-
import React from 'react';
2-
import { Form, Input, Radio } from 'antd';
1+
import { Checkbox, Form, Input, Radio } from 'antd';
32
import { useTranslation } from 'react-i18next';
3+
import { FileColumnDelimiter } from '@entities/file/types';
44

55
import { FileCompression } from '../FileCompression';
6+
import { FileLineSeparator } from '../FileLineSeparator';
67

7-
import { CSV_COMPRESSION_SELECT_OPTIONS } from './constants';
8+
import {
9+
CSV_COMPRESSION_SELECT_OPTIONS,
10+
CSV_DELIMITER_SELECT_OPTIONS,
11+
CSV_ESCAPE_SELECT_OPTIONS,
12+
CSV_QUOTE_SELECT_OPTIONS,
13+
CSV_SEPARATOR_SELECT_OPTIONS,
14+
} from './constants';
815
import { FileFormatCsvProps } from './types';
916

1017
export const FileFormatCsv = ({ name }: FileFormatCsvProps) => {
1118
const { t } = useTranslation('file');
1219

1320
return (
1421
<>
15-
<Form.Item label={t('delimiter')} name={[...name, 'delimiter']}>
16-
<Input className="nodrag" size="large" />
17-
</Form.Item>
1822
<Form.Item label={t('encoding')} name={[...name, 'encoding']}>
1923
<Input className="nodrag" size="large" />
2024
</Form.Item>
21-
<Form.Item label={t('quote')} name={[...name, 'quote']}>
22-
<Input className="nodrag" size="large" />
25+
26+
<Form.Item name={[...name, 'include_header']}>
27+
<Checkbox>{t('includeHeader')}</Checkbox>
2328
</Form.Item>
24-
<Form.Item label={t('escape')} name={[...name, 'escape']}>
25-
<Input className="nodrag" size="large" />
29+
30+
<Form.Item
31+
label={t('delimiter')}
32+
name={[...name, 'delimiter']}
33+
initialValue={CSV_DELIMITER_SELECT_OPTIONS[0].value}
34+
>
35+
<Radio.Group>
36+
{CSV_DELIMITER_SELECT_OPTIONS.map((option) => (
37+
<Radio.Button key={option.value} value={option.value}>
38+
{t(`delimiters.${option.label as FileColumnDelimiter}`)}
39+
</Radio.Button>
40+
))}
41+
</Radio.Group>
2642
</Form.Item>
27-
<Form.Item label={t('includeHeader')} name={[...name, 'include_header']}>
43+
44+
<FileLineSeparator name={name} options={CSV_SEPARATOR_SELECT_OPTIONS} />
45+
46+
<Form.Item label={t('quote')} name={[...name, 'quote']} initialValue={null}>
2847
<Radio.Group>
29-
<Radio value={true}>{t('yes', { ns: 'shared' })}</Radio>
30-
<Radio value={false}>{t('no', { ns: 'shared' })}</Radio>
48+
{CSV_QUOTE_SELECT_OPTIONS.map((option) => (
49+
<Radio.Button key={option.value} value={option.value}>
50+
{option.label}
51+
</Radio.Button>
52+
))}
53+
<Radio.Button value={null}>{t('no', { ns: 'shared' })}</Radio.Button>
3154
</Radio.Group>
3255
</Form.Item>
33-
<Form.Item label={t('lineSeparator')} name={[...name, 'line_sep']}>
34-
<Input className="nodrag" size="large" />
56+
57+
<Form.Item label={t('escape')} name={[...name, 'escape']} initialValue={CSV_ESCAPE_SELECT_OPTIONS[0].value}>
58+
<Radio.Group>
59+
{CSV_ESCAPE_SELECT_OPTIONS.map((option) => (
60+
<Radio.Button key={option.value} value={option.value}>
61+
{option.label}
62+
</Radio.Button>
63+
))}
64+
</Radio.Group>
3565
</Form.Item>
66+
3667
<FileCompression name={name} options={CSV_COMPRESSION_SELECT_OPTIONS} />
3768
</>
3869
);

src/entities/file/ui/FileFormatParams/components/FileFormatExcel/index.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Form, Input, Radio } from 'antd';
2-
import React from 'react';
1+
import { Checkbox, Form, Input } from 'antd';
32
import { useTranslation } from 'react-i18next';
43

54
import { FileFormatExcelProps } from './types';
@@ -9,12 +8,10 @@ export const FileFormatExcel = ({ name }: FileFormatExcelProps) => {
98

109
return (
1110
<>
12-
<Form.Item label={t('includeHeader')} name={[...name, 'include_header']}>
13-
<Radio.Group>
14-
<Radio value={true}>{t('yes', { ns: 'shared' })}</Radio>
15-
<Radio value={false}>{t('no', { ns: 'shared' })}</Radio>
16-
</Radio.Group>
11+
<Form.Item name={[...name, 'include_header']}>
12+
<Checkbox>{t('includeHeader')}</Checkbox>
1713
</Form.Item>
14+
1815
<Form.Item label={t('startCell')} name={[...name, 'start_cell']}>
1916
<Input className="nodrag" size="large" />
2017
</Form.Item>

src/entities/file/ui/FileFormatParams/components/FileFormatJson/constants.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { prepareOptionsForSelect } from '@shared/ui';
2+
import { FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';
23

3-
import { FileCompression, Json } from '../../../../types';
4+
import { Csv, FileCompression, FileLineSeparator, Json } from '../../../../types';
45

56
export const JSON_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json['compression']>({
67
data: [
@@ -13,3 +14,9 @@ export const JSON_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json['com
1314
renderLabel: (data) => data,
1415
renderValue: (data) => data,
1516
});
17+
18+
export const JSON_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
19+
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
20+
renderLabel: (data) => data,
21+
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
22+
});

src/entities/file/ui/FileFormatParams/components/FileFormatJson/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import React from 'react';
21
import { Form, Input } from 'antd';
32
import { useTranslation } from 'react-i18next';
43

54
import { FileCompression } from '../FileCompression';
5+
import { FileLineSeparator } from '../FileLineSeparator';
66

7-
import { JSON_COMPRESSION_SELECT_OPTIONS } from './constants';
7+
import { JSON_COMPRESSION_SELECT_OPTIONS, JSON_SEPARATOR_SELECT_OPTIONS } from './constants';
88
import { FileFormatJsonProps } from './types';
99

1010
export const FileFormatJson = ({ name }: FileFormatJsonProps) => {
@@ -15,9 +15,9 @@ export const FileFormatJson = ({ name }: FileFormatJsonProps) => {
1515
<Form.Item label={t('encoding')} name={[...name, 'encoding']}>
1616
<Input className="nodrag" size="large" />
1717
</Form.Item>
18-
<Form.Item label={t('lineSeparator')} name={[...name, 'line_sep']}>
19-
<Input className="nodrag" size="large" />
20-
</Form.Item>
18+
19+
<FileLineSeparator name={name} options={JSON_SEPARATOR_SELECT_OPTIONS} />
20+
2121
<FileCompression name={name} options={JSON_COMPRESSION_SELECT_OPTIONS} />
2222
</>
2323
);

src/entities/file/ui/FileFormatParams/components/FileFormatJsonLine/constants.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { prepareOptionsForSelect } from '@shared/ui';
2+
import { FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';
23

3-
import { FileCompression, JsonLine } from '../../../../types';
4+
import { Csv, FileCompression, FileLineSeparator, JsonLine } from '../../../../types';
45

56
export const JSON_LINE_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<JsonLine['compression']>({
67
data: [
@@ -13,3 +14,9 @@ export const JSON_LINE_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json
1314
renderLabel: (data) => data,
1415
renderValue: (data) => data,
1516
});
17+
18+
export const JSON_LINE_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
19+
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
20+
renderLabel: (data) => data,
21+
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
22+
});

0 commit comments

Comments
 (0)