@akinon/akifilter 1.3.5 → 1.3.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.
- package/dist/cjs/akifilter.d.ts +16 -4
- package/dist/cjs/akifilter.d.ts.map +1 -1
- package/dist/cjs/akifilter.js +93 -26
- package/dist/cjs/common/storage.d.ts.map +1 -1
- package/dist/cjs/common/storage.js +6 -1
- package/dist/cjs/components/applied-filters.d.ts.map +1 -1
- package/dist/cjs/components/applied-filters.js +2 -2
- package/dist/cjs/components/filter-toolbar.d.ts +2 -2
- package/dist/cjs/components/filter-toolbar.d.ts.map +1 -1
- package/dist/cjs/components/filter-toolbar.js +18 -2
- package/dist/cjs/filter-builder.d.ts +3 -3
- package/dist/cjs/filter-builder.d.ts.map +1 -1
- package/dist/cjs/filter-builder.js +5 -8
- package/dist/cjs/hooks/use-dynamic-visibility.d.ts +8 -0
- package/dist/cjs/hooks/use-dynamic-visibility.d.ts.map +1 -0
- package/dist/cjs/hooks/use-dynamic-visibility.js +36 -0
- package/dist/cjs/hooks/use-visibility-cleanup.d.ts +13 -0
- package/dist/cjs/hooks/use-visibility-cleanup.d.ts.map +1 -0
- package/dist/cjs/hooks/use-visibility-cleanup.js +39 -0
- package/dist/cjs/i18n/translations/en.d.ts +2 -2
- package/dist/cjs/i18n/translations/en.js +2 -2
- package/dist/cjs/i18n/translations/tr.d.ts +2 -2
- package/dist/cjs/i18n/translations/tr.js +2 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/styles.css +11 -0
- package/dist/cjs/styles.d.ts +1 -0
- package/dist/cjs/types.d.ts +9 -6
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/utils/schema.d.ts +5 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -1
- package/dist/cjs/utils/schema.js +25 -3
- package/dist/cjs/utils/values.d.ts.map +1 -1
- package/dist/cjs/utils/values.js +3 -0
- package/dist/esm/akifilter.d.ts +16 -4
- package/dist/esm/akifilter.d.ts.map +1 -1
- package/dist/esm/akifilter.js +94 -27
- package/dist/esm/common/storage.d.ts.map +1 -1
- package/dist/esm/common/storage.js +6 -1
- package/dist/esm/components/applied-filters.d.ts.map +1 -1
- package/dist/esm/components/applied-filters.js +2 -2
- package/dist/esm/components/filter-toolbar.d.ts +2 -2
- package/dist/esm/components/filter-toolbar.d.ts.map +1 -1
- package/dist/esm/components/filter-toolbar.js +18 -2
- package/dist/esm/filter-builder.d.ts +3 -3
- package/dist/esm/filter-builder.d.ts.map +1 -1
- package/dist/esm/filter-builder.js +5 -8
- package/dist/esm/hooks/use-dynamic-visibility.d.ts +8 -0
- package/dist/esm/hooks/use-dynamic-visibility.d.ts.map +1 -0
- package/dist/esm/hooks/use-dynamic-visibility.js +32 -0
- package/dist/esm/hooks/use-visibility-cleanup.d.ts +13 -0
- package/dist/esm/hooks/use-visibility-cleanup.d.ts.map +1 -0
- package/dist/esm/hooks/use-visibility-cleanup.js +35 -0
- package/dist/esm/i18n/translations/en.d.ts +2 -2
- package/dist/esm/i18n/translations/en.js +2 -2
- package/dist/esm/i18n/translations/tr.d.ts +2 -2
- package/dist/esm/i18n/translations/tr.js +2 -2
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/styles.css +11 -0
- package/dist/esm/styles.d.ts +1 -0
- package/dist/esm/types.d.ts +9 -6
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/utils/schema.d.ts +5 -0
- package/dist/esm/utils/schema.d.ts.map +1 -1
- package/dist/esm/utils/schema.js +22 -2
- package/dist/esm/utils/values.d.ts.map +1 -1
- package/dist/esm/utils/values.js +3 -0
- package/package.json +25 -22
package/dist/cjs/akifilter.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import './styles.css';
|
|
2
2
|
import { FieldValues, Path } from '@akinon/akiform';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import { type AppliedFilter } from './components/applied-filters';
|
|
4
5
|
import type { AkifilterActionsRef, AkifilterSchema } from './types';
|
|
5
6
|
type AkifilterFieldValues = FieldValues;
|
|
6
7
|
export type AkifilterProps<TFieldValues extends AkifilterFieldValues = AkifilterFieldValues> = {
|
|
@@ -25,13 +26,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
|
|
|
25
26
|
*/
|
|
26
27
|
onVisibleFieldsChange?: (keys: Array<Path<TFieldValues>>) => void;
|
|
27
28
|
/**
|
|
28
|
-
* Triggered when user
|
|
29
|
+
* Triggered when user selects a file via the CSV import button.
|
|
30
|
+
* Receives the selected File object.
|
|
29
31
|
*/
|
|
30
|
-
onImportCsv?: () => void;
|
|
32
|
+
onImportCsv?: (file: File) => void;
|
|
31
33
|
/**
|
|
32
|
-
* Triggered when user
|
|
34
|
+
* Triggered when user selects a file via the XLS import button.
|
|
35
|
+
* Receives the selected File object.
|
|
33
36
|
*/
|
|
34
|
-
onImportXls?: () => void;
|
|
37
|
+
onImportXls?: (file: File) => void;
|
|
35
38
|
/**
|
|
36
39
|
* Triggered when user requests clearing all filters.
|
|
37
40
|
*/
|
|
@@ -48,6 +51,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
|
|
|
48
51
|
* Ref to access imperative filter actions like clearing values.
|
|
49
52
|
*/
|
|
50
53
|
filterActionsRef?: React.Ref<AkifilterActionsRef>;
|
|
54
|
+
/**
|
|
55
|
+
* Additional chips to display in the applied filters area alongside form-based filters.
|
|
56
|
+
* Useful for out-of-band filters such as file uploads.
|
|
57
|
+
*/
|
|
58
|
+
externalAppliedFilters?: AppliedFilter[];
|
|
59
|
+
/**
|
|
60
|
+
* Called when the user removes an externally-provided chip.
|
|
61
|
+
*/
|
|
62
|
+
onRemoveExternalFilter?: (key: string) => void;
|
|
51
63
|
};
|
|
52
64
|
export declare const Akifilter: {
|
|
53
65
|
<TFieldValues extends AkifilterFieldValues = FieldValues>(props: AkifilterProps<TFieldValues>): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EACX,IAAI,EAIL,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"akifilter.d.ts","sourceRoot":"","sources":["../../src/akifilter.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,EAIL,WAAW,EACX,IAAI,EAIL,MAAM,iBAAiB,CAAC;AAazB,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AAYtC,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAajB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AA8JxC,MAAM,MAAM,cAAc,CACxB,YAAY,SAAS,oBAAoB,GAAG,oBAAoB,IAC9D;IACF;;OAEG;IACH,YAAY,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACzD;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAClD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,aAAa,EAAE,CAAC;IACzC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,CAAC;AAu1BF,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
|
package/dist/cjs/akifilter.js
CHANGED
|
@@ -24,6 +24,7 @@ const ui_input_1 = require("@akinon/ui-input");
|
|
|
24
24
|
const ui_input_number_1 = require("@akinon/ui-input-number");
|
|
25
25
|
const ui_select_1 = require("@akinon/ui-select");
|
|
26
26
|
const ui_typography_1 = require("@akinon/ui-typography");
|
|
27
|
+
const ui_upload_1 = require("@akinon/ui-upload");
|
|
27
28
|
const antd_1 = require("antd");
|
|
28
29
|
const react_1 = require("react");
|
|
29
30
|
const react_error_boundary_1 = require("react-error-boundary");
|
|
@@ -34,6 +35,8 @@ const filter_toolbar_1 = require("./components/filter-toolbar");
|
|
|
34
35
|
const visibility_modal_1 = require("./components/visibility-modal");
|
|
35
36
|
const constants_1 = require("./constants");
|
|
36
37
|
const use_debounced_value_1 = require("./hooks/use-debounced-value");
|
|
38
|
+
const use_dynamic_visibility_1 = require("./hooks/use-dynamic-visibility");
|
|
39
|
+
const use_visibility_cleanup_1 = require("./hooks/use-visibility-cleanup");
|
|
37
40
|
const i18n_1 = require("./i18n");
|
|
38
41
|
const schema_1 = require("./utils/schema");
|
|
39
42
|
const values_1 = require("./utils/values");
|
|
@@ -63,6 +66,21 @@ const FilterFormItem = (_a) => {
|
|
|
63
66
|
});
|
|
64
67
|
return (react_1.default.createElement(akiform_1.Akiform.Item, Object.assign({}, props, { validateStatus: fieldState.invalid ? 'error' : undefined, help: (_c = (_b = fieldState.error) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : props.help, className: props.className }), childrenWithProps));
|
|
65
68
|
};
|
|
69
|
+
const FileFilterInput = ({ value, onChange, accept, disabled, 'aria-label': ariaLabel }) => {
|
|
70
|
+
const handleBeforeUpload = (file) => {
|
|
71
|
+
var _a;
|
|
72
|
+
onChange === null || onChange === void 0 ? void 0 : onChange((_a = file.originFileObj) !== null && _a !== void 0 ? _a : file);
|
|
73
|
+
// Prevent antd from uploading automatically
|
|
74
|
+
return false;
|
|
75
|
+
};
|
|
76
|
+
const handleRemove = () => {
|
|
77
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(null);
|
|
78
|
+
};
|
|
79
|
+
const fileList = value
|
|
80
|
+
? [{ uid: value.name, name: value.name, originFileObj: value }]
|
|
81
|
+
: [];
|
|
82
|
+
return (react_1.default.createElement(ui_upload_1.Upload, { accept: accept, beforeUpload: handleBeforeUpload, onRemove: handleRemove, fileList: fileList, maxCount: 1, disabled: disabled, "aria-label": ariaLabel }));
|
|
83
|
+
};
|
|
66
84
|
/**
|
|
67
85
|
* Checks if a field should be disabled based on config.disabled property.
|
|
68
86
|
*/
|
|
@@ -74,17 +92,6 @@ const checkIsDisabled = (field, formValues) => {
|
|
|
74
92
|
}
|
|
75
93
|
return Boolean(configDisabled);
|
|
76
94
|
};
|
|
77
|
-
/**
|
|
78
|
-
* Checks if a field should be visible based on config.visible property.
|
|
79
|
-
*/
|
|
80
|
-
const checkIsVisible = (field, formValues) => {
|
|
81
|
-
var _a;
|
|
82
|
-
const configVisible = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
|
|
83
|
-
if (typeof configVisible === 'function') {
|
|
84
|
-
return configVisible(formValues);
|
|
85
|
-
}
|
|
86
|
-
return configVisible !== false;
|
|
87
|
-
};
|
|
88
95
|
const resolveClearedFieldValue = (field, defaultValue) => {
|
|
89
96
|
if (defaultValue !== undefined) {
|
|
90
97
|
return defaultValue;
|
|
@@ -97,13 +104,19 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
97
104
|
return false;
|
|
98
105
|
case 'number':
|
|
99
106
|
case 'date':
|
|
107
|
+
return null;
|
|
100
108
|
case 'select':
|
|
109
|
+
if (field.mode === 'multiple' || field.mode === 'tags') {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
case 'file':
|
|
101
114
|
return null;
|
|
102
115
|
default:
|
|
103
116
|
return undefined;
|
|
104
117
|
}
|
|
105
118
|
};
|
|
106
|
-
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef }) => {
|
|
119
|
+
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
|
|
107
120
|
// Separate regular fields from section fields
|
|
108
121
|
const { regularFields, sectionFields } = react_1.default.useMemo(() => (0, schema_1.partitionSchema)(filterSchema), [filterSchema]);
|
|
109
122
|
// Flatten schema for storage and form value operations
|
|
@@ -151,15 +164,29 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
151
164
|
return acc;
|
|
152
165
|
}
|
|
153
166
|
const label = field.label || field.placeholder || key;
|
|
154
|
-
const
|
|
167
|
+
const fieldOptions = 'options' in field && field.options ? field.options : undefined;
|
|
168
|
+
const resolveLabel = (val) => {
|
|
155
169
|
var _a;
|
|
156
|
-
|
|
170
|
+
const match = fieldOptions === null || fieldOptions === void 0 ? void 0 : fieldOptions.find(option => option.value === val);
|
|
171
|
+
return String((_a = match === null || match === void 0 ? void 0 : match.label) !== null && _a !== void 0 ? _a : val);
|
|
172
|
+
};
|
|
173
|
+
const resolveArrayLabels = (values) => {
|
|
174
|
+
return values.map(resolveLabel).join(', ');
|
|
175
|
+
};
|
|
176
|
+
const resolveSelectLabel = () => {
|
|
177
|
+
if (!fieldOptions) {
|
|
157
178
|
return String(currentValue);
|
|
158
179
|
}
|
|
159
|
-
|
|
160
|
-
|
|
180
|
+
if (Array.isArray(currentValue)) {
|
|
181
|
+
return resolveArrayLabels(currentValue);
|
|
182
|
+
}
|
|
183
|
+
return resolveLabel(currentValue);
|
|
161
184
|
};
|
|
162
185
|
const resolveValue = () => {
|
|
186
|
+
if (field.type === 'file') {
|
|
187
|
+
const fileValue = currentValue;
|
|
188
|
+
return fileValue instanceof File ? fileValue.name : String(fileValue);
|
|
189
|
+
}
|
|
163
190
|
if (field.type === 'select') {
|
|
164
191
|
return resolveSelectLabel();
|
|
165
192
|
}
|
|
@@ -178,7 +205,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
178
205
|
}
|
|
179
206
|
}
|
|
180
207
|
if (Array.isArray(currentValue)) {
|
|
181
|
-
return currentValue
|
|
208
|
+
return resolveArrayLabels(currentValue);
|
|
182
209
|
}
|
|
183
210
|
if (typeof currentValue === 'boolean') {
|
|
184
211
|
return currentValue ? constants_1.BOOLEAN_STRING.TRUE : constants_1.BOOLEAN_STRING.FALSE;
|
|
@@ -200,10 +227,24 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
200
227
|
}, [flattenedSchema, formValues]);
|
|
201
228
|
const resolveInitialVisibleKeys = react_1.default.useCallback(() => {
|
|
202
229
|
const storedKeys = (0, storage_1.readVisibleKeys)(regularFields, storageKey);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
230
|
+
const defaultKeys = (0, schema_1.deriveDefaultVisibleKeys)(regularFields);
|
|
231
|
+
const baseKeys = storedKeys && storedKeys.length > 0
|
|
232
|
+
? (0, schema_1.ensureSchemaOrder)(regularFields, storedKeys)
|
|
233
|
+
: defaultKeys;
|
|
234
|
+
return regularFields.reduce((acc, field) => {
|
|
235
|
+
const key = String(field.key);
|
|
236
|
+
const explicitVisibility = (0, schema_1.resolveFieldVisibility)(field);
|
|
237
|
+
if (explicitVisibility !== undefined) {
|
|
238
|
+
if (explicitVisibility)
|
|
239
|
+
acc.push(key);
|
|
240
|
+
return acc;
|
|
241
|
+
}
|
|
242
|
+
// No explicit boolean visibility, use stored/default
|
|
243
|
+
if (baseKeys.includes(key)) {
|
|
244
|
+
acc.push(key);
|
|
245
|
+
}
|
|
246
|
+
return acc;
|
|
247
|
+
}, []);
|
|
207
248
|
}, [regularFields, storageKey]);
|
|
208
249
|
const [visibleKeys, setVisibleKeys] = react_1.default.useState(resolveInitialVisibleKeys);
|
|
209
250
|
react_1.default.useEffect(() => {
|
|
@@ -428,8 +469,31 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
428
469
|
const start = (modalPage - 1) * modalPageSize;
|
|
429
470
|
return filteredFields.slice(start, start + modalPageSize);
|
|
430
471
|
}, [filteredFields, modalPage, modalPageSize]);
|
|
431
|
-
const visibleFields = react_1.default.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key))
|
|
432
|
-
|
|
472
|
+
const visibleFields = react_1.default.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key))), [regularFields, visibleKeys]);
|
|
473
|
+
// Dynamic visibility
|
|
474
|
+
(0, use_dynamic_visibility_1.useDynamicVisibility)({
|
|
475
|
+
regularFields,
|
|
476
|
+
formValues: normalisedValues,
|
|
477
|
+
setVisibleKeys
|
|
478
|
+
});
|
|
479
|
+
// Visibility cleanup
|
|
480
|
+
(0, use_visibility_cleanup_1.useVisibilityCleanup)({
|
|
481
|
+
visibleKeys,
|
|
482
|
+
regularFields,
|
|
483
|
+
onRemove: handleRemoveFilter
|
|
484
|
+
});
|
|
485
|
+
const handleAppliedFilterRemove = react_1.default.useCallback((key) => {
|
|
486
|
+
if (externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.some(f => f.key === key)) {
|
|
487
|
+
onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(key);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
handleRemoveFilter(key);
|
|
491
|
+
}
|
|
492
|
+
}, [externalAppliedFilters, onRemoveExternalFilter, handleRemoveFilter]);
|
|
493
|
+
const handleClearAllApplied = react_1.default.useCallback(() => {
|
|
494
|
+
handleClearAll();
|
|
495
|
+
externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.forEach(f => onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(f.key));
|
|
496
|
+
}, [handleClearAll, externalAppliedFilters, onRemoveExternalFilter]);
|
|
433
497
|
const renderFieldComponent = (field) => {
|
|
434
498
|
const ariaLabel = (0, schema_1.getFieldAriaLabel)(field);
|
|
435
499
|
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
@@ -439,17 +503,20 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
439
503
|
case 'number':
|
|
440
504
|
return (react_1.default.createElement(ui_input_number_1.InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
441
505
|
case 'select':
|
|
442
|
-
return (react_1.default.createElement(ui_select_1.Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
506
|
+
return (react_1.default.createElement(ui_select_1.Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled, mode: field.mode }));
|
|
443
507
|
case 'checkbox':
|
|
444
508
|
return react_1.default.createElement(ui_checkbox_1.Checkbox, { disabled: isDisabled }, field.label);
|
|
445
509
|
case 'date':
|
|
446
510
|
return (react_1.default.createElement(ui_date_picker_1.DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
447
511
|
case 'textarea':
|
|
448
512
|
return (react_1.default.createElement(ui_input_1.InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
513
|
+
case 'file':
|
|
514
|
+
return (react_1.default.createElement(FileFilterInput, { accept: field.fileAccept, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
449
515
|
case 'custom':
|
|
450
516
|
if (typeof field.render === 'function') {
|
|
451
517
|
return field.render({
|
|
452
|
-
|
|
518
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
519
|
+
field: field,
|
|
453
520
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
454
521
|
control: formMethods.control,
|
|
455
522
|
formValues: formMethods.getValues(),
|
|
@@ -471,7 +538,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
471
538
|
return (react_1.default.createElement(ui_card_1.Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
|
|
472
539
|
react_1.default.createElement(antd_1.ConfigProvider, { theme: theme_overrides_1.themeOverrides },
|
|
473
540
|
react_1.default.createElement(filter_toolbar_1.FilterToolbar, { onOpenModal: handleOpenModal, enableImportCsv: enableImportCsv, enableImportXls: enableImportXls, onImportCsv: onImportCsv, onImportXls: onImportXls }),
|
|
474
|
-
react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: appliedFilters, onRemove:
|
|
541
|
+
react_1.default.createElement(applied_filters_1.AppliedFilters, { filters: [...appliedFilters, ...(externalAppliedFilters !== null && externalAppliedFilters !== void 0 ? externalAppliedFilters : [])], onRemove: handleAppliedFilterRemove, onClearAll: handleClearAllApplied }),
|
|
475
542
|
react_1.default.createElement("div", { className: "akinon-filter__body" },
|
|
476
543
|
react_1.default.createElement(akiform_1.Akiform, { layout: "vertical", className: "akinon-filter__form" },
|
|
477
544
|
react_1.default.createElement("div", { className: "akinon-filter__form-grid", "data-testid": "akifilter-form-grid" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/common/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/common/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA2B/C,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAKF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,EAC9D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,MAAM,EAAE,GAAG,IAoBb,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,IAQrE,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,KAAG,IAQrD,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,YAAY,SAAS,WAAW,EAC/D,QAAQ,cAAc,CAAC,YAAY,CAAC,EAAE,EACtC,YAAY,MAAM,KACjB,OAAO,CAAC,YAAY,CAAC,GAAG,IA+B1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,SAAS,WAAW,EAChE,YAAY,MAAM,EAClB,QAAQ,OAAO,CAAC,YAAY,CAAC,KAC5B,IAeF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,IAQtD,CAAC"}
|
|
@@ -14,7 +14,12 @@ const hashString = (value) => {
|
|
|
14
14
|
return Math.abs(hash).toString(36);
|
|
15
15
|
};
|
|
16
16
|
const buildSchemaSignature = (schema) => {
|
|
17
|
-
return schema
|
|
17
|
+
return schema
|
|
18
|
+
.map(field => {
|
|
19
|
+
const mode = field.type === 'select' && field.mode ? `:${field.mode}` : '';
|
|
20
|
+
return `${String(field.key)}:${field.type}${mode}`;
|
|
21
|
+
})
|
|
22
|
+
.join('|');
|
|
18
23
|
};
|
|
19
24
|
const buildStorageKey = (schema, namespace) => {
|
|
20
25
|
const signature = buildSchemaSignature(schema);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applied-filters.d.ts","sourceRoot":"","sources":["../../../src/components/applied-filters.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,mCAI5B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"applied-filters.d.ts","sourceRoot":"","sources":["../../../src/components/applied-filters.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,mCAI5B,mBAAmB,sBAwDrB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -13,9 +13,9 @@ const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
|
|
|
13
13
|
react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__applied-summary", size: 8 },
|
|
14
14
|
react_1.default.createElement(ui_typography_1.Text, { className: "akinon-filter__applied-label" }, i18n_1.i18n.t('applied.label')),
|
|
15
15
|
hasFilters ? (react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__applied-items", size: 8, wrap: true }, filters.map(item => (react_1.default.createElement("div", { key: `${item.key}-${item.value}`, className: "akinon-filter__chip" },
|
|
16
|
-
react_1.default.createElement("span", { className: "akinon-filter__chip-label" },
|
|
16
|
+
item.label ? (react_1.default.createElement("span", { className: "akinon-filter__chip-label" },
|
|
17
17
|
item.label,
|
|
18
|
-
":"),
|
|
18
|
+
":")) : null,
|
|
19
19
|
react_1.default.createElement("span", { className: "akinon-filter__chip-value" }, item.value),
|
|
20
20
|
react_1.default.createElement("button", { type: "button", "aria-label": i18n_1.i18n.t('applied.clearSingle', {
|
|
21
21
|
field: item.label
|
|
@@ -3,8 +3,8 @@ type FilterToolbarProps = {
|
|
|
3
3
|
onOpenModal: () => void;
|
|
4
4
|
enableImportCsv?: boolean;
|
|
5
5
|
enableImportXls?: boolean;
|
|
6
|
-
onImportCsv?: () => void;
|
|
7
|
-
onImportXls?: () => void;
|
|
6
|
+
onImportCsv?: (file: File) => void;
|
|
7
|
+
onImportXls?: (file: File) => void;
|
|
8
8
|
};
|
|
9
9
|
export declare const FilterToolbar: ({ onOpenModal, enableImportCsv, enableImportXls, onImportCsv, onImportXls }: FilterToolbarProps) => React.JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/filter-toolbar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"filter-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/filter-toolbar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACpC,CAAC;AAgDF,eAAO,MAAM,aAAa,GAAI,6EAM3B,kBAAkB,sBAoCpB,CAAC"}
|
|
@@ -6,12 +6,28 @@ const ui_space_1 = require("@akinon/ui-space");
|
|
|
6
6
|
const ui_typography_1 = require("@akinon/ui-typography");
|
|
7
7
|
const react_1 = require("react");
|
|
8
8
|
const i18n_1 = require("../i18n");
|
|
9
|
+
const FileImportButton = ({ accept, label, onImport }) => {
|
|
10
|
+
const inputRef = react_1.default.useRef(null);
|
|
11
|
+
const handleClick = () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click(); };
|
|
12
|
+
const handleChange = (e) => {
|
|
13
|
+
var _a;
|
|
14
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
15
|
+
if (file) {
|
|
16
|
+
onImport(file);
|
|
17
|
+
}
|
|
18
|
+
// Reset so same file can be re-selected
|
|
19
|
+
e.target.value = '';
|
|
20
|
+
};
|
|
21
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
22
|
+
react_1.default.createElement("input", { ref: inputRef, type: "file", accept: accept, style: { display: 'none' }, onChange: handleChange }),
|
|
23
|
+
react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item akinon-filter__toolbar-item--file", icon: "filter", iconSize: 13, onClick: handleClick, type: "primary", title: label, "aria-label": label }, label)));
|
|
24
|
+
};
|
|
9
25
|
const FilterToolbar = ({ onOpenModal, enableImportCsv, enableImportXls, onImportCsv, onImportXls }) => {
|
|
10
26
|
return (react_1.default.createElement("div", { className: "akinon-filter__top" },
|
|
11
27
|
react_1.default.createElement(ui_typography_1.Title, { className: "akinon-filter__title", level: 4 }, i18n_1.i18n.t('header.title')),
|
|
12
28
|
react_1.default.createElement(ui_space_1.Space, { className: "akinon-filter__toolbar", size: 6 },
|
|
13
|
-
enableImportCsv && onImportCsv ? (react_1.default.createElement(
|
|
14
|
-
enableImportXls && onImportXls ? (react_1.default.createElement(
|
|
29
|
+
enableImportCsv && onImportCsv ? (react_1.default.createElement(FileImportButton, { accept: ".csv", label: i18n_1.i18n.t('header.actions.importCsv'), onImport: onImportCsv })) : null,
|
|
30
|
+
enableImportXls && onImportXls ? (react_1.default.createElement(FileImportButton, { accept: ".xls,.xlsx", label: i18n_1.i18n.t('header.actions.importXls'), onImport: onImportXls })) : null,
|
|
15
31
|
react_1.default.createElement(ui_button_1.Button, { className: "akinon-filter__toolbar-item", icon: "filter", iconSize: 16, onClick: onOpenModal, type: "primary", title: i18n_1.i18n.t('header.actions.selectFilters'), "aria-label": i18n_1.i18n.t('header.actions.selectFilters') }))));
|
|
16
32
|
};
|
|
17
33
|
exports.FilterToolbar = FilterToolbar;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { FieldValues } from '@akinon/akiform';
|
|
2
2
|
import { field } from '@akinon/akiform-builder';
|
|
3
|
-
import type { AkifilterField } from './types';
|
|
3
|
+
import type { AkifilterField, AkifilterFieldConfig } from './types';
|
|
4
4
|
type BaseBuilder<TFieldValues extends FieldValues> = ReturnType<typeof field<TFieldValues>>;
|
|
5
|
-
type AkifilterFieldBuilder<TFieldValues extends FieldValues> = BaseBuilder<TFieldValues> & {
|
|
6
|
-
|
|
5
|
+
type AkifilterFieldBuilder<TFieldValues extends FieldValues> = Omit<BaseBuilder<TFieldValues>, 'build' | 'config'> & {
|
|
6
|
+
config(cfg: AkifilterFieldConfig<TFieldValues>): AkifilterFieldBuilder<TFieldValues>;
|
|
7
7
|
build(): AkifilterField<TFieldValues>;
|
|
8
8
|
};
|
|
9
9
|
export declare const filterField: <TFieldValues extends FieldValues = FieldValues>() => AkifilterFieldBuilder<TFieldValues>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-builder.d.ts","sourceRoot":"","sources":["../../src/filter-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"filter-builder.d.ts","sourceRoot":"","sources":["../../src/filter-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpE,KAAK,WAAW,CAAC,YAAY,SAAS,WAAW,IAAI,UAAU,CAC7D,OAAO,KAAK,CAAC,YAAY,CAAC,CAC3B,CAAC;AAEF,KAAK,qBAAqB,CAAC,YAAY,SAAS,WAAW,IAAI,IAAI,CACjE,WAAW,CAAC,YAAY,CAAC,EACzB,OAAO,GAAG,QAAQ,CACnB,GAAG;IACF,MAAM,CACJ,GAAG,EAAE,oBAAoB,CAAC,YAAY,CAAC,GACtC,qBAAqB,CAAC,YAAY,CAAC,CAAC;IACvC,KAAK,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,YAAY,SAAS,WAAW,GAAG,WAAW,0CA+B/C,CAAC;AAEF,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -4,21 +4,18 @@ exports.filterField = void 0;
|
|
|
4
4
|
const akiform_builder_1 = require("@akinon/akiform-builder");
|
|
5
5
|
const filterField = () => {
|
|
6
6
|
const baseBuilder = (0, akiform_builder_1.field)();
|
|
7
|
-
let
|
|
7
|
+
let fieldConfig;
|
|
8
8
|
const builder = baseBuilder;
|
|
9
|
-
builder.
|
|
10
|
-
|
|
9
|
+
builder.config = cfg => {
|
|
10
|
+
fieldConfig = Object.assign(Object.assign({}, fieldConfig), cfg);
|
|
11
11
|
return builder;
|
|
12
12
|
};
|
|
13
13
|
const originalBuild = baseBuilder.build.bind(baseBuilder);
|
|
14
14
|
builder.build = () => {
|
|
15
15
|
const builtField = originalBuild();
|
|
16
16
|
const filterFieldDefinition = Object.assign({}, builtField);
|
|
17
|
-
if (
|
|
18
|
-
filterFieldDefinition.
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
delete filterFieldDefinition.isVisible;
|
|
17
|
+
if (fieldConfig !== undefined) {
|
|
18
|
+
filterFieldDefinition.config = Object.assign(Object.assign({}, filterFieldDefinition.config), fieldConfig);
|
|
22
19
|
}
|
|
23
20
|
return filterFieldDefinition;
|
|
24
21
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FieldValues } from '@akinon/akiform';
|
|
2
|
+
import type { AkifilterSchema } from '../types';
|
|
3
|
+
export declare const useDynamicVisibility: <TFieldValues extends FieldValues>({ regularFields, formValues, setVisibleKeys }: {
|
|
4
|
+
regularFields: AkifilterSchema<TFieldValues>;
|
|
5
|
+
formValues: Partial<TFieldValues> | undefined;
|
|
6
|
+
setVisibleKeys: React.Dispatch<React.SetStateAction<string[]>>;
|
|
7
|
+
}) => void;
|
|
8
|
+
//# sourceMappingURL=use-dynamic-visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-dynamic-visibility.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-dynamic-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA0ChD,eAAO,MAAM,oBAAoB,GAAI,YAAY,SAAS,WAAW,EAAE,+CAIpE;IACD,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IAC9C,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAChE,SAcA,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDynamicVisibility = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const schema_1 = require("../utils/schema");
|
|
6
|
+
const computeDynamicKeys = (fields, prev, formValues) => {
|
|
7
|
+
const prevSet = new Set(prev);
|
|
8
|
+
const fieldKeySet = new Set(fields.map(f => String(f.key)));
|
|
9
|
+
const { keys, changed } = fields.reduce((acc, field) => {
|
|
10
|
+
const key = String(field.key);
|
|
11
|
+
const isCurrentlyVisible = prevSet.has(key);
|
|
12
|
+
if (!(0, schema_1.hasDynamicVisibility)(field)) {
|
|
13
|
+
if (isCurrentlyVisible)
|
|
14
|
+
acc.keys.push(key);
|
|
15
|
+
return acc;
|
|
16
|
+
}
|
|
17
|
+
const shouldBeVisible = (0, schema_1.resolveFieldVisibility)(field, formValues, isCurrentlyVisible);
|
|
18
|
+
if (shouldBeVisible)
|
|
19
|
+
acc.keys.push(key);
|
|
20
|
+
if (shouldBeVisible !== isCurrentlyVisible)
|
|
21
|
+
acc.changed = true;
|
|
22
|
+
return acc;
|
|
23
|
+
}, { keys: prev.filter(k => !fieldKeySet.has(k)), changed: false });
|
|
24
|
+
return changed ? (0, schema_1.ensureSchemaOrder)(fields, keys) : null;
|
|
25
|
+
};
|
|
26
|
+
const useDynamicVisibility = ({ regularFields, formValues, setVisibleKeys }) => {
|
|
27
|
+
(0, react_1.useEffect)(() => {
|
|
28
|
+
if (!regularFields.some(schema_1.hasDynamicVisibility))
|
|
29
|
+
return;
|
|
30
|
+
setVisibleKeys(prev => {
|
|
31
|
+
var _a;
|
|
32
|
+
return ((_a = computeDynamicKeys(regularFields, prev, (formValues !== null && formValues !== void 0 ? formValues : {}))) !== null && _a !== void 0 ? _a : prev);
|
|
33
|
+
});
|
|
34
|
+
}, [regularFields, formValues, setVisibleKeys]);
|
|
35
|
+
};
|
|
36
|
+
exports.useDynamicVisibility = useDynamicVisibility;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FieldValues } from '@akinon/akiform';
|
|
2
|
+
import type { AkifilterSchema } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Cleans up form values when fields become hidden.
|
|
5
|
+
* On first render, clears fields explicitly marked as invisible.
|
|
6
|
+
* On subsequent renders, clears fields that were removed from visibleKeys.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useVisibilityCleanup: <TFieldValues extends FieldValues = FieldValues>({ visibleKeys, regularFields, onRemove }: {
|
|
9
|
+
visibleKeys: string[];
|
|
10
|
+
regularFields: AkifilterSchema<TFieldValues>;
|
|
11
|
+
onRemove: (key: string) => void;
|
|
12
|
+
}) => void;
|
|
13
|
+
//# sourceMappingURL=use-visibility-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visibility-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-visibility-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA+BhD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,0CAIC;IACD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,SAcA,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useVisibilityCleanup = void 0;
|
|
4
|
+
const lodash_es_1 = require("lodash-es");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const schema_1 = require("../utils/schema");
|
|
7
|
+
const getInitialKeysToClean = (fields) => fields
|
|
8
|
+
.filter(field => (0, schema_1.resolveFieldVisibility)(field) === false)
|
|
9
|
+
.map(field => String(field.key));
|
|
10
|
+
const getRemovedKeys = (prev, current) => prev.filter(key => !current.includes(key));
|
|
11
|
+
const cleanupKeys = (keys, onRemove) => {
|
|
12
|
+
keys.forEach(key => onRemove(key));
|
|
13
|
+
};
|
|
14
|
+
const resolveKeysToClean = ({ prev, current, fields }) => {
|
|
15
|
+
if (prev === null)
|
|
16
|
+
return getInitialKeysToClean(fields);
|
|
17
|
+
if ((0, lodash_es_1.isEqual)(prev, current))
|
|
18
|
+
return [];
|
|
19
|
+
return getRemovedKeys(prev, current);
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Cleans up form values when fields become hidden.
|
|
23
|
+
* On first render, clears fields explicitly marked as invisible.
|
|
24
|
+
* On subsequent renders, clears fields that were removed from visibleKeys.
|
|
25
|
+
*/
|
|
26
|
+
const useVisibilityCleanup = ({ visibleKeys, regularFields, onRemove }) => {
|
|
27
|
+
const previousVisibleKeysRef = (0, react_1.useRef)(null);
|
|
28
|
+
(0, react_1.useEffect)(() => {
|
|
29
|
+
const prev = previousVisibleKeysRef.current;
|
|
30
|
+
previousVisibleKeysRef.current = visibleKeys;
|
|
31
|
+
const keysToClean = resolveKeysToClean({
|
|
32
|
+
prev,
|
|
33
|
+
current: visibleKeys,
|
|
34
|
+
fields: regularFields
|
|
35
|
+
});
|
|
36
|
+
cleanupKeys(keysToClean, onRemove);
|
|
37
|
+
}, [visibleKeys, onRemove, regularFields]);
|
|
38
|
+
};
|
|
39
|
+
exports.useVisibilityCleanup = useVisibilityCleanup;
|
|
@@ -3,8 +3,8 @@ declare const translations: {
|
|
|
3
3
|
readonly title: "Filters";
|
|
4
4
|
readonly actions: {
|
|
5
5
|
readonly selectFilters: "Select filters";
|
|
6
|
-
readonly importCsv: "
|
|
7
|
-
readonly importXls: "
|
|
6
|
+
readonly importCsv: "CSV";
|
|
7
|
+
readonly importXls: "XLS";
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
readonly applied: {
|
|
@@ -3,8 +3,8 @@ declare const translations: {
|
|
|
3
3
|
readonly title: "Filtreler";
|
|
4
4
|
readonly actions: {
|
|
5
5
|
readonly selectFilters: "Filtreleri seç";
|
|
6
|
-
readonly importCsv: "CSV
|
|
7
|
-
readonly importXls: "XLS
|
|
6
|
+
readonly importCsv: "CSV";
|
|
7
|
+
readonly importXls: "XLS";
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
readonly applied: {
|
package/dist/cjs/index.d.ts
CHANGED
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./akifilter"), exports);
|
|
18
|
+
__exportStar(require("./components/applied-filters"), exports);
|
|
18
19
|
__exportStar(require("./filter-builder"), exports);
|
|
19
20
|
__exportStar(require("./i18n"), exports);
|
|
20
21
|
__exportStar(require("./types"), exports);
|
package/dist/cjs/styles.css
CHANGED
|
@@ -22,6 +22,17 @@
|
|
|
22
22
|
height: 36px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
.akinon-filter__toolbar-item--file {
|
|
26
|
+
width: 36px;
|
|
27
|
+
font-size: 11px;
|
|
28
|
+
font-weight: bold;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
justify-content: flex-end;
|
|
31
|
+
gap: 2px;
|
|
32
|
+
padding-inline: 0;
|
|
33
|
+
padding-block-end: 4px;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
.akinon-filter__applied {
|
|
26
37
|
display: flex;
|
|
27
38
|
align-items: center;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css';
|