venice-ui 2.3.7 → 2.4.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/dist/cjs/components/Filters/Filters.js +246 -126
- package/dist/cjs/components/Filters/filtersHelper.js +1 -16
- package/dist/cjs/components/Table/Table.js +33 -1
- package/dist/cjs/components/Table/tableHelper.js +1 -10
- package/dist/esm/components/Filters/Filters.js +247 -127
- package/dist/esm/components/Filters/filtersHelper.js +0 -14
- package/dist/esm/components/Table/Table.js +34 -2
- package/dist/esm/components/Table/tableHelper.js +0 -8
- package/dist/types/components/Filters/Filters.d.ts +26 -7
- package/dist/types/components/Filters/filtersHelper.d.ts +1 -2
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/Table/tableHelper.d.ts +0 -2
- package/package.json +1 -1
|
@@ -32,166 +32,286 @@ const Icons_1 = require("../Icons");
|
|
|
32
32
|
const Modal_1 = require("../Modal");
|
|
33
33
|
const Filters_styles_1 = require("./Filters.styles");
|
|
34
34
|
const Theme_1 = require("../../Theme");
|
|
35
|
-
const common_1 = require("../common");
|
|
36
35
|
const Input_1 = require("../Input");
|
|
37
36
|
const Chips_1 = require("../Chips");
|
|
38
|
-
const
|
|
39
|
-
|
|
37
|
+
const List_1 = require("../List");
|
|
38
|
+
const Filters = ({ theme = Theme_1.mainTheme, title = 'Select filters', labelConfirm = 'Approve', labelClose = 'Cancel', filters = [], headers = [], elements = [], fullElements, labelClearAll = 'Wyczyść', handleSubmitFilters, externalClearSignal, onClear, }) => {
|
|
39
|
+
const filtersConfig = (0, react_1.useMemo)(() => {
|
|
40
|
+
const uniq = (arr) => Array.from(new Set(arr.filter((v) => v !== undefined && v !== null)));
|
|
41
|
+
if (filters && filters.length) {
|
|
42
|
+
return filters.map((h) => ({
|
|
43
|
+
label: h.label,
|
|
44
|
+
name: h.name,
|
|
45
|
+
type: h.type || 'select',
|
|
46
|
+
allowValues: (h.allowValues || []).map((v) => String(v)),
|
|
47
|
+
min: h.min,
|
|
48
|
+
max: h.max,
|
|
49
|
+
collapsible: h.collapsible ?? true,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
if (!headers || headers.length === 0)
|
|
53
|
+
return [];
|
|
54
|
+
return headers
|
|
55
|
+
.filter((h) => !h.action)
|
|
56
|
+
.map((h) => {
|
|
57
|
+
const key = h.valueSource || h.name;
|
|
58
|
+
const values = (elements || []).map((it) => it?.[key]).filter((v) => v !== undefined && v !== null);
|
|
59
|
+
const nameLower = (h.name || '').toString().toLowerCase();
|
|
60
|
+
if (nameLower === 'age' || nameLower.includes('age')) {
|
|
61
|
+
const nums = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
62
|
+
const min = nums.length ? Math.min(...nums) : 0;
|
|
63
|
+
const max = nums.length ? Math.max(...nums) : 0;
|
|
64
|
+
return { label: h.name, name: key, type: 'range', min, max, collapsible: true };
|
|
65
|
+
}
|
|
66
|
+
if (h.scope && h.scope.length) {
|
|
67
|
+
return { label: h.name, name: key, type: 'select', allowValues: h.scope.map((s) => (s.label ?? s.value ?? s.key ?? String(s))), collapsible: true };
|
|
68
|
+
}
|
|
69
|
+
if (h.date) {
|
|
70
|
+
const dates = values.map((v) => (v ? new Date(v).getTime() : NaN)).filter((d) => !Number.isNaN(d));
|
|
71
|
+
const min = dates.length ? new Date(Math.min(...dates)).toISOString() : undefined;
|
|
72
|
+
const max = dates.length ? new Date(Math.max(...dates)).toISOString() : undefined;
|
|
73
|
+
return { label: h.name, name: key, type: 'date', min, max, collapsible: true };
|
|
74
|
+
}
|
|
75
|
+
if (h.isCount) {
|
|
76
|
+
const nums = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
77
|
+
return { label: h.name, name: key, type: 'range', min: nums.length ? Math.min(...nums) : 0, max: nums.length ? Math.max(...nums) : 0, collapsible: true };
|
|
78
|
+
}
|
|
79
|
+
const numericValues = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
80
|
+
if (numericValues.length === values.length && values.length > 0) {
|
|
81
|
+
return { label: h.name, name: key, type: 'range', min: Math.min(...numericValues), max: Math.max(...numericValues), collapsible: true };
|
|
82
|
+
}
|
|
83
|
+
return { label: h.name, name: key, type: 'select', allowValues: uniq(values).map((v) => String(v)), collapsible: true };
|
|
84
|
+
});
|
|
85
|
+
}, [filters, headers, elements]);
|
|
86
|
+
const generateStateObj = (0, react_1.useCallback)(() => {
|
|
40
87
|
const obj = {};
|
|
41
|
-
|
|
88
|
+
filtersConfig.forEach((filter) => {
|
|
42
89
|
obj[filter.name] = {
|
|
43
90
|
name: filter.name,
|
|
44
91
|
type: filter.type,
|
|
45
92
|
value: [],
|
|
46
93
|
rangeMin: filter.min,
|
|
47
94
|
rangeMax: filter.max,
|
|
48
|
-
min: '',
|
|
49
|
-
max: '',
|
|
95
|
+
min: (filter.type === 'range' || filter.type === 'date') && filter.min !== undefined ? String(filter.min) : '',
|
|
96
|
+
max: (filter.type === 'range' || filter.type === 'date') && filter.max !== undefined ? String(filter.max) : '',
|
|
50
97
|
};
|
|
51
98
|
});
|
|
52
99
|
return obj;
|
|
53
|
-
};
|
|
100
|
+
}, [filtersConfig]);
|
|
54
101
|
const [openFilters, setOpenFilters] = (0, react_1.useState)(false);
|
|
55
102
|
const [activeFilters, setActiveFilters] = (0, react_1.useState)(generateStateObj());
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
103
|
+
const [collapsedFilters, setCollapsedFilters] = (0, react_1.useState)({});
|
|
104
|
+
(0, react_1.useEffect)(() => {
|
|
105
|
+
const init = {};
|
|
106
|
+
filtersConfig.forEach((f) => (init[f.name] = false));
|
|
107
|
+
const prevKeys = Object.keys(collapsedFilters).sort().join(',');
|
|
108
|
+
const newKeys = Object.keys(init).sort().join(',');
|
|
109
|
+
if (prevKeys !== newKeys)
|
|
110
|
+
setCollapsedFilters(init);
|
|
111
|
+
}, [filtersConfig]);
|
|
112
|
+
const toggleCollapse = (0, react_1.useCallback)((name) => {
|
|
113
|
+
setCollapsedFilters((prev) => ({ ...prev, [name]: !prev[name] }));
|
|
114
|
+
}, []);
|
|
115
|
+
const toggleFilter = (0, react_1.useCallback)(() => setOpenFilters((v) => !v), []);
|
|
116
|
+
const isFilterActive = (0, react_1.useCallback)((filter) => {
|
|
117
|
+
if (filter.type === 'select' || filter.type === 'text') {
|
|
118
|
+
return !!(filter.value && filter.value.length > 0);
|
|
66
119
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return
|
|
120
|
+
if (filter.type === 'range' || filter.type === 'date') {
|
|
121
|
+
const defaultMin = filter.rangeMin !== undefined ? String(filter.rangeMin) : '';
|
|
122
|
+
const defaultMax = filter.rangeMax !== undefined ? String(filter.rangeMax) : '';
|
|
123
|
+
const curMin = filter.min ?? '';
|
|
124
|
+
const curMax = filter.max ?? '';
|
|
125
|
+
return (curMin !== '' && curMin !== defaultMin) || (curMax !== '' && curMax !== defaultMax);
|
|
73
126
|
}
|
|
74
127
|
return false;
|
|
75
|
-
};
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
128
|
+
}, []);
|
|
129
|
+
const isAnyFilterActive = (0, react_1.useCallback)(() => Object.values(activeFilters).some((f) => isFilterActive(f)), [activeFilters, isFilterActive]);
|
|
130
|
+
const setIconColor = (0, react_1.useCallback)(() => (isAnyFilterActive() ? theme.action : theme.textColor), [isAnyFilterActive, theme.action, theme.textColor]);
|
|
131
|
+
const clearAll = (0, react_1.useCallback)(() => {
|
|
132
|
+
const resetedFilter = {};
|
|
133
|
+
Object.keys(activeFilters).forEach((key) => {
|
|
134
|
+
const f = activeFilters[key];
|
|
135
|
+
resetedFilter[key] = {
|
|
136
|
+
...f,
|
|
137
|
+
value: f.type === 'select' || f.type === 'text' ? [] : f.value,
|
|
138
|
+
min: (f.type === 'range' || f.type === 'date') && f.rangeMin !== undefined ? String(f.rangeMin) : '',
|
|
139
|
+
max: (f.type === 'range' || f.type === 'date') && f.rangeMax !== undefined ? String(f.rangeMax) : '',
|
|
140
|
+
};
|
|
89
141
|
});
|
|
90
142
|
return resetedFilter;
|
|
91
|
-
};
|
|
92
|
-
const resetAllFilters = () => {
|
|
143
|
+
}, [activeFilters]);
|
|
144
|
+
const resetAllFilters = (0, react_1.useCallback)(() => {
|
|
93
145
|
const cleared = clearAll();
|
|
94
|
-
setActiveFilters({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
};
|
|
98
|
-
const resetAllFiltersAndSubmit = () => {
|
|
146
|
+
setActiveFilters({ ...cleared });
|
|
147
|
+
}, [clearAll]);
|
|
148
|
+
const resetAllFiltersAndSubmit = (0, react_1.useCallback)(() => {
|
|
99
149
|
resetAllFilters();
|
|
100
150
|
applyFilter();
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
[filterName]: {
|
|
116
|
-
...activeFilters[filterName],
|
|
117
|
-
min: '',
|
|
118
|
-
max: '',
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
const setSelectFilter = (filterValue, filterName) => {
|
|
124
|
-
let values = [];
|
|
125
|
-
const existingValues = activeFilters[filterName].value;
|
|
126
|
-
if (existingValues.includes(filterValue)) {
|
|
127
|
-
values = existingValues.filter((item) => item !== filterValue);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
existingValues.push(filterValue);
|
|
131
|
-
values = [...existingValues];
|
|
132
|
-
}
|
|
133
|
-
setActiveFilters({
|
|
134
|
-
...activeFilters,
|
|
135
|
-
[filterName]: {
|
|
136
|
-
...activeFilters[filterName],
|
|
137
|
-
value: values,
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
};
|
|
141
|
-
const setRangeFilter = (name, value) => {
|
|
142
|
-
const filterName = name.split('_')[0];
|
|
143
|
-
const filterParam = name.split('_')[1];
|
|
144
|
-
setActiveFilters({
|
|
145
|
-
...activeFilters,
|
|
146
|
-
[filterName]: {
|
|
147
|
-
...activeFilters[filterName],
|
|
148
|
-
[filterParam]: value,
|
|
149
|
-
},
|
|
151
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
152
|
+
}, [resetAllFilters]);
|
|
153
|
+
const resetFilter = (0, react_1.useCallback)((filterName, filterType) => {
|
|
154
|
+
setActiveFilters((prev) => {
|
|
155
|
+
const current = prev[filterName] || {};
|
|
156
|
+
if (filterType === 'select' || filterType === 'text') {
|
|
157
|
+
return { ...prev, [filterName]: { ...current, value: [] } };
|
|
158
|
+
}
|
|
159
|
+
if (filterType === 'range' || filterType === 'date') {
|
|
160
|
+
const defaultMin = current.rangeMin !== undefined ? String(current.rangeMin) : '';
|
|
161
|
+
const defaultMax = current.rangeMax !== undefined ? String(current.rangeMax) : '';
|
|
162
|
+
return { ...prev, [filterName]: { ...current, min: defaultMin, max: defaultMax } };
|
|
163
|
+
}
|
|
164
|
+
return prev;
|
|
150
165
|
});
|
|
151
|
-
};
|
|
152
|
-
const
|
|
153
|
-
const
|
|
166
|
+
}, []);
|
|
167
|
+
const setRangeFilter = (0, react_1.useCallback)((name, value) => {
|
|
168
|
+
const [filterName, filterParam] = String(name).split('_');
|
|
169
|
+
setActiveFilters((prev) => ({ ...prev, [filterName]: { ...prev[filterName], [filterParam]: value } }));
|
|
170
|
+
}, []);
|
|
171
|
+
const setTextFilter = (0, react_1.useCallback)((name, value) => {
|
|
172
|
+
const filterName = (name || '').split('_')[0];
|
|
173
|
+
setActiveFilters((prev) => ({ ...prev, [filterName]: { ...(prev[filterName] || { name: filterName, type: 'text', value: [] }), value: value ? [String(value)] : [] } }));
|
|
174
|
+
}, []);
|
|
175
|
+
const applyFilter = (0, react_1.useCallback)(() => {
|
|
176
|
+
let result = (elements || []).slice();
|
|
154
177
|
Object.keys(activeFilters).forEach((key) => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
178
|
+
const f = activeFilters[key];
|
|
179
|
+
if (!f)
|
|
180
|
+
return;
|
|
181
|
+
if (f.type === 'select') {
|
|
182
|
+
if (f.value && f.value.length > 0) {
|
|
183
|
+
const sel = new Set(f.value.map((v) => String(v)));
|
|
184
|
+
result = result.filter((it) => sel.has(String(it?.[key])));
|
|
162
185
|
}
|
|
163
186
|
}
|
|
164
|
-
else if (
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
187
|
+
else if (f.type === 'range') {
|
|
188
|
+
if (!isFilterActive(f))
|
|
189
|
+
return;
|
|
190
|
+
const min = f.min !== '' ? Number(f.min) : undefined;
|
|
191
|
+
const max = f.max !== '' ? Number(f.max) : undefined;
|
|
192
|
+
result = result.filter((it) => {
|
|
193
|
+
const val = Number(it?.[key]);
|
|
194
|
+
if (Number.isNaN(val))
|
|
195
|
+
return false;
|
|
196
|
+
if (min !== undefined && val < min)
|
|
197
|
+
return false;
|
|
198
|
+
if (max !== undefined && val > max)
|
|
199
|
+
return false;
|
|
200
|
+
return true;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else if (f.type === 'date') {
|
|
204
|
+
if (!isFilterActive(f))
|
|
205
|
+
return;
|
|
206
|
+
const fromDate = f.min ? new Date(f.min) : null;
|
|
207
|
+
const toDate = f.max ? new Date(f.max) : null;
|
|
208
|
+
const fromTs = fromDate ? new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate(), 0, 0, 0, 0).getTime() : null;
|
|
209
|
+
const toTs = toDate ? new Date(toDate.getFullYear(), toDate.getMonth(), toDate.getDate(), 23, 59, 59, 999).getTime() : null;
|
|
210
|
+
result = result.filter((it) => {
|
|
211
|
+
const raw = it?.[key];
|
|
212
|
+
if (!raw)
|
|
213
|
+
return false;
|
|
214
|
+
const d = new Date(raw);
|
|
215
|
+
if (Number.isNaN(d.getTime()))
|
|
216
|
+
return false;
|
|
217
|
+
const ts = d.getTime();
|
|
218
|
+
if (fromTs !== null && ts < fromTs)
|
|
219
|
+
return false;
|
|
220
|
+
if (toTs !== null && ts > toTs)
|
|
221
|
+
return false;
|
|
222
|
+
return true;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const q = Array.isArray(f.value) ? f.value[0] : f.value;
|
|
227
|
+
if (q) {
|
|
228
|
+
const qs = String(q).toLowerCase();
|
|
229
|
+
result = result.filter((it) => String(it?.[key] ?? '').toLowerCase().includes(qs));
|
|
172
230
|
}
|
|
173
231
|
}
|
|
174
232
|
});
|
|
175
|
-
handleSubmitFilters && handleSubmitFilters(
|
|
233
|
+
handleSubmitFilters && handleSubmitFilters(result);
|
|
176
234
|
setOpenFilters(false);
|
|
177
|
-
};
|
|
235
|
+
}, [activeFilters, elements, handleSubmitFilters, isFilterActive]);
|
|
236
|
+
const prevConfigKeysRef = (0, react_1.useRef)(null);
|
|
237
|
+
(0, react_1.useEffect)(() => {
|
|
238
|
+
const newState = generateStateObj();
|
|
239
|
+
const keysSerialized = JSON.stringify(Object.keys(newState));
|
|
240
|
+
if (prevConfigKeysRef.current !== keysSerialized) {
|
|
241
|
+
setActiveFilters(newState);
|
|
242
|
+
prevConfigKeysRef.current = keysSerialized;
|
|
243
|
+
}
|
|
244
|
+
}, [generateStateObj]);
|
|
245
|
+
const prevExternalClearRef = (0, react_1.useRef)(externalClearSignal ?? 0);
|
|
246
|
+
(0, react_1.useEffect)(() => {
|
|
247
|
+
if (externalClearSignal === undefined)
|
|
248
|
+
return;
|
|
249
|
+
if (prevExternalClearRef.current !== externalClearSignal) {
|
|
250
|
+
prevExternalClearRef.current = externalClearSignal;
|
|
251
|
+
const cleared = clearAll();
|
|
252
|
+
setActiveFilters(cleared);
|
|
253
|
+
handleSubmitFilters && handleSubmitFilters((fullElements && fullElements.length ? fullElements : elements) || []);
|
|
254
|
+
}
|
|
255
|
+
}, [externalClearSignal, clearAll, handleSubmitFilters, fullElements, elements]);
|
|
256
|
+
const mapListItems = (0, react_1.useCallback)((filterName, allowValues) => {
|
|
257
|
+
const sel = (activeFilters[filterName]?.value || []).map(String);
|
|
258
|
+
return (allowValues || []).map((v) => ({ id: String(v), value: String(v), children: [], selected: sel.includes(String(v)) }));
|
|
259
|
+
}, [activeFilters]);
|
|
178
260
|
return (react_1.default.createElement(styled_components_1.ThemeProvider, { theme: theme },
|
|
179
261
|
react_1.default.createElement(Filters_styles_1.FilterIconArea, null,
|
|
180
|
-
react_1.default.createElement(Icons_1.Icon, { name: "filters", onClick:
|
|
181
|
-
isAnyFilterActive() && (react_1.default.createElement(Chips_1.Chips, { label: labelClearAll, handleClose:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
262
|
+
react_1.default.createElement(Icons_1.Icon, { name: "filters", onClick: toggleFilter, iconColor: setIconColor() }),
|
|
263
|
+
isAnyFilterActive() && (react_1.default.createElement(Chips_1.Chips, { label: labelClearAll, handleClose: () => {
|
|
264
|
+
if (onClear) {
|
|
265
|
+
onClear();
|
|
266
|
+
const cleared = clearAll();
|
|
267
|
+
setActiveFilters(cleared);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
const cleared = clearAll();
|
|
271
|
+
setActiveFilters(cleared);
|
|
272
|
+
handleSubmitFilters && handleSubmitFilters((fullElements && fullElements.length ? fullElements : elements) || []);
|
|
273
|
+
}
|
|
274
|
+
} }))),
|
|
275
|
+
openFilters && (react_1.default.createElement(Modal_1.Modal, { title: title, handleConfirm: applyFilter, handleClose: toggleFilter, handleAdditional: () => {
|
|
276
|
+
if (onClear) {
|
|
277
|
+
onClear();
|
|
278
|
+
const cleared = clearAll();
|
|
279
|
+
setActiveFilters(cleared);
|
|
280
|
+
setOpenFilters(false);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
resetAllFiltersAndSubmit();
|
|
284
|
+
}
|
|
285
|
+
}, labelConfirm: labelConfirm, labelClose: labelClose, labelAdditional: labelClearAll, isOpen: openFilters },
|
|
286
|
+
react_1.default.createElement(Aligment_1.Aligment, { direction: "column", align: "flex-end" },
|
|
287
|
+
react_1.default.createElement(Filters_styles_1.FiltersArea, null, filtersConfig.map((filter) => (react_1.default.createElement(Filters_styles_1.FilterSection, { key: filter.name },
|
|
288
|
+
react_1.default.createElement(Aligment_1.Aligment, { wrap: "nowrap", style: { alignItems: 'center', justifyContent: 'start' } },
|
|
289
|
+
react_1.default.createElement(Aligment_1.Aligment, { wrap: "nowrap", onClick: () => filter.collapsible && toggleCollapse(filter.name), style: { cursor: filter.collapsible ? 'pointer' : 'default', alignItems: 'center', justifyContent: 'start' } },
|
|
290
|
+
react_1.default.createElement(Typography_1.TextAccent, { style: { marginRight: 0 } }, filter.label),
|
|
291
|
+
react_1.default.createElement(Icons_1.Icon, { name: collapsedFilters[filter.name] ? 'arrow_drop_down' : 'arrow_drop_up', size: 16, iconColor: theme.textColor })),
|
|
187
292
|
react_1.default.createElement(Icons_1.Icon, { name: "close", size: 14, onClick: () => resetFilter(filter.name, filter.type) })),
|
|
188
|
-
filter.type === 'select'
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
293
|
+
!filter.collapsible || !collapsedFilters[filter.name] ? (filter.type === 'select' ? (react_1.default.createElement("div", { style: { width: '100%' } },
|
|
294
|
+
react_1.default.createElement(List_1.List, { items: mapListItems(filter.name, filter.allowValues), handleChange: (items) => {
|
|
295
|
+
const collectSelected = (list) => list.reduce((acc, it) => {
|
|
296
|
+
if (it.selected)
|
|
297
|
+
acc.push(String(it.id));
|
|
298
|
+
if (it.children && it.children.length)
|
|
299
|
+
acc.push(...collectSelected(it.children));
|
|
300
|
+
return acc;
|
|
301
|
+
}, []);
|
|
302
|
+
const selectedIds = collectSelected(items);
|
|
303
|
+
setActiveFilters((prev) => ({ ...prev, [filter.name]: { ...(prev[filter.name] || { name: filter.name, type: filter.type, value: [] }), value: selectedIds } }));
|
|
304
|
+
}, isCheckbox: true, isCollapsable: true }))) : filter.type === 'range' ? (react_1.default.createElement(Aligment_1.Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme_1.Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
305
|
+
react_1.default.createElement(Filters_styles_1.FilterInputWrapper, null,
|
|
306
|
+
react_1.default.createElement(Input_1.Input, { type: "number", name: `${filter.name}_min`, value: activeFilters[filter.name].min, handleChange: setRangeFilter })),
|
|
307
|
+
react_1.default.createElement(Filters_styles_1.FilterInputWrapper, null,
|
|
308
|
+
react_1.default.createElement(Input_1.Input, { type: "number", name: `${filter.name}_max`, value: activeFilters[filter.name].max, handleChange: setRangeFilter })))) : filter.type === 'date' ? (react_1.default.createElement(Aligment_1.Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme_1.Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
309
|
+
react_1.default.createElement(Filters_styles_1.FilterInputWrapper, null,
|
|
310
|
+
react_1.default.createElement(Input_1.Input, { type: "date", name: `${filter.name}_min`, value: activeFilters[filter.name].min, handleChange: setRangeFilter })),
|
|
192
311
|
react_1.default.createElement(Filters_styles_1.FilterInputWrapper, null,
|
|
193
|
-
react_1.default.createElement(Input_1.Input, { type: "
|
|
312
|
+
react_1.default.createElement(Input_1.Input, { type: "date", name: `${filter.name}_max`, value: activeFilters[filter.name].max, handleChange: setRangeFilter })))) : filter.type === 'text' ? (react_1.default.createElement(Aligment_1.Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme_1.Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
194
313
|
react_1.default.createElement(Filters_styles_1.FilterInputWrapper, null,
|
|
195
|
-
react_1.default.createElement(Input_1.Input, { type: "
|
|
314
|
+
react_1.default.createElement(Input_1.Input, { type: "text", name: `${filter.name}_query`, value: (activeFilters[filter.name]?.value && activeFilters[filter.name].value[0]) || '', handleChange: setTextFilter })))) : null) : null)))))))));
|
|
196
315
|
};
|
|
197
316
|
exports.Filters = Filters;
|
|
317
|
+
exports.default = exports.Filters;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.applyFiltersToTable = exports.
|
|
3
|
+
exports.applyFiltersToTable = exports.getMaxValue = exports.getMinValue = exports.getUniqueValues = void 0;
|
|
4
4
|
const getUniqueValues = (elements, source) => {
|
|
5
5
|
const result = [...new Set(elements.map((item) => item[source]))];
|
|
6
6
|
return result;
|
|
@@ -14,21 +14,6 @@ const getMaxValue = (elements, source) => {
|
|
|
14
14
|
return Math.max(...elements.map((item) => item[source]));
|
|
15
15
|
};
|
|
16
16
|
exports.getMaxValue = getMaxValue;
|
|
17
|
-
const setTableFilterSet = (headers, elements) => {
|
|
18
|
-
const filterSetting = [];
|
|
19
|
-
headers.forEach((filter) => {
|
|
20
|
-
filterSetting.push({
|
|
21
|
-
label: filter.name,
|
|
22
|
-
name: filter.valueSource,
|
|
23
|
-
type: filter.filterType ? filter.filterType : 'select',
|
|
24
|
-
allowValues: (0, exports.getUniqueValues)(elements, filter.valueSource),
|
|
25
|
-
min: (0, exports.getMinValue)(elements, filter.valueSource),
|
|
26
|
-
max: (0, exports.getMaxValue)(elements, filter.valueSource),
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
return filterSetting;
|
|
30
|
-
};
|
|
31
|
-
exports.setTableFilterSet = setTableFilterSet;
|
|
32
17
|
const applyFiltersToTable = (elements, filters) => {
|
|
33
18
|
let filtered = [...elements];
|
|
34
19
|
filters.forEach((filter) => {
|
|
@@ -32,10 +32,20 @@ const tableHelper_1 = require("./tableHelper");
|
|
|
32
32
|
const HeaderCell_1 = require("./HeaderCell");
|
|
33
33
|
const Cell_1 = require("./Cell");
|
|
34
34
|
const Pagination_1 = require("../Pagination");
|
|
35
|
+
const Filters_1 = require("../Filters");
|
|
36
|
+
const Typography_1 = require("../Typography");
|
|
35
37
|
const Table = ({ theme = Theme_1.mainTheme, headers, elements, hover = true, selectable = true, sortable = true, sort = {
|
|
36
38
|
name: '',
|
|
37
39
|
order: 'none',
|
|
38
40
|
}, pageSize = 10, ifPagination = false, moreActions = [], onRowClick, }) => {
|
|
41
|
+
const initialElementsRef = (0, react_1.useRef)(null);
|
|
42
|
+
(0, react_1.useEffect)(() => {
|
|
43
|
+
if (!initialElementsRef.current && Array.isArray(elements) && elements.length > 0) {
|
|
44
|
+
initialElementsRef.current = elements.slice();
|
|
45
|
+
}
|
|
46
|
+
setTableProps((prev) => ({ ...prev, elements: Array.isArray(elements) ? elements : [] }));
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [elements]);
|
|
39
49
|
const checkHeaders = () => {
|
|
40
50
|
const tableHeaders = [...headers];
|
|
41
51
|
if (moreActions.length > 0) {
|
|
@@ -75,7 +85,6 @@ const Table = ({ theme = Theme_1.mainTheme, headers, elements, hover = true, sel
|
|
|
75
85
|
});
|
|
76
86
|
}
|
|
77
87
|
};
|
|
78
|
-
// PAGINACJA
|
|
79
88
|
const [currentPage, setCurrentPage] = (0, react_1.useState)(1);
|
|
80
89
|
const [currentPageSize, setCurrentPageSize] = (0, react_1.useState)(pageSize || 10);
|
|
81
90
|
const totalPages = Math.ceil(tableProps.elements.length / currentPageSize);
|
|
@@ -83,7 +92,28 @@ const Table = ({ theme = Theme_1.mainTheme, headers, elements, hover = true, sel
|
|
|
83
92
|
(0, react_1.useEffect)(() => {
|
|
84
93
|
setCurrentPage(1);
|
|
85
94
|
}, [elements, currentPageSize]);
|
|
95
|
+
const [noResultsMessage, setNoResultsMessage] = (0, react_1.useState)(null);
|
|
96
|
+
const handleApplyFilters = (0, react_1.useCallback)((filteredElements) => {
|
|
97
|
+
setTableProps((prev) => ({
|
|
98
|
+
...prev,
|
|
99
|
+
elements: filteredElements,
|
|
100
|
+
}));
|
|
101
|
+
setCurrentPage(1);
|
|
102
|
+
setNoResultsMessage(filteredElements && filteredElements.length === 0 ? 'Nie ma żadnych wyników' : null);
|
|
103
|
+
}, [setCurrentPage, setTableProps]);
|
|
104
|
+
const [filtersClearSignal, setFiltersClearSignal] = (0, react_1.useState)(0);
|
|
105
|
+
const handleClearFilters = (0, react_1.useCallback)(() => {
|
|
106
|
+
setFiltersClearSignal((s) => s + 1);
|
|
107
|
+
const full = (initialElementsRef.current && initialElementsRef.current.length > 0)
|
|
108
|
+
? initialElementsRef.current
|
|
109
|
+
: (Array.isArray(elements) ? elements : []);
|
|
110
|
+
setTableProps((prev) => ({ ...prev, elements: Array.isArray(full) ? full.slice() : [] }));
|
|
111
|
+
setCurrentPage(1);
|
|
112
|
+
setNoResultsMessage(null);
|
|
113
|
+
}, [elements, setCurrentPage, setNoResultsMessage]);
|
|
86
114
|
return (react_1.default.createElement(styled_components_1.ThemeProvider, { theme: theme },
|
|
115
|
+
react_1.default.createElement("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 12 } },
|
|
116
|
+
react_1.default.createElement(Filters_1.Filters, { title: "Select filters", labelConfirm: "Apply", labelClose: "Cancel", labelClearAll: "Clear", headers: headers, elements: initialElementsRef.current && initialElementsRef.current.length > 0 ? initialElementsRef.current : elements, fullElements: initialElementsRef.current && initialElementsRef.current.length > 0 ? initialElementsRef.current : elements, handleSubmitFilters: handleApplyFilters, externalClearSignal: filtersClearSignal, onClear: handleClearFilters })),
|
|
87
117
|
react_1.default.createElement(Table_styles_1.TableWrapper, { cellPadding: "0", cellSpacing: "0" },
|
|
88
118
|
react_1.default.createElement(Table_styles_1.TableHead, null,
|
|
89
119
|
react_1.default.createElement(Table_styles_1.TableRow, { hover: false, selectable: false, active: false }, tableProps.headers.map((header) => (react_1.default.createElement(HeaderCell_1.HeaderCell, { key: `header_${header.name}`, header: header, sortable: sortable, handleSort: handleHeaderCellClick, sort: tableProps.sort }))))),
|
|
@@ -92,6 +122,8 @@ const Table = ({ theme = Theme_1.mainTheme, headers, elements, hover = true, sel
|
|
|
92
122
|
return (react_1.default.createElement(Cell_1.Cell, { key: `cell_${header.name}_${item.id}`, header: header, moreActions: moreActions, item: item, theme: theme, marked: item.marked && index === 0, isDisabled: item.disabled }));
|
|
93
123
|
})));
|
|
94
124
|
}))),
|
|
125
|
+
noResultsMessage && (react_1.default.createElement("div", { style: { padding: '8px 12px', textAlign: 'center' } },
|
|
126
|
+
react_1.default.createElement(Typography_1.TextAccent, null, noResultsMessage))),
|
|
95
127
|
ifPagination && (react_1.default.createElement(Pagination_1.Pagination, { currentPage: currentPage, totalPages: totalPages, pageSize: currentPageSize, onPageChange: setCurrentPage, onPageSizeChange: setCurrentPageSize }))));
|
|
96
128
|
};
|
|
97
129
|
exports.Table = Table;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getValueFormScope = exports.
|
|
3
|
+
exports.getValueFormScope = exports.applySort = exports.setSortParams = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
|
-
const Filters_1 = require("../Filters");
|
|
6
5
|
const setSortParams = (target, order, sort) => {
|
|
7
6
|
const newSort = {
|
|
8
7
|
name: target,
|
|
@@ -19,14 +18,6 @@ const applySort = (sort, elements) => {
|
|
|
19
18
|
return sorted;
|
|
20
19
|
};
|
|
21
20
|
exports.applySort = applySort;
|
|
22
|
-
const setElements = (elements, sort, filters) => {
|
|
23
|
-
let tableElements = [...(0, Filters_1.applyFiltersToTable)(elements, filters)];
|
|
24
|
-
if (sort.name !== '') {
|
|
25
|
-
tableElements = (0, exports.applySort)(sort, tableElements);
|
|
26
|
-
}
|
|
27
|
-
return tableElements;
|
|
28
|
-
};
|
|
29
|
-
exports.setElements = setElements;
|
|
30
21
|
const getValueFormScope = (item, valuesScope) => {
|
|
31
22
|
return valuesScope.find((_value) => _value.key === item)?.value || '';
|
|
32
23
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
|
|
2
2
|
import { ThemeProvider } from 'styled-components';
|
|
3
3
|
import { TextAccent } from '../Typography';
|
|
4
4
|
import { Aligment } from '../Aligment';
|
|
@@ -6,165 +6,285 @@ import { Icon } from '../Icons';
|
|
|
6
6
|
import { Modal } from '../Modal';
|
|
7
7
|
import { FilterIconArea, FilterInputWrapper, FiltersArea, FilterSection, } from './Filters.styles';
|
|
8
8
|
import { Theme, mainTheme } from '../../Theme';
|
|
9
|
-
import { PanelOption } from '../common';
|
|
10
9
|
import { Input } from '../Input';
|
|
11
10
|
import { Chips } from '../Chips';
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
import { List } from '../List';
|
|
12
|
+
export const Filters = ({ theme = mainTheme, title = 'Select filters', labelConfirm = 'Approve', labelClose = 'Cancel', filters = [], headers = [], elements = [], fullElements, labelClearAll = 'Wyczyść', handleSubmitFilters, externalClearSignal, onClear, }) => {
|
|
13
|
+
const filtersConfig = useMemo(() => {
|
|
14
|
+
const uniq = (arr) => Array.from(new Set(arr.filter((v) => v !== undefined && v !== null)));
|
|
15
|
+
if (filters && filters.length) {
|
|
16
|
+
return filters.map((h) => ({
|
|
17
|
+
label: h.label,
|
|
18
|
+
name: h.name,
|
|
19
|
+
type: h.type || 'select',
|
|
20
|
+
allowValues: (h.allowValues || []).map((v) => String(v)),
|
|
21
|
+
min: h.min,
|
|
22
|
+
max: h.max,
|
|
23
|
+
collapsible: h.collapsible ?? true,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
if (!headers || headers.length === 0)
|
|
27
|
+
return [];
|
|
28
|
+
return headers
|
|
29
|
+
.filter((h) => !h.action)
|
|
30
|
+
.map((h) => {
|
|
31
|
+
const key = h.valueSource || h.name;
|
|
32
|
+
const values = (elements || []).map((it) => it?.[key]).filter((v) => v !== undefined && v !== null);
|
|
33
|
+
const nameLower = (h.name || '').toString().toLowerCase();
|
|
34
|
+
if (nameLower === 'age' || nameLower.includes('age')) {
|
|
35
|
+
const nums = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
36
|
+
const min = nums.length ? Math.min(...nums) : 0;
|
|
37
|
+
const max = nums.length ? Math.max(...nums) : 0;
|
|
38
|
+
return { label: h.name, name: key, type: 'range', min, max, collapsible: true };
|
|
39
|
+
}
|
|
40
|
+
if (h.scope && h.scope.length) {
|
|
41
|
+
return { label: h.name, name: key, type: 'select', allowValues: h.scope.map((s) => (s.label ?? s.value ?? s.key ?? String(s))), collapsible: true };
|
|
42
|
+
}
|
|
43
|
+
if (h.date) {
|
|
44
|
+
const dates = values.map((v) => (v ? new Date(v).getTime() : NaN)).filter((d) => !Number.isNaN(d));
|
|
45
|
+
const min = dates.length ? new Date(Math.min(...dates)).toISOString() : undefined;
|
|
46
|
+
const max = dates.length ? new Date(Math.max(...dates)).toISOString() : undefined;
|
|
47
|
+
return { label: h.name, name: key, type: 'date', min, max, collapsible: true };
|
|
48
|
+
}
|
|
49
|
+
if (h.isCount) {
|
|
50
|
+
const nums = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
51
|
+
return { label: h.name, name: key, type: 'range', min: nums.length ? Math.min(...nums) : 0, max: nums.length ? Math.max(...nums) : 0, collapsible: true };
|
|
52
|
+
}
|
|
53
|
+
const numericValues = values.map((v) => Number(v)).filter((n) => !Number.isNaN(n));
|
|
54
|
+
if (numericValues.length === values.length && values.length > 0) {
|
|
55
|
+
return { label: h.name, name: key, type: 'range', min: Math.min(...numericValues), max: Math.max(...numericValues), collapsible: true };
|
|
56
|
+
}
|
|
57
|
+
return { label: h.name, name: key, type: 'select', allowValues: uniq(values).map((v) => String(v)), collapsible: true };
|
|
58
|
+
});
|
|
59
|
+
}, [filters, headers, elements]);
|
|
60
|
+
const generateStateObj = useCallback(() => {
|
|
14
61
|
const obj = {};
|
|
15
|
-
|
|
62
|
+
filtersConfig.forEach((filter) => {
|
|
16
63
|
obj[filter.name] = {
|
|
17
64
|
name: filter.name,
|
|
18
65
|
type: filter.type,
|
|
19
66
|
value: [],
|
|
20
67
|
rangeMin: filter.min,
|
|
21
68
|
rangeMax: filter.max,
|
|
22
|
-
min: '',
|
|
23
|
-
max: '',
|
|
69
|
+
min: (filter.type === 'range' || filter.type === 'date') && filter.min !== undefined ? String(filter.min) : '',
|
|
70
|
+
max: (filter.type === 'range' || filter.type === 'date') && filter.max !== undefined ? String(filter.max) : '',
|
|
24
71
|
};
|
|
25
72
|
});
|
|
26
73
|
return obj;
|
|
27
|
-
};
|
|
74
|
+
}, [filtersConfig]);
|
|
28
75
|
const [openFilters, setOpenFilters] = useState(false);
|
|
29
76
|
const [activeFilters, setActiveFilters] = useState(generateStateObj());
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
77
|
+
const [collapsedFilters, setCollapsedFilters] = useState({});
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
const init = {};
|
|
80
|
+
filtersConfig.forEach((f) => (init[f.name] = false));
|
|
81
|
+
const prevKeys = Object.keys(collapsedFilters).sort().join(',');
|
|
82
|
+
const newKeys = Object.keys(init).sort().join(',');
|
|
83
|
+
if (prevKeys !== newKeys)
|
|
84
|
+
setCollapsedFilters(init);
|
|
85
|
+
}, [filtersConfig]);
|
|
86
|
+
const toggleCollapse = useCallback((name) => {
|
|
87
|
+
setCollapsedFilters((prev) => ({ ...prev, [name]: !prev[name] }));
|
|
88
|
+
}, []);
|
|
89
|
+
const toggleFilter = useCallback(() => setOpenFilters((v) => !v), []);
|
|
90
|
+
const isFilterActive = useCallback((filter) => {
|
|
91
|
+
if (filter.type === 'select' || filter.type === 'text') {
|
|
92
|
+
return !!(filter.value && filter.value.length > 0);
|
|
40
93
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return
|
|
94
|
+
if (filter.type === 'range' || filter.type === 'date') {
|
|
95
|
+
const defaultMin = filter.rangeMin !== undefined ? String(filter.rangeMin) : '';
|
|
96
|
+
const defaultMax = filter.rangeMax !== undefined ? String(filter.rangeMax) : '';
|
|
97
|
+
const curMin = filter.min ?? '';
|
|
98
|
+
const curMax = filter.max ?? '';
|
|
99
|
+
return (curMin !== '' && curMin !== defaultMin) || (curMax !== '' && curMax !== defaultMax);
|
|
47
100
|
}
|
|
48
101
|
return false;
|
|
49
|
-
};
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
102
|
+
}, []);
|
|
103
|
+
const isAnyFilterActive = useCallback(() => Object.values(activeFilters).some((f) => isFilterActive(f)), [activeFilters, isFilterActive]);
|
|
104
|
+
const setIconColor = useCallback(() => (isAnyFilterActive() ? theme.action : theme.textColor), [isAnyFilterActive, theme.action, theme.textColor]);
|
|
105
|
+
const clearAll = useCallback(() => {
|
|
106
|
+
const resetedFilter = {};
|
|
107
|
+
Object.keys(activeFilters).forEach((key) => {
|
|
108
|
+
const f = activeFilters[key];
|
|
109
|
+
resetedFilter[key] = {
|
|
110
|
+
...f,
|
|
111
|
+
value: f.type === 'select' || f.type === 'text' ? [] : f.value,
|
|
112
|
+
min: (f.type === 'range' || f.type === 'date') && f.rangeMin !== undefined ? String(f.rangeMin) : '',
|
|
113
|
+
max: (f.type === 'range' || f.type === 'date') && f.rangeMax !== undefined ? String(f.rangeMax) : '',
|
|
114
|
+
};
|
|
63
115
|
});
|
|
64
116
|
return resetedFilter;
|
|
65
|
-
};
|
|
66
|
-
const resetAllFilters = () => {
|
|
117
|
+
}, [activeFilters]);
|
|
118
|
+
const resetAllFilters = useCallback(() => {
|
|
67
119
|
const cleared = clearAll();
|
|
68
|
-
setActiveFilters({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
72
|
-
const resetAllFiltersAndSubmit = () => {
|
|
120
|
+
setActiveFilters({ ...cleared });
|
|
121
|
+
}, [clearAll]);
|
|
122
|
+
const resetAllFiltersAndSubmit = useCallback(() => {
|
|
73
123
|
resetAllFilters();
|
|
74
124
|
applyFilter();
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
[filterName]: {
|
|
90
|
-
...activeFilters[filterName],
|
|
91
|
-
min: '',
|
|
92
|
-
max: '',
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
const setSelectFilter = (filterValue, filterName) => {
|
|
98
|
-
let values = [];
|
|
99
|
-
const existingValues = activeFilters[filterName].value;
|
|
100
|
-
if (existingValues.includes(filterValue)) {
|
|
101
|
-
values = existingValues.filter((item) => item !== filterValue);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
existingValues.push(filterValue);
|
|
105
|
-
values = [...existingValues];
|
|
106
|
-
}
|
|
107
|
-
setActiveFilters({
|
|
108
|
-
...activeFilters,
|
|
109
|
-
[filterName]: {
|
|
110
|
-
...activeFilters[filterName],
|
|
111
|
-
value: values,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
const setRangeFilter = (name, value) => {
|
|
116
|
-
const filterName = name.split('_')[0];
|
|
117
|
-
const filterParam = name.split('_')[1];
|
|
118
|
-
setActiveFilters({
|
|
119
|
-
...activeFilters,
|
|
120
|
-
[filterName]: {
|
|
121
|
-
...activeFilters[filterName],
|
|
122
|
-
[filterParam]: value,
|
|
123
|
-
},
|
|
125
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
126
|
+
}, [resetAllFilters]);
|
|
127
|
+
const resetFilter = useCallback((filterName, filterType) => {
|
|
128
|
+
setActiveFilters((prev) => {
|
|
129
|
+
const current = prev[filterName] || {};
|
|
130
|
+
if (filterType === 'select' || filterType === 'text') {
|
|
131
|
+
return { ...prev, [filterName]: { ...current, value: [] } };
|
|
132
|
+
}
|
|
133
|
+
if (filterType === 'range' || filterType === 'date') {
|
|
134
|
+
const defaultMin = current.rangeMin !== undefined ? String(current.rangeMin) : '';
|
|
135
|
+
const defaultMax = current.rangeMax !== undefined ? String(current.rangeMax) : '';
|
|
136
|
+
return { ...prev, [filterName]: { ...current, min: defaultMin, max: defaultMax } };
|
|
137
|
+
}
|
|
138
|
+
return prev;
|
|
124
139
|
});
|
|
125
|
-
};
|
|
126
|
-
const
|
|
127
|
-
const
|
|
140
|
+
}, []);
|
|
141
|
+
const setRangeFilter = useCallback((name, value) => {
|
|
142
|
+
const [filterName, filterParam] = String(name).split('_');
|
|
143
|
+
setActiveFilters((prev) => ({ ...prev, [filterName]: { ...prev[filterName], [filterParam]: value } }));
|
|
144
|
+
}, []);
|
|
145
|
+
const setTextFilter = useCallback((name, value) => {
|
|
146
|
+
const filterName = (name || '').split('_')[0];
|
|
147
|
+
setActiveFilters((prev) => ({ ...prev, [filterName]: { ...(prev[filterName] || { name: filterName, type: 'text', value: [] }), value: value ? [String(value)] : [] } }));
|
|
148
|
+
}, []);
|
|
149
|
+
const applyFilter = useCallback(() => {
|
|
150
|
+
let result = (elements || []).slice();
|
|
128
151
|
Object.keys(activeFilters).forEach((key) => {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
152
|
+
const f = activeFilters[key];
|
|
153
|
+
if (!f)
|
|
154
|
+
return;
|
|
155
|
+
if (f.type === 'select') {
|
|
156
|
+
if (f.value && f.value.length > 0) {
|
|
157
|
+
const sel = new Set(f.value.map((v) => String(v)));
|
|
158
|
+
result = result.filter((it) => sel.has(String(it?.[key])));
|
|
136
159
|
}
|
|
137
160
|
}
|
|
138
|
-
else if (
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
else if (f.type === 'range') {
|
|
162
|
+
if (!isFilterActive(f))
|
|
163
|
+
return;
|
|
164
|
+
const min = f.min !== '' ? Number(f.min) : undefined;
|
|
165
|
+
const max = f.max !== '' ? Number(f.max) : undefined;
|
|
166
|
+
result = result.filter((it) => {
|
|
167
|
+
const val = Number(it?.[key]);
|
|
168
|
+
if (Number.isNaN(val))
|
|
169
|
+
return false;
|
|
170
|
+
if (min !== undefined && val < min)
|
|
171
|
+
return false;
|
|
172
|
+
if (max !== undefined && val > max)
|
|
173
|
+
return false;
|
|
174
|
+
return true;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
else if (f.type === 'date') {
|
|
178
|
+
if (!isFilterActive(f))
|
|
179
|
+
return;
|
|
180
|
+
const fromDate = f.min ? new Date(f.min) : null;
|
|
181
|
+
const toDate = f.max ? new Date(f.max) : null;
|
|
182
|
+
const fromTs = fromDate ? new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate(), 0, 0, 0, 0).getTime() : null;
|
|
183
|
+
const toTs = toDate ? new Date(toDate.getFullYear(), toDate.getMonth(), toDate.getDate(), 23, 59, 59, 999).getTime() : null;
|
|
184
|
+
result = result.filter((it) => {
|
|
185
|
+
const raw = it?.[key];
|
|
186
|
+
if (!raw)
|
|
187
|
+
return false;
|
|
188
|
+
const d = new Date(raw);
|
|
189
|
+
if (Number.isNaN(d.getTime()))
|
|
190
|
+
return false;
|
|
191
|
+
const ts = d.getTime();
|
|
192
|
+
if (fromTs !== null && ts < fromTs)
|
|
193
|
+
return false;
|
|
194
|
+
if (toTs !== null && ts > toTs)
|
|
195
|
+
return false;
|
|
196
|
+
return true;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
const q = Array.isArray(f.value) ? f.value[0] : f.value;
|
|
201
|
+
if (q) {
|
|
202
|
+
const qs = String(q).toLowerCase();
|
|
203
|
+
result = result.filter((it) => String(it?.[key] ?? '').toLowerCase().includes(qs));
|
|
146
204
|
}
|
|
147
205
|
}
|
|
148
206
|
});
|
|
149
|
-
handleSubmitFilters && handleSubmitFilters(
|
|
207
|
+
handleSubmitFilters && handleSubmitFilters(result);
|
|
150
208
|
setOpenFilters(false);
|
|
151
|
-
};
|
|
209
|
+
}, [activeFilters, elements, handleSubmitFilters, isFilterActive]);
|
|
210
|
+
const prevConfigKeysRef = useRef(null);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
const newState = generateStateObj();
|
|
213
|
+
const keysSerialized = JSON.stringify(Object.keys(newState));
|
|
214
|
+
if (prevConfigKeysRef.current !== keysSerialized) {
|
|
215
|
+
setActiveFilters(newState);
|
|
216
|
+
prevConfigKeysRef.current = keysSerialized;
|
|
217
|
+
}
|
|
218
|
+
}, [generateStateObj]);
|
|
219
|
+
const prevExternalClearRef = useRef(externalClearSignal ?? 0);
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (externalClearSignal === undefined)
|
|
222
|
+
return;
|
|
223
|
+
if (prevExternalClearRef.current !== externalClearSignal) {
|
|
224
|
+
prevExternalClearRef.current = externalClearSignal;
|
|
225
|
+
const cleared = clearAll();
|
|
226
|
+
setActiveFilters(cleared);
|
|
227
|
+
handleSubmitFilters && handleSubmitFilters((fullElements && fullElements.length ? fullElements : elements) || []);
|
|
228
|
+
}
|
|
229
|
+
}, [externalClearSignal, clearAll, handleSubmitFilters, fullElements, elements]);
|
|
230
|
+
const mapListItems = useCallback((filterName, allowValues) => {
|
|
231
|
+
const sel = (activeFilters[filterName]?.value || []).map(String);
|
|
232
|
+
return (allowValues || []).map((v) => ({ id: String(v), value: String(v), children: [], selected: sel.includes(String(v)) }));
|
|
233
|
+
}, [activeFilters]);
|
|
152
234
|
return (React.createElement(ThemeProvider, { theme: theme },
|
|
153
235
|
React.createElement(FilterIconArea, null,
|
|
154
|
-
React.createElement(Icon, { name: "filters", onClick:
|
|
155
|
-
isAnyFilterActive() && (React.createElement(Chips, { label: labelClearAll, handleClose:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
236
|
+
React.createElement(Icon, { name: "filters", onClick: toggleFilter, iconColor: setIconColor() }),
|
|
237
|
+
isAnyFilterActive() && (React.createElement(Chips, { label: labelClearAll, handleClose: () => {
|
|
238
|
+
if (onClear) {
|
|
239
|
+
onClear();
|
|
240
|
+
const cleared = clearAll();
|
|
241
|
+
setActiveFilters(cleared);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
const cleared = clearAll();
|
|
245
|
+
setActiveFilters(cleared);
|
|
246
|
+
handleSubmitFilters && handleSubmitFilters((fullElements && fullElements.length ? fullElements : elements) || []);
|
|
247
|
+
}
|
|
248
|
+
} }))),
|
|
249
|
+
openFilters && (React.createElement(Modal, { title: title, handleConfirm: applyFilter, handleClose: toggleFilter, handleAdditional: () => {
|
|
250
|
+
if (onClear) {
|
|
251
|
+
onClear();
|
|
252
|
+
const cleared = clearAll();
|
|
253
|
+
setActiveFilters(cleared);
|
|
254
|
+
setOpenFilters(false);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
resetAllFiltersAndSubmit();
|
|
258
|
+
}
|
|
259
|
+
}, labelConfirm: labelConfirm, labelClose: labelClose, labelAdditional: labelClearAll, isOpen: openFilters },
|
|
260
|
+
React.createElement(Aligment, { direction: "column", align: "flex-end" },
|
|
261
|
+
React.createElement(FiltersArea, null, filtersConfig.map((filter) => (React.createElement(FilterSection, { key: filter.name },
|
|
262
|
+
React.createElement(Aligment, { wrap: "nowrap", style: { alignItems: 'center', justifyContent: 'start' } },
|
|
263
|
+
React.createElement(Aligment, { wrap: "nowrap", onClick: () => filter.collapsible && toggleCollapse(filter.name), style: { cursor: filter.collapsible ? 'pointer' : 'default', alignItems: 'center', justifyContent: 'start' } },
|
|
264
|
+
React.createElement(TextAccent, { style: { marginRight: 0 } }, filter.label),
|
|
265
|
+
React.createElement(Icon, { name: collapsedFilters[filter.name] ? 'arrow_drop_down' : 'arrow_drop_up', size: 16, iconColor: theme.textColor })),
|
|
161
266
|
React.createElement(Icon, { name: "close", size: 14, onClick: () => resetFilter(filter.name, filter.type) })),
|
|
162
|
-
filter.type === 'select'
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
267
|
+
!filter.collapsible || !collapsedFilters[filter.name] ? (filter.type === 'select' ? (React.createElement("div", { style: { width: '100%' } },
|
|
268
|
+
React.createElement(List, { items: mapListItems(filter.name, filter.allowValues), handleChange: (items) => {
|
|
269
|
+
const collectSelected = (list) => list.reduce((acc, it) => {
|
|
270
|
+
if (it.selected)
|
|
271
|
+
acc.push(String(it.id));
|
|
272
|
+
if (it.children && it.children.length)
|
|
273
|
+
acc.push(...collectSelected(it.children));
|
|
274
|
+
return acc;
|
|
275
|
+
}, []);
|
|
276
|
+
const selectedIds = collectSelected(items);
|
|
277
|
+
setActiveFilters((prev) => ({ ...prev, [filter.name]: { ...(prev[filter.name] || { name: filter.name, type: filter.type, value: [] }), value: selectedIds } }));
|
|
278
|
+
}, isCheckbox: true, isCollapsable: true }))) : filter.type === 'range' ? (React.createElement(Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
279
|
+
React.createElement(FilterInputWrapper, null,
|
|
280
|
+
React.createElement(Input, { type: "number", name: `${filter.name}_min`, value: activeFilters[filter.name].min, handleChange: setRangeFilter })),
|
|
281
|
+
React.createElement(FilterInputWrapper, null,
|
|
282
|
+
React.createElement(Input, { type: "number", name: `${filter.name}_max`, value: activeFilters[filter.name].max, handleChange: setRangeFilter })))) : filter.type === 'date' ? (React.createElement(Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
283
|
+
React.createElement(FilterInputWrapper, null,
|
|
284
|
+
React.createElement(Input, { type: "date", name: `${filter.name}_min`, value: activeFilters[filter.name].min, handleChange: setRangeFilter })),
|
|
166
285
|
React.createElement(FilterInputWrapper, null,
|
|
167
|
-
React.createElement(Input, { type: "
|
|
286
|
+
React.createElement(Input, { type: "date", name: `${filter.name}_max`, value: activeFilters[filter.name].max, handleChange: setRangeFilter })))) : filter.type === 'text' ? (React.createElement(Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
168
287
|
React.createElement(FilterInputWrapper, null,
|
|
169
|
-
React.createElement(Input, { type: "
|
|
288
|
+
React.createElement(Input, { type: "text", name: `${filter.name}_query`, value: (activeFilters[filter.name]?.value && activeFilters[filter.name].value[0]) || '', handleChange: setTextFilter })))) : null) : null)))))))));
|
|
170
289
|
};
|
|
290
|
+
export default Filters;
|
|
@@ -8,20 +8,6 @@ export const getMinValue = (elements, source) => {
|
|
|
8
8
|
export const getMaxValue = (elements, source) => {
|
|
9
9
|
return Math.max(...elements.map((item) => item[source]));
|
|
10
10
|
};
|
|
11
|
-
export const setTableFilterSet = (headers, elements) => {
|
|
12
|
-
const filterSetting = [];
|
|
13
|
-
headers.forEach((filter) => {
|
|
14
|
-
filterSetting.push({
|
|
15
|
-
label: filter.name,
|
|
16
|
-
name: filter.valueSource,
|
|
17
|
-
type: filter.filterType ? filter.filterType : 'select',
|
|
18
|
-
allowValues: getUniqueValues(elements, filter.valueSource),
|
|
19
|
-
min: getMinValue(elements, filter.valueSource),
|
|
20
|
-
max: getMaxValue(elements, filter.valueSource),
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
return filterSetting;
|
|
24
|
-
};
|
|
25
11
|
export const applyFiltersToTable = (elements, filters) => {
|
|
26
12
|
let filtered = [...elements];
|
|
27
13
|
filters.forEach((filter) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
|
2
2
|
import { ThemeProvider } from 'styled-components';
|
|
3
3
|
import { TableHead, TableRow, TableWrapper } from './Table.styles';
|
|
4
4
|
import { mainTheme } from '../../Theme';
|
|
@@ -6,10 +6,20 @@ import { applySort, setSortParams } from './tableHelper';
|
|
|
6
6
|
import { HeaderCell } from './HeaderCell';
|
|
7
7
|
import { Cell } from './Cell';
|
|
8
8
|
import { Pagination } from '../Pagination';
|
|
9
|
+
import { Filters } from '../Filters';
|
|
10
|
+
import { TextAccent } from '../Typography';
|
|
9
11
|
export const Table = ({ theme = mainTheme, headers, elements, hover = true, selectable = true, sortable = true, sort = {
|
|
10
12
|
name: '',
|
|
11
13
|
order: 'none',
|
|
12
14
|
}, pageSize = 10, ifPagination = false, moreActions = [], onRowClick, }) => {
|
|
15
|
+
const initialElementsRef = useRef(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!initialElementsRef.current && Array.isArray(elements) && elements.length > 0) {
|
|
18
|
+
initialElementsRef.current = elements.slice();
|
|
19
|
+
}
|
|
20
|
+
setTableProps((prev) => ({ ...prev, elements: Array.isArray(elements) ? elements : [] }));
|
|
21
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
|
+
}, [elements]);
|
|
13
23
|
const checkHeaders = () => {
|
|
14
24
|
const tableHeaders = [...headers];
|
|
15
25
|
if (moreActions.length > 0) {
|
|
@@ -49,7 +59,6 @@ export const Table = ({ theme = mainTheme, headers, elements, hover = true, sele
|
|
|
49
59
|
});
|
|
50
60
|
}
|
|
51
61
|
};
|
|
52
|
-
// PAGINACJA
|
|
53
62
|
const [currentPage, setCurrentPage] = useState(1);
|
|
54
63
|
const [currentPageSize, setCurrentPageSize] = useState(pageSize || 10);
|
|
55
64
|
const totalPages = Math.ceil(tableProps.elements.length / currentPageSize);
|
|
@@ -57,7 +66,28 @@ export const Table = ({ theme = mainTheme, headers, elements, hover = true, sele
|
|
|
57
66
|
useEffect(() => {
|
|
58
67
|
setCurrentPage(1);
|
|
59
68
|
}, [elements, currentPageSize]);
|
|
69
|
+
const [noResultsMessage, setNoResultsMessage] = useState(null);
|
|
70
|
+
const handleApplyFilters = useCallback((filteredElements) => {
|
|
71
|
+
setTableProps((prev) => ({
|
|
72
|
+
...prev,
|
|
73
|
+
elements: filteredElements,
|
|
74
|
+
}));
|
|
75
|
+
setCurrentPage(1);
|
|
76
|
+
setNoResultsMessage(filteredElements && filteredElements.length === 0 ? 'Nie ma żadnych wyników' : null);
|
|
77
|
+
}, [setCurrentPage, setTableProps]);
|
|
78
|
+
const [filtersClearSignal, setFiltersClearSignal] = useState(0);
|
|
79
|
+
const handleClearFilters = useCallback(() => {
|
|
80
|
+
setFiltersClearSignal((s) => s + 1);
|
|
81
|
+
const full = (initialElementsRef.current && initialElementsRef.current.length > 0)
|
|
82
|
+
? initialElementsRef.current
|
|
83
|
+
: (Array.isArray(elements) ? elements : []);
|
|
84
|
+
setTableProps((prev) => ({ ...prev, elements: Array.isArray(full) ? full.slice() : [] }));
|
|
85
|
+
setCurrentPage(1);
|
|
86
|
+
setNoResultsMessage(null);
|
|
87
|
+
}, [elements, setCurrentPage, setNoResultsMessage]);
|
|
60
88
|
return (React.createElement(ThemeProvider, { theme: theme },
|
|
89
|
+
React.createElement("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 12 } },
|
|
90
|
+
React.createElement(Filters, { title: "Select filters", labelConfirm: "Apply", labelClose: "Cancel", labelClearAll: "Clear", headers: headers, elements: initialElementsRef.current && initialElementsRef.current.length > 0 ? initialElementsRef.current : elements, fullElements: initialElementsRef.current && initialElementsRef.current.length > 0 ? initialElementsRef.current : elements, handleSubmitFilters: handleApplyFilters, externalClearSignal: filtersClearSignal, onClear: handleClearFilters })),
|
|
61
91
|
React.createElement(TableWrapper, { cellPadding: "0", cellSpacing: "0" },
|
|
62
92
|
React.createElement(TableHead, null,
|
|
63
93
|
React.createElement(TableRow, { hover: false, selectable: false, active: false }, tableProps.headers.map((header) => (React.createElement(HeaderCell, { key: `header_${header.name}`, header: header, sortable: sortable, handleSort: handleHeaderCellClick, sort: tableProps.sort }))))),
|
|
@@ -66,5 +96,7 @@ export const Table = ({ theme = mainTheme, headers, elements, hover = true, sele
|
|
|
66
96
|
return (React.createElement(Cell, { key: `cell_${header.name}_${item.id}`, header: header, moreActions: moreActions, item: item, theme: theme, marked: item.marked && index === 0, isDisabled: item.disabled }));
|
|
67
97
|
})));
|
|
68
98
|
}))),
|
|
99
|
+
noResultsMessage && (React.createElement("div", { style: { padding: '8px 12px', textAlign: 'center' } },
|
|
100
|
+
React.createElement(TextAccent, null, noResultsMessage))),
|
|
69
101
|
ifPagination && (React.createElement(Pagination, { currentPage: currentPage, totalPages: totalPages, pageSize: currentPageSize, onPageChange: setCurrentPage, onPageSizeChange: setCurrentPageSize }))));
|
|
70
102
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { orderBy } from 'lodash';
|
|
2
|
-
import { applyFiltersToTable } from '../Filters';
|
|
3
2
|
export const setSortParams = (target, order, sort) => {
|
|
4
3
|
const newSort = {
|
|
5
4
|
name: target,
|
|
@@ -14,13 +13,6 @@ export const applySort = (sort, elements) => {
|
|
|
14
13
|
}
|
|
15
14
|
return sorted;
|
|
16
15
|
};
|
|
17
|
-
export const setElements = (elements, sort, filters) => {
|
|
18
|
-
let tableElements = [...applyFiltersToTable(elements, filters)];
|
|
19
|
-
if (sort.name !== '') {
|
|
20
|
-
tableElements = applySort(sort, tableElements);
|
|
21
|
-
}
|
|
22
|
-
return tableElements;
|
|
23
|
-
};
|
|
24
16
|
export const getValueFormScope = (item, valuesScope) => {
|
|
25
17
|
return valuesScope.find((_value) => _value.key === item)?.value || '';
|
|
26
18
|
};
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
|
|
2
|
+
interface IHeader {
|
|
3
3
|
name: string;
|
|
4
|
-
valueSource
|
|
4
|
+
valueSource?: string;
|
|
5
5
|
date?: boolean;
|
|
6
|
-
|
|
6
|
+
isCount?: boolean;
|
|
7
|
+
scope?: Array<{
|
|
8
|
+
key?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
}>;
|
|
7
12
|
}
|
|
8
13
|
export interface IApplyFilterResults {
|
|
9
14
|
name: string;
|
|
@@ -13,6 +18,15 @@ export interface IApplyFilterResults {
|
|
|
13
18
|
max?: number;
|
|
14
19
|
}
|
|
15
20
|
export interface IFilterProps {
|
|
21
|
+
collapsible: boolean;
|
|
22
|
+
valueSource?: string;
|
|
23
|
+
date?: boolean;
|
|
24
|
+
isCount?: boolean;
|
|
25
|
+
scope?: Array<{
|
|
26
|
+
key?: string;
|
|
27
|
+
value?: string;
|
|
28
|
+
label?: string;
|
|
29
|
+
}>;
|
|
16
30
|
label: string;
|
|
17
31
|
name: string;
|
|
18
32
|
type: 'select' | 'range' | string;
|
|
@@ -25,9 +39,14 @@ interface IFiltersProps {
|
|
|
25
39
|
title: string;
|
|
26
40
|
labelConfirm: string;
|
|
27
41
|
labelClose: string;
|
|
28
|
-
filters
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
filters?: IFilterProps[];
|
|
43
|
+
headers?: IHeader[];
|
|
44
|
+
elements?: any[];
|
|
45
|
+
fullElements?: any[];
|
|
46
|
+
labelClearAll?: string;
|
|
47
|
+
handleSubmitFilters: (filteredElements: any[]) => void;
|
|
48
|
+
externalClearSignal?: number;
|
|
49
|
+
onClear?: () => void;
|
|
31
50
|
}
|
|
32
51
|
export declare const Filters: FC<IFiltersProps>;
|
|
33
|
-
export
|
|
52
|
+
export default Filters;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { IApplyFilterResults
|
|
1
|
+
import { IApplyFilterResults } from './Filters';
|
|
2
2
|
export type TAllowValues = 'string' | 'number';
|
|
3
3
|
export declare const getUniqueValues: (elements: any, source: string) => string[];
|
|
4
4
|
export declare const getMinValue: (elements: any, source: string) => number;
|
|
5
5
|
export declare const getMaxValue: (elements: any, source: string) => number;
|
|
6
|
-
export declare const setTableFilterSet: (headers: IFilterConfigProps[], elements: any) => IFilterProps[];
|
|
7
6
|
export declare const applyFiltersToTable: (elements: any, filters: IApplyFilterResults[]) => any[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { InputType, IFormElement } from '../../types';
|
|
3
3
|
export interface IInputProps extends IFormElement {
|
|
4
|
-
type?: InputType;
|
|
4
|
+
type?: InputType | 'date';
|
|
5
5
|
handleChange: (name: string, value: string | number) => void;
|
|
6
6
|
placeholder?: string;
|
|
7
7
|
min?: number;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { IApplyFilterResults } from '../Filters';
|
|
2
1
|
import { ITableScopeProps, ITableSortProps } from './Table';
|
|
3
2
|
export declare const setSortParams: (target: string, order: string, sort: ITableSortProps) => ITableSortProps;
|
|
4
3
|
export declare const applySort: (sort: ITableSortProps, elements: any) => any;
|
|
5
|
-
export declare const setElements: (elements: any, sort: ITableSortProps, filters: IApplyFilterResults[]) => any;
|
|
6
4
|
export declare const getValueFormScope: (item: string, valuesScope: ITableScopeProps[]) => string;
|