@true-engineering/true-react-common-ui-kit 3.40.0 → 3.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +16 -1
- package/dist/components/FiltersPane/FiltersPane.stories.d.ts +2 -1
- package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.styles.d.ts +1 -1
- package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.d.ts +1 -1
- package/dist/components/FiltersPane/types.d.ts +1 -0
- package/dist/components/Input/Input.styles.d.ts +1 -1
- package/dist/components/SearchInput/SearchInput.stories.d.ts +1 -1
- package/dist/components/Select/Select.styles.d.ts +3 -3
- package/dist/components/SmartInput/SmartInput.d.ts +8 -6
- package/dist/components/SmartInput/constants.d.ts +4 -6
- package/dist/components/SmartInput/helpers.d.ts +2 -4
- package/dist/components/SmartInput/types.d.ts +5 -0
- package/dist/true-react-common-ui-kit.js +1154 -998
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1154 -998
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/package.json +3 -2
- package/src/components/AccountInfo/AccountInfo.stories.tsx +32 -32
- package/src/components/AccountInfo/AccountInfo.tsx +80 -80
- package/src/components/AddButton/AddButton.stories.tsx +21 -21
- package/src/components/AddButton/AddButton.tsx +52 -52
- package/src/components/Colors/Colors.stories.tsx +7 -7
- package/src/components/DateInput/DateInput.tsx +90 -90
- package/src/components/DateInput/constants.ts +2 -2
- package/src/components/Description/Description.stories.tsx +27 -27
- package/src/components/Description/Description.tsx +61 -61
- package/src/components/FiltersPane/FiltersPane.stories.tsx +12 -0
- package/src/components/FiltersPane/components/FilterValueView/FilterValueView.tsx +166 -166
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +210 -210
- package/src/components/FiltersPane/components/FilterWithPeriod/FilterWithPeriod.tsx +177 -177
- package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.styles.ts +4 -0
- package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.tsx +20 -2
- package/src/components/FiltersPane/types.ts +1 -0
- package/src/components/Flag/Flag.stories.tsx +29 -29
- package/src/components/Flag/Flag.tsx +26 -26
- package/src/components/Flag/augment.d.ts +1 -1
- package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.ts +25 -25
- package/src/components/Icon/Icon.stories.tsx +86 -86
- package/src/components/Icon/complexIcons/augment.d.ts +1 -1
- package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
- package/src/components/Icon/complexIcons/index.ts +1 -1
- package/src/components/IncrementInput/IncrementInput.tsx +105 -105
- package/src/components/Input/types.ts +32 -32
- package/src/components/Modal/Modal.stories.tsx +105 -105
- package/src/components/MultiSelect/MultiSelect.stories.tsx +46 -46
- package/src/components/MultiSelect/MultiSelect.tsx +106 -106
- package/src/components/MultiSelect/components/MultiSelectInput/MultiSelectInput.tsx +53 -53
- package/src/components/Notification/Notification.stories.tsx +55 -55
- package/src/components/Notification/Notification.styles.ts +57 -57
- package/src/components/Notification/Notification.tsx +77 -77
- package/src/components/Notification/types.ts +1 -1
- package/src/components/NumberInput/NumberInput.tsx +137 -137
- package/src/components/NumberInput/index.ts +1 -1
- package/src/components/PhoneInput/PhoneInput.tsx +214 -214
- package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.tsx +155 -155
- package/src/components/PhoneInput/types.ts +16 -16
- package/src/components/RadioButton/RadioButton.stories.tsx +46 -46
- package/src/components/RadioButton/RadioButton.tsx +57 -57
- package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
- package/src/components/Select/constants.ts +2 -2
- package/src/components/Select/types.ts +1 -1
- package/src/components/Selector/Selector.stories.tsx +62 -62
- package/src/components/Selector/Selector.tsx +115 -115
- package/src/components/Selector/index.ts +2 -2
- package/src/components/Selector/types.ts +12 -12
- package/src/components/Skeleton/Skeleton.stories.tsx +19 -19
- package/src/components/SmartInput/SmartInput.stories.tsx +2 -1
- package/src/components/SmartInput/SmartInput.tsx +76 -94
- package/src/components/SmartInput/constants.ts +9 -2
- package/src/components/SmartInput/helpers.ts +26 -13
- package/src/components/SmartInput/types.ts +7 -0
- package/src/components/Status/Status.stories.tsx +73 -73
- package/src/components/Status/Status.styles.ts +143 -143
- package/src/components/Status/Status.tsx +49 -49
- package/src/components/Status/constants.ts +11 -11
- package/src/components/Status/index.ts +3 -3
- package/src/components/Status/types.ts +5 -5
- package/src/components/Switch/Switch.stories.tsx +40 -40
- package/src/components/Switch/Switch.tsx +75 -75
- package/src/components/TextWithInfo/TextWithInfo.stories.tsx +53 -53
- package/src/components/TextWithInfo/TextWithInfo.tsx +62 -62
- package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
- package/src/components/ThemedPreloader/ThemedPreloader.stories.tsx +41 -41
- package/src/components/ThemedPreloader/ThemedPreloader.tsx +54 -54
- package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
- package/src/components/Toaster/Toaster.stories.tsx +30 -30
- package/src/components/Tooltip/Tooltip.stories.tsx +19 -19
- package/src/components/Tooltip/Tooltip.tsx +35 -35
- package/src/components/Tooltip/types.ts +1 -1
- package/src/helpers/popper-helpers.ts +17 -17
- package/src/hooks/use-dropdown.ts +84 -84
- package/src/hooks/use-is-mounted.ts +15 -15
- package/src/theme/helpers.ts +76 -76
- package/src/vite-env.d.ts +1 -1
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { FC, useState } from 'react';
|
|
2
|
-
import { addDataTestId } from '@true-engineering/true-react-platform-helpers';
|
|
3
|
-
import { addDataAttributes } from '../../helpers';
|
|
4
|
-
import { ICommonProps } from '../../types';
|
|
5
|
-
import { LINK_REGEXP } from './constants';
|
|
6
|
-
import { useStyles, IDescriptionStyles } from './Description.styles';
|
|
7
|
-
|
|
8
|
-
export interface IDescriptionProps extends ICommonProps<IDescriptionStyles> {
|
|
9
|
-
text: string;
|
|
10
|
-
moreTitle?: string;
|
|
11
|
-
lessTitle?: string;
|
|
12
|
-
/** @default 150 */
|
|
13
|
-
truncateIndex?: number;
|
|
14
|
-
/** @default true */
|
|
15
|
-
isAlwaysOpen?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const Description: FC<IDescriptionProps> = ({
|
|
19
|
-
text,
|
|
20
|
-
moreTitle,
|
|
21
|
-
lessTitle,
|
|
22
|
-
truncateIndex = 150,
|
|
23
|
-
isAlwaysOpen = true,
|
|
24
|
-
testId,
|
|
25
|
-
data,
|
|
26
|
-
tweakStyles,
|
|
27
|
-
}) => {
|
|
28
|
-
const classes = useStyles({ theme: tweakStyles });
|
|
29
|
-
|
|
30
|
-
const isTooShort = text.length < truncateIndex;
|
|
31
|
-
const [isOpen, setIsOpen] = useState(isAlwaysOpen);
|
|
32
|
-
const link = text.match(LINK_REGEXP);
|
|
33
|
-
const linkText = link && link[0];
|
|
34
|
-
const textWithNoLink = text.replace(LINK_REGEXP, '');
|
|
35
|
-
|
|
36
|
-
const shortText = text.slice(0, text.slice(0, truncateIndex).lastIndexOf(' '));
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<div className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
|
|
40
|
-
{isAlwaysOpen || isOpen || isTooShort ? (
|
|
41
|
-
<div>
|
|
42
|
-
<span>{textWithNoLink} </span>
|
|
43
|
-
{!!linkText && (
|
|
44
|
-
<a className={classes.link} href={linkText} target="_blank" rel="noopener noreferrer">
|
|
45
|
-
{linkText}
|
|
46
|
-
</a>
|
|
47
|
-
)}
|
|
48
|
-
</div>
|
|
49
|
-
) : (
|
|
50
|
-
<div>
|
|
51
|
-
<span>{shortText}</span>
|
|
52
|
-
</div>
|
|
53
|
-
)}
|
|
54
|
-
{isAlwaysOpen || isTooShort ? undefined : (
|
|
55
|
-
<div className={classes.button} onClick={() => setIsOpen(!isOpen)}>
|
|
56
|
-
{isOpen ? lessTitle : moreTitle}
|
|
57
|
-
</div>
|
|
58
|
-
)}
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
};
|
|
1
|
+
import { FC, useState } from 'react';
|
|
2
|
+
import { addDataTestId } from '@true-engineering/true-react-platform-helpers';
|
|
3
|
+
import { addDataAttributes } from '../../helpers';
|
|
4
|
+
import { ICommonProps } from '../../types';
|
|
5
|
+
import { LINK_REGEXP } from './constants';
|
|
6
|
+
import { useStyles, IDescriptionStyles } from './Description.styles';
|
|
7
|
+
|
|
8
|
+
export interface IDescriptionProps extends ICommonProps<IDescriptionStyles> {
|
|
9
|
+
text: string;
|
|
10
|
+
moreTitle?: string;
|
|
11
|
+
lessTitle?: string;
|
|
12
|
+
/** @default 150 */
|
|
13
|
+
truncateIndex?: number;
|
|
14
|
+
/** @default true */
|
|
15
|
+
isAlwaysOpen?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Description: FC<IDescriptionProps> = ({
|
|
19
|
+
text,
|
|
20
|
+
moreTitle,
|
|
21
|
+
lessTitle,
|
|
22
|
+
truncateIndex = 150,
|
|
23
|
+
isAlwaysOpen = true,
|
|
24
|
+
testId,
|
|
25
|
+
data,
|
|
26
|
+
tweakStyles,
|
|
27
|
+
}) => {
|
|
28
|
+
const classes = useStyles({ theme: tweakStyles });
|
|
29
|
+
|
|
30
|
+
const isTooShort = text.length < truncateIndex;
|
|
31
|
+
const [isOpen, setIsOpen] = useState(isAlwaysOpen);
|
|
32
|
+
const link = text.match(LINK_REGEXP);
|
|
33
|
+
const linkText = link && link[0];
|
|
34
|
+
const textWithNoLink = text.replace(LINK_REGEXP, '');
|
|
35
|
+
|
|
36
|
+
const shortText = text.slice(0, text.slice(0, truncateIndex).lastIndexOf(' '));
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
|
|
40
|
+
{isAlwaysOpen || isOpen || isTooShort ? (
|
|
41
|
+
<div>
|
|
42
|
+
<span>{textWithNoLink} </span>
|
|
43
|
+
{!!linkText && (
|
|
44
|
+
<a className={classes.link} href={linkText} target="_blank" rel="noopener noreferrer">
|
|
45
|
+
{linkText}
|
|
46
|
+
</a>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
) : (
|
|
50
|
+
<div>
|
|
51
|
+
<span>{shortText}</span>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
{isAlwaysOpen || isTooShort ? undefined : (
|
|
55
|
+
<div className={classes.button} onClick={() => setIsOpen(!isOpen)}>
|
|
56
|
+
{isOpen ? lessTitle : moreTitle}
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -78,6 +78,7 @@ interface IFiltersPaneWithCustomProps<Values, Content> extends IFiltersPaneProps
|
|
|
78
78
|
withFieldNameInLabel: boolean;
|
|
79
79
|
isGroupingEnabled: boolean;
|
|
80
80
|
checkboxPosition: 'left' | 'right';
|
|
81
|
+
isClearableFields: boolean;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
function FiltersPaneWithCustomProps<Values, Content>({
|
|
@@ -88,12 +89,14 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
88
89
|
withFieldNameInLabel,
|
|
89
90
|
isGroupingEnabled,
|
|
90
91
|
checkboxPosition,
|
|
92
|
+
isClearableFields,
|
|
91
93
|
...args
|
|
92
94
|
}: IFiltersPaneWithCustomProps<Values, Content>) {
|
|
93
95
|
const config: ConfigType<ConfigValues> = {
|
|
94
96
|
name: {
|
|
95
97
|
name: 'name',
|
|
96
98
|
type: 'select',
|
|
99
|
+
isClearable: isClearableFields,
|
|
97
100
|
options: selectOptions,
|
|
98
101
|
getValueView: (v: unknown) => v + '123',
|
|
99
102
|
getSelectedValueView: (v: unknown) => v + '1234',
|
|
@@ -104,6 +107,7 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
104
107
|
type: 'select',
|
|
105
108
|
isSearchEnabled: true,
|
|
106
109
|
isGroupingEnabled: true,
|
|
110
|
+
isClearable: isClearableFields,
|
|
107
111
|
options: selectOptions,
|
|
108
112
|
},
|
|
109
113
|
|
|
@@ -115,6 +119,7 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
115
119
|
searchPlaceholder: 'Фу',
|
|
116
120
|
},
|
|
117
121
|
isSearchEnabled: true,
|
|
122
|
+
isClearable: isClearableFields,
|
|
118
123
|
options: selectOptions,
|
|
119
124
|
},
|
|
120
125
|
|
|
@@ -134,6 +139,7 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
134
139
|
['MINE', myPeriodGetter],
|
|
135
140
|
'CUSTOM',
|
|
136
141
|
],
|
|
142
|
+
isClearable: isClearableFields,
|
|
137
143
|
},
|
|
138
144
|
|
|
139
145
|
multiSelect: {
|
|
@@ -142,6 +148,7 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
142
148
|
pageSize: 15,
|
|
143
149
|
checkboxPosition,
|
|
144
150
|
isGroupingEnabled,
|
|
151
|
+
isClearable: isClearableFields,
|
|
145
152
|
fetchOptions: (_q = '', p = 0) => {
|
|
146
153
|
if (p > 1) {
|
|
147
154
|
return Promise.resolve([]);
|
|
@@ -158,6 +165,7 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
158
165
|
type: 'multiSelect',
|
|
159
166
|
isSearchEnabled: true,
|
|
160
167
|
isGroupingEnabled,
|
|
168
|
+
isClearable: isClearableFields,
|
|
161
169
|
checkboxPosition,
|
|
162
170
|
searchMaxLength: 12,
|
|
163
171
|
fetchOptions: (q?: string): Promise<Array<{ v: string }>> => {
|
|
@@ -191,16 +199,19 @@ function FiltersPaneWithCustomProps<Values, Content>({
|
|
|
191
199
|
type: 'interval',
|
|
192
200
|
withFieldNameInLabel,
|
|
193
201
|
canBeFloat: true,
|
|
202
|
+
isClearable: isClearableFields,
|
|
194
203
|
},
|
|
195
204
|
|
|
196
205
|
isActive: {
|
|
197
206
|
name: 'isActive',
|
|
198
207
|
type: 'boolean',
|
|
208
|
+
isClearable: isClearableFields,
|
|
199
209
|
},
|
|
200
210
|
|
|
201
211
|
custom: {
|
|
202
212
|
type: 'custom',
|
|
203
213
|
name: 'Custom',
|
|
214
|
+
isClearable: isClearableFields,
|
|
204
215
|
options: [LONG_STRING, '2', '3'],
|
|
205
216
|
component: ({ filter, ...props }) => <FilterSelect {...props} {...filter} />,
|
|
206
217
|
},
|
|
@@ -279,6 +290,7 @@ Default.args = {
|
|
|
279
290
|
isSearchAutosizeable: true,
|
|
280
291
|
isSearchDisabled: false,
|
|
281
292
|
hasClearButton: true,
|
|
293
|
+
isClearableFields: false,
|
|
282
294
|
isDisabled: false,
|
|
283
295
|
containerWidth: 400,
|
|
284
296
|
withFieldNameInLabel: true,
|
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { format } from 'date-fns';
|
|
3
|
-
import { isEmpty, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
4
|
-
import { ICommonProps } from '../../../../types';
|
|
5
|
-
import { IMultiSelectListValues } from '../../../MultiSelectList';
|
|
6
|
-
import { DEFAULT_DATE_FORMAT } from '../../constants';
|
|
7
|
-
import { defaultConvertFunction, getLocale } from '../../helpers';
|
|
8
|
-
import { IDateRangeConfigItem, IFilterWithDatesValue, IPeriod } from '../../types';
|
|
9
|
-
import type { IFilterWrapperProps } from '../FilterWrapper';
|
|
10
|
-
import { IFilterValueViewStyles, useStyles } from './FilterValueView.styles';
|
|
11
|
-
|
|
12
|
-
export function FilterValueView<Values, Key extends keyof Values>({
|
|
13
|
-
locale,
|
|
14
|
-
localeKey,
|
|
15
|
-
filter,
|
|
16
|
-
value,
|
|
17
|
-
tweakStyles,
|
|
18
|
-
}: Omit<IFilterWrapperProps<Values, Key>, 'onChange' | 'filtersPaneRef' | 'tweakStyles'> &
|
|
19
|
-
ICommonProps<IFilterValueViewStyles>): JSX.Element {
|
|
20
|
-
const classes = useStyles({ theme: tweakStyles });
|
|
21
|
-
|
|
22
|
-
const translatesLocaleKey = filter.localeKey ?? localeKey;
|
|
23
|
-
const translates = useMemo(
|
|
24
|
-
() => getLocale(translatesLocaleKey, locale, filter.locale),
|
|
25
|
-
[translatesLocaleKey, locale, filter.locale],
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
if (isEmpty(value)) {
|
|
29
|
-
return <></>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (filter.getSelectedValueView !== undefined) {
|
|
33
|
-
return <span className={classes.text}>{filter.getSelectedValueView(value)}</span>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const isMultiple = filter.type === 'custom' && filter.valueViewType === 'multiple';
|
|
37
|
-
const isRange = filter.type === 'custom' && filter.valueViewType === 'range';
|
|
38
|
-
const isDate = filter.type === 'dateRange' || filter.type === 'dateRangeWithoutPeriod';
|
|
39
|
-
|
|
40
|
-
const displayValue = (v: unknown): string => {
|
|
41
|
-
if (!isNotEmpty(v)) {
|
|
42
|
-
return '';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (v instanceof Date) {
|
|
46
|
-
return format(
|
|
47
|
-
v,
|
|
48
|
-
(filter as IDateRangeConfigItem<IFilterWithDatesValue>).dateFormat || DEFAULT_DATE_FORMAT,
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (typeof v === 'object' && 'value' in v && isNotEmpty(v.value)) {
|
|
53
|
-
return String(v.value);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {
|
|
57
|
-
return String(v);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
console.warn(
|
|
61
|
-
`%c Ошибка конфигурации фильтра ${filter.name}. Невозможно отобразить значение фильтра. Задайте filterValueViewComponent или filterValueViewType.`,
|
|
62
|
-
'background: orange; color: black',
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
return '';
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
if (filter.type === 'select') {
|
|
69
|
-
const getView = filter.getValueView ?? defaultConvertFunction;
|
|
70
|
-
return <span className={classes.text}>{getView(value)}</span>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (filter.type === 'multiSelect') {
|
|
74
|
-
const multiSelectValue = value as IMultiSelectListValues<any>;
|
|
75
|
-
const getView = filter.getValueView ?? defaultConvertFunction;
|
|
76
|
-
const { include } = multiSelectValue;
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<>
|
|
80
|
-
{Array.isArray(include) && include.length > 0 && (
|
|
81
|
-
<>
|
|
82
|
-
<span className={classes.text}>{getView(include[0])}</span>
|
|
83
|
-
<span className={classes.count}>
|
|
84
|
-
{include.length > 1 && ` (+${include.length - 1})`}
|
|
85
|
-
</span>
|
|
86
|
-
</>
|
|
87
|
-
)}
|
|
88
|
-
</>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (filter.type === 'interval') {
|
|
93
|
-
const intervalValue = value as unknown as number[];
|
|
94
|
-
const intervalValueFrom = intervalValue[0];
|
|
95
|
-
const intervalValueTo = intervalValue[1];
|
|
96
|
-
|
|
97
|
-
const intervals = [];
|
|
98
|
-
if (intervalValueFrom !== undefined) {
|
|
99
|
-
intervals.push(`${translates.from.toLowerCase()} ${String(intervalValueFrom)}`);
|
|
100
|
-
}
|
|
101
|
-
if (intervalValueTo !== undefined) {
|
|
102
|
-
intervals.push(`${translates.to.toLowerCase()} ${String(intervalValueTo)}`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return <span className={classes.text}>{intervals.join(' ')}</span>;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (isMultiple) {
|
|
109
|
-
return (
|
|
110
|
-
<>
|
|
111
|
-
{Array.isArray(value) && value.length > 0 && (
|
|
112
|
-
<>
|
|
113
|
-
<span className={classes.text}>{displayValue(value[0])}</span>
|
|
114
|
-
<span className={classes.count}>{value.length > 1 && ` (+${value.length - 1})`}</span>
|
|
115
|
-
</>
|
|
116
|
-
)}
|
|
117
|
-
</>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (isDate) {
|
|
122
|
-
const { from, to, periodType, label } = value as unknown as IPeriod;
|
|
123
|
-
const hasFrom = from !== undefined && from !== null;
|
|
124
|
-
const hasTo = to !== undefined && to !== null;
|
|
125
|
-
|
|
126
|
-
if (periodType !== 'CUSTOM') {
|
|
127
|
-
return <span className={classes.text}>{displayValue(label)}</span>;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const range = [];
|
|
131
|
-
if (hasFrom) {
|
|
132
|
-
if (!hasTo) {
|
|
133
|
-
range.push(translates.from.toLowerCase());
|
|
134
|
-
}
|
|
135
|
-
range.push(displayValue(from));
|
|
136
|
-
}
|
|
137
|
-
if (hasTo) {
|
|
138
|
-
if (hasFrom) {
|
|
139
|
-
range.push('—');
|
|
140
|
-
} else {
|
|
141
|
-
range.push(translates.to.toLowerCase());
|
|
142
|
-
}
|
|
143
|
-
range.push(displayValue(to));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return <span className={classes.text}>{range.join(' ')}</span>;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (isRange && Array.isArray(value)) {
|
|
150
|
-
const rangeValue = value as unknown as number[];
|
|
151
|
-
const rangeValueFrom = rangeValue[0];
|
|
152
|
-
const rangeValueTo = rangeValue[1];
|
|
153
|
-
|
|
154
|
-
const range = [];
|
|
155
|
-
if (rangeValueFrom !== undefined) {
|
|
156
|
-
range.push(`${translates.from.toLowerCase()} ${String(rangeValueFrom)}`);
|
|
157
|
-
}
|
|
158
|
-
if (rangeValueTo !== undefined) {
|
|
159
|
-
range.push(`${translates.to.toLowerCase()} ${String(rangeValueTo)}`);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return <span className={classes.text}>{range.join(' ')}</span>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return <span className={classes.text}>{displayValue(value)}</span>;
|
|
166
|
-
}
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { format } from 'date-fns';
|
|
3
|
+
import { isEmpty, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
4
|
+
import { ICommonProps } from '../../../../types';
|
|
5
|
+
import { IMultiSelectListValues } from '../../../MultiSelectList';
|
|
6
|
+
import { DEFAULT_DATE_FORMAT } from '../../constants';
|
|
7
|
+
import { defaultConvertFunction, getLocale } from '../../helpers';
|
|
8
|
+
import { IDateRangeConfigItem, IFilterWithDatesValue, IPeriod } from '../../types';
|
|
9
|
+
import type { IFilterWrapperProps } from '../FilterWrapper';
|
|
10
|
+
import { IFilterValueViewStyles, useStyles } from './FilterValueView.styles';
|
|
11
|
+
|
|
12
|
+
export function FilterValueView<Values, Key extends keyof Values>({
|
|
13
|
+
locale,
|
|
14
|
+
localeKey,
|
|
15
|
+
filter,
|
|
16
|
+
value,
|
|
17
|
+
tweakStyles,
|
|
18
|
+
}: Omit<IFilterWrapperProps<Values, Key>, 'onChange' | 'filtersPaneRef' | 'tweakStyles'> &
|
|
19
|
+
ICommonProps<IFilterValueViewStyles>): JSX.Element {
|
|
20
|
+
const classes = useStyles({ theme: tweakStyles });
|
|
21
|
+
|
|
22
|
+
const translatesLocaleKey = filter.localeKey ?? localeKey;
|
|
23
|
+
const translates = useMemo(
|
|
24
|
+
() => getLocale(translatesLocaleKey, locale, filter.locale),
|
|
25
|
+
[translatesLocaleKey, locale, filter.locale],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (isEmpty(value)) {
|
|
29
|
+
return <></>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (filter.getSelectedValueView !== undefined) {
|
|
33
|
+
return <span className={classes.text}>{filter.getSelectedValueView(value)}</span>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const isMultiple = filter.type === 'custom' && filter.valueViewType === 'multiple';
|
|
37
|
+
const isRange = filter.type === 'custom' && filter.valueViewType === 'range';
|
|
38
|
+
const isDate = filter.type === 'dateRange' || filter.type === 'dateRangeWithoutPeriod';
|
|
39
|
+
|
|
40
|
+
const displayValue = (v: unknown): string => {
|
|
41
|
+
if (!isNotEmpty(v)) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (v instanceof Date) {
|
|
46
|
+
return format(
|
|
47
|
+
v,
|
|
48
|
+
(filter as IDateRangeConfigItem<IFilterWithDatesValue>).dateFormat || DEFAULT_DATE_FORMAT,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof v === 'object' && 'value' in v && isNotEmpty(v.value)) {
|
|
53
|
+
return String(v.value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {
|
|
57
|
+
return String(v);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.warn(
|
|
61
|
+
`%c Ошибка конфигурации фильтра ${filter.name}. Невозможно отобразить значение фильтра. Задайте filterValueViewComponent или filterValueViewType.`,
|
|
62
|
+
'background: orange; color: black',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return '';
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
if (filter.type === 'select') {
|
|
69
|
+
const getView = filter.getValueView ?? defaultConvertFunction;
|
|
70
|
+
return <span className={classes.text}>{getView(value)}</span>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (filter.type === 'multiSelect') {
|
|
74
|
+
const multiSelectValue = value as IMultiSelectListValues<any>;
|
|
75
|
+
const getView = filter.getValueView ?? defaultConvertFunction;
|
|
76
|
+
const { include } = multiSelectValue;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
{Array.isArray(include) && include.length > 0 && (
|
|
81
|
+
<>
|
|
82
|
+
<span className={classes.text}>{getView(include[0])}</span>
|
|
83
|
+
<span className={classes.count}>
|
|
84
|
+
{include.length > 1 && ` (+${include.length - 1})`}
|
|
85
|
+
</span>
|
|
86
|
+
</>
|
|
87
|
+
)}
|
|
88
|
+
</>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (filter.type === 'interval') {
|
|
93
|
+
const intervalValue = value as unknown as number[];
|
|
94
|
+
const intervalValueFrom = intervalValue[0];
|
|
95
|
+
const intervalValueTo = intervalValue[1];
|
|
96
|
+
|
|
97
|
+
const intervals = [];
|
|
98
|
+
if (intervalValueFrom !== undefined) {
|
|
99
|
+
intervals.push(`${translates.from.toLowerCase()} ${String(intervalValueFrom)}`);
|
|
100
|
+
}
|
|
101
|
+
if (intervalValueTo !== undefined) {
|
|
102
|
+
intervals.push(`${translates.to.toLowerCase()} ${String(intervalValueTo)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return <span className={classes.text}>{intervals.join(' ')}</span>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (isMultiple) {
|
|
109
|
+
return (
|
|
110
|
+
<>
|
|
111
|
+
{Array.isArray(value) && value.length > 0 && (
|
|
112
|
+
<>
|
|
113
|
+
<span className={classes.text}>{displayValue(value[0])}</span>
|
|
114
|
+
<span className={classes.count}>{value.length > 1 && ` (+${value.length - 1})`}</span>
|
|
115
|
+
</>
|
|
116
|
+
)}
|
|
117
|
+
</>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (isDate) {
|
|
122
|
+
const { from, to, periodType, label } = value as unknown as IPeriod;
|
|
123
|
+
const hasFrom = from !== undefined && from !== null;
|
|
124
|
+
const hasTo = to !== undefined && to !== null;
|
|
125
|
+
|
|
126
|
+
if (periodType !== 'CUSTOM') {
|
|
127
|
+
return <span className={classes.text}>{displayValue(label)}</span>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const range = [];
|
|
131
|
+
if (hasFrom) {
|
|
132
|
+
if (!hasTo) {
|
|
133
|
+
range.push(translates.from.toLowerCase());
|
|
134
|
+
}
|
|
135
|
+
range.push(displayValue(from));
|
|
136
|
+
}
|
|
137
|
+
if (hasTo) {
|
|
138
|
+
if (hasFrom) {
|
|
139
|
+
range.push('—');
|
|
140
|
+
} else {
|
|
141
|
+
range.push(translates.to.toLowerCase());
|
|
142
|
+
}
|
|
143
|
+
range.push(displayValue(to));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return <span className={classes.text}>{range.join(' ')}</span>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (isRange && Array.isArray(value)) {
|
|
150
|
+
const rangeValue = value as unknown as number[];
|
|
151
|
+
const rangeValueFrom = rangeValue[0];
|
|
152
|
+
const rangeValueTo = rangeValue[1];
|
|
153
|
+
|
|
154
|
+
const range = [];
|
|
155
|
+
if (rangeValueFrom !== undefined) {
|
|
156
|
+
range.push(`${translates.from.toLowerCase()} ${String(rangeValueFrom)}`);
|
|
157
|
+
}
|
|
158
|
+
if (rangeValueTo !== undefined) {
|
|
159
|
+
range.push(`${translates.to.toLowerCase()} ${String(rangeValueTo)}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return <span className={classes.text}>{range.join(' ')}</span>;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return <span className={classes.text}>{displayValue(value)}</span>;
|
|
166
|
+
}
|