@bit.rhplus/ui2.filter-panel 0.0.5 → 0.0.7

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.
@@ -0,0 +1,6 @@
1
+ export function buildValueLabelsMap(filterConfigs: Object): Object;
2
+ export function buildFieldLabelsMap(filterConfigs: Object): Object;
3
+ export function formatFilterValue(value: any, fieldName: string, valueLabelsMap?: Object, moduleLabels?: Object, fieldKey?: string): string;
4
+ export function normalizeFilterValueForBackend(value: any): any;
5
+ export function throttle(func: Function, wait: number): Function;
6
+ export function debounce(func: Function, wait: number): Function;
@@ -0,0 +1,184 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Sdílené utility funkce pro práci s filtry v Master komponentách
4
+ *
5
+ * Tyto funkce jsou memoizovány a používány jak v Desktop tak Mobile verzích
6
+ * pro zajištění konzistentního chování a lepšího výkonu.
7
+ */
8
+ /**
9
+ * Vytvoří mapu hodnot pro převod value → label z filterConfigs
10
+ * @param {Object} filterConfigs - Konfigurace filtrů
11
+ * @returns {Object} Mapa ve formátu { field: { value: label } }
12
+ */
13
+ export const buildValueLabelsMap = (filterConfigs) => {
14
+ if (!filterConfigs)
15
+ return {};
16
+ const map = {};
17
+ Object.values(filterConfigs).forEach(config => {
18
+ config.fields.forEach(field => {
19
+ if (field.type === 'select' && field.options) {
20
+ map[field.field] = {};
21
+ field.options.forEach(option => {
22
+ map[field.field][option.value] = option.label;
23
+ });
24
+ }
25
+ });
26
+ });
27
+ return map;
28
+ };
29
+ /**
30
+ * Vytvoří mapu labelů pro fieldy z filterConfigs
31
+ * @param {Object} filterConfigs - Konfigurace filtrů
32
+ * @returns {Object} Mapa ve formátu { field: label }
33
+ */
34
+ export const buildFieldLabelsMap = (filterConfigs) => {
35
+ if (!filterConfigs)
36
+ return {};
37
+ const labels = {};
38
+ Object.values(filterConfigs).forEach(config => {
39
+ config.fields.forEach(field => {
40
+ labels[field.field] = field.label;
41
+ });
42
+ });
43
+ return labels;
44
+ };
45
+ /**
46
+ * Formátuje hodnotu filtru pro zobrazení uživateli
47
+ * @param {*} value - Hodnota k formátování
48
+ * @param {string} fieldName - Název pole
49
+ * @param {Object} valueLabelsMap - Mapa hodnot na labely
50
+ * @param {Object} moduleLabels - Dodatečné modulo labely
51
+ * @param {string} fieldKey - Klíč pro moduleLabels lookup
52
+ * @returns {string} Zformátovaná hodnota
53
+ */
54
+ export const formatFilterValue = (value, fieldName, valueLabelsMap = {}, moduleLabels = {}, fieldKey = null) => {
55
+ // Array hodnoty
56
+ if (Array.isArray(value)) {
57
+ if (valueLabelsMap[fieldName]) {
58
+ return value.map(v => valueLabelsMap[fieldName][v] || v).join(', ');
59
+ }
60
+ return value.join(', ');
61
+ }
62
+ // Boolean hodnoty
63
+ if (typeof value === 'boolean') {
64
+ return value ? 'Ano' : 'Ne';
65
+ }
66
+ // Null/undefined
67
+ if (value === null || value === undefined) {
68
+ return '';
69
+ }
70
+ // Module labels (priorita)
71
+ if (fieldKey && moduleLabels[fieldKey]) {
72
+ return moduleLabels[fieldKey];
73
+ }
74
+ // Value labels map
75
+ if (valueLabelsMap[fieldName] && valueLabelsMap[fieldName][value]) {
76
+ return valueLabelsMap[fieldName][value];
77
+ }
78
+ // Datumové hodnoty
79
+ if (value instanceof Date || (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}/.test(value))) {
80
+ try {
81
+ const date = new Date(value);
82
+ return date.toLocaleDateString('cs-CZ');
83
+ }
84
+ catch {
85
+ return String(value);
86
+ }
87
+ }
88
+ return String(value);
89
+ };
90
+ /**
91
+ * Normalizuje hodnotu filtru pro backend (hlavně datumové formáty)
92
+ * @param {*} value - Hodnota k normalizaci
93
+ * @returns {*} Normalizovaná hodnota
94
+ */
95
+ export const normalizeFilterValueForBackend = (value) => {
96
+ if (value === null || value === undefined) {
97
+ return value;
98
+ }
99
+ // Pokud je už Date objekt, převeď na ISO string
100
+ if (value instanceof Date) {
101
+ return value.toISOString();
102
+ }
103
+ // Pokud je string, zkus ho parsovat jako datum
104
+ if (typeof value === 'string') {
105
+ let cleanedValue = value.trim();
106
+ // Odstraň duplicitní časové části (bug fix z původního kódu)
107
+ if (/^\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}/.test(cleanedValue)) {
108
+ cleanedValue = cleanedValue.replace(/(\d{2}:\d{2}:\d{2})\s+\d{2}:\d{2}:\d{2}$/, '$1');
109
+ }
110
+ // Formát: DD/MM/YYYY HH:MM:SS
111
+ const ddmmyyyyWithTime = cleanedValue.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})/);
112
+ if (ddmmyyyyWithTime) {
113
+ const [, day, month, year, hours, minutes, seconds] = ddmmyyyyWithTime;
114
+ const date = new Date(year, month - 1, day, hours, minutes, seconds);
115
+ if (!isNaN(date.getTime())) {
116
+ return date.toISOString();
117
+ }
118
+ }
119
+ // Formát: DD/MM/YYYY
120
+ const ddmmyyyy = cleanedValue.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
121
+ if (ddmmyyyy) {
122
+ const [, day, month, year] = ddmmyyyy;
123
+ const date = new Date(year, month - 1, day);
124
+ if (!isNaN(date.getTime())) {
125
+ return date.toISOString();
126
+ }
127
+ }
128
+ // ISO formát: YYYY-MM-DD
129
+ if (/^\d{4}-\d{2}-\d{2}/.test(cleanedValue)) {
130
+ try {
131
+ const date = new Date(cleanedValue);
132
+ if (!isNaN(date.getTime())) {
133
+ return date.toISOString();
134
+ }
135
+ }
136
+ catch {
137
+ return value;
138
+ }
139
+ }
140
+ }
141
+ return value;
142
+ };
143
+ /**
144
+ * Vytvoří throttle funkci pro omezení frekvence volání
145
+ * @param {Function} func - Funkce k throttle
146
+ * @param {number} wait - Čekací doba v ms
147
+ * @returns {Function} Throttled funkce
148
+ */
149
+ export const throttle = (func, wait) => {
150
+ let timeout = null;
151
+ let lastRan = null;
152
+ return function throttled(...args) {
153
+ const now = Date.now();
154
+ if (lastRan && now - lastRan < wait) {
155
+ // Pokud jsme volali příliš brzy, naplánuj volání na později
156
+ clearTimeout(timeout);
157
+ timeout = setTimeout(() => {
158
+ lastRan = now;
159
+ func.apply(this, args);
160
+ }, wait - (now - lastRan));
161
+ }
162
+ else {
163
+ // První volání nebo už uplynul čas
164
+ lastRan = now;
165
+ func.apply(this, args);
166
+ }
167
+ };
168
+ };
169
+ /**
170
+ * Vytvoří debounce funkci pro odložení volání
171
+ * @param {Function} func - Funkce k debounce
172
+ * @param {number} wait - Čekací doba v ms
173
+ * @returns {Function} Debounced funkce
174
+ */
175
+ export const debounce = (func, wait) => {
176
+ let timeout = null;
177
+ return function debounced(...args) {
178
+ clearTimeout(timeout);
179
+ timeout = setTimeout(() => {
180
+ func.apply(this, args);
181
+ }, wait);
182
+ };
183
+ };
184
+ //# sourceMappingURL=filterHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterHelpers.js","sourceRoot":"","sources":["../filterHelpers.js"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export default FilterPanel;
2
- declare function FilterPanel({ filters, onRemoveFilter, onClearAll, onRefresh, fieldLabels, valueLabelsMap, alwaysVisible, isLoading, current, pageSize, total, pageSizeOptions, onPageChange, onPageSizeChange, showPagination, }: {
1
+ declare const _default: React.MemoExoticComponent<({ filters, onRemoveFilter, onClearAll, onRefresh, fieldLabels, valueLabelsMap, alwaysVisible, isLoading, current, pageSize, total, pageSizeOptions, onPageChange, onPageSizeChange, showPagination, filterFields, onApplyFilters, initialFilterValues, accessToken, }: {
3
2
  filters?: any[] | undefined;
4
3
  onRemoveFilter: any;
5
4
  onClearAll: any;
@@ -15,4 +14,11 @@ declare function FilterPanel({ filters, onRemoveFilter, onClearAll, onRefresh, f
15
14
  onPageChange: any;
16
15
  onPageSizeChange: any;
17
16
  showPagination?: boolean | undefined;
18
- }): import("react/jsx-runtime").JSX.Element | null;
17
+ filterFields?: any[] | undefined;
18
+ onApplyFilters: any;
19
+ initialFilterValues?: {} | undefined;
20
+ accessToken: any;
21
+ }) => import("react/jsx-runtime").JSX.Element | null>;
22
+ export default _default;
23
+ import React from 'react';
24
+ export { buildValueLabelsMap, buildFieldLabelsMap, formatFilterValue, normalizeFilterValueForBackend, throttle, debounce } from "./filterHelpers";
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable */
3
- import React from 'react';
4
- import { Tag, Space, Button, Spin, Pagination } from 'antd';
5
- import { CloseOutlined, FilterOutlined, LoadingOutlined, ReloadOutlined } from '@ant-design/icons';
3
+ import React, { useState, useCallback, useMemo } from 'react';
4
+ import { Tag, Space, Button, Spin, Pagination, Row, Col, Input, Select, Radio } from 'antd';
5
+ import { CloseOutlined, FilterOutlined, LoadingOutlined, ReloadOutlined, DownOutlined, FilterFilled } from '@ant-design/icons';
6
6
  import { filterCondition } from '@bit.rhplus/ui2.filter';
7
+ import { formatFilterValue } from './filterHelpers';
8
+ // Konstanty extrahované mimo komponentu pro stabilní references
7
9
  const conditionLabels = {
8
10
  [filterCondition.equals]: 'je',
9
11
  [filterCondition.notEquals]: 'není',
@@ -19,68 +21,187 @@ const conditionLabels = {
19
21
  [filterCondition.in]: 'obsahuje',
20
22
  [filterCondition.notIn]: 'neobsahuje',
21
23
  };
22
- const formatValue = (value, fieldName, valueLabelsMap) => {
23
- if (Array.isArray(value)) {
24
- if (valueLabelsMap[fieldName]) {
25
- return value.map(v => valueLabelsMap[fieldName][v] || v).join(', ');
26
- }
27
- return value.join(', ');
28
- }
29
- if (typeof value === 'boolean') {
30
- return value ? 'Ano' : 'Ne';
31
- }
32
- if (value === null || value === undefined) {
33
- return '';
34
- }
35
- if (valueLabelsMap[fieldName] && valueLabelsMap[fieldName][value]) {
36
- return valueLabelsMap[fieldName][value];
37
- }
38
- return String(value);
39
- };
40
- const FilterPanel = ({ filters = [], onRemoveFilter, onClearAll, onRefresh, fieldLabels = {}, valueLabelsMap = {}, alwaysVisible = false, isLoading = false, current = 1, pageSize = 100, total = 0, pageSizeOptions = ['100', '200', '300', '500', '1000'], onPageChange, onPageSizeChange, showPagination = true, }) => {
41
- if (!alwaysVisible && (!filters || filters.length === 0)) {
24
+ // Konstantní loading ikona
25
+ const LOADING_ICON = _jsx(LoadingOutlined, { style: { fontSize: 18, color: '#1890ff', fontWeight: 900, strokeWidth: 4 }, spin: true });
26
+ const FilterPanel = ({ filters = [], onRemoveFilter, onClearAll, onRefresh, fieldLabels = {}, valueLabelsMap = {}, alwaysVisible = false, isLoading = false, current = 1, pageSize = 100, total = 0, pageSizeOptions = ['100', '200', '300', '500', '1000'], onPageChange, onPageSizeChange, showPagination = true, filterFields = [], onApplyFilters, initialFilterValues = {}, accessToken, }) => {
27
+ const [expanded, setExpanded] = useState(false);
28
+ const [filterValues, setFilterValues] = useState(initialFilterValues);
29
+ const [moduleLabels, setModuleLabels] = useState({});
30
+ // Memoizované hodnoty pro optimalizaci
31
+ const hasFilters = useMemo(() => filters && filters.length > 0, [filters]);
32
+ const hasFilterFields = useMemo(() => filterFields && filterFields.length > 0, [filterFields]);
33
+ // Early return pokud není co zobrazit
34
+ if (!alwaysVisible && !hasFilters) {
42
35
  return null;
43
36
  }
44
- const hasFilters = filters && filters.length > 0;
45
- const loadingIcon = _jsx(LoadingOutlined, { style: { fontSize: 18, color: '#1890ff', fontWeight: 900, strokeWidth: 4 }, spin: true });
46
- return (_jsxs("div", { style: {
47
- display: 'flex',
48
- justifyContent: 'space-between',
49
- alignItems: 'center',
50
- padding: '7px 0px 7px 7px',
51
- borderRadius: '4px',
52
- backgroundColor: '#fafafa',
53
- borderTop: '1px solid #f0f0f0',
54
- }, children: [_jsxs(Space, { style: { lineHeight: 'normal', flexWrap: 'wrap' }, size: [8, 8], children: [_jsx(Button, { type: "text", size: "small", icon: isLoading ? _jsx(Spin, { indicator: loadingIcon }) : _jsx(ReloadOutlined, {}), onClick: onRefresh, disabled: isLoading, style: {
55
- color: '#1890ff',
56
- padding: '0 4px',
57
- height: '22px',
58
- minWidth: '22px'
59
- } }), hasFilters ? (filters.map((filter, index) => {
60
- const fieldLabel = filter.label || fieldLabels[filter.field] || filter.field;
61
- const conditionLabel = conditionLabels[filter.condition] || 'filtr';
62
- const valueLabel = formatValue(filter.value, filter.field, valueLabelsMap);
63
- const displayText = filter.text || (valueLabel
64
- ? `${fieldLabel} ${conditionLabel} (${valueLabel})`
65
- : `${fieldLabel} ${conditionLabel}`);
66
- return (_jsx(Tag, { closable: true, onClose: (e) => {
67
- e.preventDefault();
68
- if (onRemoveFilter) {
69
- onRemoveFilter(index);
70
- }
71
- }, style: {
72
- backgroundColor: '#e6f7ff',
73
- borderColor: '#91d5ff',
74
- color: '#0050b3',
75
- fontSize: '13px',
76
- padding: '2px 8px',
77
- margin: 0,
78
- }, children: displayText }, `${filter.field}-${index}`));
79
- })) : (_jsx("span", { style: { color: '#999', fontSize: '13px' }, children: "\u017D\u00E1dn\u00E9 aktivn\u00ED filtry" }))] }), _jsxs(Space, { style: { lineHeight: 'normal', paddingRight: '7px' }, size: [16, 8], children: [hasFilters && onClearAll && (_jsx(Button, { type: "link", size: "small", onClick: onClearAll, style: { color: '#999' }, children: "Vymazat v\u0161e" })), showPagination && (_jsx(Pagination, { size: "small", current: current, pageSize: pageSize, total: total, pageSizeOptions: pageSizeOptions, showSizeChanger: true, showQuickJumper: true, showTotal: (total, range) => `${range[0]}-${range[1]} z ${total}`, onChange: onPageChange, onShowSizeChange: (current, size) => {
80
- if (onPageSizeChange) {
81
- onPageSizeChange(current, size);
82
- }
83
- }, style: { marginBottom: 0 } }))] })] }));
37
+ const handleFieldChange = useCallback((fieldKey, value, displayValue) => {
38
+ setFilterValues(prev => ({
39
+ ...prev,
40
+ [fieldKey]: value
41
+ }));
42
+ if (displayValue !== undefined) {
43
+ setModuleLabels(prev => ({
44
+ ...prev,
45
+ [fieldKey]: displayValue
46
+ }));
47
+ }
48
+ }, []);
49
+ const handleApplyFilters = useCallback(() => {
50
+ const appliedFilters = filterFields
51
+ .filter(field => {
52
+ const fieldKey = `${field.field}_${field.condition}`;
53
+ const value = filterValues[fieldKey];
54
+ if (Array.isArray(value)) {
55
+ return value.length > 0;
56
+ }
57
+ return value !== undefined && value !== '' && value !== null;
58
+ })
59
+ .map(field => {
60
+ const fieldKey = `${field.field}_${field.condition}`;
61
+ const value = filterValues[fieldKey];
62
+ return {
63
+ field: field.field,
64
+ condition: field.condition,
65
+ value: value,
66
+ label: field.label
67
+ };
68
+ });
69
+ if (onApplyFilters) {
70
+ onApplyFilters(appliedFilters);
71
+ }
72
+ setExpanded(false);
73
+ }, [filterFields, filterValues, onApplyFilters]);
74
+ const handleRefreshOrFilter = useCallback(() => {
75
+ if (expanded) {
76
+ handleApplyFilters();
77
+ }
78
+ else {
79
+ onRefresh();
80
+ }
81
+ }, [expanded, handleApplyFilters, onRefresh]);
82
+ const renderField = useCallback((field) => {
83
+ const fieldKey = `${field.field}_${field.condition}`;
84
+ if (field.type === 'select') {
85
+ return (_jsx(Select, { placeholder: `Vyber ${field.label}`, allowClear: true, value: filterValues[fieldKey], onChange: (value) => handleFieldChange(fieldKey, value), options: field.options, style: { width: '100%' }, getPopupContainer: () => document.body, dropdownStyle: { zIndex: 9999 } }));
86
+ }
87
+ if (field.type === 'date') {
88
+ return (_jsx(Input, { type: "date", placeholder: field.label, value: filterValues[fieldKey] || '', onChange: (e) => handleFieldChange(fieldKey, e.target.value) }));
89
+ }
90
+ if (field.type === 'radio') {
91
+ return (_jsx(Radio.Group, { value: filterValues[fieldKey], onChange: (e) => handleFieldChange(fieldKey, e.target.value), options: field.options }));
92
+ }
93
+ if (field.type === 'module' && field.component) {
94
+ const ModuleComponent = field.component;
95
+ return (_jsx(ModuleComponent, { value: filterValues[fieldKey], onChange: (value, selectedItem) => {
96
+ let displayValue = value;
97
+ if (selectedItem && field.moduleDefinition) {
98
+ const labelField = field.moduleDefinition.labelField || 'name';
99
+ displayValue = selectedItem[labelField] || field.moduleDefinition.getDisplayValue?.(selectedItem) || value;
100
+ }
101
+ handleFieldChange(fieldKey, value, displayValue);
102
+ }, placeholder: `Vyber ${field.label}`, accessToken: accessToken }));
103
+ }
104
+ return (_jsx(Input, { placeholder: `Zadej ${field.label}`, allowClear: true, value: filterValues[fieldKey] || '', onChange: (e) => handleFieldChange(fieldKey, e.target.value) }));
105
+ }, [filterValues, handleFieldChange, accessToken]);
106
+ return (_jsxs("div", { style: { position: 'relative', zIndex: 10 }, children: [_jsxs("div", { style: {
107
+ display: 'flex',
108
+ justifyContent: 'space-between',
109
+ alignItems: 'center',
110
+ padding: '7px 0px 7px 7px',
111
+ borderRadius: '4px',
112
+ backgroundColor: '#fafafa',
113
+ borderTop: '1px solid #f0f0f0',
114
+ }, children: [_jsxs(Space, { style: { lineHeight: 'normal', flexWrap: 'wrap' }, size: [8, 8], children: [hasFilterFields && (_jsx(Button, { type: "text", size: "small", icon: _jsx(DownOutlined, { style: {
115
+ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)',
116
+ transition: 'transform 0.3s ease'
117
+ } }), onClick: () => setExpanded(!expanded), style: {
118
+ color: '#1890ff',
119
+ padding: '0 4px',
120
+ height: '22px',
121
+ minWidth: '22px'
122
+ } })), _jsx(Button, { type: "text", size: "small", icon: isLoading ? _jsx(Spin, { indicator: LOADING_ICON }) : (expanded ? _jsx(FilterFilled, {}) : _jsx(ReloadOutlined, {})), onClick: handleRefreshOrFilter, disabled: isLoading, style: {
123
+ color: '#1890ff',
124
+ padding: '0 4px',
125
+ height: '22px',
126
+ minWidth: '22px'
127
+ } }), hasFilters ? (filters.map((filter, index) => {
128
+ const fieldLabel = filter.label || fieldLabels[filter.field] || filter.field;
129
+ const conditionLabel = conditionLabels[filter.condition] || 'filtr';
130
+ const fieldKey = `${filter.field}_${filter.condition}`;
131
+ const valueLabel = formatFilterValue(filter.value, filter.field, valueLabelsMap, moduleLabels, fieldKey);
132
+ const displayText = filter.text || (valueLabel
133
+ ? `${fieldLabel} ${conditionLabel} (${valueLabel})`
134
+ : `${fieldLabel} ${conditionLabel}`);
135
+ return (_jsx(Tag, { closable: true, onClose: (e) => {
136
+ e.preventDefault();
137
+ if (onRemoveFilter) {
138
+ onRemoveFilter(index);
139
+ }
140
+ }, style: {
141
+ backgroundColor: '#e6f7ff',
142
+ borderColor: '#91d5ff',
143
+ color: '#0050b3',
144
+ fontSize: '13px',
145
+ padding: '2px 8px',
146
+ margin: 0,
147
+ }, children: displayText }, `${filter.field}-${index}`));
148
+ })) : (_jsx("span", { style: { color: '#999', fontSize: '13px' }, children: "\u017D\u00E1dn\u00E9 aktivn\u00ED filtry" }))] }), _jsxs(Space, { style: { lineHeight: 'normal', paddingRight: '7px' }, size: [16, 8], children: [hasFilters && onClearAll && (_jsx(Button, { type: "link", size: "small", onClick: onClearAll, style: { color: '#999' }, children: "Vymazat v\u0161e" })), showPagination && (_jsx(Pagination, { size: "small", current: current, pageSize: pageSize, total: total, pageSizeOptions: pageSizeOptions, showSizeChanger: true, showQuickJumper: true, showTotal: (total, range) => `${range[0]}-${range[1]} z ${total}`, onChange: onPageChange, onShowSizeChange: (current, size) => {
149
+ if (onPageSizeChange) {
150
+ onPageSizeChange(current, size);
151
+ }
152
+ }, style: { marginBottom: 0 } }))] })] }), _jsx("div", { style: {
153
+ maxHeight: expanded ? '500px' : '0px',
154
+ overflow: 'hidden',
155
+ transition: 'max-height 0.3s ease-in-out',
156
+ position: 'relative',
157
+ zIndex: 100,
158
+ }, children: _jsx("div", { style: {
159
+ padding: '16px',
160
+ backgroundColor: '#f5f5f5',
161
+ borderTop: '1px solid #f0f0f0',
162
+ borderBottom: '1px solid #f0f0f0',
163
+ }, children: _jsx("div", { style: {
164
+ display: 'flex',
165
+ flexDirection: 'row',
166
+ flexWrap: 'wrap',
167
+ gap: '16px',
168
+ alignItems: 'flex-start'
169
+ }, children: filterFields.map((field) => {
170
+ const fieldKey = `${field.field}_${field.condition}`;
171
+ return (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px', width: '287px' }, children: [_jsxs("div", { style: {
172
+ width: '100px',
173
+ fontWeight: '500',
174
+ fontSize: '13px',
175
+ color: '#333',
176
+ textAlign: 'right',
177
+ flexShrink: 0
178
+ }, children: [field.label, ":"] }), _jsx("div", { style: { width: '175px' }, children: renderField(field) })] }, fieldKey));
179
+ }) }) }) })] }));
180
+ };
181
+ // Custom comparison funkce pro React.memo
182
+ const areEqual = (prevProps, nextProps) => {
183
+ return (prevProps.filters === nextProps.filters &&
184
+ prevProps.isLoading === nextProps.isLoading &&
185
+ prevProps.current === nextProps.current &&
186
+ prevProps.pageSize === nextProps.pageSize &&
187
+ prevProps.total === nextProps.total &&
188
+ prevProps.alwaysVisible === nextProps.alwaysVisible &&
189
+ prevProps.showPagination === nextProps.showPagination &&
190
+ prevProps.fieldLabels === nextProps.fieldLabels &&
191
+ prevProps.valueLabelsMap === nextProps.valueLabelsMap &&
192
+ prevProps.filterFields === nextProps.filterFields &&
193
+ prevProps.initialFilterValues === nextProps.initialFilterValues &&
194
+ prevProps.pageSizeOptions === nextProps.pageSizeOptions &&
195
+ prevProps.accessToken === nextProps.accessToken &&
196
+ // Callback props
197
+ prevProps.onRemoveFilter === nextProps.onRemoveFilter &&
198
+ prevProps.onClearAll === nextProps.onClearAll &&
199
+ prevProps.onRefresh === nextProps.onRefresh &&
200
+ prevProps.onPageChange === nextProps.onPageChange &&
201
+ prevProps.onPageSizeChange === nextProps.onPageSizeChange &&
202
+ prevProps.onApplyFilters === nextProps.onApplyFilters);
84
203
  };
85
- export default FilterPanel;
204
+ // Export s React.memo pro optimalizaci re-renderů
205
+ export default React.memo(FilterPanel, areEqual);
206
+ export { buildValueLabelsMap, buildFieldLabelsMap, formatFilterValue, normalizeFilterValueForBackend, throttle, debounce } from './filterHelpers';
86
207
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ /* eslint-disable */
2
+
3
+ /**
4
+ * Sdílené utility funkce pro práci s filtry v Master komponentách
5
+ *
6
+ * Tyto funkce jsou memoizovány a používány jak v Desktop tak Mobile verzích
7
+ * pro zajištění konzistentního chování a lepšího výkonu.
8
+ */
9
+
10
+ /**
11
+ * Vytvoří mapu hodnot pro převod value → label z filterConfigs
12
+ * @param {Object} filterConfigs - Konfigurace filtrů
13
+ * @returns {Object} Mapa ve formátu { field: { value: label } }
14
+ */
15
+ export const buildValueLabelsMap = (filterConfigs) => {
16
+ if (!filterConfigs) return {};
17
+ const map = {};
18
+
19
+ Object.values(filterConfigs).forEach(config => {
20
+ config.fields.forEach(field => {
21
+ if (field.type === 'select' && field.options) {
22
+ map[field.field] = {};
23
+ field.options.forEach(option => {
24
+ map[field.field][option.value] = option.label;
25
+ });
26
+ }
27
+ });
28
+ });
29
+
30
+ return map;
31
+ };
32
+
33
+ /**
34
+ * Vytvoří mapu labelů pro fieldy z filterConfigs
35
+ * @param {Object} filterConfigs - Konfigurace filtrů
36
+ * @returns {Object} Mapa ve formátu { field: label }
37
+ */
38
+ export const buildFieldLabelsMap = (filterConfigs) => {
39
+ if (!filterConfigs) return {};
40
+ const labels = {};
41
+
42
+ Object.values(filterConfigs).forEach(config => {
43
+ config.fields.forEach(field => {
44
+ labels[field.field] = field.label;
45
+ });
46
+ });
47
+
48
+ return labels;
49
+ };
50
+
51
+ /**
52
+ * Formátuje hodnotu filtru pro zobrazení uživateli
53
+ * @param {*} value - Hodnota k formátování
54
+ * @param {string} fieldName - Název pole
55
+ * @param {Object} valueLabelsMap - Mapa hodnot na labely
56
+ * @param {Object} moduleLabels - Dodatečné modulo labely
57
+ * @param {string} fieldKey - Klíč pro moduleLabels lookup
58
+ * @returns {string} Zformátovaná hodnota
59
+ */
60
+ export const formatFilterValue = (value, fieldName, valueLabelsMap = {}, moduleLabels = {}, fieldKey = null) => {
61
+ // Array hodnoty
62
+ if (Array.isArray(value)) {
63
+ if (valueLabelsMap[fieldName]) {
64
+ return value.map(v => valueLabelsMap[fieldName][v] || v).join(', ');
65
+ }
66
+ return value.join(', ');
67
+ }
68
+
69
+ // Boolean hodnoty
70
+ if (typeof value === 'boolean') {
71
+ return value ? 'Ano' : 'Ne';
72
+ }
73
+
74
+ // Null/undefined
75
+ if (value === null || value === undefined) {
76
+ return '';
77
+ }
78
+
79
+ // Module labels (priorita)
80
+ if (fieldKey && moduleLabels[fieldKey]) {
81
+ return moduleLabels[fieldKey];
82
+ }
83
+
84
+ // Value labels map
85
+ if (valueLabelsMap[fieldName] && valueLabelsMap[fieldName][value]) {
86
+ return valueLabelsMap[fieldName][value];
87
+ }
88
+
89
+ // Datumové hodnoty
90
+ if (value instanceof Date || (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}/.test(value))) {
91
+ try {
92
+ const date = new Date(value);
93
+ return date.toLocaleDateString('cs-CZ');
94
+ } catch {
95
+ return String(value);
96
+ }
97
+ }
98
+
99
+ return String(value);
100
+ };
101
+
102
+ /**
103
+ * Normalizuje hodnotu filtru pro backend (hlavně datumové formáty)
104
+ * @param {*} value - Hodnota k normalizaci
105
+ * @returns {*} Normalizovaná hodnota
106
+ */
107
+ export const normalizeFilterValueForBackend = (value) => {
108
+ if (value === null || value === undefined) {
109
+ return value;
110
+ }
111
+
112
+ // Pokud je už Date objekt, převeď na ISO string
113
+ if (value instanceof Date) {
114
+ return value.toISOString();
115
+ }
116
+
117
+ // Pokud je string, zkus ho parsovat jako datum
118
+ if (typeof value === 'string') {
119
+ let cleanedValue = value.trim();
120
+
121
+ // Odstraň duplicitní časové části (bug fix z původního kódu)
122
+ if (/^\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}/.test(cleanedValue)) {
123
+ cleanedValue = cleanedValue.replace(/(\d{2}:\d{2}:\d{2})\s+\d{2}:\d{2}:\d{2}$/, '$1');
124
+ }
125
+
126
+ // Formát: DD/MM/YYYY HH:MM:SS
127
+ const ddmmyyyyWithTime = cleanedValue.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})/);
128
+ if (ddmmyyyyWithTime) {
129
+ const [, day, month, year, hours, minutes, seconds] = ddmmyyyyWithTime;
130
+ const date = new Date(year, month - 1, day, hours, minutes, seconds);
131
+ if (!isNaN(date.getTime())) {
132
+ return date.toISOString();
133
+ }
134
+ }
135
+
136
+ // Formát: DD/MM/YYYY
137
+ const ddmmyyyy = cleanedValue.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
138
+ if (ddmmyyyy) {
139
+ const [, day, month, year] = ddmmyyyy;
140
+ const date = new Date(year, month - 1, day);
141
+ if (!isNaN(date.getTime())) {
142
+ return date.toISOString();
143
+ }
144
+ }
145
+
146
+ // ISO formát: YYYY-MM-DD
147
+ if (/^\d{4}-\d{2}-\d{2}/.test(cleanedValue)) {
148
+ try {
149
+ const date = new Date(cleanedValue);
150
+ if (!isNaN(date.getTime())) {
151
+ return date.toISOString();
152
+ }
153
+ } catch {
154
+ return value;
155
+ }
156
+ }
157
+ }
158
+
159
+ return value;
160
+ };
161
+
162
+ /**
163
+ * Vytvoří throttle funkci pro omezení frekvence volání
164
+ * @param {Function} func - Funkce k throttle
165
+ * @param {number} wait - Čekací doba v ms
166
+ * @returns {Function} Throttled funkce
167
+ */
168
+ export const throttle = (func, wait) => {
169
+ let timeout = null;
170
+ let lastRan = null;
171
+
172
+ return function throttled(...args) {
173
+ const now = Date.now();
174
+
175
+ if (lastRan && now - lastRan < wait) {
176
+ // Pokud jsme volali příliš brzy, naplánuj volání na později
177
+ clearTimeout(timeout);
178
+ timeout = setTimeout(() => {
179
+ lastRan = now;
180
+ func.apply(this, args);
181
+ }, wait - (now - lastRan));
182
+ } else {
183
+ // První volání nebo už uplynul čas
184
+ lastRan = now;
185
+ func.apply(this, args);
186
+ }
187
+ };
188
+ };
189
+
190
+ /**
191
+ * Vytvoří debounce funkci pro odložení volání
192
+ * @param {Function} func - Funkce k debounce
193
+ * @param {number} wait - Čekací doba v ms
194
+ * @returns {Function} Debounced funkce
195
+ */
196
+ export const debounce = (func, wait) => {
197
+ let timeout = null;
198
+
199
+ return function debounced(...args) {
200
+ clearTimeout(timeout);
201
+ timeout = setTimeout(() => {
202
+ func.apply(this, args);
203
+ }, wait);
204
+ };
205
+ };
package/index.jsx CHANGED
@@ -1,9 +1,11 @@
1
1
  /* eslint-disable */
2
- import React from 'react';
3
- import { Tag, Space, Button, Spin, Pagination } from 'antd';
4
- import { CloseOutlined, FilterOutlined, LoadingOutlined, ReloadOutlined } from '@ant-design/icons';
2
+ import React, { useState, useCallback, useMemo } from 'react';
3
+ import { Tag, Space, Button, Spin, Pagination, Row, Col, Input, Select, Radio } from 'antd';
4
+ import { CloseOutlined, FilterOutlined, LoadingOutlined, ReloadOutlined, DownOutlined, FilterFilled } from '@ant-design/icons';
5
5
  import { filterCondition } from '@bit.rhplus/ui2.filter';
6
+ import { formatFilterValue } from './filterHelpers';
6
7
 
8
+ // Konstanty extrahované mimo komponentu pro stabilní references
7
9
  const conditionLabels = {
8
10
  [filterCondition.equals]: 'je',
9
11
  [filterCondition.notEquals]: 'není',
@@ -20,29 +22,11 @@ const conditionLabels = {
20
22
  [filterCondition.notIn]: 'neobsahuje',
21
23
  };
22
24
 
23
- const formatValue = (value, fieldName, valueLabelsMap) => {
24
- if (Array.isArray(value)) {
25
- if (valueLabelsMap[fieldName]) {
26
- return value.map(v => valueLabelsMap[fieldName][v] || v).join(', ');
27
- }
28
- return value.join(', ');
29
- }
30
- if (typeof value === 'boolean') {
31
- return value ? 'Ano' : 'Ne';
32
- }
33
- if (value === null || value === undefined) {
34
- return '';
35
- }
36
-
37
- if (valueLabelsMap[fieldName] && valueLabelsMap[fieldName][value]) {
38
- return valueLabelsMap[fieldName][value];
39
- }
40
-
41
- return String(value);
42
- };
25
+ // Konstantní loading ikona
26
+ const LOADING_ICON = <LoadingOutlined style={{ fontSize: 18, color: '#1890ff', fontWeight: 900, strokeWidth: 4 }} spin />;
43
27
 
44
- const FilterPanel = ({
45
- filters = [],
28
+ const FilterPanel = ({
29
+ filters = [],
46
30
  onRemoveFilter,
47
31
  onClearAll,
48
32
  onRefresh,
@@ -57,48 +41,198 @@ const FilterPanel = ({
57
41
  onPageChange,
58
42
  onPageSizeChange,
59
43
  showPagination = true,
44
+ filterFields = [],
45
+ onApplyFilters,
46
+ initialFilterValues = {},
47
+ accessToken,
60
48
  }) => {
61
- if (!alwaysVisible && (!filters || filters.length === 0)) {
49
+ const [expanded, setExpanded] = useState(false);
50
+ const [filterValues, setFilterValues] = useState(initialFilterValues);
51
+ const [moduleLabels, setModuleLabels] = useState({});
52
+
53
+ // Memoizované hodnoty pro optimalizaci
54
+ const hasFilters = useMemo(() => filters && filters.length > 0, [filters]);
55
+ const hasFilterFields = useMemo(() => filterFields && filterFields.length > 0, [filterFields]);
56
+
57
+ // Early return pokud není co zobrazit
58
+ if (!alwaysVisible && !hasFilters) {
62
59
  return null;
63
60
  }
64
61
 
65
- const hasFilters = filters && filters.length > 0;
66
-
67
- const loadingIcon = <LoadingOutlined style={{ fontSize: 18, color: '#1890ff', fontWeight: 900, strokeWidth: 4 }} spin />;
62
+ const handleFieldChange = useCallback((fieldKey, value, displayValue) => {
63
+ setFilterValues(prev => ({
64
+ ...prev,
65
+ [fieldKey]: value
66
+ }));
68
67
 
69
- return (
70
- <div
71
- style={{
72
- display: 'flex',
73
- justifyContent: 'space-between',
74
- alignItems: 'center',
75
- padding: '7px 0px 7px 7px',
76
- borderRadius: '4px',
77
- backgroundColor: '#fafafa',
78
- borderTop: '1px solid #f0f0f0',
79
- }}
80
- >
81
- <Space style={{ lineHeight: 'normal', flexWrap: 'wrap' }} size={[8, 8]}>
82
- <Button
83
- type="text"
84
- size="small"
85
- icon={isLoading ? <Spin indicator={loadingIcon} /> : <ReloadOutlined />}
86
- onClick={onRefresh}
87
- disabled={isLoading}
88
- style={{
89
- color: '#1890ff',
90
- padding: '0 4px',
91
- height: '22px',
92
- minWidth: '22px'
68
+ if (displayValue !== undefined) {
69
+ setModuleLabels(prev => ({
70
+ ...prev,
71
+ [fieldKey]: displayValue
72
+ }));
73
+ }
74
+ }, []);
75
+
76
+ const handleApplyFilters = useCallback(() => {
77
+ const appliedFilters = filterFields
78
+ .filter(field => {
79
+ const fieldKey = `${field.field}_${field.condition}`;
80
+ const value = filterValues[fieldKey];
81
+ if (Array.isArray(value)) {
82
+ return value.length > 0;
83
+ }
84
+ return value !== undefined && value !== '' && value !== null;
85
+ })
86
+ .map(field => {
87
+ const fieldKey = `${field.field}_${field.condition}`;
88
+ const value = filterValues[fieldKey];
89
+ return {
90
+ field: field.field,
91
+ condition: field.condition,
92
+ value: value,
93
+ label: field.label
94
+ };
95
+ });
96
+
97
+ if (onApplyFilters) {
98
+ onApplyFilters(appliedFilters);
99
+ }
100
+
101
+ setExpanded(false);
102
+ }, [filterFields, filterValues, onApplyFilters]);
103
+
104
+ const handleRefreshOrFilter = useCallback(() => {
105
+ if (expanded) {
106
+ handleApplyFilters();
107
+ } else {
108
+ onRefresh();
109
+ }
110
+ }, [expanded, handleApplyFilters, onRefresh]);
111
+
112
+ const renderField = useCallback((field) => {
113
+ const fieldKey = `${field.field}_${field.condition}`;
114
+
115
+ if (field.type === 'select') {
116
+ return (
117
+ <Select
118
+ placeholder={`Vyber ${field.label}`}
119
+ allowClear
120
+ value={filterValues[fieldKey]}
121
+ onChange={(value) => handleFieldChange(fieldKey, value)}
122
+ options={field.options}
123
+ style={{ width: '100%' }}
124
+ getPopupContainer={() => document.body}
125
+ dropdownStyle={{ zIndex: 9999 }}
126
+ />
127
+ );
128
+ }
129
+
130
+ if (field.type === 'date') {
131
+ return (
132
+ <Input
133
+ type="date"
134
+ placeholder={field.label}
135
+ value={filterValues[fieldKey] || ''}
136
+ onChange={(e) => handleFieldChange(fieldKey, e.target.value)}
137
+ />
138
+ );
139
+ }
140
+
141
+ if (field.type === 'radio') {
142
+ return (
143
+ <Radio.Group
144
+ value={filterValues[fieldKey]}
145
+ onChange={(e) => handleFieldChange(fieldKey, e.target.value)}
146
+ options={field.options}
147
+ />
148
+ );
149
+ }
150
+
151
+ if (field.type === 'module' && field.component) {
152
+ const ModuleComponent = field.component;
153
+ return (
154
+ <ModuleComponent
155
+ value={filterValues[fieldKey]}
156
+ onChange={(value, selectedItem) => {
157
+ let displayValue = value;
158
+ if (selectedItem && field.moduleDefinition) {
159
+ const labelField = field.moduleDefinition.labelField || 'name';
160
+ displayValue = selectedItem[labelField] || field.moduleDefinition.getDisplayValue?.(selectedItem) || value;
161
+ }
162
+ handleFieldChange(fieldKey, value, displayValue);
93
163
  }}
164
+ placeholder={`Vyber ${field.label}`}
165
+ accessToken={accessToken}
94
166
  />
167
+ );
168
+ }
169
+
170
+ return (
171
+ <Input
172
+ placeholder={`Zadej ${field.label}`}
173
+ allowClear
174
+ value={filterValues[fieldKey] || ''}
175
+ onChange={(e) => handleFieldChange(fieldKey, e.target.value)}
176
+ />
177
+ );
178
+ }, [filterValues, handleFieldChange, accessToken]);
179
+
180
+ return (
181
+ <div style={{ position: 'relative', zIndex: 10 }}>
182
+ <div
183
+ style={{
184
+ display: 'flex',
185
+ justifyContent: 'space-between',
186
+ alignItems: 'center',
187
+ padding: '7px 0px 7px 7px',
188
+ borderRadius: '4px',
189
+ backgroundColor: '#fafafa',
190
+ borderTop: '1px solid #f0f0f0',
191
+ }}
192
+ >
193
+ <Space style={{ lineHeight: 'normal', flexWrap: 'wrap' }} size={[8, 8]}>
194
+ {hasFilterFields && (
195
+ <Button
196
+ type="text"
197
+ size="small"
198
+ icon={
199
+ <DownOutlined
200
+ style={{
201
+ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)',
202
+ transition: 'transform 0.3s ease'
203
+ }}
204
+ />
205
+ }
206
+ onClick={() => setExpanded(!expanded)}
207
+ style={{
208
+ color: '#1890ff',
209
+ padding: '0 4px',
210
+ height: '22px',
211
+ minWidth: '22px'
212
+ }}
213
+ />
214
+ )}
215
+ <Button
216
+ type="text"
217
+ size="small"
218
+ icon={isLoading ? <Spin indicator={LOADING_ICON} /> : (expanded ? <FilterFilled /> : <ReloadOutlined />)}
219
+ onClick={handleRefreshOrFilter}
220
+ disabled={isLoading}
221
+ style={{
222
+ color: '#1890ff',
223
+ padding: '0 4px',
224
+ height: '22px',
225
+ minWidth: '22px'
226
+ }}
227
+ />
95
228
  {hasFilters ? (
96
229
  filters.map((filter, index) => {
97
230
  const fieldLabel = filter.label || fieldLabels[filter.field] || filter.field;
98
231
  const conditionLabel = conditionLabels[filter.condition] || 'filtr';
99
- const valueLabel = formatValue(filter.value, filter.field, valueLabelsMap);
100
-
101
- const displayText = filter.text || (valueLabel
232
+ const fieldKey = `${filter.field}_${filter.condition}`;
233
+ const valueLabel = formatFilterValue(filter.value, filter.field, valueLabelsMap, moduleLabels, fieldKey);
234
+
235
+ const displayText = filter.text || (valueLabel
102
236
  ? `${fieldLabel} ${conditionLabel} (${valueLabel})`
103
237
  : `${fieldLabel} ${conditionLabel}`);
104
238
 
@@ -129,7 +263,7 @@ const FilterPanel = ({
129
263
  <span style={{ color: '#999', fontSize: '13px' }}>Žádné aktivní filtry</span>
130
264
  )}
131
265
  </Space>
132
-
266
+
133
267
  <Space style={{ lineHeight: 'normal', paddingRight: '7px' }} size={[16, 8]}>
134
268
  {hasFilters && onClearAll && (
135
269
  <Button
@@ -161,8 +295,92 @@ const FilterPanel = ({
161
295
  />
162
296
  )}
163
297
  </Space>
298
+ </div>
299
+
300
+ <div
301
+ style={{
302
+ maxHeight: expanded ? '500px' : '0px',
303
+ overflow: 'hidden',
304
+ transition: 'max-height 0.3s ease-in-out',
305
+ position: 'relative',
306
+ zIndex: 100,
307
+ }}
308
+ >
309
+ <div
310
+ style={{
311
+ padding: '16px',
312
+ backgroundColor: '#f5f5f5',
313
+ borderTop: '1px solid #f0f0f0',
314
+ borderBottom: '1px solid #f0f0f0',
315
+ }}
316
+ >
317
+ <div style={{
318
+ display: 'flex',
319
+ flexDirection: 'row',
320
+ flexWrap: 'wrap',
321
+ gap: '16px',
322
+ alignItems: 'flex-start'
323
+ }}>
324
+ {filterFields.map((field) => {
325
+ const fieldKey = `${field.field}_${field.condition}`;
326
+ return (
327
+ <div key={fieldKey} style={{ display: 'flex', alignItems: 'center', gap: '12px', width: '287px' }}>
328
+ <div style={{
329
+ width: '100px',
330
+ fontWeight: '500',
331
+ fontSize: '13px',
332
+ color: '#333',
333
+ textAlign: 'right',
334
+ flexShrink: 0
335
+ }}>
336
+ {field.label}:
337
+ </div>
338
+ <div style={{ width: '175px' }}>
339
+ {renderField(field)}
340
+ </div>
341
+ </div>
342
+ );
343
+ })}
344
+ </div>
345
+ </div>
346
+ </div>
164
347
  </div>
165
348
  );
166
349
  };
167
350
 
168
- export default FilterPanel;
351
+ // Custom comparison funkce pro React.memo
352
+ const areEqual = (prevProps, nextProps) => {
353
+ return (
354
+ prevProps.filters === nextProps.filters &&
355
+ prevProps.isLoading === nextProps.isLoading &&
356
+ prevProps.current === nextProps.current &&
357
+ prevProps.pageSize === nextProps.pageSize &&
358
+ prevProps.total === nextProps.total &&
359
+ prevProps.alwaysVisible === nextProps.alwaysVisible &&
360
+ prevProps.showPagination === nextProps.showPagination &&
361
+ prevProps.fieldLabels === nextProps.fieldLabels &&
362
+ prevProps.valueLabelsMap === nextProps.valueLabelsMap &&
363
+ prevProps.filterFields === nextProps.filterFields &&
364
+ prevProps.initialFilterValues === nextProps.initialFilterValues &&
365
+ prevProps.pageSizeOptions === nextProps.pageSizeOptions &&
366
+ prevProps.accessToken === nextProps.accessToken &&
367
+ // Callback props
368
+ prevProps.onRemoveFilter === nextProps.onRemoveFilter &&
369
+ prevProps.onClearAll === nextProps.onClearAll &&
370
+ prevProps.onRefresh === nextProps.onRefresh &&
371
+ prevProps.onPageChange === nextProps.onPageChange &&
372
+ prevProps.onPageSizeChange === nextProps.onPageSizeChange &&
373
+ prevProps.onApplyFilters === nextProps.onApplyFilters
374
+ );
375
+ };
376
+
377
+ // Export s React.memo pro optimalizaci re-renderů
378
+ export default React.memo(FilterPanel, areEqual);
379
+ export {
380
+ buildValueLabelsMap,
381
+ buildFieldLabelsMap,
382
+ formatFilterValue,
383
+ normalizeFilterValueForBackend,
384
+ throttle,
385
+ debounce
386
+ } from './filterHelpers';
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bit.rhplus/ui2.filter-panel",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "homepage": "https://bit.cloud/remote-scope/ui2/filter-panel",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "remote-scope",
8
8
  "name": "ui2/filter-panel",
9
- "version": "0.0.5"
9
+ "version": "0.0.7"
10
10
  },
11
11
  "dependencies": {
12
12
  "@ant-design/icons": "^5.4.0",