@trackunit/filters-filter-bar 0.0.579 → 0.0.581
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/index.cjs.js +93 -46
- package/index.esm.js +95 -49
- package/package.json +1 -1
- package/src/lib/FilterBar.d.ts +5 -1
- package/src/lib/components/DefaultRadioFilter.d.ts +1 -1
- package/src/lib/components/StarredFilters.d.ts +7 -2
- package/src/lib/hooks/useFilterBar.d.ts +3 -0
- package/src/lib/types/FilterTypes.d.ts +15 -6
- package/src/lib/utils/createInitialState.d.ts +7 -1
- package/src/lib/utils/validateFilter.d.ts +6 -2
package/index.cjs.js
CHANGED
|
@@ -4,13 +4,13 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
|
|
5
5
|
var reactCoreHooks = require('@trackunit/react-core-hooks');
|
|
6
6
|
var reactFilterComponents = require('@trackunit/react-filter-components');
|
|
7
|
-
var sharedUtils = require('@trackunit/shared-utils');
|
|
8
7
|
var react = require('react');
|
|
8
|
+
var stringTs = require('string-ts');
|
|
9
9
|
var reactCoreContextsApi = require('@trackunit/react-core-contexts-api');
|
|
10
10
|
var reactComponents = require('@trackunit/react-components');
|
|
11
11
|
var reactFormComponents = require('@trackunit/react-form-components');
|
|
12
12
|
var reactDateAndTimeComponents = require('@trackunit/react-date-and-time-components');
|
|
13
|
-
var
|
|
13
|
+
var sharedUtils = require('@trackunit/shared-utils');
|
|
14
14
|
var tailwindMerge = require('tailwind-merge');
|
|
15
15
|
var dequal = require('dequal');
|
|
16
16
|
var isEqual = require('lodash/isEqual');
|
|
@@ -408,7 +408,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
408
408
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
409
409
|
const handleSetValue = (value) => {
|
|
410
410
|
logEvent("Filters Applied - V2", {
|
|
411
|
-
type: filterName !== null && filterName !== void 0 ? filterName : `${
|
|
411
|
+
type: filterName !== null && filterName !== void 0 ? filterName : `${stringTs.capitalize(filterDefinition.filterKey)}Filter`,
|
|
412
412
|
value: value.key,
|
|
413
413
|
});
|
|
414
414
|
if (filterDefinition.type === "stringArray") {
|
|
@@ -421,10 +421,10 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
421
421
|
return toggleFilterValue(value.key)(prev);
|
|
422
422
|
});
|
|
423
423
|
}
|
|
424
|
-
else if (filterDefinition.type === "
|
|
424
|
+
else if (filterDefinition.type === "valueNameArray") {
|
|
425
425
|
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
426
|
-
const
|
|
427
|
-
|
|
426
|
+
const setValueAsValueNameArray = setValue;
|
|
427
|
+
setValueAsValueNameArray(prev => {
|
|
428
428
|
if (!prev) {
|
|
429
429
|
return [{ name: value.label, value: value.key }];
|
|
430
430
|
}
|
|
@@ -462,7 +462,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
462
462
|
count: undefinedCount ? filteredOptions.length - 1 : filteredOptions.length,
|
|
463
463
|
} }), jsxRuntime.jsx(FilterResults, { ignoreUndefined: undefinedCount !== null, loading: loading, results: results, children: res => (jsxRuntime.jsx(DynamicFilterList, { checked: index => {
|
|
464
464
|
var _a, _b;
|
|
465
|
-
return filterDefinition.type === "
|
|
465
|
+
return filterDefinition.type === "valueNameArray"
|
|
466
466
|
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || "")
|
|
467
467
|
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, ((_b = res[index]) === null || _b === void 0 ? void 0 : _b.key) || "");
|
|
468
468
|
}, count: index => { var _a; return (_a = res[index]) === null || _a === void 0 ? void 0 : _a.count; }, keyMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""; }, labelMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.label) || ""; }, onChange: index => {
|
|
@@ -470,7 +470,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
470
470
|
if (result) {
|
|
471
471
|
handleSetValue(result);
|
|
472
472
|
}
|
|
473
|
-
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsxRuntime.jsx(reactFilterComponents.CheckBoxFilterItem, { checked: filterDefinition.type === "
|
|
473
|
+
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsxRuntime.jsx(reactFilterComponents.CheckBoxFilterItem, { checked: filterDefinition.type === "valueNameArray"
|
|
474
474
|
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, ((_c = results[undefinedCount.index]) === null || _c === void 0 ? void 0 : _c.key) || "")
|
|
475
475
|
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, ((_d = results[undefinedCount.index]) === null || _d === void 0 ? void 0 : _d.key) || ""), className: "rounded-none border-t-2", dataTestId: "dynamic-filter-check-box-undefined", itemCount: undefinedCount.count, label: (_e = results[undefinedCount.index]) === null || _e === void 0 ? void 0 : _e.label, name: "dynamic-filter-check-box-undefined", onChange: () => {
|
|
476
476
|
const result = results[undefinedCount.index];
|
|
@@ -564,29 +564,29 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
|
|
|
564
564
|
*
|
|
565
565
|
* @returns {JSX.Element} - Returns the DefaultRadioFilter component.
|
|
566
566
|
*/
|
|
567
|
-
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, }) => {
|
|
568
|
-
var _a, _b
|
|
567
|
+
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, setValue, }) => {
|
|
568
|
+
var _a, _b;
|
|
569
569
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
570
570
|
const [filteredOptions, searchText, setSearchText] = reactCoreHooks.useTextSearch(options, item => [item.label]);
|
|
571
571
|
const handleClick = (selectedId) => {
|
|
572
572
|
var _a;
|
|
573
573
|
const { key, label } = (_a = filteredOptions.find(({ key: id }) => id === selectedId)) !== null && _a !== void 0 ? _a : {};
|
|
574
574
|
if (key && label) {
|
|
575
|
-
|
|
575
|
+
setValue(() => ({ value: key, name: label }));
|
|
576
576
|
logEvent("Filters Applied - V2", {
|
|
577
|
-
type: filterName !== null && filterName !== void 0 ? filterName : `${
|
|
577
|
+
type: filterName !== null && filterName !== void 0 ? filterName : `${stringTs.capitalize(filterDefinition.filterKey)}Filter`,
|
|
578
578
|
value: String(label),
|
|
579
579
|
});
|
|
580
580
|
}
|
|
581
581
|
};
|
|
582
|
-
const selectedRadioId =
|
|
582
|
+
const selectedRadioId = filteredOptions.find(option => filterBarActions.objectIncludesValue(filterDefinition.filterKey, option.key));
|
|
583
583
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(FilterHeader, { ...filterBarActions, ...filterDefinition, loading: loading, searchEnabled: true, searchProps: {
|
|
584
|
-
value: (
|
|
585
|
-
onChange: (
|
|
584
|
+
value: (_a = customSearch === null || customSearch === void 0 ? void 0 : customSearch.value) !== null && _a !== void 0 ? _a : searchText,
|
|
585
|
+
onChange: (_b = customSearch === null || customSearch === void 0 ? void 0 : customSearch.onChange) !== null && _b !== void 0 ? _b : setSearchText,
|
|
586
586
|
count: filteredOptions.length,
|
|
587
587
|
} }), jsxRuntime.jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsxRuntime.jsx(reactFormComponents.RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
|
|
588
588
|
handleClick(e.currentTarget.value);
|
|
589
|
-
}, value: selectedRadioId, children: jsxRuntime.jsx(DynamicFilterList, { checked: index => { var _a; return filterBarActions.
|
|
589
|
+
}, value: (selectedRadioId === null || selectedRadioId === void 0 ? void 0 : selectedRadioId.key) || "", children: jsxRuntime.jsx(DynamicFilterList, { checked: index => { var _a; return filterBarActions.objectIncludesValue(filterDefinition.filterKey, ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""); }, count: index => { var _a; return (_a = res[index]) === null || _a === void 0 ? void 0 : _a.count; }, keyMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""; }, labelMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.label) || ""; }, rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
|
|
590
590
|
};
|
|
591
591
|
|
|
592
592
|
/**
|
|
@@ -637,17 +637,20 @@ const reduceFilterText = (input) => {
|
|
|
637
637
|
*/
|
|
638
638
|
const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
639
639
|
const values = filterBarActions.getValuesByKey(filter.filterKey);
|
|
640
|
-
const
|
|
641
|
-
if (values) {
|
|
642
|
-
|
|
643
|
-
return reduceFilterText(filter.valueAsText(values));
|
|
644
|
-
}
|
|
645
|
-
else if (filter.type === "valueName") {
|
|
646
|
-
return reduceFilterText(values.map(value => value.name));
|
|
647
|
-
}
|
|
648
|
-
return values.toString();
|
|
640
|
+
const getFilterText = () => {
|
|
641
|
+
if (!values) {
|
|
642
|
+
return undefined;
|
|
649
643
|
}
|
|
650
|
-
|
|
644
|
+
if (filter.valueAsText) {
|
|
645
|
+
return reduceFilterText(filter.valueAsText(values));
|
|
646
|
+
}
|
|
647
|
+
else if (filter.type === "valueNameArray") {
|
|
648
|
+
return reduceFilterText(values.map(value => value.name));
|
|
649
|
+
}
|
|
650
|
+
else if (filter.type === "valueName") {
|
|
651
|
+
return values.name;
|
|
652
|
+
}
|
|
653
|
+
return values.toString();
|
|
651
654
|
};
|
|
652
655
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
653
656
|
const setValue = (callback) => {
|
|
@@ -664,9 +667,12 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
664
667
|
else if (filter.type === "area") {
|
|
665
668
|
filterBarActions.setArea(newValue);
|
|
666
669
|
}
|
|
667
|
-
else if (filter.type === "
|
|
670
|
+
else if (filter.type === "valueNameArray") {
|
|
668
671
|
filterBarActions.setArrayObjectValue(filter.filterKey, newValue);
|
|
669
672
|
}
|
|
673
|
+
else if (filter.type === "valueName") {
|
|
674
|
+
filterBarActions.setObjectValue(filter.filterKey, newValue);
|
|
675
|
+
}
|
|
670
676
|
else if (filter.type === "minMax") {
|
|
671
677
|
filterBarActions.setMinMaxValue(filter.filterKey, newValue);
|
|
672
678
|
}
|
|
@@ -677,7 +683,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
677
683
|
filterBarActions.setNumberValue(filter.filterKey, newValue);
|
|
678
684
|
}
|
|
679
685
|
};
|
|
680
|
-
const text =
|
|
686
|
+
const text = getFilterText();
|
|
681
687
|
const activeFilterText = Array.isArray(text) ? text.join(", ") : text;
|
|
682
688
|
const showDirectly = filter.showDirectly || false;
|
|
683
689
|
return showDirectly ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: filter.component({
|
|
@@ -687,7 +693,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
687
693
|
setValue,
|
|
688
694
|
filterBarActions,
|
|
689
695
|
filterState,
|
|
690
|
-
}) })) : (jsxRuntime.jsx(reactFilterComponents.Filter, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive:
|
|
696
|
+
}) })) : (jsxRuntime.jsx(reactFilterComponents.Filter, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text === null || text === void 0 ? void 0 : text.length), popoverProps: { placement: "right-start" }, title: filter.title, withStickyHeader: true, children: filter.component({
|
|
691
697
|
filterDefinition: filter,
|
|
692
698
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
693
699
|
value: values,
|
|
@@ -772,9 +778,10 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
772
778
|
* @template TFilterBarDefinition - The type representing the filter bar definition.
|
|
773
779
|
* @returns {JSX.Element} - Returns the StarredFilters component.
|
|
774
780
|
*/
|
|
775
|
-
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], }) => {
|
|
781
|
+
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], compact, dataTestId, className, }) => {
|
|
776
782
|
const [t] = useTranslation();
|
|
777
|
-
const { isLg } = reactComponents.
|
|
783
|
+
const { isLg } = reactComponents.useViewportBreakpoints();
|
|
784
|
+
const isCompactMode = compact !== null && compact !== void 0 ? compact : !isLg;
|
|
778
785
|
const hideInMenu = react.useMemo(() => {
|
|
779
786
|
return sharedUtils.objectValues(filterBarDefinition)
|
|
780
787
|
.map(filter => {
|
|
@@ -799,9 +806,9 @@ const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters =
|
|
|
799
806
|
const appliedFilters = starredFilters.filter(filter => filterBarConfig.appliedFilterKeys.includes(filter.filterKey));
|
|
800
807
|
const filtersToShow = starredFilters.filter(filter => !filter.showDirectly);
|
|
801
808
|
const showDirectlyFilters = allFilters.filter(filter => filter.showDirectly);
|
|
802
|
-
return (jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [jsxRuntime.jsx(reactComponents.Popover, { placement: "bottom-start", children: modalState => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactComponents.PopoverTrigger, { children: jsxRuntime.jsx("div", { "data-testid": "starred-filters-menu-trigger", children: jsxRuntime.jsxs(reactComponents.Tooltip, { disabled:
|
|
809
|
+
return (jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex flex-wrap items-center gap-2", className), "data-testid": dataTestId, children: [jsxRuntime.jsx(reactComponents.Popover, { placement: "bottom-start", children: modalState => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactComponents.PopoverTrigger, { children: jsxRuntime.jsx("div", { "data-testid": "starred-filters-menu-trigger", children: jsxRuntime.jsxs(reactComponents.Tooltip, { disabled: !isCompactMode || modalState.isOpen, label: jsxRuntime.jsx(FilterButtonTooltipLabel, { filterBarConfig: filterBarConfig }), children: [jsxRuntime.jsx(reactComponents.Button, { className: "@xs:flex hidden", prefix: jsxRuntime.jsx(reactComponents.Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", suffix: isCompactMode && filterBarConfig.appliedFilterKeys.length > 0
|
|
803
810
|
? `(${filterBarConfig.appliedFilterKeys.length})`
|
|
804
|
-
: undefined, variant: "secondary", children: t("filtersBar.filtersHeading") }), jsxRuntime.jsx(reactComponents.IconButton, { className: "@xs:hidden", icon: jsxRuntime.jsx(reactComponents.Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", variant: "secondary" })] }) }) }), jsxRuntime.jsx(reactComponents.PopoverContent, { cellPadding: 100, children: jsxRuntime.jsxs(reactComponents.Card, { className: "max-h-[min(600px,_calc(100dvh-32px))] overflow-hidden", children: [filtersToShow.length > 0 ? (jsxRuntime.jsx(reactComponents.CardBody, { density: "dense", children: jsxRuntime.jsx("div", { className: "flex h-full min-w-min flex-col gap-2", children: jsxRuntime.jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: filtersToShow }) }) })) : null, jsxRuntime.jsxs(reactComponents.CardFooter, { className: filtersToShow.length === 0 ? "border-none" : undefined, density: "dense", children: [jsxRuntime.jsx(StarredFiltersMenu, { className: "mr-auto", filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters, starredFilterKeys: filterBarConfig.starredFilterKeys, updateStarredFilters: filterBarConfig.updateStarredFilters }),
|
|
811
|
+
: undefined, variant: "secondary", children: t("filtersBar.filtersHeading") }), jsxRuntime.jsx(reactComponents.IconButton, { className: "@xs:hidden", icon: jsxRuntime.jsx(reactComponents.Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", variant: "secondary" })] }) }) }), jsxRuntime.jsx(reactComponents.PopoverContent, { cellPadding: 100, children: jsxRuntime.jsxs(reactComponents.Card, { className: "max-h-[min(600px,_calc(100dvh-32px))] overflow-hidden", children: [filtersToShow.length > 0 ? (jsxRuntime.jsx(reactComponents.CardBody, { density: "dense", children: jsxRuntime.jsx("div", { className: "flex h-full min-w-min flex-col gap-2", children: jsxRuntime.jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: filtersToShow }) }) })) : null, jsxRuntime.jsxs(reactComponents.CardFooter, { className: filtersToShow.length === 0 ? "border-none" : undefined, density: "dense", children: [jsxRuntime.jsx(StarredFiltersMenu, { className: "mr-auto", filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters, starredFilterKeys: filterBarConfig.starredFilterKeys, updateStarredFilters: filterBarConfig.updateStarredFilters }), !isCompactMode ? null : (jsxRuntime.jsx(ResetFiltersButton, { filtersHaveBeenApplied: filterBarConfig.appliedFilterKeys.length > 0, resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState }))] })] }) })] })) }), showDirectlyFilters.length > 0 ? (jsxRuntime.jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: showDirectlyFilters })) : null, !isCompactMode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [appliedFilters.filter(filter => !filter.showDirectly).length > 0 ? (jsxRuntime.jsx("div", { className: "h-4 w-[1px] bg-slate-300" })) : null, jsxRuntime.jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: appliedFilters }), jsxRuntime.jsx(ResetFiltersButton, { filtersHaveBeenApplied: filterBarConfig.appliedFilterKeys.length > 0, resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState })] })) : null] }));
|
|
805
812
|
};
|
|
806
813
|
const FiltersList = ({ filters, filterBarConfig }) => {
|
|
807
814
|
return filters.length === 0
|
|
@@ -829,8 +836,8 @@ const FilterButtonTooltipLabel = ({ filterBarConfig, }) => {
|
|
|
829
836
|
/**
|
|
830
837
|
* The FilterBar component serves as a wrapper for managing filters.
|
|
831
838
|
*/
|
|
832
|
-
const FilterBar = ({ hiddenFilters, className, filterBarDefinition, filterBarConfig, }) => {
|
|
833
|
-
return (jsxRuntime.jsx(
|
|
839
|
+
const FilterBar = ({ hiddenFilters, className, filterBarDefinition, filterBarConfig, compact, }) => {
|
|
840
|
+
return (jsxRuntime.jsx(StarredFilters, { className: className, compact: compact, dataTestId: `${filterBarConfig.name}-filterbar`, filterBarConfig: filterBarConfig, filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters }));
|
|
834
841
|
};
|
|
835
842
|
|
|
836
843
|
// Can't import jest.fn so must define a function that does nothing but mimics the jest.fn
|
|
@@ -867,6 +874,9 @@ const mockFilterBar = {
|
|
|
867
874
|
setCriticality: doNothing,
|
|
868
875
|
setServicePlan: doNothing,
|
|
869
876
|
},
|
|
877
|
+
objectIncludesValue: doNothing,
|
|
878
|
+
setObjectValue: doNothing,
|
|
879
|
+
toggleObjectValue: doNothing,
|
|
870
880
|
},
|
|
871
881
|
filterBarDefinition: {},
|
|
872
882
|
};
|
|
@@ -883,9 +893,12 @@ const getInitialValueFromType = (type) => {
|
|
|
883
893
|
if (type === "stringArray") {
|
|
884
894
|
return [];
|
|
885
895
|
}
|
|
886
|
-
if (type === "
|
|
896
|
+
if (type === "valueNameArray") {
|
|
887
897
|
return [];
|
|
888
898
|
}
|
|
899
|
+
if (type === "valueName") {
|
|
900
|
+
return { value: undefined, name: undefined };
|
|
901
|
+
}
|
|
889
902
|
if (type === "minMax") {
|
|
890
903
|
return { min: undefined, max: undefined };
|
|
891
904
|
}
|
|
@@ -952,7 +965,8 @@ const hasValue = (value) => {
|
|
|
952
965
|
return !(Array.isArray(value) && value.length === 0);
|
|
953
966
|
};
|
|
954
967
|
const isNotRightType = (filterDefinition, foundFilter) => {
|
|
955
|
-
return ((filterDefinition.type === "
|
|
968
|
+
return ((filterDefinition.type === "valueNameArray" && !isValueNameArray(foundFilter)) ||
|
|
969
|
+
(filterDefinition.type === "valueName" && !isValueName(foundFilter)) ||
|
|
956
970
|
(filterDefinition.type === "stringArray" && !isStringArrayFilterValue(foundFilter)) ||
|
|
957
971
|
(filterDefinition.type === "dateRange" && !isDateRangeValue(foundFilter)) ||
|
|
958
972
|
(filterDefinition.type === "area" && !isAreaFilterValue(foundFilter)) ||
|
|
@@ -1011,13 +1025,21 @@ const isBooleanValue = (value) => {
|
|
|
1011
1025
|
return value ? typeof value === "object" && Object.keys(value).includes("booleanValue") : false;
|
|
1012
1026
|
};
|
|
1013
1027
|
/**
|
|
1014
|
-
*
|
|
1028
|
+
* Type guard to check if a value is a single ValueName object
|
|
1015
1029
|
*/
|
|
1016
|
-
const
|
|
1017
|
-
return (
|
|
1018
|
-
value
|
|
1030
|
+
const isValueName = (value) => {
|
|
1031
|
+
return (typeof value === "object" &&
|
|
1032
|
+
value !== null &&
|
|
1033
|
+
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1034
|
+
Object.keys(value).includes("name") &&
|
|
1019
1035
|
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1020
|
-
|
|
1036
|
+
Object.keys(value).includes("value"));
|
|
1037
|
+
};
|
|
1038
|
+
/**
|
|
1039
|
+
* Type guard to check if a value is an array of ValueName objects
|
|
1040
|
+
*/
|
|
1041
|
+
const isValueNameArray = (value) => {
|
|
1042
|
+
return isArrayFilterValue(value) && value.every(isValueName);
|
|
1021
1043
|
};
|
|
1022
1044
|
/**
|
|
1023
1045
|
* Validates a filter configuration against filter definitions.
|
|
@@ -1112,9 +1134,7 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1112
1134
|
return initialFilterBarConfig;
|
|
1113
1135
|
});
|
|
1114
1136
|
react.useEffect(() => {
|
|
1115
|
-
|
|
1116
|
-
onValuesChange(filterBarConfig.values);
|
|
1117
|
-
}
|
|
1137
|
+
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(filterBarConfig.values);
|
|
1118
1138
|
}, [filterBarConfig.values, filterBarConfig, onValuesChange]);
|
|
1119
1139
|
react.useEffect(() => {
|
|
1120
1140
|
localStorage.setItem(`filter-${name}`, JSON.stringify(filterBarConfig));
|
|
@@ -1166,6 +1186,10 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1166
1186
|
const filter = filterBarConfig.values[key];
|
|
1167
1187
|
return (filter === null || filter === void 0 ? void 0 : filter.find(f => f.value === value)) !== undefined || false;
|
|
1168
1188
|
},
|
|
1189
|
+
objectIncludesValue(key, value) {
|
|
1190
|
+
const filter = filterBarConfig.values[key];
|
|
1191
|
+
return (filter === null || filter === void 0 ? void 0 : filter.value) === value || false;
|
|
1192
|
+
},
|
|
1169
1193
|
};
|
|
1170
1194
|
}, [filterBarConfig.initialState, filterBarConfig.name, filterBarConfig.values, filterBarDefinition]);
|
|
1171
1195
|
const filterMapActions = react.useMemo(() => {
|
|
@@ -1341,6 +1365,17 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1341
1365
|
};
|
|
1342
1366
|
});
|
|
1343
1367
|
},
|
|
1368
|
+
setObjectValue(key, filterValue) {
|
|
1369
|
+
setFilterBarConfig(prevState => {
|
|
1370
|
+
return {
|
|
1371
|
+
...prevState,
|
|
1372
|
+
values: {
|
|
1373
|
+
...prevState.values,
|
|
1374
|
+
[key]: filterValue,
|
|
1375
|
+
},
|
|
1376
|
+
};
|
|
1377
|
+
});
|
|
1378
|
+
},
|
|
1344
1379
|
//Setting multiple value name objects
|
|
1345
1380
|
toggleArrayObjectValue(key, filterValue) {
|
|
1346
1381
|
setFilterBarConfig(prevState => {
|
|
@@ -1361,6 +1396,17 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1361
1396
|
};
|
|
1362
1397
|
});
|
|
1363
1398
|
},
|
|
1399
|
+
toggleObjectValue(key, filterValue) {
|
|
1400
|
+
setFilterBarConfig(prevState => {
|
|
1401
|
+
return {
|
|
1402
|
+
...prevState,
|
|
1403
|
+
values: {
|
|
1404
|
+
...prevState.values,
|
|
1405
|
+
[key]: filterValue,
|
|
1406
|
+
},
|
|
1407
|
+
};
|
|
1408
|
+
});
|
|
1409
|
+
},
|
|
1364
1410
|
// Reset filters to initial state
|
|
1365
1411
|
resetFiltersToInitialState() {
|
|
1366
1412
|
setFilterBarConfig(prevState => {
|
|
@@ -1426,7 +1472,8 @@ exports.isBooleanValue = isBooleanValue;
|
|
|
1426
1472
|
exports.isDateRangeValue = isDateRangeValue;
|
|
1427
1473
|
exports.isMinMaxFilterValue = isMinMaxFilterValue;
|
|
1428
1474
|
exports.isStringArrayFilterValue = isStringArrayFilterValue;
|
|
1429
|
-
exports.
|
|
1475
|
+
exports.isValueName = isValueName;
|
|
1476
|
+
exports.isValueNameArray = isValueNameArray;
|
|
1430
1477
|
exports.mergeFilters = mergeFilters;
|
|
1431
1478
|
exports.mockFilterBar = mockFilterBar;
|
|
1432
1479
|
exports.toggleFilterValue = toggleFilterValue;
|
package/index.esm.js
CHANGED
|
@@ -2,13 +2,13 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { useAnalytics, useTextSearch } from '@trackunit/react-core-hooks';
|
|
4
4
|
import { FilterBody, RadioFilterItem, CheckBoxFilterItem, FilterHeader as FilterHeader$1, FilterFooter, Filter as Filter$1 } from '@trackunit/react-filter-components';
|
|
5
|
-
import { capitalize, nonNullable, objectValues, truthy } from '@trackunit/shared-utils';
|
|
6
5
|
import { useRef, useMemo, useState, useEffect, useCallback } from 'react';
|
|
6
|
+
import { capitalize } from 'string-ts';
|
|
7
7
|
import { createEvent } from '@trackunit/react-core-contexts-api';
|
|
8
|
-
import { VirtualizedList, Text, Button, Popover, PopoverTrigger, PopoverContent, MenuList,
|
|
8
|
+
import { VirtualizedList, Text, Button, Popover, PopoverTrigger, PopoverContent, MenuList, useViewportBreakpoints, Tooltip, Icon, IconButton, Card, CardBody, CardFooter } from '@trackunit/react-components';
|
|
9
9
|
import { Search, NumberField, RadioGroup, Toggle } from '@trackunit/react-form-components';
|
|
10
10
|
import { DayRangePicker } from '@trackunit/react-date-and-time-components';
|
|
11
|
-
import { capitalize as capitalize$1 } from '
|
|
11
|
+
import { nonNullable, capitalize as capitalize$1, objectValues, truthy } from '@trackunit/shared-utils';
|
|
12
12
|
import { twMerge } from 'tailwind-merge';
|
|
13
13
|
import { dequal } from 'dequal';
|
|
14
14
|
import isEqual from 'lodash/isEqual';
|
|
@@ -419,10 +419,10 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
419
419
|
return toggleFilterValue(value.key)(prev);
|
|
420
420
|
});
|
|
421
421
|
}
|
|
422
|
-
else if (filterDefinition.type === "
|
|
422
|
+
else if (filterDefinition.type === "valueNameArray") {
|
|
423
423
|
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
424
|
-
const
|
|
425
|
-
|
|
424
|
+
const setValueAsValueNameArray = setValue;
|
|
425
|
+
setValueAsValueNameArray(prev => {
|
|
426
426
|
if (!prev) {
|
|
427
427
|
return [{ name: value.label, value: value.key }];
|
|
428
428
|
}
|
|
@@ -460,7 +460,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
460
460
|
count: undefinedCount ? filteredOptions.length - 1 : filteredOptions.length,
|
|
461
461
|
} }), jsx(FilterResults, { ignoreUndefined: undefinedCount !== null, loading: loading, results: results, children: res => (jsx(DynamicFilterList, { checked: index => {
|
|
462
462
|
var _a, _b;
|
|
463
|
-
return filterDefinition.type === "
|
|
463
|
+
return filterDefinition.type === "valueNameArray"
|
|
464
464
|
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || "")
|
|
465
465
|
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, ((_b = res[index]) === null || _b === void 0 ? void 0 : _b.key) || "");
|
|
466
466
|
}, count: index => { var _a; return (_a = res[index]) === null || _a === void 0 ? void 0 : _a.count; }, keyMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""; }, labelMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.label) || ""; }, onChange: index => {
|
|
@@ -468,7 +468,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
468
468
|
if (result) {
|
|
469
469
|
handleSetValue(result);
|
|
470
470
|
}
|
|
471
|
-
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsx(CheckBoxFilterItem, { checked: filterDefinition.type === "
|
|
471
|
+
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsx(CheckBoxFilterItem, { checked: filterDefinition.type === "valueNameArray"
|
|
472
472
|
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, ((_c = results[undefinedCount.index]) === null || _c === void 0 ? void 0 : _c.key) || "")
|
|
473
473
|
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, ((_d = results[undefinedCount.index]) === null || _d === void 0 ? void 0 : _d.key) || ""), className: "rounded-none border-t-2", dataTestId: "dynamic-filter-check-box-undefined", itemCount: undefinedCount.count, label: (_e = results[undefinedCount.index]) === null || _e === void 0 ? void 0 : _e.label, name: "dynamic-filter-check-box-undefined", onChange: () => {
|
|
474
474
|
const result = results[undefinedCount.index];
|
|
@@ -514,7 +514,7 @@ const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue,
|
|
|
514
514
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
515
515
|
const handleApply = (fromDateValue, toDateValue) => {
|
|
516
516
|
logEvent("Filters Applied - V2", {
|
|
517
|
-
type: filterName !== null && filterName !== void 0 ? filterName : `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
517
|
+
type: filterName !== null && filterName !== void 0 ? filterName : `${capitalize$1(filterDefinition.filterKey)}Filter`,
|
|
518
518
|
value: JSON.stringify({ from: fromDateValue, to: toDateValue }),
|
|
519
519
|
});
|
|
520
520
|
setValue(() => ({ from: fromDateValue, to: toDateValue }));
|
|
@@ -547,7 +547,7 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
|
|
|
547
547
|
const realMinValue = minValue === 0 ? undefined : minValue !== null && minValue !== void 0 ? minValue : undefined;
|
|
548
548
|
const realMaxValue = maxValue === 0 ? undefined : maxValue !== null && maxValue !== void 0 ? maxValue : undefined;
|
|
549
549
|
logEvent("Filters Applied - V2", {
|
|
550
|
-
type: filterName !== null && filterName !== void 0 ? filterName : `${capitalize
|
|
550
|
+
type: filterName !== null && filterName !== void 0 ? filterName : `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
551
551
|
value: JSON.stringify({ min: realMinValue, max: realMaxValue }),
|
|
552
552
|
});
|
|
553
553
|
setValue(() => {
|
|
@@ -562,29 +562,29 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
|
|
|
562
562
|
*
|
|
563
563
|
* @returns {JSX.Element} - Returns the DefaultRadioFilter component.
|
|
564
564
|
*/
|
|
565
|
-
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, }) => {
|
|
566
|
-
var _a, _b
|
|
565
|
+
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, setValue, }) => {
|
|
566
|
+
var _a, _b;
|
|
567
567
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
568
568
|
const [filteredOptions, searchText, setSearchText] = useTextSearch(options, item => [item.label]);
|
|
569
569
|
const handleClick = (selectedId) => {
|
|
570
570
|
var _a;
|
|
571
571
|
const { key, label } = (_a = filteredOptions.find(({ key: id }) => id === selectedId)) !== null && _a !== void 0 ? _a : {};
|
|
572
572
|
if (key && label) {
|
|
573
|
-
|
|
573
|
+
setValue(() => ({ value: key, name: label }));
|
|
574
574
|
logEvent("Filters Applied - V2", {
|
|
575
575
|
type: filterName !== null && filterName !== void 0 ? filterName : `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
576
576
|
value: String(label),
|
|
577
577
|
});
|
|
578
578
|
}
|
|
579
579
|
};
|
|
580
|
-
const selectedRadioId =
|
|
580
|
+
const selectedRadioId = filteredOptions.find(option => filterBarActions.objectIncludesValue(filterDefinition.filterKey, option.key));
|
|
581
581
|
return (jsxs(Fragment, { children: [jsx(FilterHeader, { ...filterBarActions, ...filterDefinition, loading: loading, searchEnabled: true, searchProps: {
|
|
582
|
-
value: (
|
|
583
|
-
onChange: (
|
|
582
|
+
value: (_a = customSearch === null || customSearch === void 0 ? void 0 : customSearch.value) !== null && _a !== void 0 ? _a : searchText,
|
|
583
|
+
onChange: (_b = customSearch === null || customSearch === void 0 ? void 0 : customSearch.onChange) !== null && _b !== void 0 ? _b : setSearchText,
|
|
584
584
|
count: filteredOptions.length,
|
|
585
585
|
} }), jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsx(RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
|
|
586
586
|
handleClick(e.currentTarget.value);
|
|
587
|
-
}, value: selectedRadioId, children: jsx(DynamicFilterList, { checked: index => { var _a; return filterBarActions.
|
|
587
|
+
}, value: (selectedRadioId === null || selectedRadioId === void 0 ? void 0 : selectedRadioId.key) || "", children: jsx(DynamicFilterList, { checked: index => { var _a; return filterBarActions.objectIncludesValue(filterDefinition.filterKey, ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""); }, count: index => { var _a; return (_a = res[index]) === null || _a === void 0 ? void 0 : _a.count; }, keyMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.key) || ""; }, labelMapper: index => { var _a; return ((_a = res[index]) === null || _a === void 0 ? void 0 : _a.label) || ""; }, rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
|
|
588
588
|
};
|
|
589
589
|
|
|
590
590
|
/**
|
|
@@ -635,17 +635,20 @@ const reduceFilterText = (input) => {
|
|
|
635
635
|
*/
|
|
636
636
|
const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
637
637
|
const values = filterBarActions.getValuesByKey(filter.filterKey);
|
|
638
|
-
const
|
|
639
|
-
if (values) {
|
|
640
|
-
|
|
641
|
-
return reduceFilterText(filter.valueAsText(values));
|
|
642
|
-
}
|
|
643
|
-
else if (filter.type === "valueName") {
|
|
644
|
-
return reduceFilterText(values.map(value => value.name));
|
|
645
|
-
}
|
|
646
|
-
return values.toString();
|
|
638
|
+
const getFilterText = () => {
|
|
639
|
+
if (!values) {
|
|
640
|
+
return undefined;
|
|
647
641
|
}
|
|
648
|
-
|
|
642
|
+
if (filter.valueAsText) {
|
|
643
|
+
return reduceFilterText(filter.valueAsText(values));
|
|
644
|
+
}
|
|
645
|
+
else if (filter.type === "valueNameArray") {
|
|
646
|
+
return reduceFilterText(values.map(value => value.name));
|
|
647
|
+
}
|
|
648
|
+
else if (filter.type === "valueName") {
|
|
649
|
+
return values.name;
|
|
650
|
+
}
|
|
651
|
+
return values.toString();
|
|
649
652
|
};
|
|
650
653
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
651
654
|
const setValue = (callback) => {
|
|
@@ -662,9 +665,12 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
662
665
|
else if (filter.type === "area") {
|
|
663
666
|
filterBarActions.setArea(newValue);
|
|
664
667
|
}
|
|
665
|
-
else if (filter.type === "
|
|
668
|
+
else if (filter.type === "valueNameArray") {
|
|
666
669
|
filterBarActions.setArrayObjectValue(filter.filterKey, newValue);
|
|
667
670
|
}
|
|
671
|
+
else if (filter.type === "valueName") {
|
|
672
|
+
filterBarActions.setObjectValue(filter.filterKey, newValue);
|
|
673
|
+
}
|
|
668
674
|
else if (filter.type === "minMax") {
|
|
669
675
|
filterBarActions.setMinMaxValue(filter.filterKey, newValue);
|
|
670
676
|
}
|
|
@@ -675,7 +681,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
675
681
|
filterBarActions.setNumberValue(filter.filterKey, newValue);
|
|
676
682
|
}
|
|
677
683
|
};
|
|
678
|
-
const text =
|
|
684
|
+
const text = getFilterText();
|
|
679
685
|
const activeFilterText = Array.isArray(text) ? text.join(", ") : text;
|
|
680
686
|
const showDirectly = filter.showDirectly || false;
|
|
681
687
|
return showDirectly ? (jsx(Fragment, { children: filter.component({
|
|
@@ -685,7 +691,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
685
691
|
setValue,
|
|
686
692
|
filterBarActions,
|
|
687
693
|
filterState,
|
|
688
|
-
}) })) : (jsx(Filter$1, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive:
|
|
694
|
+
}) })) : (jsx(Filter$1, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text === null || text === void 0 ? void 0 : text.length), popoverProps: { placement: "right-start" }, title: filter.title, withStickyHeader: true, children: filter.component({
|
|
689
695
|
filterDefinition: filter,
|
|
690
696
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
691
697
|
value: values,
|
|
@@ -770,9 +776,10 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
770
776
|
* @template TFilterBarDefinition - The type representing the filter bar definition.
|
|
771
777
|
* @returns {JSX.Element} - Returns the StarredFilters component.
|
|
772
778
|
*/
|
|
773
|
-
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], }) => {
|
|
779
|
+
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], compact, dataTestId, className, }) => {
|
|
774
780
|
const [t] = useTranslation();
|
|
775
|
-
const { isLg } =
|
|
781
|
+
const { isLg } = useViewportBreakpoints();
|
|
782
|
+
const isCompactMode = compact !== null && compact !== void 0 ? compact : !isLg;
|
|
776
783
|
const hideInMenu = useMemo(() => {
|
|
777
784
|
return objectValues(filterBarDefinition)
|
|
778
785
|
.map(filter => {
|
|
@@ -797,9 +804,9 @@ const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters =
|
|
|
797
804
|
const appliedFilters = starredFilters.filter(filter => filterBarConfig.appliedFilterKeys.includes(filter.filterKey));
|
|
798
805
|
const filtersToShow = starredFilters.filter(filter => !filter.showDirectly);
|
|
799
806
|
const showDirectlyFilters = allFilters.filter(filter => filter.showDirectly);
|
|
800
|
-
return (jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [jsx(Popover, { placement: "bottom-start", children: modalState => (jsxs(Fragment, { children: [jsx(PopoverTrigger, { children: jsx("div", { "data-testid": "starred-filters-menu-trigger", children: jsxs(Tooltip, { disabled:
|
|
807
|
+
return (jsxs("div", { className: twMerge("flex flex-wrap items-center gap-2", className), "data-testid": dataTestId, children: [jsx(Popover, { placement: "bottom-start", children: modalState => (jsxs(Fragment, { children: [jsx(PopoverTrigger, { children: jsx("div", { "data-testid": "starred-filters-menu-trigger", children: jsxs(Tooltip, { disabled: !isCompactMode || modalState.isOpen, label: jsx(FilterButtonTooltipLabel, { filterBarConfig: filterBarConfig }), children: [jsx(Button, { className: "@xs:flex hidden", prefix: jsx(Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", suffix: isCompactMode && filterBarConfig.appliedFilterKeys.length > 0
|
|
801
808
|
? `(${filterBarConfig.appliedFilterKeys.length})`
|
|
802
|
-
: undefined, variant: "secondary", children: t("filtersBar.filtersHeading") }), jsx(IconButton, { className: "@xs:hidden", icon: jsx(Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", variant: "secondary" })] }) }) }), jsx(PopoverContent, { cellPadding: 100, children: jsxs(Card, { className: "max-h-[min(600px,_calc(100dvh-32px))] overflow-hidden", children: [filtersToShow.length > 0 ? (jsx(CardBody, { density: "dense", children: jsx("div", { className: "flex h-full min-w-min flex-col gap-2", children: jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: filtersToShow }) }) })) : null, jsxs(CardFooter, { className: filtersToShow.length === 0 ? "border-none" : undefined, density: "dense", children: [jsx(StarredFiltersMenu, { className: "mr-auto", filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters, starredFilterKeys: filterBarConfig.starredFilterKeys, updateStarredFilters: filterBarConfig.updateStarredFilters }),
|
|
809
|
+
: undefined, variant: "secondary", children: t("filtersBar.filtersHeading") }), jsx(IconButton, { className: "@xs:hidden", icon: jsx(Icon, { color: filterBarConfig.appliedFilterKeys.length > 0 ? "primary" : undefined, name: "Funnel", size: "small" }), size: "small", variant: "secondary" })] }) }) }), jsx(PopoverContent, { cellPadding: 100, children: jsxs(Card, { className: "max-h-[min(600px,_calc(100dvh-32px))] overflow-hidden", children: [filtersToShow.length > 0 ? (jsx(CardBody, { density: "dense", children: jsx("div", { className: "flex h-full min-w-min flex-col gap-2", children: jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: filtersToShow }) }) })) : null, jsxs(CardFooter, { className: filtersToShow.length === 0 ? "border-none" : undefined, density: "dense", children: [jsx(StarredFiltersMenu, { className: "mr-auto", filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters, starredFilterKeys: filterBarConfig.starredFilterKeys, updateStarredFilters: filterBarConfig.updateStarredFilters }), !isCompactMode ? null : (jsx(ResetFiltersButton, { filtersHaveBeenApplied: filterBarConfig.appliedFilterKeys.length > 0, resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState }))] })] }) })] })) }), showDirectlyFilters.length > 0 ? (jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: showDirectlyFilters })) : null, !isCompactMode ? (jsxs(Fragment, { children: [appliedFilters.filter(filter => !filter.showDirectly).length > 0 ? (jsx("div", { className: "h-4 w-[1px] bg-slate-300" })) : null, jsx(FiltersList, { filterBarConfig: filterBarConfig, filters: appliedFilters }), jsx(ResetFiltersButton, { filtersHaveBeenApplied: filterBarConfig.appliedFilterKeys.length > 0, resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState })] })) : null] }));
|
|
803
810
|
};
|
|
804
811
|
const FiltersList = ({ filters, filterBarConfig }) => {
|
|
805
812
|
return filters.length === 0
|
|
@@ -827,8 +834,8 @@ const FilterButtonTooltipLabel = ({ filterBarConfig, }) => {
|
|
|
827
834
|
/**
|
|
828
835
|
* The FilterBar component serves as a wrapper for managing filters.
|
|
829
836
|
*/
|
|
830
|
-
const FilterBar = ({ hiddenFilters, className, filterBarDefinition, filterBarConfig, }) => {
|
|
831
|
-
return (jsx(
|
|
837
|
+
const FilterBar = ({ hiddenFilters, className, filterBarDefinition, filterBarConfig, compact, }) => {
|
|
838
|
+
return (jsx(StarredFilters, { className: className, compact: compact, dataTestId: `${filterBarConfig.name}-filterbar`, filterBarConfig: filterBarConfig, filterBarDefinition: filterBarDefinition, hiddenFilters: hiddenFilters }));
|
|
832
839
|
};
|
|
833
840
|
|
|
834
841
|
// Can't import jest.fn so must define a function that does nothing but mimics the jest.fn
|
|
@@ -865,6 +872,9 @@ const mockFilterBar = {
|
|
|
865
872
|
setCriticality: doNothing,
|
|
866
873
|
setServicePlan: doNothing,
|
|
867
874
|
},
|
|
875
|
+
objectIncludesValue: doNothing,
|
|
876
|
+
setObjectValue: doNothing,
|
|
877
|
+
toggleObjectValue: doNothing,
|
|
868
878
|
},
|
|
869
879
|
filterBarDefinition: {},
|
|
870
880
|
};
|
|
@@ -881,9 +891,12 @@ const getInitialValueFromType = (type) => {
|
|
|
881
891
|
if (type === "stringArray") {
|
|
882
892
|
return [];
|
|
883
893
|
}
|
|
884
|
-
if (type === "
|
|
894
|
+
if (type === "valueNameArray") {
|
|
885
895
|
return [];
|
|
886
896
|
}
|
|
897
|
+
if (type === "valueName") {
|
|
898
|
+
return { value: undefined, name: undefined };
|
|
899
|
+
}
|
|
887
900
|
if (type === "minMax") {
|
|
888
901
|
return { min: undefined, max: undefined };
|
|
889
902
|
}
|
|
@@ -916,7 +929,7 @@ const createInitialState = (name, mainFilters, initialState, setValue) => {
|
|
|
916
929
|
const key = curr.filterKey;
|
|
917
930
|
return {
|
|
918
931
|
...prev,
|
|
919
|
-
[`set${capitalize
|
|
932
|
+
[`set${capitalize(key)}`]: (callback) => setValue(key, callback),
|
|
920
933
|
};
|
|
921
934
|
}, {});
|
|
922
935
|
const updatedInitialState = mainFilters.reduce((prev, curr) => {
|
|
@@ -950,7 +963,8 @@ const hasValue = (value) => {
|
|
|
950
963
|
return !(Array.isArray(value) && value.length === 0);
|
|
951
964
|
};
|
|
952
965
|
const isNotRightType = (filterDefinition, foundFilter) => {
|
|
953
|
-
return ((filterDefinition.type === "
|
|
966
|
+
return ((filterDefinition.type === "valueNameArray" && !isValueNameArray(foundFilter)) ||
|
|
967
|
+
(filterDefinition.type === "valueName" && !isValueName(foundFilter)) ||
|
|
954
968
|
(filterDefinition.type === "stringArray" && !isStringArrayFilterValue(foundFilter)) ||
|
|
955
969
|
(filterDefinition.type === "dateRange" && !isDateRangeValue(foundFilter)) ||
|
|
956
970
|
(filterDefinition.type === "area" && !isAreaFilterValue(foundFilter)) ||
|
|
@@ -1009,13 +1023,21 @@ const isBooleanValue = (value) => {
|
|
|
1009
1023
|
return value ? typeof value === "object" && Object.keys(value).includes("booleanValue") : false;
|
|
1010
1024
|
};
|
|
1011
1025
|
/**
|
|
1012
|
-
*
|
|
1026
|
+
* Type guard to check if a value is a single ValueName object
|
|
1013
1027
|
*/
|
|
1014
|
-
const
|
|
1015
|
-
return (
|
|
1016
|
-
value
|
|
1028
|
+
const isValueName = (value) => {
|
|
1029
|
+
return (typeof value === "object" &&
|
|
1030
|
+
value !== null &&
|
|
1017
1031
|
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1018
|
-
|
|
1032
|
+
Object.keys(value).includes("name") &&
|
|
1033
|
+
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1034
|
+
Object.keys(value).includes("value"));
|
|
1035
|
+
};
|
|
1036
|
+
/**
|
|
1037
|
+
* Type guard to check if a value is an array of ValueName objects
|
|
1038
|
+
*/
|
|
1039
|
+
const isValueNameArray = (value) => {
|
|
1040
|
+
return isArrayFilterValue(value) && value.every(isValueName);
|
|
1019
1041
|
};
|
|
1020
1042
|
/**
|
|
1021
1043
|
* Validates a filter configuration against filter definitions.
|
|
@@ -1105,14 +1127,12 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1105
1127
|
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1106
1128
|
Object.keys(initialFilterBarConfig.values).forEach(key => {
|
|
1107
1129
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1108
|
-
initialFilterBarConfig.setters[`set${capitalize
|
|
1130
|
+
initialFilterBarConfig.setters[`set${capitalize(key)}`] = (callback) => setValue(key, callback);
|
|
1109
1131
|
});
|
|
1110
1132
|
return initialFilterBarConfig;
|
|
1111
1133
|
});
|
|
1112
1134
|
useEffect(() => {
|
|
1113
|
-
|
|
1114
|
-
onValuesChange(filterBarConfig.values);
|
|
1115
|
-
}
|
|
1135
|
+
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(filterBarConfig.values);
|
|
1116
1136
|
}, [filterBarConfig.values, filterBarConfig, onValuesChange]);
|
|
1117
1137
|
useEffect(() => {
|
|
1118
1138
|
localStorage.setItem(`filter-${name}`, JSON.stringify(filterBarConfig));
|
|
@@ -1164,6 +1184,10 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1164
1184
|
const filter = filterBarConfig.values[key];
|
|
1165
1185
|
return (filter === null || filter === void 0 ? void 0 : filter.find(f => f.value === value)) !== undefined || false;
|
|
1166
1186
|
},
|
|
1187
|
+
objectIncludesValue(key, value) {
|
|
1188
|
+
const filter = filterBarConfig.values[key];
|
|
1189
|
+
return (filter === null || filter === void 0 ? void 0 : filter.value) === value || false;
|
|
1190
|
+
},
|
|
1167
1191
|
};
|
|
1168
1192
|
}, [filterBarConfig.initialState, filterBarConfig.name, filterBarConfig.values, filterBarDefinition]);
|
|
1169
1193
|
const filterMapActions = useMemo(() => {
|
|
@@ -1339,6 +1363,17 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1339
1363
|
};
|
|
1340
1364
|
});
|
|
1341
1365
|
},
|
|
1366
|
+
setObjectValue(key, filterValue) {
|
|
1367
|
+
setFilterBarConfig(prevState => {
|
|
1368
|
+
return {
|
|
1369
|
+
...prevState,
|
|
1370
|
+
values: {
|
|
1371
|
+
...prevState.values,
|
|
1372
|
+
[key]: filterValue,
|
|
1373
|
+
},
|
|
1374
|
+
};
|
|
1375
|
+
});
|
|
1376
|
+
},
|
|
1342
1377
|
//Setting multiple value name objects
|
|
1343
1378
|
toggleArrayObjectValue(key, filterValue) {
|
|
1344
1379
|
setFilterBarConfig(prevState => {
|
|
@@ -1359,6 +1394,17 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1359
1394
|
};
|
|
1360
1395
|
});
|
|
1361
1396
|
},
|
|
1397
|
+
toggleObjectValue(key, filterValue) {
|
|
1398
|
+
setFilterBarConfig(prevState => {
|
|
1399
|
+
return {
|
|
1400
|
+
...prevState,
|
|
1401
|
+
values: {
|
|
1402
|
+
...prevState.values,
|
|
1403
|
+
[key]: filterValue,
|
|
1404
|
+
},
|
|
1405
|
+
};
|
|
1406
|
+
});
|
|
1407
|
+
},
|
|
1362
1408
|
// Reset filters to initial state
|
|
1363
1409
|
resetFiltersToInitialState() {
|
|
1364
1410
|
setFilterBarConfig(prevState => {
|
|
@@ -1408,4 +1454,4 @@ const mergeFilters = (filterBarDefinition, extraFilters) => {
|
|
|
1408
1454
|
*/
|
|
1409
1455
|
setupLibraryTranslations();
|
|
1410
1456
|
|
|
1411
|
-
export { DefaultCheckboxFilter, DefaultDateRangeFilter, DefaultMinMaxFilter, DefaultRadioFilter, DynamicFilterList, FilterBar, FilterEvents, FilterHeader, FilterResults, StarredFilters, isAreaFilterValue, isArrayFilterValue, isBooleanValue, isDateRangeValue, isMinMaxFilterValue, isStringArrayFilterValue,
|
|
1457
|
+
export { DefaultCheckboxFilter, DefaultDateRangeFilter, DefaultMinMaxFilter, DefaultRadioFilter, DynamicFilterList, FilterBar, FilterEvents, FilterHeader, FilterResults, StarredFilters, isAreaFilterValue, isArrayFilterValue, isBooleanValue, isDateRangeValue, isMinMaxFilterValue, isStringArrayFilterValue, isValueName, isValueNameArray, mergeFilters, mockFilterBar, toggleFilterValue, useFilterBar, validateFilter };
|
package/package.json
CHANGED
package/src/lib/FilterBar.d.ts
CHANGED
|
@@ -18,9 +18,13 @@ interface FilterBarProps<TFilterBarDefinition extends FilterBarDefinition> {
|
|
|
18
18
|
* @see FilterBarConfig
|
|
19
19
|
*/
|
|
20
20
|
filterBarConfig: FilterBarConfig<TFilterBarDefinition> & FilterMapActions & FilterMapGetter;
|
|
21
|
+
/**
|
|
22
|
+
* If true, the starred filters will be displayed in a compact mode
|
|
23
|
+
*/
|
|
24
|
+
compact?: boolean;
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
23
27
|
* The FilterBar component serves as a wrapper for managing filters.
|
|
24
28
|
*/
|
|
25
|
-
export declare const FilterBar: <TFilterBarDefinition extends FilterBarDefinition>({ hiddenFilters, className, filterBarDefinition, filterBarConfig, }: FilterBarProps<TFilterBarDefinition>) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare const FilterBar: <TFilterBarDefinition extends FilterBarDefinition>({ hiddenFilters, className, filterBarDefinition, filterBarConfig, compact, }: FilterBarProps<TFilterBarDefinition>) => import("react/jsx-runtime").JSX.Element;
|
|
26
30
|
export {};
|
|
@@ -5,4 +5,4 @@ import { DefaultFilterProps } from "./DefaultFilterTypes";
|
|
|
5
5
|
*
|
|
6
6
|
* @returns {JSX.Element} - Returns the DefaultRadioFilter component.
|
|
7
7
|
*/
|
|
8
|
-
export declare const DefaultRadioFilter: ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch, }: DefaultFilterProps<ValueName
|
|
8
|
+
export declare const DefaultRadioFilter: ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch, setValue, }: DefaultFilterProps<ValueName>) => JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { CommonProps } from "@trackunit/react-components";
|
|
1
2
|
import { FilterBarConfig, FilterBarDefinition, FilterMapActions, FilterMapGetter } from "../types/FilterTypes";
|
|
2
|
-
interface StarredFiltersProps<TFilterBarDefinition extends FilterBarDefinition> {
|
|
3
|
+
interface StarredFiltersProps<TFilterBarDefinition extends FilterBarDefinition> extends CommonProps {
|
|
3
4
|
/**
|
|
4
5
|
* Configuration for the filter bar.
|
|
5
6
|
*/
|
|
@@ -12,6 +13,10 @@ interface StarredFiltersProps<TFilterBarDefinition extends FilterBarDefinition>
|
|
|
12
13
|
* If you want some of the filters to be hidden, but still programmatically enabled
|
|
13
14
|
*/
|
|
14
15
|
hiddenFilters?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* If true, the starred filters will be displayed in a compact mode
|
|
18
|
+
*/
|
|
19
|
+
compact?: boolean;
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
17
22
|
* StarredFilters is a React component that displays a list of starred filters based on the provided filter bar configuration.
|
|
@@ -19,5 +24,5 @@ interface StarredFiltersProps<TFilterBarDefinition extends FilterBarDefinition>
|
|
|
19
24
|
* @template TFilterBarDefinition - The type representing the filter bar definition.
|
|
20
25
|
* @returns {JSX.Element} - Returns the StarredFilters component.
|
|
21
26
|
*/
|
|
22
|
-
export declare const StarredFilters: <TFilterBarDefinition extends FilterBarDefinition>({ filterBarDefinition, filterBarConfig, hiddenFilters, }: StarredFiltersProps<TFilterBarDefinition>) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare const StarredFilters: <TFilterBarDefinition extends FilterBarDefinition>({ filterBarDefinition, filterBarConfig, hiddenFilters, compact, dataTestId, className, }: StarredFiltersProps<TFilterBarDefinition>) => import("react/jsx-runtime").JSX.Element;
|
|
23
28
|
export {};
|
|
@@ -29,6 +29,7 @@ export declare const useFilterBar: <TFilterBarDefinition extends FilterBarDefini
|
|
|
29
29
|
getFilterTitle: (key: string) => string;
|
|
30
30
|
getFilterBarName: () => string;
|
|
31
31
|
objectArrayIncludesValue: (key: string, value: string) => boolean;
|
|
32
|
+
objectIncludesValue: (key: string, value: string) => boolean;
|
|
32
33
|
getValuesByKey: (key: string) => FilterValueType;
|
|
33
34
|
arrayIncludesValue: (key: string, value: string | boolean) => boolean;
|
|
34
35
|
appliedFilterKeys: (keyof FilterBarDefinition)[];
|
|
@@ -44,7 +45,9 @@ export declare const useFilterBar: <TFilterBarDefinition extends FilterBarDefini
|
|
|
44
45
|
setDateRange: (key: string, value: DateRangeValue) => void;
|
|
45
46
|
setMinMaxValue: (key: string, minMaxValue: MinMaxFilterValue) => void;
|
|
46
47
|
setArrayObjectValue: (key: string, value: ValueName[]) => void;
|
|
48
|
+
setObjectValue: (key: string, value: ValueName) => void;
|
|
47
49
|
toggleArrayObjectValue: (key: string, value: ValueName) => void;
|
|
50
|
+
toggleObjectValue: (key: string, value: ValueName) => void;
|
|
48
51
|
resetFiltersToInitialState: () => void;
|
|
49
52
|
resetIndividualFilterToInitialState: (key: string) => void;
|
|
50
53
|
name: string;
|
|
@@ -14,8 +14,8 @@ export type MinMaxFilterValue = {
|
|
|
14
14
|
min?: number;
|
|
15
15
|
max?: number;
|
|
16
16
|
};
|
|
17
|
-
export type FilterValueType = string[] | ValueName[] | MinMaxFilterValue | GeoJsonPolygon | string | number | BooleanValue | undefined;
|
|
18
|
-
export declare type FilterTypes = "boolean" | "string" | "number" | "dateRange" | "area" | "valueName" | "stringArray" | "minMax";
|
|
17
|
+
export type FilterValueType = string[] | ValueName[] | ValueName | MinMaxFilterValue | GeoJsonPolygon | string | number | BooleanValue | undefined;
|
|
18
|
+
export declare type FilterTypes = "boolean" | "string" | "number" | "dateRange" | "area" | "valueNameArray" | "valueName" | "stringArray" | "minMax";
|
|
19
19
|
export type FilterMapActions = {
|
|
20
20
|
updateStarredFilters: (filterkey: string) => void;
|
|
21
21
|
toggleArrayValue: (key: string, value: string) => void;
|
|
@@ -27,7 +27,9 @@ export type FilterMapActions = {
|
|
|
27
27
|
setDateRange: (key: string, value: DateRangeValue) => void;
|
|
28
28
|
setMinMaxValue: (key: string, minMaxValue: MinMaxFilterValue) => void;
|
|
29
29
|
setArrayObjectValue: (key: string, value: ValueName[]) => void;
|
|
30
|
+
setObjectValue: (key: string, value: ValueName) => void;
|
|
30
31
|
toggleArrayObjectValue: (key: string, value: ValueName) => void;
|
|
32
|
+
toggleObjectValue: (key: string, value: ValueName) => void;
|
|
31
33
|
resetFiltersToInitialState: () => void;
|
|
32
34
|
resetIndividualFilterToInitialState: (key: string) => void;
|
|
33
35
|
};
|
|
@@ -35,6 +37,7 @@ export type FilterMapGetter = {
|
|
|
35
37
|
getFilterTitle: (key: string) => string;
|
|
36
38
|
getFilterBarName: () => string;
|
|
37
39
|
objectArrayIncludesValue: (key: string, value: string) => boolean;
|
|
40
|
+
objectIncludesValue: (key: string, value: string) => boolean;
|
|
38
41
|
getValuesByKey: (key: string) => FilterValueType;
|
|
39
42
|
arrayIncludesValue: (key: string, value: string | boolean) => boolean;
|
|
40
43
|
readonly appliedFilterKeys: (keyof FilterBarDefinition)[];
|
|
@@ -109,12 +112,18 @@ export interface AreaFilterDefinition extends AbstractFilterDefinition {
|
|
|
109
112
|
valueAsText?: (value: GeoJsonPolygon) => string;
|
|
110
113
|
component: (filterComponentProps: FilterViewProps<GeoJsonPolygon>) => React.ReactNode;
|
|
111
114
|
}
|
|
112
|
-
export interface
|
|
113
|
-
type: "
|
|
115
|
+
export interface ValueNameArrayFilterDefinition extends AbstractFilterDefinition {
|
|
116
|
+
type: "valueNameArray";
|
|
114
117
|
defaultValue?: ValueName[];
|
|
115
118
|
valueAsText?: (value: ValueName[]) => string[];
|
|
116
119
|
component: (filterComponentProps: FilterViewProps<ValueName[]>) => React.ReactNode;
|
|
117
120
|
}
|
|
121
|
+
export interface ValueNameFilterDefinition extends AbstractFilterDefinition {
|
|
122
|
+
type: "valueName";
|
|
123
|
+
defaultValue?: ValueName;
|
|
124
|
+
valueAsText?: (value: ValueName) => string;
|
|
125
|
+
component: (filterComponentProps: FilterViewProps<ValueName>) => React.ReactNode;
|
|
126
|
+
}
|
|
118
127
|
export interface StringArrayFilterDefinition extends AbstractFilterDefinition {
|
|
119
128
|
type: "stringArray";
|
|
120
129
|
defaultValue?: string[];
|
|
@@ -153,7 +162,7 @@ export interface DateRangeFilterDefinition extends AbstractFilterDefinition {
|
|
|
153
162
|
valueAsText?: (value: DateRangeValue) => string;
|
|
154
163
|
component: (filterComponentProps: FilterViewProps<DateRangeValue>) => React.ReactNode;
|
|
155
164
|
}
|
|
156
|
-
export type FilterDefinition = BooleanFilterDefinition | MinMaxFilterDefinition | StringFilterDefinition | NumberFilterDefinition | DateRangeFilterDefinition | AreaFilterDefinition | ValueNameFilterDefinition | StringArrayFilterDefinition;
|
|
165
|
+
export type FilterDefinition = BooleanFilterDefinition | MinMaxFilterDefinition | StringFilterDefinition | NumberFilterDefinition | DateRangeFilterDefinition | AreaFilterDefinition | ValueNameFilterDefinition | ValueNameArrayFilterDefinition | StringArrayFilterDefinition;
|
|
157
166
|
export type FilterDefinitionValue = NonNullable<FilterDefinition["defaultValue"]>;
|
|
158
167
|
export interface FilterViewProps<TReturnType> {
|
|
159
168
|
filterDefinition: FilterDefinition;
|
|
@@ -169,7 +178,7 @@ export type FiltersStoreInstance<T extends FilterBarDefinition> = Partial<Filter
|
|
|
169
178
|
export interface FilterStateMap<T extends FilterBarDefinition> {
|
|
170
179
|
filtersMap: Record<string, FilterBarConfig<T>>;
|
|
171
180
|
}
|
|
172
|
-
export type FilterBarInferredValue<T extends FilterBarDefinition, K extends keyof T> = T[K]["type"] extends infer Type ? Type extends "boolean" ? BooleanValue | undefined : Type extends "string" ? string | undefined : Type extends "number" ? number | undefined : Type extends "area" ? GeoJsonPolygon | undefined : Type extends "
|
|
181
|
+
export type FilterBarInferredValue<T extends FilterBarDefinition, K extends keyof T> = T[K]["type"] extends infer Type ? Type extends "boolean" ? BooleanValue | undefined : Type extends "string" ? string | undefined : Type extends "number" ? number | undefined : Type extends "area" ? GeoJsonPolygon | undefined : Type extends "valueNameArray" ? ValueName[] | undefined : Type extends "valueName" ? ValueName | undefined : Type extends "stringArray" ? string[] | undefined : Type extends "minMax" ? MinMaxFilterValue | undefined : Type extends "dateRange" ? DateRangeValue | undefined : undefined : undefined;
|
|
173
182
|
export type SetterKey<T extends string> = `set${Capitalize<T>}`;
|
|
174
183
|
export type ReverseSetterKey<T extends string> = Uncapitalize<T extends `set${infer U}` ? U : never>;
|
|
175
184
|
export type ExtractFilterKeys<T extends FilterBarDefinition> = Extract<keyof T, string>;
|
|
@@ -6,8 +6,14 @@ type InitialTypes = {
|
|
|
6
6
|
Arg: "stringArray";
|
|
7
7
|
Init: string[];
|
|
8
8
|
} | {
|
|
9
|
-
Arg: "
|
|
9
|
+
Arg: "valueNameArray";
|
|
10
10
|
Init: ValueName[];
|
|
11
|
+
} | {
|
|
12
|
+
Arg: "valueName";
|
|
13
|
+
Init: {
|
|
14
|
+
value: undefined;
|
|
15
|
+
name: undefined;
|
|
16
|
+
};
|
|
11
17
|
} | {
|
|
12
18
|
Arg: "minMax";
|
|
13
19
|
Init: {
|
|
@@ -28,9 +28,13 @@ export declare const isStringArrayFilterValue: (value: FilterDefinitionValue) =>
|
|
|
28
28
|
*/
|
|
29
29
|
export declare const isBooleanValue: (value: FilterDefinitionValue) => value is BooleanValue;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Type guard to check if a value is a single ValueName object
|
|
32
|
+
*/
|
|
33
|
+
export declare const isValueName: (value: unknown) => value is ValueName;
|
|
34
|
+
/**
|
|
35
|
+
* Type guard to check if a value is an array of ValueName objects
|
|
32
36
|
*/
|
|
33
|
-
export declare const
|
|
37
|
+
export declare const isValueNameArray: (value: FilterDefinitionValue) => value is ValueName[];
|
|
34
38
|
/**
|
|
35
39
|
* Validates a filter configuration against filter definitions.
|
|
36
40
|
*
|