@akinon/akifilter 1.3.6 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/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 +15 -3
- 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 +15 -3
- 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/styles.css
CHANGED
|
@@ -22,13 +22,24 @@
|
|
|
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;
|
|
28
39
|
padding: 6px;
|
|
29
40
|
background-color: var(--color-ebonyClay-500);
|
|
30
41
|
border-radius: 6px;
|
|
31
|
-
box-shadow: inset 0 1px 4px 0
|
|
42
|
+
box-shadow: inset 0 1px 4px 0 var(--color-neutral-1000-20);
|
|
32
43
|
margin-bottom: 1rem;
|
|
33
44
|
}
|
|
34
45
|
|
|
@@ -89,12 +100,13 @@
|
|
|
89
100
|
color: var(--color-gray-500);
|
|
90
101
|
}
|
|
91
102
|
|
|
92
|
-
.akinon-filter__section-fields
|
|
103
|
+
.akinon-filter__section-fields
|
|
104
|
+
.akinon-collapse-expand-icon
|
|
105
|
+
.akinon-collapse-arrow {
|
|
93
106
|
font-size: 1rem !important;
|
|
94
107
|
color: var(--color-gray-500) !important;
|
|
95
108
|
}
|
|
96
109
|
|
|
97
|
-
|
|
98
110
|
@media (max-width: 1024px) {
|
|
99
111
|
.akinon-filter__form-grid {
|
|
100
112
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css';
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -10,17 +10,19 @@ export interface AkifilterFieldConfig<TFieldValues extends FieldValues = FieldVa
|
|
|
10
10
|
* Controls whether the field is visible.
|
|
11
11
|
* Can be a boolean or a function that receives form values and returns a boolean.
|
|
12
12
|
*/
|
|
13
|
-
visible?: boolean | ((formValues: TFieldValues) => boolean);
|
|
13
|
+
visible?: boolean | ((formValues: TFieldValues, currentVisible?: boolean) => boolean);
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* Controls whether the field is shown in the main filter form by default.
|
|
18
|
-
*/
|
|
19
|
-
isVisible?: boolean;
|
|
15
|
+
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
16
|
+
export type AkifilterField<TFieldValues extends FieldValues = FieldValues> = DistributiveOmit<FormField<TFieldValues>, 'config'> & {
|
|
20
17
|
/**
|
|
21
18
|
* Configuration options for field behavior (disabled, visible).
|
|
22
19
|
*/
|
|
23
20
|
config?: AkifilterFieldConfig<TFieldValues>;
|
|
21
|
+
/**
|
|
22
|
+
* Accepted file types for file fields (e.g. '.csv,.xls').
|
|
23
|
+
* Only applicable when `type` is `'file'`.
|
|
24
|
+
*/
|
|
25
|
+
fileAccept?: string;
|
|
24
26
|
};
|
|
25
27
|
export type AkifilterFieldKey<TFieldValues extends FieldValues = FieldValues> = Path<TFieldValues>;
|
|
26
28
|
export type AkifilterSchema<TFieldValues extends FieldValues = FieldValues> = AkifilterField<TFieldValues>[];
|
|
@@ -34,4 +36,5 @@ export interface AkifilterActionsRef {
|
|
|
34
36
|
*/
|
|
35
37
|
clearValue: (keys: string | string[]) => void;
|
|
36
38
|
}
|
|
39
|
+
export {};
|
|
37
40
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,oBAAoB,CACnC,YAAY,SAAS,WAAW,GAAG,WAAW;IAE9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;IAC7D;;;OAGG;IACH,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,oBAAoB,CACnC,YAAY,SAAS,WAAW,GAAG,WAAW;IAE9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;IAC7D;;;OAGG;IACH,OAAO,CAAC,EACJ,OAAO,GACP,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;CACvE;AAED,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,OAAO,GAC/D,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACV,KAAK,CAAC;AAEV,MAAM,MAAM,cAAc,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACvE,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,GAAG;IACpD;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEJ,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IAC1E,IAAI,CAAC,YAAY,CAAC,CAAC;AAErB,MAAM,MAAM,eAAe,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IACxE,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC/C"}
|
|
@@ -17,7 +17,12 @@ export declare const partitionSchema: <TFieldValues extends FieldValues = FieldV
|
|
|
17
17
|
export declare const getDisplayLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
18
18
|
export declare const getFieldAriaLabel: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>) => string;
|
|
19
19
|
export declare const ensureSchemaOrder: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>, keys: string[]) => string[];
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the visibility of a field.
|
|
22
|
+
*/
|
|
23
|
+
export declare const resolveFieldVisibility: <TFieldValues extends FieldValues = FieldValues>(field: AkifilterField<TFieldValues>, formValues?: TFieldValues, currentVisible?: boolean) => boolean | undefined;
|
|
20
24
|
export declare const deriveDefaultVisibleKeys: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>) => string[];
|
|
21
25
|
export declare const extractDefaultValues: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>) => Partial<TFieldValues>;
|
|
26
|
+
export declare const hasDynamicVisibility: <TFieldValues extends FieldValues>(field: AkifilterField<TFieldValues>) => boolean;
|
|
22
27
|
export declare const normaliseValuesBySchema: <TFieldValues extends FieldValues = FieldValues>(schema: AkifilterSchema<TFieldValues>, values?: Partial<TFieldValues>) => Partial<TFieldValues>;
|
|
23
28
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -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;AAInD,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,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;KACvC,CACF,CAAC;CAwBH,CAAC;AAEF,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,CAyCtB,CAAC"}
|
package/dist/cjs/utils/schema.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normaliseValuesBySchema = exports.extractDefaultValues = exports.deriveDefaultVisibleKeys = 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.partitionSchema = exports.flattenSchema = void 0;
|
|
4
4
|
const akidate_1 = require("@akinon/akidate");
|
|
5
|
+
const lodash_es_1 = require("lodash-es");
|
|
5
6
|
const constants_1 = require("../constants");
|
|
6
7
|
/**
|
|
7
8
|
* Flattens schema by extracting all nested fields from section fields.
|
|
@@ -50,12 +51,24 @@ const ensureSchemaOrder = (schema, keys) => {
|
|
|
50
51
|
return schema.map(field => String(field.key)).filter(key => keySet.has(key));
|
|
51
52
|
};
|
|
52
53
|
exports.ensureSchemaOrder = ensureSchemaOrder;
|
|
54
|
+
const resolveVisibilityValue = (value, formValues, currentVisible) => {
|
|
55
|
+
if ((0, lodash_es_1.isBoolean)(value))
|
|
56
|
+
return value;
|
|
57
|
+
if ((0, lodash_es_1.isFunction)(value))
|
|
58
|
+
return value(formValues !== null && formValues !== void 0 ? formValues : {}, currentVisible !== null && currentVisible !== void 0 ? currentVisible : false);
|
|
59
|
+
return undefined;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the visibility of a field.
|
|
63
|
+
*/
|
|
64
|
+
const resolveFieldVisibility = (field, formValues, currentVisible) => { var _a; return resolveVisibilityValue((_a = field.config) === null || _a === void 0 ? void 0 : _a.visible, formValues, currentVisible); };
|
|
65
|
+
exports.resolveFieldVisibility = resolveFieldVisibility;
|
|
53
66
|
const deriveDefaultVisibleKeys = (schema) => {
|
|
54
67
|
const explicitKeys = schema
|
|
55
|
-
.filter(field =>
|
|
68
|
+
.filter(field => (0, exports.resolveFieldVisibility)(field) === true)
|
|
56
69
|
.map(field => String(field.key));
|
|
57
70
|
if (explicitKeys.length > 0) {
|
|
58
|
-
return (0, exports.ensureSchemaOrder)(schema,
|
|
71
|
+
return (0, exports.ensureSchemaOrder)(schema, explicitKeys);
|
|
59
72
|
}
|
|
60
73
|
return schema.slice(0, constants_1.DEFAULT_VISIBLE_COUNT).map(field => String(field.key));
|
|
61
74
|
};
|
|
@@ -70,6 +83,8 @@ const extractDefaultValues = (schema) => {
|
|
|
70
83
|
}, {});
|
|
71
84
|
};
|
|
72
85
|
exports.extractDefaultValues = extractDefaultValues;
|
|
86
|
+
const hasDynamicVisibility = (field) => { var _a; return (0, lodash_es_1.isFunction)((_a = field.config) === null || _a === void 0 ? void 0 : _a.visible); };
|
|
87
|
+
exports.hasDynamicVisibility = hasDynamicVisibility;
|
|
73
88
|
const normaliseValuesBySchema = (schema, values) => {
|
|
74
89
|
if (!values) {
|
|
75
90
|
return {};
|
|
@@ -88,6 +103,13 @@ const normaliseValuesBySchema = (schema, values) => {
|
|
|
88
103
|
return acc;
|
|
89
104
|
}
|
|
90
105
|
}
|
|
106
|
+
if (field.type === 'select' &&
|
|
107
|
+
(field.mode === 'multiple' || field.mode === 'tags') &&
|
|
108
|
+
currentValue != null &&
|
|
109
|
+
!Array.isArray(currentValue)) {
|
|
110
|
+
acc[key] = [currentValue];
|
|
111
|
+
return acc;
|
|
112
|
+
}
|
|
91
113
|
acc[key] = currentValue;
|
|
92
114
|
return acc;
|
|
93
115
|
}, {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../../src/utils/values.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhE,eAAO,MAAM,kBAAkB,GAC7B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,GAAG,SAAS,EAC/C,OAAO,OAAO,KACb,
|
|
1
|
+
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../../src/utils/values.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhE,eAAO,MAAM,kBAAkB,GAC7B,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,OAAO,cAAc,CAAC,YAAY,CAAC,GAAG,SAAS,EAC/C,OAAO,OAAO,KACb,OAsBF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,YAAY,SAAS,WAAW,GAAG,WAAW,EAE9C,QAAQ,eAAe,CAAC,YAAY,CAAC,EACrC,SAAS,OAAO,CAAC,YAAY,CAAC,GAAG,WAAW,KAC3C,OAAO,CAAC,YAAY,CAkCtB,CAAC"}
|
package/dist/cjs/utils/values.js
CHANGED
|
@@ -16,6 +16,9 @@ const shouldPersistValue = (field, value) => {
|
|
|
16
16
|
if ((field === null || field === void 0 ? void 0 : field.type) === 'checkbox' && value !== true) {
|
|
17
17
|
return false;
|
|
18
18
|
}
|
|
19
|
+
if ((field === null || field === void 0 ? void 0 : field.type) === 'file') {
|
|
20
|
+
return value instanceof File;
|
|
21
|
+
}
|
|
19
22
|
return true;
|
|
20
23
|
};
|
|
21
24
|
exports.shouldPersistValue = shouldPersistValue;
|
package/dist/esm/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/esm/akifilter.js
CHANGED
|
@@ -21,6 +21,7 @@ import { Input, InputTextArea } from '@akinon/ui-input';
|
|
|
21
21
|
import { InputNumber } from '@akinon/ui-input-number';
|
|
22
22
|
import { Select } from '@akinon/ui-select';
|
|
23
23
|
import { Text, Title } from '@akinon/ui-typography';
|
|
24
|
+
import { Upload } from '@akinon/ui-upload';
|
|
24
25
|
import { ConfigProvider } from 'antd';
|
|
25
26
|
import React from 'react';
|
|
26
27
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
@@ -31,8 +32,10 @@ import { FilterToolbar } from './components/filter-toolbar';
|
|
|
31
32
|
import { VisibilityModal } from './components/visibility-modal';
|
|
32
33
|
import { BOOLEAN_STRING, DEFAULT_MODAL_PAGE_SIZE, FILTER_DEBOUNCE_DELAY } from './constants';
|
|
33
34
|
import { useDebouncedValue } from './hooks/use-debounced-value';
|
|
35
|
+
import { useDynamicVisibility } from './hooks/use-dynamic-visibility';
|
|
36
|
+
import { useVisibilityCleanup } from './hooks/use-visibility-cleanup';
|
|
34
37
|
import { i18n } from './i18n';
|
|
35
|
-
import { deriveDefaultVisibleKeys, ensureSchemaOrder, extractDefaultValues, flattenSchema, getFieldAriaLabel, normaliseValuesBySchema, partitionSchema } from './utils/schema';
|
|
38
|
+
import { deriveDefaultVisibleKeys, ensureSchemaOrder, extractDefaultValues, flattenSchema, getFieldAriaLabel, normaliseValuesBySchema, partitionSchema, resolveFieldVisibility } from './utils/schema';
|
|
36
39
|
import { normaliseOutputValues } from './utils/values';
|
|
37
40
|
const FilterFormItem = (_a) => {
|
|
38
41
|
var _b, _c;
|
|
@@ -60,6 +63,21 @@ const FilterFormItem = (_a) => {
|
|
|
60
63
|
});
|
|
61
64
|
return (React.createElement(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));
|
|
62
65
|
};
|
|
66
|
+
const FileFilterInput = ({ value, onChange, accept, disabled, 'aria-label': ariaLabel }) => {
|
|
67
|
+
const handleBeforeUpload = (file) => {
|
|
68
|
+
var _a;
|
|
69
|
+
onChange === null || onChange === void 0 ? void 0 : onChange((_a = file.originFileObj) !== null && _a !== void 0 ? _a : file);
|
|
70
|
+
// Prevent antd from uploading automatically
|
|
71
|
+
return false;
|
|
72
|
+
};
|
|
73
|
+
const handleRemove = () => {
|
|
74
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(null);
|
|
75
|
+
};
|
|
76
|
+
const fileList = value
|
|
77
|
+
? [{ uid: value.name, name: value.name, originFileObj: value }]
|
|
78
|
+
: [];
|
|
79
|
+
return (React.createElement(Upload, { accept: accept, beforeUpload: handleBeforeUpload, onRemove: handleRemove, fileList: fileList, maxCount: 1, disabled: disabled, "aria-label": ariaLabel }));
|
|
80
|
+
};
|
|
63
81
|
/**
|
|
64
82
|
* Checks if a field should be disabled based on config.disabled property.
|
|
65
83
|
*/
|
|
@@ -71,17 +89,6 @@ const checkIsDisabled = (field, formValues) => {
|
|
|
71
89
|
}
|
|
72
90
|
return Boolean(configDisabled);
|
|
73
91
|
};
|
|
74
|
-
/**
|
|
75
|
-
* Checks if a field should be visible based on config.visible property.
|
|
76
|
-
*/
|
|
77
|
-
const checkIsVisible = (field, formValues) => {
|
|
78
|
-
var _a;
|
|
79
|
-
const configVisible = (_a = field.config) === null || _a === void 0 ? void 0 : _a.visible;
|
|
80
|
-
if (typeof configVisible === 'function') {
|
|
81
|
-
return configVisible(formValues);
|
|
82
|
-
}
|
|
83
|
-
return configVisible !== false;
|
|
84
|
-
};
|
|
85
92
|
const resolveClearedFieldValue = (field, defaultValue) => {
|
|
86
93
|
if (defaultValue !== undefined) {
|
|
87
94
|
return defaultValue;
|
|
@@ -94,13 +101,19 @@ const resolveClearedFieldValue = (field, defaultValue) => {
|
|
|
94
101
|
return false;
|
|
95
102
|
case 'number':
|
|
96
103
|
case 'date':
|
|
104
|
+
return null;
|
|
97
105
|
case 'select':
|
|
106
|
+
if (field.mode === 'multiple' || field.mode === 'tags') {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
case 'file':
|
|
98
111
|
return null;
|
|
99
112
|
default:
|
|
100
113
|
return undefined;
|
|
101
114
|
}
|
|
102
115
|
};
|
|
103
|
-
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef }) => {
|
|
116
|
+
const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onValuesChange, onVisibleFieldsChange, onImportCsv, onImportXls, onClearAll, enableImportCsv, enableImportXls, filterActionsRef, externalAppliedFilters, onRemoveExternalFilter }) => {
|
|
104
117
|
// Separate regular fields from section fields
|
|
105
118
|
const { regularFields, sectionFields } = React.useMemo(() => partitionSchema(filterSchema), [filterSchema]);
|
|
106
119
|
// Flatten schema for storage and form value operations
|
|
@@ -148,15 +161,29 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
148
161
|
return acc;
|
|
149
162
|
}
|
|
150
163
|
const label = field.label || field.placeholder || key;
|
|
151
|
-
const
|
|
164
|
+
const fieldOptions = 'options' in field && field.options ? field.options : undefined;
|
|
165
|
+
const resolveLabel = (val) => {
|
|
152
166
|
var _a;
|
|
153
|
-
|
|
167
|
+
const match = fieldOptions === null || fieldOptions === void 0 ? void 0 : fieldOptions.find(option => option.value === val);
|
|
168
|
+
return String((_a = match === null || match === void 0 ? void 0 : match.label) !== null && _a !== void 0 ? _a : val);
|
|
169
|
+
};
|
|
170
|
+
const resolveArrayLabels = (values) => {
|
|
171
|
+
return values.map(resolveLabel).join(', ');
|
|
172
|
+
};
|
|
173
|
+
const resolveSelectLabel = () => {
|
|
174
|
+
if (!fieldOptions) {
|
|
154
175
|
return String(currentValue);
|
|
155
176
|
}
|
|
156
|
-
|
|
157
|
-
|
|
177
|
+
if (Array.isArray(currentValue)) {
|
|
178
|
+
return resolveArrayLabels(currentValue);
|
|
179
|
+
}
|
|
180
|
+
return resolveLabel(currentValue);
|
|
158
181
|
};
|
|
159
182
|
const resolveValue = () => {
|
|
183
|
+
if (field.type === 'file') {
|
|
184
|
+
const fileValue = currentValue;
|
|
185
|
+
return fileValue instanceof File ? fileValue.name : String(fileValue);
|
|
186
|
+
}
|
|
160
187
|
if (field.type === 'select') {
|
|
161
188
|
return resolveSelectLabel();
|
|
162
189
|
}
|
|
@@ -175,7 +202,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
175
202
|
}
|
|
176
203
|
}
|
|
177
204
|
if (Array.isArray(currentValue)) {
|
|
178
|
-
return currentValue
|
|
205
|
+
return resolveArrayLabels(currentValue);
|
|
179
206
|
}
|
|
180
207
|
if (typeof currentValue === 'boolean') {
|
|
181
208
|
return currentValue ? BOOLEAN_STRING.TRUE : BOOLEAN_STRING.FALSE;
|
|
@@ -197,10 +224,24 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
197
224
|
}, [flattenedSchema, formValues]);
|
|
198
225
|
const resolveInitialVisibleKeys = React.useCallback(() => {
|
|
199
226
|
const storedKeys = readVisibleKeys(regularFields, storageKey);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
const defaultKeys = deriveDefaultVisibleKeys(regularFields);
|
|
228
|
+
const baseKeys = storedKeys && storedKeys.length > 0
|
|
229
|
+
? ensureSchemaOrder(regularFields, storedKeys)
|
|
230
|
+
: defaultKeys;
|
|
231
|
+
return regularFields.reduce((acc, field) => {
|
|
232
|
+
const key = String(field.key);
|
|
233
|
+
const explicitVisibility = resolveFieldVisibility(field);
|
|
234
|
+
if (explicitVisibility !== undefined) {
|
|
235
|
+
if (explicitVisibility)
|
|
236
|
+
acc.push(key);
|
|
237
|
+
return acc;
|
|
238
|
+
}
|
|
239
|
+
// No explicit boolean visibility, use stored/default
|
|
240
|
+
if (baseKeys.includes(key)) {
|
|
241
|
+
acc.push(key);
|
|
242
|
+
}
|
|
243
|
+
return acc;
|
|
244
|
+
}, []);
|
|
204
245
|
}, [regularFields, storageKey]);
|
|
205
246
|
const [visibleKeys, setVisibleKeys] = React.useState(resolveInitialVisibleKeys);
|
|
206
247
|
React.useEffect(() => {
|
|
@@ -425,8 +466,31 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
425
466
|
const start = (modalPage - 1) * modalPageSize;
|
|
426
467
|
return filteredFields.slice(start, start + modalPageSize);
|
|
427
468
|
}, [filteredFields, modalPage, modalPageSize]);
|
|
428
|
-
const visibleFields = React.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key))
|
|
429
|
-
|
|
469
|
+
const visibleFields = React.useMemo(() => regularFields.filter(field => visibleKeys.includes(String(field.key))), [regularFields, visibleKeys]);
|
|
470
|
+
// Dynamic visibility
|
|
471
|
+
useDynamicVisibility({
|
|
472
|
+
regularFields,
|
|
473
|
+
formValues: normalisedValues,
|
|
474
|
+
setVisibleKeys
|
|
475
|
+
});
|
|
476
|
+
// Visibility cleanup
|
|
477
|
+
useVisibilityCleanup({
|
|
478
|
+
visibleKeys,
|
|
479
|
+
regularFields,
|
|
480
|
+
onRemove: handleRemoveFilter
|
|
481
|
+
});
|
|
482
|
+
const handleAppliedFilterRemove = React.useCallback((key) => {
|
|
483
|
+
if (externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.some(f => f.key === key)) {
|
|
484
|
+
onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(key);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
handleRemoveFilter(key);
|
|
488
|
+
}
|
|
489
|
+
}, [externalAppliedFilters, onRemoveExternalFilter, handleRemoveFilter]);
|
|
490
|
+
const handleClearAllApplied = React.useCallback(() => {
|
|
491
|
+
handleClearAll();
|
|
492
|
+
externalAppliedFilters === null || externalAppliedFilters === void 0 ? void 0 : externalAppliedFilters.forEach(f => onRemoveExternalFilter === null || onRemoveExternalFilter === void 0 ? void 0 : onRemoveExternalFilter(f.key));
|
|
493
|
+
}, [handleClearAll, externalAppliedFilters, onRemoveExternalFilter]);
|
|
430
494
|
const renderFieldComponent = (field) => {
|
|
431
495
|
const ariaLabel = getFieldAriaLabel(field);
|
|
432
496
|
const isDisabled = checkIsDisabled(field, formValues !== null && formValues !== void 0 ? formValues : {});
|
|
@@ -436,17 +500,20 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
436
500
|
case 'number':
|
|
437
501
|
return (React.createElement(InputNumber, { placeholder: field.placeholder, size: "large", className: "akinon-filter__field--number", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
438
502
|
case 'select':
|
|
439
|
-
return (React.createElement(Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
503
|
+
return (React.createElement(Select, { placeholder: field.placeholder, size: "large", options: field.options, showSearch: true, optionFilterProp: "label", "aria-label": ariaLabel, disabled: isDisabled, mode: field.mode }));
|
|
440
504
|
case 'checkbox':
|
|
441
505
|
return React.createElement(Checkbox, { disabled: isDisabled }, field.label);
|
|
442
506
|
case 'date':
|
|
443
507
|
return (React.createElement(DatePicker, { placeholder: field.placeholder, showTime: field.showTime, suffixIcon: "calendar", suffixIconSize: "16px", "aria-label": ariaLabel, disabled: isDisabled }));
|
|
444
508
|
case 'textarea':
|
|
445
509
|
return (React.createElement(InputTextArea, { placeholder: field.placeholder, autoSize: { minRows: 3, maxRows: 6 }, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
510
|
+
case 'file':
|
|
511
|
+
return (React.createElement(FileFilterInput, { accept: field.fileAccept, "aria-label": ariaLabel, disabled: isDisabled }));
|
|
446
512
|
case 'custom':
|
|
447
513
|
if (typeof field.render === 'function') {
|
|
448
514
|
return field.render({
|
|
449
|
-
|
|
515
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
516
|
+
field: field,
|
|
450
517
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
451
518
|
control: formMethods.control,
|
|
452
519
|
formValues: formMethods.getValues(),
|
|
@@ -468,7 +535,7 @@ const AkifilterContent = ({ filterSchema, storageNamespace, defaultValues, onVal
|
|
|
468
535
|
return (React.createElement(Card, { size: "small", className: "akinon-filter shadow", "data-testid": "akifilter-root" },
|
|
469
536
|
React.createElement(ConfigProvider, { theme: themeOverrides },
|
|
470
537
|
React.createElement(FilterToolbar, { onOpenModal: handleOpenModal, enableImportCsv: enableImportCsv, enableImportXls: enableImportXls, onImportCsv: onImportCsv, onImportXls: onImportXls }),
|
|
471
|
-
React.createElement(AppliedFilters, { filters: appliedFilters, onRemove:
|
|
538
|
+
React.createElement(AppliedFilters, { filters: [...appliedFilters, ...(externalAppliedFilters !== null && externalAppliedFilters !== void 0 ? externalAppliedFilters : [])], onRemove: handleAppliedFilterRemove, onClearAll: handleClearAllApplied }),
|
|
472
539
|
React.createElement("div", { className: "akinon-filter__body" },
|
|
473
540
|
React.createElement(Akiform, { layout: "vertical", className: "akinon-filter__form" },
|
|
474
541
|
React.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"}
|
|
@@ -11,7 +11,12 @@ const hashString = (value) => {
|
|
|
11
11
|
return Math.abs(hash).toString(36);
|
|
12
12
|
};
|
|
13
13
|
const buildSchemaSignature = (schema) => {
|
|
14
|
-
return schema
|
|
14
|
+
return schema
|
|
15
|
+
.map(field => {
|
|
16
|
+
const mode = field.type === 'select' && field.mode ? `:${field.mode}` : '';
|
|
17
|
+
return `${String(field.key)}:${field.type}${mode}`;
|
|
18
|
+
})
|
|
19
|
+
.join('|');
|
|
15
20
|
};
|
|
16
21
|
export const buildStorageKey = (schema, namespace) => {
|
|
17
22
|
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"}
|
|
@@ -10,9 +10,9 @@ export const AppliedFilters = ({ filters, onRemove, onClearAll }) => {
|
|
|
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
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" },
|
|
13
|
-
React.createElement("span", { className: "akinon-filter__chip-label" },
|
|
13
|
+
item.label ? (React.createElement("span", { className: "akinon-filter__chip-label" },
|
|
14
14
|
item.label,
|
|
15
|
-
":"),
|
|
15
|
+
":")) : null,
|
|
16
16
|
React.createElement("span", { className: "akinon-filter__chip-value" }, item.value),
|
|
17
17
|
React.createElement("button", { type: "button", "aria-label": i18n.t('applied.clearSingle', {
|
|
18
18
|
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"}
|
|
@@ -3,11 +3,27 @@ import { Space } from '@akinon/ui-space';
|
|
|
3
3
|
import { Title } from '@akinon/ui-typography';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { i18n } from '../i18n';
|
|
6
|
+
const FileImportButton = ({ accept, label, onImport }) => {
|
|
7
|
+
const inputRef = React.useRef(null);
|
|
8
|
+
const handleClick = () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click(); };
|
|
9
|
+
const handleChange = (e) => {
|
|
10
|
+
var _a;
|
|
11
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
12
|
+
if (file) {
|
|
13
|
+
onImport(file);
|
|
14
|
+
}
|
|
15
|
+
// Reset so same file can be re-selected
|
|
16
|
+
e.target.value = '';
|
|
17
|
+
};
|
|
18
|
+
return (React.createElement(React.Fragment, null,
|
|
19
|
+
React.createElement("input", { ref: inputRef, type: "file", accept: accept, style: { display: 'none' }, onChange: handleChange }),
|
|
20
|
+
React.createElement(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)));
|
|
21
|
+
};
|
|
6
22
|
export const FilterToolbar = ({ onOpenModal, enableImportCsv, enableImportXls, onImportCsv, onImportXls }) => {
|
|
7
23
|
return (React.createElement("div", { className: "akinon-filter__top" },
|
|
8
24
|
React.createElement(Title, { className: "akinon-filter__title", level: 4 }, i18n.t('header.title')),
|
|
9
25
|
React.createElement(Space, { className: "akinon-filter__toolbar", size: 6 },
|
|
10
|
-
enableImportCsv && onImportCsv ? (React.createElement(
|
|
11
|
-
enableImportXls && onImportXls ? (React.createElement(
|
|
26
|
+
enableImportCsv && onImportCsv ? (React.createElement(FileImportButton, { accept: ".csv", label: i18n.t('header.actions.importCsv'), onImport: onImportCsv })) : null,
|
|
27
|
+
enableImportXls && onImportXls ? (React.createElement(FileImportButton, { accept: ".xls,.xlsx", label: i18n.t('header.actions.importXls'), onImport: onImportXls })) : null,
|
|
12
28
|
React.createElement(Button, { className: "akinon-filter__toolbar-item", icon: "filter", iconSize: 16, onClick: onOpenModal, type: "primary", title: i18n.t('header.actions.selectFilters'), "aria-label": i18n.t('header.actions.selectFilters') }))));
|
|
13
29
|
};
|
|
@@ -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"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { field } from '@akinon/akiform-builder';
|
|
2
2
|
export const filterField = () => {
|
|
3
3
|
const baseBuilder = field();
|
|
4
|
-
let
|
|
4
|
+
let fieldConfig;
|
|
5
5
|
const builder = baseBuilder;
|
|
6
|
-
builder.
|
|
7
|
-
|
|
6
|
+
builder.config = cfg => {
|
|
7
|
+
fieldConfig = Object.assign(Object.assign({}, fieldConfig), cfg);
|
|
8
8
|
return builder;
|
|
9
9
|
};
|
|
10
10
|
const originalBuild = baseBuilder.build.bind(baseBuilder);
|
|
11
11
|
builder.build = () => {
|
|
12
12
|
const builtField = originalBuild();
|
|
13
13
|
const filterFieldDefinition = Object.assign({}, builtField);
|
|
14
|
-
if (
|
|
15
|
-
filterFieldDefinition.
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
delete filterFieldDefinition.isVisible;
|
|
14
|
+
if (fieldConfig !== undefined) {
|
|
15
|
+
filterFieldDefinition.config = Object.assign(Object.assign({}, filterFieldDefinition.config), fieldConfig);
|
|
19
16
|
}
|
|
20
17
|
return filterFieldDefinition;
|
|
21
18
|
};
|
|
@@ -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"}
|