@akinon/akifilter 1.4.4-260521-2 → 1.5.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/akifilter.d.ts +10 -0
- package/dist/cjs/akifilter.d.ts.map +1 -1
- package/dist/cjs/akifilter.js +48 -28
- package/dist/cjs/components/applied-filters.d.ts +1 -0
- package/dist/cjs/components/applied-filters.d.ts.map +1 -1
- package/dist/cjs/components/applied-filters.js +2 -1
- package/dist/cjs/constants.d.ts +15 -0
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +16 -1
- package/dist/cjs/styles.css +26 -12
- package/dist/cjs/utils/schema.d.ts +9 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -1
- package/dist/cjs/utils/schema.js +11 -6
- package/dist/cjs/utils/values.js +3 -3
- package/dist/esm/akifilter.d.ts +10 -0
- package/dist/esm/akifilter.d.ts.map +1 -1
- package/dist/esm/akifilter.js +48 -29
- package/dist/esm/components/applied-filters.d.ts +1 -0
- package/dist/esm/components/applied-filters.d.ts.map +1 -1
- package/dist/esm/components/applied-filters.js +2 -1
- package/dist/esm/constants.d.ts +15 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +15 -0
- package/dist/esm/styles.css +26 -12
- package/dist/esm/utils/schema.d.ts +9 -0
- package/dist/esm/utils/schema.d.ts.map +1 -1
- package/dist/esm/utils/schema.js +10 -6
- package/dist/esm/utils/values.js +4 -4
- package/package.json +3 -3
package/dist/cjs/akifilter.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import './styles.css';
|
|
2
2
|
import { FieldValues, Path } from '@akinon/akiform';
|
|
3
|
+
import { type PanelProps } from '@akinon/ui-collapse';
|
|
3
4
|
import React from 'react';
|
|
4
5
|
import { type AppliedFilter } from './components/applied-filters';
|
|
5
6
|
import type { AkifilterActionsRef, AkifilterSchema } from './types';
|
|
@@ -61,6 +62,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
|
|
|
61
62
|
*/
|
|
62
63
|
onRemoveExternalFilter?: (key: string) => void;
|
|
63
64
|
};
|
|
65
|
+
export declare const ExpandIcon: ({ isActive }: PanelProps) => {
|
|
66
|
+
name: "chevron_down";
|
|
67
|
+
size: number;
|
|
68
|
+
style: {
|
|
69
|
+
transform: string;
|
|
70
|
+
transition: string;
|
|
71
|
+
marginTop: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
64
74
|
export declare const Akifilter: {
|
|
65
75
|
<TFieldValues extends AkifilterFieldValues = FieldValues>(props: AkifilterProps<TFieldValues>): React.JSX.Element;
|
|
66
76
|
displayName: string;
|
|
@@ -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;AAIzB,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAShE,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AActC,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAcjB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AAiKxC,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;AAq0BF,eAAO,MAAM,UAAU,GAAI,cAAc,UAAU;;;;;;;;CAQjD,CAAC;AA8CH,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
|
package/dist/cjs/akifilter.js
CHANGED
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.Akifilter = void 0;
|
|
14
|
+
exports.Akifilter = exports.ExpandIcon = void 0;
|
|
15
15
|
require("./styles.css");
|
|
16
16
|
const akidate_1 = require("@akinon/akidate");
|
|
17
17
|
const akiform_1 = require("@akinon/akiform");
|
|
@@ -97,20 +97,21 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
97
97
|
return defaultValue;
|
|
98
98
|
}
|
|
99
99
|
switch (field.type) {
|
|
100
|
-
case
|
|
101
|
-
case
|
|
100
|
+
case constants_1.FIELD_TYPES.TEXT:
|
|
101
|
+
case constants_1.FIELD_TYPES.TEXTAREA:
|
|
102
102
|
return '';
|
|
103
|
-
case
|
|
103
|
+
case constants_1.FIELD_TYPES.CHECKBOX:
|
|
104
104
|
return false;
|
|
105
|
-
case
|
|
106
|
-
case
|
|
105
|
+
case constants_1.FIELD_TYPES.NUMBER:
|
|
106
|
+
case constants_1.FIELD_TYPES.DATE:
|
|
107
107
|
return null;
|
|
108
|
-
case
|
|
109
|
-
if (field.mode ===
|
|
108
|
+
case constants_1.FIELD_TYPES.SELECT:
|
|
109
|
+
if (field.mode === constants_1.FIELD_MODES.MULTIPLE ||
|
|
110
|
+
field.mode === constants_1.FIELD_MODES.TAGS) {
|
|
110
111
|
return [];
|
|
111
112
|
}
|
|
112
113
|
return null;
|
|
113
|
-
case
|
|
114
|
+
case constants_1.FIELD_TYPES.FILE:
|
|
114
115
|
return null;
|
|
115
116
|
default:
|
|
116
117
|
return undefined;
|
|
@@ -119,6 +120,7 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
119
120
|
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
|
|
120
121
|
// Separate regular fields from section fields
|
|
121
122
|
const { regularFields, sectionFields } = react_1.default.useMemo(() => (0, schema_1.partitionSchema)(filterSchema), [filterSchema]);
|
|
123
|
+
const excludeSectionKeys = react_1.default.useMemo(() => (0, schema_1.deriveExcludeSectionKeys)(sectionFields), [sectionFields]);
|
|
122
124
|
// Flatten schema for storage and form value operations
|
|
123
125
|
const flattenedSchema = react_1.default.useMemo(() => (0, schema_1.flattenSchema)(filterSchema), [filterSchema]);
|
|
124
126
|
const storageKey = react_1.default.useMemo(() => (0, storage_1.buildStorageKey)(regularFields, storageNamespace), [regularFields, storageNamespace]);
|
|
@@ -160,7 +162,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
160
162
|
if (Array.isArray(currentValue) && currentValue.length === 0) {
|
|
161
163
|
return acc;
|
|
162
164
|
}
|
|
163
|
-
if (field.type ===
|
|
165
|
+
if (field.type === constants_1.FIELD_TYPES.CHECKBOX && currentValue !== true) {
|
|
164
166
|
return acc;
|
|
165
167
|
}
|
|
166
168
|
const label = field.label || field.placeholder || key;
|
|
@@ -183,18 +185,20 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
183
185
|
return resolveLabel(currentValue);
|
|
184
186
|
};
|
|
185
187
|
const resolveValue = () => {
|
|
186
|
-
if (field.type ===
|
|
188
|
+
if (field.type === constants_1.FIELD_TYPES.FILE) {
|
|
187
189
|
const fileValue = currentValue;
|
|
188
190
|
return fileValue instanceof File ? fileValue.name : String(fileValue);
|
|
189
191
|
}
|
|
190
|
-
if (field.type ===
|
|
192
|
+
if (field.type === constants_1.FIELD_TYPES.SELECT) {
|
|
191
193
|
return resolveSelectLabel();
|
|
192
194
|
}
|
|
193
195
|
// For custom fields with options (like custom selects), try to find the label
|
|
194
|
-
if (field.type ===
|
|
196
|
+
if (field.type === constants_1.FIELD_TYPES.CUSTOM &&
|
|
197
|
+
'options' in field &&
|
|
198
|
+
field.options) {
|
|
195
199
|
return resolveSelectLabel();
|
|
196
200
|
}
|
|
197
|
-
if (field.type ===
|
|
201
|
+
if (field.type === constants_1.FIELD_TYPES.DATE) {
|
|
198
202
|
const iso = akidate_1.akidate.toIsoDate(currentValue);
|
|
199
203
|
if (iso) {
|
|
200
204
|
// Use localized format with time if showTime is enabled
|
|
@@ -221,10 +225,15 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
221
225
|
}
|
|
222
226
|
return String(currentValue);
|
|
223
227
|
};
|
|
224
|
-
acc.push({
|
|
228
|
+
acc.push({
|
|
229
|
+
key,
|
|
230
|
+
label,
|
|
231
|
+
value: resolveValue(),
|
|
232
|
+
isExclude: excludeSectionKeys.has(key)
|
|
233
|
+
});
|
|
225
234
|
return acc;
|
|
226
235
|
}, []);
|
|
227
|
-
}, [flattenedSchema, formValues]);
|
|
236
|
+
}, [flattenedSchema, formValues, excludeSectionKeys]);
|
|
228
237
|
const resolveInitialVisibleKeys = react_1.default.useCallback(() => {
|
|
229
238
|
const storedKeys = (0, storage_1.readVisibleKeys)(regularFields, storageKey);
|
|
230
239
|
const defaultKeys = (0, schema_1.deriveDefaultVisibleKeys)(regularFields);
|
|
@@ -498,21 +507,21 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
498
507
|
const ariaLabel = (0, schema_1.getFieldAriaLabel)(field);
|
|
499
508
|
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
500
509
|
switch (field.type) {
|
|
501
|
-
case
|
|
510
|
+
case constants_1.FIELD_TYPES.TEXT:
|
|
502
511
|
return (react_1.default.createElement(ui_input_1.Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
503
|
-
case
|
|
512
|
+
case constants_1.FIELD_TYPES.NUMBER:
|
|
504
513
|
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 }));
|
|
505
|
-
case
|
|
514
|
+
case constants_1.FIELD_TYPES.SELECT:
|
|
506
515
|
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 }));
|
|
507
|
-
case
|
|
516
|
+
case constants_1.FIELD_TYPES.CHECKBOX:
|
|
508
517
|
return react_1.default.createElement(ui_checkbox_1.Checkbox, { disabled: isDisabled }, field.label);
|
|
509
|
-
case
|
|
518
|
+
case constants_1.FIELD_TYPES.DATE:
|
|
510
519
|
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 }));
|
|
511
|
-
case
|
|
520
|
+
case constants_1.FIELD_TYPES.TEXTAREA:
|
|
512
521
|
return (react_1.default.createElement(ui_input_1.InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
513
|
-
case
|
|
522
|
+
case constants_1.FIELD_TYPES.FILE:
|
|
514
523
|
return (react_1.default.createElement(FileFilterInput, { accept: field.fileAccept, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
515
|
-
case
|
|
524
|
+
case constants_1.FIELD_TYPES.CUSTOM:
|
|
516
525
|
if (typeof field.render === 'function') {
|
|
517
526
|
return field.render({
|
|
518
527
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -524,7 +533,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
524
533
|
});
|
|
525
534
|
}
|
|
526
535
|
return (react_1.default.createElement(ui_typography_1.Text, { type: "secondary", className: "akinon-filter__unsupported" }, i18n_1.i18n.t('form.unsupportedField', { field: String(field.type) })));
|
|
527
|
-
case
|
|
536
|
+
case constants_1.FIELD_TYPES.SECTION:
|
|
528
537
|
// Section fields should not be rendered inline
|
|
529
538
|
// They are rendered separately after the main grid
|
|
530
539
|
return null;
|
|
@@ -533,7 +542,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
533
542
|
}
|
|
534
543
|
};
|
|
535
544
|
const renderFormField = (field) => {
|
|
536
|
-
return (react_1.default.createElement(FilterFormItem, { key: String(field.key), control: formMethods.control, name: field.key, tooltip: field.tooltip, help: field.help, labelDescription: field.labelDescription, required: Boolean(field.validation), className: "mb-0", valuePropName: field.type ===
|
|
545
|
+
return (react_1.default.createElement(FilterFormItem, { key: String(field.key), control: formMethods.control, name: field.key, tooltip: field.tooltip, help: field.help, labelDescription: field.labelDescription, required: Boolean(field.validation), className: "mb-0", valuePropName: field.type === constants_1.FIELD_TYPES.CHECKBOX ? 'checked' : undefined }, renderFieldComponent(field)));
|
|
537
546
|
};
|
|
538
547
|
return (react_1.default.createElement(ui_card_1.Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
|
|
539
548
|
react_1.default.createElement(antd_1.ConfigProvider, { theme: theme_overrides_1.themeOverrides },
|
|
@@ -545,10 +554,11 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
545
554
|
visibleFields.map(renderFormField),
|
|
546
555
|
visibleFields.length === 0 ? (react_1.default.createElement("div", { className: "akinon-filter__empty" }, i18n_1.i18n.t('form.noVisibleFields'))) : null),
|
|
547
556
|
sectionFields.length > 0 && (react_1.default.createElement("div", { className: "akinon-filter__section-fields" }, sectionFields.map(section => {
|
|
548
|
-
return (react_1.default.createElement(ui_collapse_1.Collapse, { key: section.key, defaultActiveKey: section.key, ghost: true, items: [
|
|
557
|
+
return (react_1.default.createElement(ui_collapse_1.Collapse, { expandIconPosition: "end", key: section.key, expandIcon: exports.ExpandIcon, defaultActiveKey: section.defaultExpanded === false ? [] : [section.key], ghost: true, items: [
|
|
549
558
|
{
|
|
550
559
|
key: section.key,
|
|
551
|
-
label: section.label,
|
|
560
|
+
label: (react_1.default.createElement(ui_typography_1.Title, { className: "akinon-filter__title", level: 4 }, section.label)),
|
|
561
|
+
headerClass: 'akinon-filter__section-header',
|
|
552
562
|
children: (react_1.default.createElement("div", { className: "akinon-filter__form-grid" }, section.fields.map(renderFormField)))
|
|
553
563
|
}
|
|
554
564
|
] }));
|
|
@@ -563,6 +573,16 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
563
573
|
}
|
|
564
574
|
}, page: modalPage, pageSize: modalPageSize }))));
|
|
565
575
|
};
|
|
576
|
+
const ExpandIcon = ({ isActive }) => ({
|
|
577
|
+
name: 'chevron_down',
|
|
578
|
+
size: 10,
|
|
579
|
+
style: {
|
|
580
|
+
transform: isActive ? 'rotate(-180deg)' : 'rotate(0deg)',
|
|
581
|
+
transition: 'transform 0.2s ease-in-out',
|
|
582
|
+
marginTop: 8
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
exports.ExpandIcon = ExpandIcon;
|
|
566
586
|
const AkifilterEmptyState = () => {
|
|
567
587
|
const { t } = i18n_1.i18n;
|
|
568
588
|
return (react_1.default.createElement(ui_card_1.Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-empty" },
|
|
@@ -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;
|
|
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;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,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,sBA+DrB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -12,7 +12,8 @@ const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
|
|
|
12
12
|
return (react_1.default.createElement("div", { className: "akinon-filter__applied", "data-testid": "akifilter-applied" },
|
|
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
|
-
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:
|
|
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${item.isExclude ? ' akinon-filter__chip--exclude' : ''}` },
|
|
16
|
+
item.isExclude ? (react_1.default.createElement(icons_1.Icon, { icon: "exclude", size: 12, className: "akinon-filter__chip-exclude-icon" })) : null,
|
|
16
17
|
item.label ? (react_1.default.createElement("span", { className: "akinon-filter__chip-label" },
|
|
17
18
|
item.label,
|
|
18
19
|
":")) : null,
|
package/dist/cjs/constants.d.ts
CHANGED
|
@@ -7,4 +7,19 @@ export declare const BOOLEAN_STRING: {
|
|
|
7
7
|
readonly TRUE: "true";
|
|
8
8
|
readonly FALSE: "false";
|
|
9
9
|
};
|
|
10
|
+
export declare const FIELD_TYPES: {
|
|
11
|
+
readonly TEXT: "text";
|
|
12
|
+
readonly NUMBER: "number";
|
|
13
|
+
readonly SELECT: "select";
|
|
14
|
+
readonly CHECKBOX: "checkbox";
|
|
15
|
+
readonly DATE: "date";
|
|
16
|
+
readonly TEXTAREA: "textarea";
|
|
17
|
+
readonly SECTION: "section";
|
|
18
|
+
readonly CUSTOM: "custom";
|
|
19
|
+
readonly FILE: "file";
|
|
20
|
+
};
|
|
21
|
+
export declare const FIELD_MODES: {
|
|
22
|
+
readonly TAGS: "tags";
|
|
23
|
+
readonly MULTIPLE: "multiple";
|
|
24
|
+
};
|
|
10
25
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,eAAO,MAAM,cAAc;;;CAGjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,eAAO,MAAM,WAAW;;;CAGd,CAAC"}
|
package/dist/cjs/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BOOLEAN_STRING = exports.DATETIME_FORMAT = exports.DATE_FORMAT = exports.FILTER_DEBOUNCE_DELAY = exports.DEFAULT_MODAL_PAGE_SIZE = exports.DEFAULT_VISIBLE_COUNT = void 0;
|
|
3
|
+
exports.FIELD_MODES = exports.FIELD_TYPES = exports.BOOLEAN_STRING = exports.DATETIME_FORMAT = exports.DATE_FORMAT = exports.FILTER_DEBOUNCE_DELAY = exports.DEFAULT_MODAL_PAGE_SIZE = exports.DEFAULT_VISIBLE_COUNT = void 0;
|
|
4
4
|
exports.DEFAULT_VISIBLE_COUNT = 8;
|
|
5
5
|
exports.DEFAULT_MODAL_PAGE_SIZE = 40;
|
|
6
6
|
exports.FILTER_DEBOUNCE_DELAY = 300;
|
|
@@ -10,3 +10,18 @@ exports.BOOLEAN_STRING = {
|
|
|
10
10
|
TRUE: 'true',
|
|
11
11
|
FALSE: 'false'
|
|
12
12
|
};
|
|
13
|
+
exports.FIELD_TYPES = {
|
|
14
|
+
TEXT: 'text',
|
|
15
|
+
NUMBER: 'number',
|
|
16
|
+
SELECT: 'select',
|
|
17
|
+
CHECKBOX: 'checkbox',
|
|
18
|
+
DATE: 'date',
|
|
19
|
+
TEXTAREA: 'textarea',
|
|
20
|
+
SECTION: 'section',
|
|
21
|
+
CUSTOM: 'custom',
|
|
22
|
+
FILE: 'file'
|
|
23
|
+
};
|
|
24
|
+
exports.FIELD_MODES = {
|
|
25
|
+
TAGS: 'tags',
|
|
26
|
+
MULTIPLE: 'multiple'
|
|
27
|
+
};
|
package/dist/cjs/styles.css
CHANGED
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
background-color: var(--color-ebonyClay-900);
|
|
48
48
|
flex: 1;
|
|
49
49
|
display: flex;
|
|
50
|
-
align-items:
|
|
50
|
+
align-items: flex-start;
|
|
51
51
|
border-radius: 5px;
|
|
52
52
|
padding: 6px 8px;
|
|
53
53
|
margin-right: 6px;
|
|
54
|
-
height: 36px;
|
|
54
|
+
min-height: 36px;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.akinon-filter__applied-label {
|
|
@@ -59,16 +59,13 @@
|
|
|
59
59
|
font-weight: 600;
|
|
60
60
|
font-size: 13px;
|
|
61
61
|
position: relative;
|
|
62
|
-
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
top: 7px;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
.akinon-
|
|
66
|
-
margin-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.akinon-filter__common-filters-title {
|
|
70
|
-
color: var(--color-gray-500);
|
|
71
|
-
margin-bottom: 1rem;
|
|
66
|
+
.akinon-filter__section-header span {
|
|
67
|
+
margin-inline-end: unset !important;
|
|
68
|
+
flex: unset !important;
|
|
72
69
|
}
|
|
73
70
|
|
|
74
71
|
.akinon-filter__form-grid {
|
|
@@ -121,8 +118,10 @@
|
|
|
121
118
|
|
|
122
119
|
.akinon-filter__applied-items {
|
|
123
120
|
display: flex;
|
|
121
|
+
flex: 1;
|
|
124
122
|
flex-wrap: wrap;
|
|
125
123
|
gap: 8px;
|
|
124
|
+
min-width: 0;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
.akinon-filter__chip {
|
|
@@ -136,6 +135,16 @@
|
|
|
136
135
|
height: 24px;
|
|
137
136
|
}
|
|
138
137
|
|
|
138
|
+
.akinon-filter__chip--exclude {
|
|
139
|
+
background-color: #ffe0e4;
|
|
140
|
+
border: 1px solid #ff354e;
|
|
141
|
+
height: 23px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.akinon-filter__chip-exclude-icon {
|
|
145
|
+
margin-right: 5px;
|
|
146
|
+
}
|
|
147
|
+
|
|
139
148
|
.akinon-filter__chip-label {
|
|
140
149
|
font-weight: 600;
|
|
141
150
|
color: var(--color-ebonyClay-300);
|
|
@@ -162,7 +171,7 @@
|
|
|
162
171
|
color: color(--color-ebonyClay-500);
|
|
163
172
|
font-size: 12px;
|
|
164
173
|
position: relative;
|
|
165
|
-
top:
|
|
174
|
+
top: 8px;
|
|
166
175
|
}
|
|
167
176
|
|
|
168
177
|
.akinon-filter__modal-list {
|
|
@@ -187,13 +196,13 @@
|
|
|
187
196
|
column-gap: 8px; /* replaces Ant's label padding, zeroed out below */
|
|
188
197
|
line-height: 1.4;
|
|
189
198
|
margin-inline-start: 0; /* override Ant's adjacent-sibling margin */
|
|
199
|
+
color: var(--color-white);
|
|
190
200
|
}
|
|
191
201
|
|
|
192
202
|
.akinon-filter__modal-list
|
|
193
203
|
.akinon-filter__modal-checkbox.ant-checkbox-wrapper
|
|
194
204
|
> .ant-checkbox {
|
|
195
205
|
align-self: start;
|
|
196
|
-
margin-block-start: 0.15em; /* em-relative baseline nudge */
|
|
197
206
|
}
|
|
198
207
|
|
|
199
208
|
.akinon-filter__modal-list
|
|
@@ -253,6 +262,11 @@
|
|
|
253
262
|
width: auto;
|
|
254
263
|
}
|
|
255
264
|
|
|
265
|
+
.akinon-filter .akinon-select-multiple .akinon-select-selector {
|
|
266
|
+
height: 40px;
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
}
|
|
269
|
+
|
|
256
270
|
/* Modal window. */
|
|
257
271
|
|
|
258
272
|
.akinon-filter__modal-toolbar {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FieldValues } from '@akinon/akiform';
|
|
2
|
+
import { FIELD_TYPES } from '../constants';
|
|
2
3
|
import type { AkifilterField, AkifilterSchema } from '../types';
|
|
3
4
|
/**
|
|
4
5
|
* Flattens schema by extracting all nested fields from section fields.
|
|
@@ -11,9 +12,17 @@ export declare const flattenSchema: <TFieldValues extends FieldValues = FieldVal
|
|
|
11
12
|
export declare const partitionSchema: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>) => {
|
|
12
13
|
regularFields: AkifilterSchema<TFieldValues>;
|
|
13
14
|
sectionFields: Array<AkifilterField<TFieldValues> & {
|
|
15
|
+
type: typeof FIELD_TYPES.SECTION;
|
|
14
16
|
fields: AkifilterSchema<TFieldValues>;
|
|
17
|
+
defaultExpanded?: boolean;
|
|
18
|
+
isExcludeSection?: boolean;
|
|
15
19
|
}>;
|
|
16
20
|
};
|
|
21
|
+
export declare const deriveExcludeSectionKeys: <TFieldValues extends FieldValues = FieldValues>(sectionFields: Array<AkifilterField<TFieldValues> & {
|
|
22
|
+
type: typeof FIELD_TYPES.SECTION;
|
|
23
|
+
fields: AkifilterSchema<TFieldValues>;
|
|
24
|
+
isExcludeSection?: boolean;
|
|
25
|
+
}>) => Set<string>;
|
|
17
26
|
export declare const getDisplayLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
18
27
|
export declare const getFieldAriaLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
19
28
|
export declare const ensureSchemaOrder: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>, keys: string[]) => string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/utils/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/utils/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAsC,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC1E,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,eAAe,CAAC,YAAY,CAW9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC5E,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC;IACD,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,aAAa,EAAE,KAAK,CAClB,cAAc,CAAC,YAAY,CAAC,GAAG;QAC7B,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAC;QACjC,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;QACtC,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CACF,CAAC;CAwBH,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,eAAe,KAAK,CAClB,cAAc,CAAC,YAAY,CAAC,GAAG;IAC7B,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAC;IACjC,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CACF,KACA,GAAG,CAAC,MAAM,CAKV,CAAC;AAEJ,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC5E,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,MAEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,MAEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,EACrC,MAAM,MAAM,EAAE,KACb,MAAM,EAGR,CAAC;AAkBF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,EACnC,aAAa,YAAY,EACzB,iBAAiB,OAAO,KACvB,OAAO,GAAG,SAC8D,CAAC;AAE5E,eAAO,MAAM,wBAAwB,GACnC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,MAAM,EAUR,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,OAAO,CAAC,YAAY,CAQtB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,YAAY,SAAS,WAAW,EACnE,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,OAA4C,CAAC;AAEhD,eAAO,MAAM,uBAAuB,GAClC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,EACrC,SAAS,OAAO,CAAC,YAAY,CAAC,KAC7B,OAAO,CAAC,YAAY,CA0CtB,CAAC"}
|
package/dist/cjs/utils/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normaliseValuesBySchema = exports.hasDynamicVisibility = exports.extractDefaultValues = exports.deriveDefaultVisibleKeys = exports.resolveFieldVisibility = exports.ensureSchemaOrder = exports.getFieldAriaLabel = exports.getDisplayLabel = exports.partitionSchema = exports.flattenSchema = void 0;
|
|
3
|
+
exports.normaliseValuesBySchema = exports.hasDynamicVisibility = exports.extractDefaultValues = exports.deriveDefaultVisibleKeys = exports.resolveFieldVisibility = exports.ensureSchemaOrder = exports.getFieldAriaLabel = exports.getDisplayLabel = exports.deriveExcludeSectionKeys = exports.partitionSchema = exports.flattenSchema = void 0;
|
|
4
4
|
const akidate_1 = require("@akinon/akidate");
|
|
5
5
|
const lodash_es_1 = require("lodash-es");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
@@ -10,7 +10,7 @@ const constants_1 = require("../constants");
|
|
|
10
10
|
*/
|
|
11
11
|
const flattenSchema = (schema) => {
|
|
12
12
|
return schema.reduce((acc, field) => {
|
|
13
|
-
if (field.type ===
|
|
13
|
+
if (field.type === constants_1.FIELD_TYPES.SECTION && 'fields' in field) {
|
|
14
14
|
// Recursively flatten nested section fields
|
|
15
15
|
return [
|
|
16
16
|
...acc,
|
|
@@ -28,7 +28,7 @@ const partitionSchema = (schema) => {
|
|
|
28
28
|
const regularFields = [];
|
|
29
29
|
const sectionFields = [];
|
|
30
30
|
schema.forEach(field => {
|
|
31
|
-
if (field.type ===
|
|
31
|
+
if (field.type === constants_1.FIELD_TYPES.SECTION) {
|
|
32
32
|
sectionFields.push(field);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
@@ -38,6 +38,10 @@ const partitionSchema = (schema) => {
|
|
|
38
38
|
return { regularFields, sectionFields };
|
|
39
39
|
};
|
|
40
40
|
exports.partitionSchema = partitionSchema;
|
|
41
|
+
const deriveExcludeSectionKeys = (sectionFields) => new Set(sectionFields
|
|
42
|
+
.filter(s => s.isExcludeSection)
|
|
43
|
+
.flatMap(s => s.fields.map(f => String(f.key))));
|
|
44
|
+
exports.deriveExcludeSectionKeys = deriveExcludeSectionKeys;
|
|
41
45
|
const getDisplayLabel = (field) => {
|
|
42
46
|
return field.label || field.placeholder || String(field.key);
|
|
43
47
|
};
|
|
@@ -96,15 +100,16 @@ const normaliseValuesBySchema = (schema, values) => {
|
|
|
96
100
|
return acc;
|
|
97
101
|
}
|
|
98
102
|
const currentValue = values[key];
|
|
99
|
-
if (field.type ===
|
|
103
|
+
if (field.type === constants_1.FIELD_TYPES.DATE) {
|
|
100
104
|
const parsed = akidate_1.akidate.parse(currentValue);
|
|
101
105
|
if (parsed) {
|
|
102
106
|
acc[key] = parsed;
|
|
103
107
|
return acc;
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
|
-
if (field.type ===
|
|
107
|
-
(field.mode ===
|
|
110
|
+
if (field.type === constants_1.FIELD_TYPES.SELECT &&
|
|
111
|
+
(field.mode === constants_1.FIELD_MODES.MULTIPLE ||
|
|
112
|
+
field.mode === constants_1.FIELD_MODES.TAGS) &&
|
|
108
113
|
currentValue != null &&
|
|
109
114
|
!Array.isArray(currentValue)) {
|
|
110
115
|
acc[key] = [currentValue];
|
package/dist/cjs/utils/values.js
CHANGED
|
@@ -13,10 +13,10 @@ const shouldPersistValue = (field, value) => {
|
|
|
13
13
|
if (Array.isArray(value) && value.length === 0) {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
16
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === constants_1.FIELD_TYPES.CHECKBOX && value !== true) {
|
|
17
17
|
return false;
|
|
18
18
|
}
|
|
19
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
19
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === constants_1.FIELD_TYPES.FILE) {
|
|
20
20
|
return value instanceof File;
|
|
21
21
|
}
|
|
22
22
|
return true;
|
|
@@ -33,7 +33,7 @@ const normaliseOutputValues = (schema, values) => {
|
|
|
33
33
|
return acc;
|
|
34
34
|
}
|
|
35
35
|
let normalisedValue = rawValue;
|
|
36
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
36
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === constants_1.FIELD_TYPES.DATE) {
|
|
37
37
|
const normalised = akidate_1.akidate.toIsoDate(rawValue);
|
|
38
38
|
if (!normalised) {
|
|
39
39
|
return acc;
|
package/dist/esm/akifilter.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import './styles.css';
|
|
2
2
|
import { FieldValues, Path } from '@akinon/akiform';
|
|
3
|
+
import { type PanelProps } from '@akinon/ui-collapse';
|
|
3
4
|
import React from 'react';
|
|
4
5
|
import { type AppliedFilter } from './components/applied-filters';
|
|
5
6
|
import type { AkifilterActionsRef, AkifilterSchema } from './types';
|
|
@@ -61,6 +62,15 @@ export type AkifilterProps<TFieldValues extends AkifilterFieldValues = Akifilter
|
|
|
61
62
|
*/
|
|
62
63
|
onRemoveExternalFilter?: (key: string) => void;
|
|
63
64
|
};
|
|
65
|
+
export declare const ExpandIcon: ({ isActive }: PanelProps) => {
|
|
66
|
+
name: "chevron_down";
|
|
67
|
+
size: number;
|
|
68
|
+
style: {
|
|
69
|
+
transform: string;
|
|
70
|
+
transition: string;
|
|
71
|
+
marginTop: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
64
74
|
export declare const Akifilter: {
|
|
65
75
|
<TFieldValues extends AkifilterFieldValues = FieldValues>(props: AkifilterProps<TFieldValues>): React.JSX.Element;
|
|
66
76
|
displayName: string;
|
|
@@ -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;AAIzB,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAShE,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AActC,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAcjB,KAAK,oBAAoB,GAAG,WAAW,CAAC;AAiKxC,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;AAq0BF,eAAO,MAAM,UAAU,GAAI,cAAc,UAAU;;;;;;;;CAQjD,CAAC;AA8CH,eAAO,MAAM,SAAS;KACpB,YAAY,SAAS,oBAAoB,uBAElC,cAAc,CAAC,YAAY,CAAC;;CAmBpC,CAAC"}
|
package/dist/esm/akifilter.js
CHANGED
|
@@ -30,12 +30,12 @@ import { themeOverrides } from './common/theme-overrides';
|
|
|
30
30
|
import { AppliedFilters } from './components/applied-filters';
|
|
31
31
|
import { FilterToolbar } from './components/filter-toolbar';
|
|
32
32
|
import { VisibilityModal } from './components/visibility-modal';
|
|
33
|
-
import { BOOLEAN_STRING, DEFAULT_MODAL_PAGE_SIZE, FILTER_DEBOUNCE_DELAY } from './constants';
|
|
33
|
+
import { BOOLEAN_STRING, DEFAULT_MODAL_PAGE_SIZE, FIELD_MODES, FIELD_TYPES, FILTER_DEBOUNCE_DELAY } from './constants';
|
|
34
34
|
import { useDebouncedValue } from './hooks/use-debounced-value';
|
|
35
35
|
import { useDynamicVisibility } from './hooks/use-dynamic-visibility';
|
|
36
36
|
import { useVisibilityCleanup } from './hooks/use-visibility-cleanup';
|
|
37
37
|
import { i18n } from './i18n';
|
|
38
|
-
import { deriveDefaultVisibleKeys, ensureSchemaOrder, extractDefaultValues, flattenSchema, getFieldAriaLabel, normaliseValuesBySchema, partitionSchema, resolveFieldVisibility } from './utils/schema';
|
|
38
|
+
import { deriveDefaultVisibleKeys, deriveExcludeSectionKeys, ensureSchemaOrder, extractDefaultValues, flattenSchema, getFieldAriaLabel, normaliseValuesBySchema, partitionSchema, resolveFieldVisibility } from './utils/schema';
|
|
39
39
|
import { normaliseOutputValues } from './utils/values';
|
|
40
40
|
const FilterFormItem = (_a) => {
|
|
41
41
|
var _b, _c;
|
|
@@ -94,20 +94,21 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
94
94
|
return defaultValue;
|
|
95
95
|
}
|
|
96
96
|
switch (field.type) {
|
|
97
|
-
case
|
|
98
|
-
case
|
|
97
|
+
case FIELD_TYPES.TEXT:
|
|
98
|
+
case FIELD_TYPES.TEXTAREA:
|
|
99
99
|
return '';
|
|
100
|
-
case
|
|
100
|
+
case FIELD_TYPES.CHECKBOX:
|
|
101
101
|
return false;
|
|
102
|
-
case
|
|
103
|
-
case
|
|
102
|
+
case FIELD_TYPES.NUMBER:
|
|
103
|
+
case FIELD_TYPES.DATE:
|
|
104
104
|
return null;
|
|
105
|
-
case
|
|
106
|
-
if (field.mode ===
|
|
105
|
+
case FIELD_TYPES.SELECT:
|
|
106
|
+
if (field.mode === FIELD_MODES.MULTIPLE ||
|
|
107
|
+
field.mode === FIELD_MODES.TAGS) {
|
|
107
108
|
return [];
|
|
108
109
|
}
|
|
109
110
|
return null;
|
|
110
|
-
case
|
|
111
|
+
case FIELD_TYPES.FILE:
|
|
111
112
|
return null;
|
|
112
113
|
default:
|
|
113
114
|
return undefined;
|
|
@@ -116,6 +117,7 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
116
117
|
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
|
|
117
118
|
// Separate regular fields from section fields
|
|
118
119
|
const { regularFields, sectionFields } = React.useMemo(() => partitionSchema(filterSchema), [filterSchema]);
|
|
120
|
+
const excludeSectionKeys = React.useMemo(() => deriveExcludeSectionKeys(sectionFields), [sectionFields]);
|
|
119
121
|
// Flatten schema for storage and form value operations
|
|
120
122
|
const flattenedSchema = React.useMemo(() => flattenSchema(filterSchema), [filterSchema]);
|
|
121
123
|
const storageKey = React.useMemo(() => buildStorageKey(regularFields, storageNamespace), [regularFields, storageNamespace]);
|
|
@@ -157,7 +159,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
157
159
|
if (Array.isArray(currentValue) && currentValue.length === 0) {
|
|
158
160
|
return acc;
|
|
159
161
|
}
|
|
160
|
-
if (field.type ===
|
|
162
|
+
if (field.type === FIELD_TYPES.CHECKBOX && currentValue !== true) {
|
|
161
163
|
return acc;
|
|
162
164
|
}
|
|
163
165
|
const label = field.label || field.placeholder || key;
|
|
@@ -180,18 +182,20 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
180
182
|
return resolveLabel(currentValue);
|
|
181
183
|
};
|
|
182
184
|
const resolveValue = () => {
|
|
183
|
-
if (field.type ===
|
|
185
|
+
if (field.type === FIELD_TYPES.FILE) {
|
|
184
186
|
const fileValue = currentValue;
|
|
185
187
|
return fileValue instanceof File ? fileValue.name : String(fileValue);
|
|
186
188
|
}
|
|
187
|
-
if (field.type ===
|
|
189
|
+
if (field.type === FIELD_TYPES.SELECT) {
|
|
188
190
|
return resolveSelectLabel();
|
|
189
191
|
}
|
|
190
192
|
// For custom fields with options (like custom selects), try to find the label
|
|
191
|
-
if (field.type ===
|
|
193
|
+
if (field.type === FIELD_TYPES.CUSTOM &&
|
|
194
|
+
'options' in field &&
|
|
195
|
+
field.options) {
|
|
192
196
|
return resolveSelectLabel();
|
|
193
197
|
}
|
|
194
|
-
if (field.type ===
|
|
198
|
+
if (field.type === FIELD_TYPES.DATE) {
|
|
195
199
|
const iso = akidate.toIsoDate(currentValue);
|
|
196
200
|
if (iso) {
|
|
197
201
|
// Use localized format with time if showTime is enabled
|
|
@@ -218,10 +222,15 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
218
222
|
}
|
|
219
223
|
return String(currentValue);
|
|
220
224
|
};
|
|
221
|
-
acc.push({
|
|
225
|
+
acc.push({
|
|
226
|
+
key,
|
|
227
|
+
label,
|
|
228
|
+
value: resolveValue(),
|
|
229
|
+
isExclude: excludeSectionKeys.has(key)
|
|
230
|
+
});
|
|
222
231
|
return acc;
|
|
223
232
|
}, []);
|
|
224
|
-
}, [flattenedSchema, formValues]);
|
|
233
|
+
}, [flattenedSchema, formValues, excludeSectionKeys]);
|
|
225
234
|
const resolveInitialVisibleKeys = React.useCallback(() => {
|
|
226
235
|
const storedKeys = readVisibleKeys(regularFields, storageKey);
|
|
227
236
|
const defaultKeys = deriveDefaultVisibleKeys(regularFields);
|
|
@@ -495,21 +504,21 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
495
504
|
const ariaLabel = getFieldAriaLabel(field);
|
|
496
505
|
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
497
506
|
switch (field.type) {
|
|
498
|
-
case
|
|
507
|
+
case FIELD_TYPES.TEXT:
|
|
499
508
|
return (React.createElement(Input, { placeholder: field.placeholder, size: "large", allowClear: true, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
500
|
-
case
|
|
509
|
+
case FIELD_TYPES.NUMBER:
|
|
501
510
|
return (React.createElement(InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
502
|
-
case
|
|
511
|
+
case FIELD_TYPES.SELECT:
|
|
503
512
|
return (React.createElement(Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled, mode: field.mode }));
|
|
504
|
-
case
|
|
513
|
+
case FIELD_TYPES.CHECKBOX:
|
|
505
514
|
return React.createElement(Checkbox, { disabled: isDisabled }, field.label);
|
|
506
|
-
case
|
|
515
|
+
case FIELD_TYPES.DATE:
|
|
507
516
|
return (React.createElement(DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
508
|
-
case
|
|
517
|
+
case FIELD_TYPES.TEXTAREA:
|
|
509
518
|
return (React.createElement(InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
510
|
-
case
|
|
519
|
+
case FIELD_TYPES.FILE:
|
|
511
520
|
return (React.createElement(FileFilterInput, { accept: field.fileAccept, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
512
|
-
case
|
|
521
|
+
case FIELD_TYPES.CUSTOM:
|
|
513
522
|
if (typeof field.render === 'function') {
|
|
514
523
|
return field.render({
|
|
515
524
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -521,7 +530,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
521
530
|
});
|
|
522
531
|
}
|
|
523
532
|
return (React.createElement(Text, { type: "secondary", className: "akinon-filter__unsupported" }, i18n.t('form.unsupportedField', { field: String(field.type) })));
|
|
524
|
-
case
|
|
533
|
+
case FIELD_TYPES.SECTION:
|
|
525
534
|
// Section fields should not be rendered inline
|
|
526
535
|
// They are rendered separately after the main grid
|
|
527
536
|
return null;
|
|
@@ -530,7 +539,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
530
539
|
}
|
|
531
540
|
};
|
|
532
541
|
const renderFormField = (field) => {
|
|
533
|
-
return (React.createElement(FilterFormItem, { key: String(field.key), control: formMethods.control, name: field.key, tooltip: field.tooltip, help: field.help, labelDescription: field.labelDescription, required: Boolean(field.validation), className: "mb-0", valuePropName: field.type ===
|
|
542
|
+
return (React.createElement(FilterFormItem, { key: String(field.key), control: formMethods.control, name: field.key, tooltip: field.tooltip, help: field.help, labelDescription: field.labelDescription, required: Boolean(field.validation), className: "mb-0", valuePropName: field.type === FIELD_TYPES.CHECKBOX ? 'checked' : undefined }, renderFieldComponent(field)));
|
|
534
543
|
};
|
|
535
544
|
return (React.createElement(Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
|
|
536
545
|
React.createElement(ConfigProvider, { theme: themeOverrides },
|
|
@@ -542,10 +551,11 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
542
551
|
visibleFields.map(renderFormField),
|
|
543
552
|
visibleFields.length === 0 ? (React.createElement("div", { className: "akinon-filter__empty" }, i18n.t('form.noVisibleFields'))) : null),
|
|
544
553
|
sectionFields.length > 0 && (React.createElement("div", { className: "akinon-filter__section-fields" }, sectionFields.map(section => {
|
|
545
|
-
return (React.createElement(Collapse, { key: section.key, defaultActiveKey: section.key, ghost: true, items: [
|
|
554
|
+
return (React.createElement(Collapse, { expandIconPosition: "end", key: section.key, expandIcon: ExpandIcon, defaultActiveKey: section.defaultExpanded === false ? [] : [section.key], ghost: true, items: [
|
|
546
555
|
{
|
|
547
556
|
key: section.key,
|
|
548
|
-
label: section.label,
|
|
557
|
+
label: (React.createElement(Title, { className: "akinon-filter__title", level: 4 }, section.label)),
|
|
558
|
+
headerClass: 'akinon-filter__section-header',
|
|
549
559
|
children: (React.createElement("div", { className: "akinon-filter__form-grid" }, section.fields.map(renderFormField)))
|
|
550
560
|
}
|
|
551
561
|
] }));
|
|
@@ -560,6 +570,15 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
560
570
|
}
|
|
561
571
|
}, page: modalPage, pageSize: modalPageSize }))));
|
|
562
572
|
};
|
|
573
|
+
export const ExpandIcon = ({ isActive }) => ({
|
|
574
|
+
name: 'chevron_down',
|
|
575
|
+
size: 10,
|
|
576
|
+
style: {
|
|
577
|
+
transform: isActive ? 'rotate(-180deg)' : 'rotate(0deg)',
|
|
578
|
+
transition: 'transform 0.2s ease-in-out',
|
|
579
|
+
marginTop: 8
|
|
580
|
+
}
|
|
581
|
+
});
|
|
563
582
|
const AkifilterEmptyState = () => {
|
|
564
583
|
const { t } = i18n;
|
|
565
584
|
return (React.createElement(Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-empty" },
|
|
@@ -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;
|
|
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;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,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,sBA+DrB,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -9,7 +9,8 @@ export const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
|
|
|
9
9
|
return (React.createElement("div", { className: "akinon-filter__applied", "data-testid": "akifilter-applied" },
|
|
10
10
|
React.createElement(Space, { className: "akinon-filter__applied-summary", size: 8 },
|
|
11
11
|
React.createElement(Text, { className: "akinon-filter__applied-label" }, i18n.t('applied.label')),
|
|
12
|
-
hasFilters ? (React.createElement(Space, { className: "akinon-filter__applied-items", size: 8, wrap: true }, filters.map(item => (React.createElement("div", { key: `${item.key}-${item.value}`, className:
|
|
12
|
+
hasFilters ? (React.createElement(Space, { className: "akinon-filter__applied-items", size: 8, wrap: true }, filters.map(item => (React.createElement("div", { key: `${item.key}-${item.value}`, className: `akinon-filter__chip${item.isExclude ? ' akinon-filter__chip--exclude' : ''}` },
|
|
13
|
+
item.isExclude ? (React.createElement(Icon, { icon: "exclude", size: 12, className: "akinon-filter__chip-exclude-icon" })) : null,
|
|
13
14
|
item.label ? (React.createElement("span", { className: "akinon-filter__chip-label" },
|
|
14
15
|
item.label,
|
|
15
16
|
":")) : null,
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -7,4 +7,19 @@ export declare const BOOLEAN_STRING: {
|
|
|
7
7
|
readonly TRUE: "true";
|
|
8
8
|
readonly FALSE: "false";
|
|
9
9
|
};
|
|
10
|
+
export declare const FIELD_TYPES: {
|
|
11
|
+
readonly TEXT: "text";
|
|
12
|
+
readonly NUMBER: "number";
|
|
13
|
+
readonly SELECT: "select";
|
|
14
|
+
readonly CHECKBOX: "checkbox";
|
|
15
|
+
readonly DATE: "date";
|
|
16
|
+
readonly TEXTAREA: "textarea";
|
|
17
|
+
readonly SECTION: "section";
|
|
18
|
+
readonly CUSTOM: "custom";
|
|
19
|
+
readonly FILE: "file";
|
|
20
|
+
};
|
|
21
|
+
export declare const FIELD_MODES: {
|
|
22
|
+
readonly TAGS: "tags";
|
|
23
|
+
readonly MULTIPLE: "multiple";
|
|
24
|
+
};
|
|
10
25
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,eAAO,MAAM,cAAc;;;CAGjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,eAAO,MAAM,WAAW;;;CAGd,CAAC"}
|
package/dist/esm/constants.js
CHANGED
|
@@ -7,3 +7,18 @@ export const BOOLEAN_STRING = {
|
|
|
7
7
|
TRUE: 'true',
|
|
8
8
|
FALSE: 'false'
|
|
9
9
|
};
|
|
10
|
+
export const FIELD_TYPES = {
|
|
11
|
+
TEXT: 'text',
|
|
12
|
+
NUMBER: 'number',
|
|
13
|
+
SELECT: 'select',
|
|
14
|
+
CHECKBOX: 'checkbox',
|
|
15
|
+
DATE: 'date',
|
|
16
|
+
TEXTAREA: 'textarea',
|
|
17
|
+
SECTION: 'section',
|
|
18
|
+
CUSTOM: 'custom',
|
|
19
|
+
FILE: 'file'
|
|
20
|
+
};
|
|
21
|
+
export const FIELD_MODES = {
|
|
22
|
+
TAGS: 'tags',
|
|
23
|
+
MULTIPLE: 'multiple'
|
|
24
|
+
};
|
package/dist/esm/styles.css
CHANGED
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
background-color: var(--color-ebonyClay-900);
|
|
48
48
|
flex: 1;
|
|
49
49
|
display: flex;
|
|
50
|
-
align-items:
|
|
50
|
+
align-items: flex-start;
|
|
51
51
|
border-radius: 5px;
|
|
52
52
|
padding: 6px 8px;
|
|
53
53
|
margin-right: 6px;
|
|
54
|
-
height: 36px;
|
|
54
|
+
min-height: 36px;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.akinon-filter__applied-label {
|
|
@@ -59,16 +59,13 @@
|
|
|
59
59
|
font-weight: 600;
|
|
60
60
|
font-size: 13px;
|
|
61
61
|
position: relative;
|
|
62
|
-
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
top: 7px;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
.akinon-
|
|
66
|
-
margin-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.akinon-filter__common-filters-title {
|
|
70
|
-
color: var(--color-gray-500);
|
|
71
|
-
margin-bottom: 1rem;
|
|
66
|
+
.akinon-filter__section-header span {
|
|
67
|
+
margin-inline-end: unset !important;
|
|
68
|
+
flex: unset !important;
|
|
72
69
|
}
|
|
73
70
|
|
|
74
71
|
.akinon-filter__form-grid {
|
|
@@ -121,8 +118,10 @@
|
|
|
121
118
|
|
|
122
119
|
.akinon-filter__applied-items {
|
|
123
120
|
display: flex;
|
|
121
|
+
flex: 1;
|
|
124
122
|
flex-wrap: wrap;
|
|
125
123
|
gap: 8px;
|
|
124
|
+
min-width: 0;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
.akinon-filter__chip {
|
|
@@ -136,6 +135,16 @@
|
|
|
136
135
|
height: 24px;
|
|
137
136
|
}
|
|
138
137
|
|
|
138
|
+
.akinon-filter__chip--exclude {
|
|
139
|
+
background-color: #ffe0e4;
|
|
140
|
+
border: 1px solid #ff354e;
|
|
141
|
+
height: 23px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.akinon-filter__chip-exclude-icon {
|
|
145
|
+
margin-right: 5px;
|
|
146
|
+
}
|
|
147
|
+
|
|
139
148
|
.akinon-filter__chip-label {
|
|
140
149
|
font-weight: 600;
|
|
141
150
|
color: var(--color-ebonyClay-300);
|
|
@@ -162,7 +171,7 @@
|
|
|
162
171
|
color: color(--color-ebonyClay-500);
|
|
163
172
|
font-size: 12px;
|
|
164
173
|
position: relative;
|
|
165
|
-
top:
|
|
174
|
+
top: 8px;
|
|
166
175
|
}
|
|
167
176
|
|
|
168
177
|
.akinon-filter__modal-list {
|
|
@@ -187,13 +196,13 @@
|
|
|
187
196
|
column-gap: 8px; /* replaces Ant's label padding, zeroed out below */
|
|
188
197
|
line-height: 1.4;
|
|
189
198
|
margin-inline-start: 0; /* override Ant's adjacent-sibling margin */
|
|
199
|
+
color: var(--color-white);
|
|
190
200
|
}
|
|
191
201
|
|
|
192
202
|
.akinon-filter__modal-list
|
|
193
203
|
.akinon-filter__modal-checkbox.ant-checkbox-wrapper
|
|
194
204
|
> .ant-checkbox {
|
|
195
205
|
align-self: start;
|
|
196
|
-
margin-block-start: 0.15em; /* em-relative baseline nudge */
|
|
197
206
|
}
|
|
198
207
|
|
|
199
208
|
.akinon-filter__modal-list
|
|
@@ -253,6 +262,11 @@
|
|
|
253
262
|
width: auto;
|
|
254
263
|
}
|
|
255
264
|
|
|
265
|
+
.akinon-filter .akinon-select-multiple .akinon-select-selector {
|
|
266
|
+
height: 40px;
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
}
|
|
269
|
+
|
|
256
270
|
/* Modal window. */
|
|
257
271
|
|
|
258
272
|
.akinon-filter__modal-toolbar {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FieldValues } from '@akinon/akiform';
|
|
2
|
+
import { FIELD_TYPES } from '../constants';
|
|
2
3
|
import type { AkifilterField, AkifilterSchema } from '../types';
|
|
3
4
|
/**
|
|
4
5
|
* Flattens schema by extracting all nested fields from section fields.
|
|
@@ -11,9 +12,17 @@ export declare const flattenSchema: <TFieldValues extends FieldValues = FieldVal
|
|
|
11
12
|
export declare const partitionSchema: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>) => {
|
|
12
13
|
regularFields: AkifilterSchema<TFieldValues>;
|
|
13
14
|
sectionFields: Array<AkifilterField<TFieldValues> & {
|
|
15
|
+
type: typeof FIELD_TYPES.SECTION;
|
|
14
16
|
fields: AkifilterSchema<TFieldValues>;
|
|
17
|
+
defaultExpanded?: boolean;
|
|
18
|
+
isExcludeSection?: boolean;
|
|
15
19
|
}>;
|
|
16
20
|
};
|
|
21
|
+
export declare const deriveExcludeSectionKeys: <TFieldValues extends FieldValues = FieldValues>(sectionFields: Array<AkifilterField<TFieldValues> & {
|
|
22
|
+
type: typeof FIELD_TYPES.SECTION;
|
|
23
|
+
fields: AkifilterSchema<TFieldValues>;
|
|
24
|
+
isExcludeSection?: boolean;
|
|
25
|
+
}>) => Set<string>;
|
|
17
26
|
export declare const getDisplayLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
18
27
|
export declare const getFieldAriaLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
19
28
|
export declare const ensureSchemaOrder: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>, keys: string[]) => string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/utils/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/utils/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAsC,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC1E,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,eAAe,CAAC,YAAY,CAW9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC5E,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC;IACD,aAAa,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC7C,aAAa,EAAE,KAAK,CAClB,cAAc,CAAC,YAAY,CAAC,GAAG;QAC7B,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAC;QACjC,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;QACtC,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CACF,CAAC;CAwBH,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,eAAe,KAAK,CAClB,cAAc,CAAC,YAAY,CAAC,GAAG;IAC7B,IAAI,EAAE,OAAO,WAAW,CAAC,OAAO,CAAC;IACjC,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CACF,KACA,GAAG,CAAC,MAAM,CAKV,CAAC;AAEJ,eAAO,MAAM,eAAe,GAAI,YAAY,SAAS,WAAW,GAAG,WAAW,EAC5E,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,MAEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,MAEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,EACrC,MAAM,MAAM,EAAE,KACb,MAAM,EAGR,CAAC;AAkBF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,EACnC,aAAa,YAAY,EACzB,iBAAiB,OAAO,KACvB,OAAO,GAAG,SAC8D,CAAC;AAE5E,eAAO,MAAM,wBAAwB,GACnC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,MAAM,EAUR,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,KACpC,OAAO,CAAC,YAAY,CAQtB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,YAAY,SAAS,WAAW,EACnE,OAAO,cAAc,CAAC,YAAY,CAAC,KAClC,OAA4C,CAAC;AAEhD,eAAO,MAAM,uBAAuB,GAClC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,EACrC,SAAS,OAAO,CAAC,YAAY,CAAC,KAC7B,OAAO,CAAC,YAAY,CA0CtB,CAAC"}
|
package/dist/esm/utils/schema.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { akidate } from '@akinon/akidate';
|
|
2
2
|
import { isBoolean, isFunction } from 'lodash-es';
|
|
3
|
-
import { DEFAULT_VISIBLE_COUNT } from '../constants';
|
|
3
|
+
import { DEFAULT_VISIBLE_COUNT, FIELD_MODES, FIELD_TYPES } from '../constants';
|
|
4
4
|
/**
|
|
5
5
|
* Flattens schema by extracting all nested fields from section fields.
|
|
6
6
|
* This is used for storage operations and form value management.
|
|
7
7
|
*/
|
|
8
8
|
export const flattenSchema = (schema) => {
|
|
9
9
|
return schema.reduce((acc, field) => {
|
|
10
|
-
if (field.type ===
|
|
10
|
+
if (field.type === FIELD_TYPES.SECTION && 'fields' in field) {
|
|
11
11
|
// Recursively flatten nested section fields
|
|
12
12
|
return [
|
|
13
13
|
...acc,
|
|
@@ -24,7 +24,7 @@ export const partitionSchema = (schema) => {
|
|
|
24
24
|
const regularFields = [];
|
|
25
25
|
const sectionFields = [];
|
|
26
26
|
schema.forEach(field => {
|
|
27
|
-
if (field.type ===
|
|
27
|
+
if (field.type === FIELD_TYPES.SECTION) {
|
|
28
28
|
sectionFields.push(field);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
@@ -33,6 +33,9 @@ export const partitionSchema = (schema) => {
|
|
|
33
33
|
});
|
|
34
34
|
return { regularFields, sectionFields };
|
|
35
35
|
};
|
|
36
|
+
export const deriveExcludeSectionKeys = (sectionFields) => new Set(sectionFields
|
|
37
|
+
.filter(s => s.isExcludeSection)
|
|
38
|
+
.flatMap(s => s.fields.map(f => String(f.key))));
|
|
36
39
|
export const getDisplayLabel = (field) => {
|
|
37
40
|
return field.label || field.placeholder || String(field.key);
|
|
38
41
|
};
|
|
@@ -84,15 +87,16 @@ export const normaliseValuesBySchema = (schema, values) => {
|
|
|
84
87
|
return acc;
|
|
85
88
|
}
|
|
86
89
|
const currentValue = values[key];
|
|
87
|
-
if (field.type ===
|
|
90
|
+
if (field.type === FIELD_TYPES.DATE) {
|
|
88
91
|
const parsed = akidate.parse(currentValue);
|
|
89
92
|
if (parsed) {
|
|
90
93
|
acc[key] = parsed;
|
|
91
94
|
return acc;
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
|
-
if (field.type ===
|
|
95
|
-
(field.mode ===
|
|
97
|
+
if (field.type === FIELD_TYPES.SELECT &&
|
|
98
|
+
(field.mode === FIELD_MODES.MULTIPLE ||
|
|
99
|
+
field.mode === FIELD_MODES.TAGS) &&
|
|
96
100
|
currentValue != null &&
|
|
97
101
|
!Array.isArray(currentValue)) {
|
|
98
102
|
acc[key] = [currentValue];
|
package/dist/esm/utils/values.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { akidate } from '@akinon/akidate';
|
|
2
|
-
import { DATE_FORMAT, DATETIME_FORMAT } from '../constants';
|
|
2
|
+
import { DATE_FORMAT, DATETIME_FORMAT, FIELD_TYPES } from '../constants';
|
|
3
3
|
export const shouldPersistValue = (field, value) => {
|
|
4
4
|
if (value === undefined || value === null) {
|
|
5
5
|
return false;
|
|
@@ -10,10 +10,10 @@ export const shouldPersistValue = (field, value) => {
|
|
|
10
10
|
if (Array.isArray(value) && value.length === 0) {
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
13
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === FIELD_TYPES.CHECKBOX && value !== true) {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
16
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === FIELD_TYPES.FILE) {
|
|
17
17
|
return value instanceof File;
|
|
18
18
|
}
|
|
19
19
|
return true;
|
|
@@ -29,7 +29,7 @@ export const normaliseOutputValues = (schema, values) => {
|
|
|
29
29
|
return acc;
|
|
30
30
|
}
|
|
31
31
|
let normalisedValue = rawValue;
|
|
32
|
-
if ((field === null || field === void 0 ? void 0 : field.type) ===
|
|
32
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === FIELD_TYPES.DATE) {
|
|
33
33
|
const normalised = akidate.toIsoDate(rawValue);
|
|
34
34
|
if (!normalised) {
|
|
35
35
|
return acc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/akifilter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Akifilter is a filtering library for Akinon frontend applications.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"@akinon/ui-collapse": "1.4.7",
|
|
24
24
|
"@akinon/ui-date-picker": "1.5.3",
|
|
25
25
|
"@akinon/ui-input": "1.2.10",
|
|
26
|
-
"@akinon/ui-modal": "1.2.10",
|
|
27
26
|
"@akinon/ui-input-number": "1.4.10",
|
|
27
|
+
"@akinon/ui-modal": "1.2.10",
|
|
28
28
|
"@akinon/ui-pagination": "1.4.13",
|
|
29
29
|
"@akinon/ui-select": "1.4.13",
|
|
30
30
|
"@akinon/ui-space": "1.4.10",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"copyfiles": "^2.4.1",
|
|
38
38
|
"rimraf": "^5.0.5",
|
|
39
39
|
"typescript": "*",
|
|
40
|
-
"@akinon/akiform-builder": "1.
|
|
40
|
+
"@akinon/akiform-builder": "1.6.0",
|
|
41
41
|
"@akinon/typescript-config": "1.1.8",
|
|
42
42
|
"@akinon/utils": "1.2.11",
|
|
43
43
|
"@akinon/ui-theme": "1.3.1",
|