@true-engineering/true-react-common-ui-kit 3.15.4 → 3.16.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/README.md +10 -0
- package/dist/components/FiltersPane/FiltersPane.styles.d.ts +2 -0
- package/dist/components/FiltersPane/components/Filter/Filter.d.ts +2 -7
- package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.d.ts +2 -1
- package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.d.ts +2 -3
- package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.styles.d.ts +1 -1
- package/dist/components/FiltersPane/components/FilterWrapper/helpers.d.ts +1 -0
- package/dist/components/NewMoreMenu/NewMoreMenu.d.ts +1 -3
- package/dist/components/WithPopup/WithPopup.d.ts +5 -4
- package/dist/components/WithPopup/types.d.ts +3 -1
- package/dist/true-react-common-ui-kit.js +1077 -1233
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1076 -1232
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/package.json +1 -1
- package/src/components/FiltersPane/FiltersPane.styles.ts +5 -1
- package/src/components/FiltersPane/FiltersPane.tsx +9 -5
- package/src/components/FiltersPane/components/Filter/Filter.tsx +53 -142
- package/src/components/FiltersPane/components/FilterSelect/FilterSelect.tsx +10 -3
- package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.styles.ts +6 -16
- package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.tsx +72 -114
- package/src/components/FiltersPane/components/FilterWrapper/helpers.ts +14 -0
- package/src/components/NewMoreMenu/NewMoreMenu.tsx +8 -13
- package/src/components/WithPopup/WithPopup.tsx +16 -22
- package/src/components/WithPopup/types.ts +4 -1
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { colors, ITweakStyles, createThemedStyles, animations } from '../../theme';
|
|
2
2
|
import { IButtonStyles } from '../Button';
|
|
3
|
+
import type { IFilterWrapperStyles } from './components';
|
|
3
4
|
|
|
4
5
|
export const FILTER_HEIGHT = 36;
|
|
5
6
|
|
|
@@ -84,5 +85,8 @@ export const innerTextButtonStyles: IButtonStyles = {
|
|
|
84
85
|
|
|
85
86
|
export type IFiltersPaneStyles = ITweakStyles<
|
|
86
87
|
typeof useStyles,
|
|
87
|
-
{
|
|
88
|
+
{
|
|
89
|
+
tweakClearButton: IButtonStyles;
|
|
90
|
+
tweakFilterWrapper: IFilterWrapperStyles;
|
|
91
|
+
}
|
|
88
92
|
>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import { addDataTestId, getTestId } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import { addDataAttributes } from '../../helpers';
|
|
4
4
|
import { useTweakStyles } from '../../hooks';
|
|
@@ -53,9 +53,13 @@ export function FiltersPane<Values extends Record<string, unknown>, Content = Va
|
|
|
53
53
|
currentComponentName: 'FiltersPane',
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
const
|
|
56
|
+
const tweakFilterWrapperStyles = useTweakStyles({
|
|
57
|
+
tweakStyles,
|
|
58
|
+
className: 'tweakFilterWrapper',
|
|
59
|
+
currentComponentName: 'FiltersPane',
|
|
60
|
+
});
|
|
57
61
|
|
|
58
|
-
const
|
|
62
|
+
const translates = useMemo(() => getLocale(localeKey, locale), [localeKey, locale]);
|
|
59
63
|
|
|
60
64
|
const filtersKeys = enabledFilters || Object.keys(filtersConfig);
|
|
61
65
|
|
|
@@ -91,7 +95,7 @@ export function FiltersPane<Values extends Record<string, unknown>, Content = Va
|
|
|
91
95
|
);
|
|
92
96
|
|
|
93
97
|
return (
|
|
94
|
-
<div className={classes.root}
|
|
98
|
+
<div className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
|
|
95
99
|
{/* Settings */}
|
|
96
100
|
{onSettingsButtonClick !== undefined && (
|
|
97
101
|
<div
|
|
@@ -137,7 +141,7 @@ export function FiltersPane<Values extends Record<string, unknown>, Content = Va
|
|
|
137
141
|
value={currentValue}
|
|
138
142
|
key={key as string}
|
|
139
143
|
isDisabled={isDisabled || filter?.requiredFilledFilters?.some((item) => !values[item])}
|
|
140
|
-
|
|
144
|
+
tweakStyles={tweakFilterWrapperStyles}
|
|
141
145
|
testId={getTestId(testId, `filter-${String(key)}`)}
|
|
142
146
|
/>
|
|
143
147
|
);
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import { Classes } from 'jss';
|
|
4
|
-
import { useOnClickOutsideWithRef } from '../../../../hooks';
|
|
1
|
+
import { useMemo } from 'react';
|
|
5
2
|
import { getLocale } from '../../helpers';
|
|
6
3
|
import { IFilterMultiSelectValues, IFilterWithDatesValue, IPeriod } from '../../types';
|
|
7
4
|
import { FilterInterval } from '../FilterInterval';
|
|
@@ -13,146 +10,55 @@ import type { IFilterWrapperProps } from '../FilterWrapper';
|
|
|
13
10
|
|
|
14
11
|
export interface IFilterProps<Values, Key extends keyof Values>
|
|
15
12
|
extends IFilterWrapperProps<Values, Key> {
|
|
16
|
-
parentRef?: RefObject<HTMLElement>;
|
|
17
|
-
isInline?: boolean;
|
|
18
|
-
filtersPaneRef: RefObject<HTMLDivElement> | null;
|
|
19
|
-
classes: Classes<'left' | 'right' | 'dropdown'>;
|
|
20
13
|
onChange: <V>(v: V) => void;
|
|
21
14
|
onClose?: () => void;
|
|
22
15
|
}
|
|
23
16
|
|
|
24
|
-
export function Filter<Values, Key extends keyof Values>(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
isInline,
|
|
29
|
-
onChange,
|
|
30
|
-
onClose,
|
|
31
|
-
localeKey,
|
|
32
|
-
locale,
|
|
33
|
-
filtersPaneRef,
|
|
34
|
-
testId,
|
|
35
|
-
classes,
|
|
36
|
-
}: IFilterProps<Values, Key>): JSX.Element | null {
|
|
37
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
38
|
-
const [dropdownPosition, setDropdownPosition] = useState<'left' | 'right'>('left');
|
|
17
|
+
export function Filter<Values, Key extends keyof Values>(
|
|
18
|
+
props: IFilterProps<Values, Key>,
|
|
19
|
+
): JSX.Element | null {
|
|
20
|
+
const { filter, value, onChange, onClose, localeKey, locale, testId } = props;
|
|
39
21
|
const translatesLocaleKey = filter.localeKey ?? localeKey;
|
|
40
22
|
const translates = useMemo(
|
|
41
23
|
() => getLocale(translatesLocaleKey, locale, filter.locale),
|
|
42
24
|
[translatesLocaleKey, locale, filter.locale],
|
|
43
25
|
);
|
|
44
26
|
|
|
45
|
-
useOnClickOutsideWithRef(
|
|
46
|
-
ref,
|
|
47
|
-
() => {
|
|
48
|
-
if (!isInline && onClose !== undefined) {
|
|
49
|
-
onClose();
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
parentRef,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
useLayoutEffect(() => {
|
|
56
|
-
if (
|
|
57
|
-
ref.current === null ||
|
|
58
|
-
filtersPaneRef === undefined ||
|
|
59
|
-
filtersPaneRef === null ||
|
|
60
|
-
filtersPaneRef?.current === null
|
|
61
|
-
) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const { width, left } = ref.current.getBoundingClientRect();
|
|
66
|
-
const filtersPaneWidth = filtersPaneRef.current.offsetWidth;
|
|
67
|
-
|
|
68
|
-
const filterValueWidth = ref.current.parentElement
|
|
69
|
-
? ref.current.parentElement.getBoundingClientRect().width
|
|
70
|
-
: 0;
|
|
71
|
-
|
|
72
|
-
if (filtersPaneWidth - left < width - filterValueWidth) {
|
|
73
|
-
setDropdownPosition('right');
|
|
74
|
-
} else if (left < 0) {
|
|
75
|
-
setDropdownPosition('left');
|
|
76
|
-
}
|
|
77
|
-
}, [value, filtersPaneRef]);
|
|
78
|
-
|
|
79
|
-
const props = {
|
|
80
|
-
ref,
|
|
81
|
-
className: clsx(classes[dropdownPosition], {
|
|
82
|
-
[classes.dropdown]: !isInline,
|
|
83
|
-
}),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const handleOnClose = () => {
|
|
87
|
-
if (onClose !== undefined) {
|
|
88
|
-
onClose();
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
if (filter.type === 'custom' && filter.component) {
|
|
93
|
-
const Component = filter.component;
|
|
94
|
-
return (
|
|
95
|
-
<div {...props}>
|
|
96
|
-
<Component
|
|
97
|
-
{...{
|
|
98
|
-
value,
|
|
99
|
-
onChange,
|
|
100
|
-
onClose,
|
|
101
|
-
filter,
|
|
102
|
-
locale,
|
|
103
|
-
localeKey,
|
|
104
|
-
testId,
|
|
105
|
-
}}
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
);
|
|
109
|
-
} else if (filter.type === 'custom' && filter.component === undefined) {
|
|
110
|
-
console.warn(
|
|
111
|
-
`%cДля фильтра типа custom (${filter.name}) в конфиге обязательно нужно задать component`,
|
|
112
|
-
'background: red; color: black',
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
27
|
if (filter.type === 'select') {
|
|
117
28
|
return (
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
</div>
|
|
29
|
+
<FilterSelect
|
|
30
|
+
value={value}
|
|
31
|
+
onChange={onChange}
|
|
32
|
+
onClose={onClose}
|
|
33
|
+
localeKey={translatesLocaleKey}
|
|
34
|
+
locale={translates}
|
|
35
|
+
testId={testId !== undefined ? `${testId}-select` : undefined}
|
|
36
|
+
{...filter}
|
|
37
|
+
/>
|
|
128
38
|
);
|
|
129
39
|
}
|
|
130
40
|
|
|
131
41
|
if (filter.type === 'dateRange') {
|
|
132
42
|
return (
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
/>
|
|
143
|
-
</div>
|
|
43
|
+
<FilterWithPeriod
|
|
44
|
+
value={{ ...value } as IPeriod}
|
|
45
|
+
onChange={onChange}
|
|
46
|
+
onClose={onClose}
|
|
47
|
+
localeKey={translatesLocaleKey}
|
|
48
|
+
locale={translates}
|
|
49
|
+
testId={testId !== undefined ? `${testId}-period` : undefined}
|
|
50
|
+
{...filter}
|
|
51
|
+
/>
|
|
144
52
|
);
|
|
145
53
|
}
|
|
146
54
|
|
|
147
55
|
if (filter.type === 'dateRangeWithoutPeriod') {
|
|
148
|
-
const dateRangeValue = value as unknown as IFilterWithDatesValue;
|
|
149
|
-
|
|
150
56
|
return (
|
|
151
|
-
<div
|
|
57
|
+
<div style={{ width: 320 }}>
|
|
152
58
|
<FilterWithDates
|
|
153
|
-
value={
|
|
154
|
-
onEndBtnSubmit={() => onChange(undefined)}
|
|
59
|
+
value={value as unknown as IFilterWithDatesValue}
|
|
155
60
|
onChange={(v) => onChange({ ...v, periodType: 'CUSTOM' })}
|
|
61
|
+
onEndBtnSubmit={() => onChange(undefined)}
|
|
156
62
|
localeKey={translatesLocaleKey}
|
|
157
63
|
locale={translates}
|
|
158
64
|
testId={testId !== undefined ? `${testId}-dates` : undefined}
|
|
@@ -164,36 +70,41 @@ export function Filter<Values, Key extends keyof Values>({
|
|
|
164
70
|
|
|
165
71
|
if (filter.type === 'multiSelect') {
|
|
166
72
|
return (
|
|
167
|
-
<
|
|
168
|
-
<
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
/>
|
|
177
|
-
</div>
|
|
73
|
+
<FilterMultiSelect
|
|
74
|
+
value={value as unknown as IFilterMultiSelectValues<any>}
|
|
75
|
+
onChange={onChange}
|
|
76
|
+
onClose={onClose}
|
|
77
|
+
localeKey={translatesLocaleKey}
|
|
78
|
+
locale={translates}
|
|
79
|
+
testId={testId !== undefined ? `${testId}-multiSelect` : undefined}
|
|
80
|
+
{...filter}
|
|
81
|
+
/>
|
|
178
82
|
);
|
|
179
83
|
}
|
|
180
84
|
|
|
181
85
|
if (filter.type === 'interval') {
|
|
182
86
|
return (
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
/>
|
|
193
|
-
</div>
|
|
87
|
+
<FilterInterval
|
|
88
|
+
value={value as unknown as number[]}
|
|
89
|
+
onChange={onChange}
|
|
90
|
+
localeKey={translatesLocaleKey}
|
|
91
|
+
locale={translates}
|
|
92
|
+
labelName={filter.name}
|
|
93
|
+
testId={testId !== undefined ? `${testId}-interval` : undefined}
|
|
94
|
+
{...filter}
|
|
95
|
+
/>
|
|
194
96
|
);
|
|
195
97
|
}
|
|
196
98
|
|
|
99
|
+
if (filter.type === 'boolean') {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (filter.type === 'custom' && filter.component) {
|
|
104
|
+
const Component = filter.component;
|
|
105
|
+
return <Component {...props} filter={filter} />;
|
|
106
|
+
}
|
|
107
|
+
|
|
197
108
|
console.warn(
|
|
198
109
|
`%cДля фильтра ${filter.name} не задан тип или component`,
|
|
199
110
|
'background: red; color: black',
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
export interface IFilterSelectProps<Value> extends ICommonProps<IFilterSelectStyles> {
|
|
23
23
|
value?: Value;
|
|
24
24
|
onChange: (value?: Value) => void;
|
|
25
|
+
onClose?: () => void;
|
|
25
26
|
/**
|
|
26
27
|
* @default false
|
|
27
28
|
*/
|
|
@@ -53,6 +54,7 @@ export function FilterSelect<Value>({
|
|
|
53
54
|
localeKey,
|
|
54
55
|
locale,
|
|
55
56
|
onChange,
|
|
57
|
+
onClose,
|
|
56
58
|
options,
|
|
57
59
|
fetchOptions,
|
|
58
60
|
footer,
|
|
@@ -137,11 +139,16 @@ export function FilterSelect<Value>({
|
|
|
137
139
|
}
|
|
138
140
|
};
|
|
139
141
|
|
|
142
|
+
const handleChange = (val?: Value) => {
|
|
143
|
+
onChange(val);
|
|
144
|
+
onClose?.();
|
|
145
|
+
};
|
|
146
|
+
|
|
140
147
|
const handleClear = () => {
|
|
141
148
|
if (options !== undefined) {
|
|
142
149
|
setAllOptions(options);
|
|
143
150
|
}
|
|
144
|
-
|
|
151
|
+
handleChange(undefined);
|
|
145
152
|
setSearchValue('');
|
|
146
153
|
};
|
|
147
154
|
|
|
@@ -252,7 +259,7 @@ export function FilterSelect<Value>({
|
|
|
252
259
|
>
|
|
253
260
|
{translates.chosen}
|
|
254
261
|
</div>
|
|
255
|
-
<div className={classes.item} onClick={() =>
|
|
262
|
+
<div className={classes.item} onClick={() => handleChange(undefined)}>
|
|
256
263
|
<div className={classes.option}>{getValueView(value)}</div>
|
|
257
264
|
<div className={classes.icon}>
|
|
258
265
|
<Icon type="check" />
|
|
@@ -278,7 +285,7 @@ export function FilterSelect<Value>({
|
|
|
278
285
|
? initIntersectionObserver
|
|
279
286
|
: undefined
|
|
280
287
|
}
|
|
281
|
-
onClick={() =>
|
|
288
|
+
onClick={() => handleChange(item)}
|
|
282
289
|
>
|
|
283
290
|
{/* data нужно ли? */}
|
|
284
291
|
<div className={classes.option} data-option={id}>
|
|
@@ -87,24 +87,14 @@ export const useStyles = createThemedStyles('FilterWrapper', {
|
|
|
87
87
|
minWidth: 0,
|
|
88
88
|
},
|
|
89
89
|
|
|
90
|
-
animationEnd:
|
|
91
|
-
opacity: 0,
|
|
92
|
-
transform: 'translateY(15px)',
|
|
93
|
-
transition: '0.15s ease-in-out',
|
|
94
|
-
transitionProperty: 'opacity, transform',
|
|
95
|
-
},
|
|
90
|
+
animationEnd: animations.slideUp['slide-up-exit'],
|
|
96
91
|
|
|
97
|
-
animationStart:
|
|
98
|
-
opacity: 1,
|
|
99
|
-
transform: 'translateY(0)',
|
|
100
|
-
transition: '0.15s ease-in-out',
|
|
101
|
-
transitionProperty: 'opacity, transform',
|
|
102
|
-
},
|
|
92
|
+
animationStart: animations.slideUp['slide-up-enter-active'],
|
|
103
93
|
|
|
104
|
-
'dropdown-
|
|
105
|
-
'dropdown-
|
|
106
|
-
'dropdown-
|
|
107
|
-
'dropdown-
|
|
94
|
+
'dropdown-initial': { extend: 'animationEnd' },
|
|
95
|
+
'dropdown-open': { extend: 'animationStart' },
|
|
96
|
+
'dropdown-close': { extend: 'animationEnd' },
|
|
97
|
+
'dropdown-unmounted': { extend: 'animationEnd' },
|
|
108
98
|
});
|
|
109
99
|
|
|
110
100
|
export type IFilterWrapperStyles = ITweakStyles<
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { useState, useRef, RefObject } from 'react';
|
|
2
|
-
import { CSSTransition } from 'react-transition-group';
|
|
3
1
|
import clsx from 'clsx';
|
|
4
2
|
import { addDataTestId, getTestId } from '@true-engineering/true-react-platform-helpers';
|
|
5
3
|
import { addDataAttributes } from '../../../../helpers';
|
|
6
4
|
import { useTweakStyles } from '../../../../hooks';
|
|
7
5
|
import { ICommonProps } from '../../../../types';
|
|
8
6
|
import { Icon } from '../../../Icon';
|
|
7
|
+
import { WithPopup } from '../../../WithPopup';
|
|
9
8
|
import { ConfigItem, IFilterLocaleKey, IPartialFilterLocale } from '../../types';
|
|
10
9
|
import { Filter } from '../Filter';
|
|
11
10
|
import { FilterValueView } from '../FilterValueView';
|
|
11
|
+
import { isContentNotEmpty } from './helpers';
|
|
12
12
|
import { useStyles, IFilterWrapperStyles } from './FilterWrapper.styles';
|
|
13
13
|
|
|
14
14
|
export interface IFilterWrapperProps<Values, Key extends keyof Values>
|
|
@@ -18,7 +18,6 @@ export interface IFilterWrapperProps<Values, Key extends keyof Values>
|
|
|
18
18
|
isDisabled?: boolean;
|
|
19
19
|
localeKey?: IFilterLocaleKey;
|
|
20
20
|
locale?: IPartialFilterLocale;
|
|
21
|
-
filtersPaneRef: RefObject<HTMLDivElement> | null;
|
|
22
21
|
onChange: <V>(value: V) => void;
|
|
23
22
|
}
|
|
24
23
|
|
|
@@ -30,7 +29,6 @@ export function FilterWrapper<Values, Key extends keyof Values>({
|
|
|
30
29
|
localeKey,
|
|
31
30
|
data,
|
|
32
31
|
testId,
|
|
33
|
-
filtersPaneRef,
|
|
34
32
|
tweakStyles,
|
|
35
33
|
onChange,
|
|
36
34
|
}: IFilterWrapperProps<Values, Key>): JSX.Element {
|
|
@@ -42,126 +40,86 @@ export function FilterWrapper<Values, Key extends keyof Values>({
|
|
|
42
40
|
currentComponentName: 'FilterWrapper',
|
|
43
41
|
});
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Object.values(value as unknown as Record<any, any>).some((v) =>
|
|
57
|
-
Array.isArray(v) ? v.length > 0 : Boolean(v),
|
|
58
|
-
)
|
|
59
|
-
) {
|
|
60
|
-
hasValue = true;
|
|
61
|
-
} else if (!Array.isArray(value) && typeof value !== 'object') {
|
|
62
|
-
hasValue = Boolean(value);
|
|
43
|
+
if (filter.isInline) {
|
|
44
|
+
return (
|
|
45
|
+
<Filter
|
|
46
|
+
value={value}
|
|
47
|
+
filter={filter}
|
|
48
|
+
localeKey={localeKey}
|
|
49
|
+
locale={locale}
|
|
50
|
+
onChange={onChange}
|
|
51
|
+
testId={testId}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
|
|
66
|
-
function handleChange<V>(v: V) {
|
|
67
|
-
if (type === 'select') {
|
|
68
|
-
setIsOpen(false);
|
|
69
|
-
}
|
|
70
|
-
onChange(v);
|
|
71
|
-
}
|
|
56
|
+
const isBoolean = filter.type === 'boolean';
|
|
72
57
|
|
|
73
58
|
const handleLabelClick = () => {
|
|
74
|
-
if (!isBoolean && !isDisabled) {
|
|
75
|
-
setIsOpen(!isOpen);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
59
|
if (isBoolean) {
|
|
79
60
|
onChange(!value);
|
|
80
61
|
}
|
|
81
62
|
};
|
|
82
63
|
|
|
83
|
-
const
|
|
84
|
-
setIsOpen(false);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const isBoolean = filter.type === 'boolean';
|
|
64
|
+
const hasValue = isContentNotEmpty(value);
|
|
88
65
|
|
|
89
|
-
return
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
66
|
+
return (
|
|
67
|
+
<WithPopup
|
|
68
|
+
placement="bottom-start"
|
|
69
|
+
canBeFlipped
|
|
70
|
+
isDisabled={isBoolean || isDisabled}
|
|
71
|
+
trigger={({ isActive }) => (
|
|
72
|
+
<div
|
|
73
|
+
className={clsx(classes.root, {
|
|
74
|
+
[classes.noValue]: !hasValue,
|
|
75
|
+
[classes.openNoValue]: isActive && !hasValue,
|
|
76
|
+
[classes.withValue]: !isActive && hasValue,
|
|
77
|
+
[classes.openWithValue]: isActive && hasValue,
|
|
78
|
+
[classes.boolean]: isBoolean,
|
|
79
|
+
[classes.disabled]: isDisabled,
|
|
80
|
+
})}
|
|
81
|
+
{...addDataTestId(testId)}
|
|
82
|
+
{...addDataAttributes(data)}
|
|
83
|
+
>
|
|
84
|
+
<div
|
|
85
|
+
onClick={handleLabelClick}
|
|
86
|
+
className={clsx(classes.item, { [classes.booleanItem]: isBoolean })}
|
|
87
|
+
>
|
|
88
|
+
<div className={classes.name}>{filter.name}</div>
|
|
89
|
+
{!isBoolean && value !== undefined && value !== null && (
|
|
90
|
+
<div className={classes.value}>
|
|
91
|
+
<FilterValueView
|
|
92
|
+
value={value}
|
|
93
|
+
filter={filter}
|
|
94
|
+
localeKey={localeKey}
|
|
95
|
+
locale={locale}
|
|
96
|
+
testId={getTestId(testId, 'value')}
|
|
97
|
+
tweakStyles={tweakFilterValueViewStyles}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
)}
|
|
101
|
+
{!isBoolean && (
|
|
102
|
+
<div className={clsx(classes.iconContainer, { [classes.open]: isActive })}>
|
|
103
|
+
<Icon type="chevron-down" />
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
125
106
|
</div>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
locale={locale}
|
|
144
|
-
onClose={handleOnClose}
|
|
145
|
-
onChange={handleChange}
|
|
146
|
-
parentRef={refItem}
|
|
147
|
-
filtersPaneRef={filtersPaneRef}
|
|
148
|
-
testId={testId}
|
|
149
|
-
classes={classes}
|
|
150
|
-
/>
|
|
151
|
-
</CSSTransition>
|
|
152
|
-
</div>
|
|
153
|
-
) : (
|
|
154
|
-
<Filter
|
|
155
|
-
value={value}
|
|
156
|
-
filter={filter}
|
|
157
|
-
localeKey={localeKey}
|
|
158
|
-
locale={locale}
|
|
159
|
-
onClose={handleOnClose}
|
|
160
|
-
onChange={onChange}
|
|
161
|
-
isInline
|
|
162
|
-
filtersPaneRef={filtersPaneRef}
|
|
163
|
-
testId={testId}
|
|
164
|
-
classes={classes}
|
|
165
|
-
/>
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
>
|
|
110
|
+
{({ onClose, status }) => (
|
|
111
|
+
<div className={classes[`dropdown-${status}`]}>
|
|
112
|
+
<Filter
|
|
113
|
+
value={value}
|
|
114
|
+
filter={filter}
|
|
115
|
+
localeKey={localeKey}
|
|
116
|
+
locale={locale}
|
|
117
|
+
onClose={onClose}
|
|
118
|
+
onChange={onChange}
|
|
119
|
+
testId={testId}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
123
|
+
</WithPopup>
|
|
166
124
|
);
|
|
167
125
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isNotEmpty, isObject } from '@true-engineering/true-react-platform-helpers';
|
|
2
|
+
|
|
3
|
+
export const isContentNotEmpty = (value: unknown): boolean => {
|
|
4
|
+
if (Array.isArray(value)) {
|
|
5
|
+
return value.some(isContentNotEmpty);
|
|
6
|
+
}
|
|
7
|
+
if (isObject(value)) {
|
|
8
|
+
return Object.values(value).some(isContentNotEmpty);
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === 'boolean') {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
return isNotEmpty(value);
|
|
14
|
+
};
|