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
16 changes: 15 additions & 1 deletion src/entities/file/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { FileSizeUnit } from './types';
import { FileColumnDelimiter, FileLineSeparator, FileSizeUnit } from './types';

export const FILE_SIZE_UNIT_DISPLAY = {
[FileSizeUnit.B]: 'b',
[FileSizeUnit.KiB]: 'kib',
[FileSizeUnit.MiB]: 'mib',
[FileSizeUnit.GiB]: 'gib',
} as const;

export const FILE_LINE_SEPARATOR_VALUES: Record<FileLineSeparator, string> = {
[FileLineSeparator.WIN]: '\r\n',
[FileLineSeparator.UNIX]: '\n',
[FileLineSeparator.MAC]: '\r',
} as const;

export const FILE_COLUMN_DELIMITER_VALUES: Record<FileColumnDelimiter, string> = {
[FileColumnDelimiter.TAB]: '\t',
[FileColumnDelimiter.SPACE]: ' ',
[FileColumnDelimiter.COMMA]: ',',
[FileColumnDelimiter.SEMICOLON]: ';',
[FileColumnDelimiter.PIPE]: '|',
} as const;
14 changes: 14 additions & 0 deletions src/entities/file/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ export enum FileCompression {
DEFLATE = 'deflate',
}

export enum FileLineSeparator {
WIN = 'win',
UNIX = 'unix',
MAC = 'mac',
}

export enum FileColumnDelimiter {
TAB = 'tab',
SPACE = 'space',
COMMA = 'comma',
SEMICOLON = 'semicolon',
PIPE = 'pipe',
}

export enum FileFormatType {
CSV = 'csv',
EXCEL = 'excel',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,23 @@
import React from 'react';
import { Form, Switch } from 'antd';
import { Select } from '@shared/ui';
import { Typography } from 'antd';
import clsx from 'clsx';
import { Form, Radio } from 'antd';
import { useTranslation } from 'react-i18next';
import { FileCompression as FileCompressionType } from '@entities/file/types';

import { FileCompressionProps } from './types';
import classes from './styles.module.less';

const { Text } = Typography;

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

/* useWatch takes a value from Form.Item, but useFormInstance takes one from general form state
* useWatch returns undefined when Form.Item has not rendered yet
* https://github.com/ant-design/ant-design/issues/49010
*/
Form.useWatch(fieldName);
const formInstance = Form.useFormInstance();

const toggleCompression = (value: boolean) => {
if (value) {
formInstance.setFieldValue(fieldName, undefined);
} else {
formInstance.setFieldValue(fieldName, 'none');
}
};

const switchChecked = formInstance.getFieldValue(fieldName) !== 'none';

const selectClassNames = clsx({
nodrag: true,
[classes.hidden]: !switchChecked,
});

return (
<div className={classes.wrapper}>
<div className={classes.switch}>
<Text className={classes.label}>{t('compression')}</Text>
<Switch className="nodrag" checked={switchChecked} onChange={toggleCompression} />
</div>
<Form.Item className={classes.formItem} name={fieldName}>
<Select
/** className "nodrag" and "nowheel" for select in custom node React Flow https://reactflow.dev/api-reference/react-flow#no-drag-class-name */
className={selectClassNames}
popupClassName="nowheel"
size="large"
options={options}
placeholder={t('selectCompression')}
showSearch
/>
</Form.Item>
</div>
<Form.Item label={t('compression')} name={fieldName} initialValue="none">
<Radio.Group>
<Radio.Button value="none">{t('no', { ns: 'shared' })}</Radio.Button>
{options.map((option) => (
<Radio.Button key={option.value} value={option.value}>
{t(`compressions.${option.label as FileCompressionType}`)}
</Radio.Button>
))}
</Radio.Group>
</Form.Item>
);
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { prepareOptionsForSelect } from '@shared/ui';

import { Csv, FileCompression } from '../../../../types';
import { FILE_COLUMN_DELIMITER_VALUES, FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';
import { Csv, FileColumnDelimiter, FileCompression, FileLineSeparator } from '@entities/file/types';

export const CSV_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Csv['compression']>({
data: [
Expand All @@ -13,3 +13,33 @@ export const CSV_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Csv['compr
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const CSV_DELIMITER_SELECT_OPTIONS = prepareOptionsForSelect<Csv['delimiter']>({
data: [
FileColumnDelimiter.TAB,
FileColumnDelimiter.SPACE,
FileColumnDelimiter.COMMA,
FileColumnDelimiter.SEMICOLON,
FileColumnDelimiter.PIPE,
],
renderLabel: (data) => data,
renderValue: (data) => FILE_COLUMN_DELIMITER_VALUES[data as FileColumnDelimiter],
});

export const CSV_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
renderLabel: (data) => data,
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
});

export const CSV_QUOTE_SELECT_OPTIONS = prepareOptionsForSelect<Csv['quote']>({
data: ['"', "'"],
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const CSV_ESCAPE_SELECT_OPTIONS = prepareOptionsForSelect<Csv['escape']>({
data: ['\\', '"', "'"],
renderLabel: (data) => data,
renderValue: (data) => data,
});
Original file line number Diff line number Diff line change
@@ -1,38 +1,69 @@
import React from 'react';
import { Form, Input, Radio } from 'antd';
import { Checkbox, Form, Input, Radio } from 'antd';
import { useTranslation } from 'react-i18next';
import { FileColumnDelimiter } from '@entities/file/types';

import { FileCompression } from '../FileCompression';
import { FileLineSeparator } from '../FileLineSeparator';

import { CSV_COMPRESSION_SELECT_OPTIONS } from './constants';
import {
CSV_COMPRESSION_SELECT_OPTIONS,
CSV_DELIMITER_SELECT_OPTIONS,
CSV_ESCAPE_SELECT_OPTIONS,
CSV_QUOTE_SELECT_OPTIONS,
CSV_SEPARATOR_SELECT_OPTIONS,
} from './constants';
import { FileFormatCsvProps } from './types';

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

return (
<>
<Form.Item label={t('delimiter')} name={[...name, 'delimiter']}>
<Input className="nodrag" size="large" />
</Form.Item>
<Form.Item label={t('encoding')} name={[...name, 'encoding']}>
<Input className="nodrag" size="large" />
</Form.Item>
<Form.Item label={t('quote')} name={[...name, 'quote']}>
<Input className="nodrag" size="large" />

<Form.Item name={[...name, 'include_header']}>
<Checkbox>{t('includeHeader')}</Checkbox>
</Form.Item>
<Form.Item label={t('escape')} name={[...name, 'escape']}>
<Input className="nodrag" size="large" />

<Form.Item
label={t('delimiter')}
name={[...name, 'delimiter']}
initialValue={CSV_DELIMITER_SELECT_OPTIONS[0].value}
>
<Radio.Group>
{CSV_DELIMITER_SELECT_OPTIONS.map((option) => (
<Radio.Button key={option.value} value={option.value}>
{t(`delimiters.${option.label as FileColumnDelimiter}`)}
</Radio.Button>
))}
</Radio.Group>
</Form.Item>
<Form.Item label={t('includeHeader')} name={[...name, 'include_header']}>

<FileLineSeparator name={name} options={CSV_SEPARATOR_SELECT_OPTIONS} />

<Form.Item label={t('quote')} name={[...name, 'quote']} initialValue={null}>
<Radio.Group>
<Radio value={true}>{t('yes', { ns: 'shared' })}</Radio>
<Radio value={false}>{t('no', { ns: 'shared' })}</Radio>
{CSV_QUOTE_SELECT_OPTIONS.map((option) => (
<Radio.Button key={option.value} value={option.value}>
{option.label}
</Radio.Button>
))}
<Radio.Button value={null}>{t('no', { ns: 'shared' })}</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label={t('lineSeparator')} name={[...name, 'line_sep']}>
<Input className="nodrag" size="large" />

<Form.Item label={t('escape')} name={[...name, 'escape']} initialValue={CSV_ESCAPE_SELECT_OPTIONS[0].value}>
<Radio.Group>
{CSV_ESCAPE_SELECT_OPTIONS.map((option) => (
<Radio.Button key={option.value} value={option.value}>
{option.label}
</Radio.Button>
))}
</Radio.Group>
</Form.Item>

<FileCompression name={name} options={CSV_COMPRESSION_SELECT_OPTIONS} />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Form, Input, Radio } from 'antd';
import React from 'react';
import { Checkbox, Form, Input } from 'antd';
import { useTranslation } from 'react-i18next';

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

return (
<>
<Form.Item label={t('includeHeader')} name={[...name, 'include_header']}>
<Radio.Group>
<Radio value={true}>{t('yes', { ns: 'shared' })}</Radio>
<Radio value={false}>{t('no', { ns: 'shared' })}</Radio>
</Radio.Group>
<Form.Item name={[...name, 'include_header']}>
<Checkbox>{t('includeHeader')}</Checkbox>
</Form.Item>

<Form.Item label={t('startCell')} name={[...name, 'start_cell']}>
<Input className="nodrag" size="large" />
</Form.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { prepareOptionsForSelect } from '@shared/ui';
import { FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';

import { FileCompression, Json } from '../../../../types';
import { Csv, FileCompression, FileLineSeparator, Json } from '../../../../types';

export const JSON_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json['compression']>({
data: [
Expand All @@ -13,3 +14,9 @@ export const JSON_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json['com
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const JSON_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
renderLabel: (data) => data,
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { Form, Input } from 'antd';
import { useTranslation } from 'react-i18next';

import { FileCompression } from '../FileCompression';
import { FileLineSeparator } from '../FileLineSeparator';

import { JSON_COMPRESSION_SELECT_OPTIONS } from './constants';
import { JSON_COMPRESSION_SELECT_OPTIONS, JSON_SEPARATOR_SELECT_OPTIONS } from './constants';
import { FileFormatJsonProps } from './types';

export const FileFormatJson = ({ name }: FileFormatJsonProps) => {
Expand All @@ -15,9 +15,9 @@ export const FileFormatJson = ({ name }: FileFormatJsonProps) => {
<Form.Item label={t('encoding')} name={[...name, 'encoding']}>
<Input className="nodrag" size="large" />
</Form.Item>
<Form.Item label={t('lineSeparator')} name={[...name, 'line_sep']}>
<Input className="nodrag" size="large" />
</Form.Item>

<FileLineSeparator name={name} options={JSON_SEPARATOR_SELECT_OPTIONS} />

<FileCompression name={name} options={JSON_COMPRESSION_SELECT_OPTIONS} />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { prepareOptionsForSelect } from '@shared/ui';
import { FILE_LINE_SEPARATOR_VALUES } from '@entities/file/constants';

import { FileCompression, JsonLine } from '../../../../types';
import { Csv, FileCompression, FileLineSeparator, JsonLine } from '../../../../types';

export const JSON_LINE_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<JsonLine['compression']>({
data: [
Expand All @@ -13,3 +14,9 @@ export const JSON_LINE_COMPRESSION_SELECT_OPTIONS = prepareOptionsForSelect<Json
renderLabel: (data) => data,
renderValue: (data) => data,
});

export const JSON_LINE_SEPARATOR_SELECT_OPTIONS = prepareOptionsForSelect<Csv['line_sep']>({
data: Object.values([FileLineSeparator.WIN, FileLineSeparator.UNIX, FileLineSeparator.MAC]),
renderLabel: (data) => data,
renderValue: (data) => FILE_LINE_SEPARATOR_VALUES[data as FileLineSeparator],
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { Form, Input } from 'antd';
import { useTranslation } from 'react-i18next';

import { FileCompression } from '../FileCompression';
import { FileLineSeparator } from '../FileLineSeparator';

import { JSON_LINE_COMPRESSION_SELECT_OPTIONS } from './constants';
import { JSON_LINE_COMPRESSION_SELECT_OPTIONS, JSON_LINE_SEPARATOR_SELECT_OPTIONS } from './constants';
import { FileFormatJsonLineProps } from './types';

export const FileFormatJsonLine = ({ name }: FileFormatJsonLineProps) => {
Expand All @@ -15,9 +15,9 @@ export const FileFormatJsonLine = ({ name }: FileFormatJsonLineProps) => {
<Form.Item label={t('encoding')} name={[...name, 'encoding']}>
<Input className="nodrag" size="large" />
</Form.Item>
<Form.Item label={t('lineSeparator')} name={[...name, 'line_sep']}>
<Input className="nodrag" size="large" />
</Form.Item>

<FileLineSeparator name={name} options={JSON_LINE_SEPARATOR_SELECT_OPTIONS} />

<FileCompression name={name} options={JSON_LINE_COMPRESSION_SELECT_OPTIONS} />
</>
);
Expand Down
Loading