@trackunit/filters-filter-bar 1.0.16 → 1.0.18
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 +55 -71
- package/index.esm.js +55 -71
- package/package.json +5 -5
package/index.cjs.js
CHANGED
|
@@ -356,7 +356,7 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
|
|
|
356
356
|
const updatedRowCount = react.useMemo(() => (showRequestMoreUseSearch ? rowCount + 1 : rowCount), [rowCount, showRequestMoreUseSearch]);
|
|
357
357
|
return (jsxRuntime.jsx(reactFilterComponents.FilterBody, { limitSize: true, ref: parentRef, children: jsxRuntime.jsx(reactComponents.VirtualizedList, { count: updatedRowCount, rowHeight: 40, separator: "space", children: index => {
|
|
358
358
|
return (jsxRuntime.jsx("div", { children: showRequestMoreUseSearch && index === rowCount ? (jsxRuntime.jsxs("div", { className: "p-3 pt-2", children: [jsxRuntime.jsx("span", { className: "text-sm text-gray-600", children: t("filter.more.options.if.you.search.title", { count: rowCount }) }), jsxRuntime.jsx("br", {}), jsxRuntime.jsx("span", { className: "text-sm italic text-gray-400", children: t("filter.more.options.if.you.search.description") })] })) : type === "Radio" ? (jsxRuntime.jsx(reactFilterComponents.RadioFilterItem, { dataTestId: "dynamic-filter-radio-" + keyMapper(index), itemCount: count(index), label: labelMapper(index), selected: checked(index), value: keyMapper(index) }, keyMapper(index))) : (jsxRuntime.jsx(reactFilterComponents.CheckBoxFilterItem, { checked: checked(index), dataTestId: "dynamic-filter-check-box-" + keyMapper(index), itemCount: count(index), label: labelMapper(index), name: keyMapper(index), onChange: () => {
|
|
359
|
-
onChange
|
|
359
|
+
onChange?.(index);
|
|
360
360
|
} }, keyMapper(index))) }));
|
|
361
361
|
} }) }));
|
|
362
362
|
};
|
|
@@ -367,17 +367,16 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
|
|
|
367
367
|
* @returns {JSX.Element} - Returns the FilterHeader component.
|
|
368
368
|
*/
|
|
369
369
|
const FilterHeader = ({ filterKey, title, searchEnabled, searchProps, filterHasChanged, resetIndividualFilterToInitialState, onResetFilter, loading = false, children, className, dataTestId, }) => {
|
|
370
|
-
var _a;
|
|
371
370
|
const [t] = useTranslation();
|
|
372
371
|
const handleResetFilter = () => {
|
|
373
372
|
resetIndividualFilterToInitialState(filterKey);
|
|
374
|
-
onResetFilter
|
|
373
|
+
onResetFilter?.();
|
|
375
374
|
};
|
|
376
|
-
return (jsxRuntime.jsxs(reactFilterComponents.FilterHeader, { className: className, dataTestId: dataTestId
|
|
375
|
+
return (jsxRuntime.jsxs(reactFilterComponents.FilterHeader, { className: className, dataTestId: dataTestId ?? `${filterKey}-filter-header`, loading: loading, onReset: handleResetFilter, resetLabel: t("filtersBar.resetFilter"), showReset: filterHasChanged(filterKey), title: title, children: [searchEnabled ? (jsxRuntime.jsx(reactFormComponents.Search, { autoFocus: true, fieldSize: "small", id: `${filterKey}-search`, onChange: e => searchProps.onChange(e.currentTarget.value), onKeyDown: e => {
|
|
377
376
|
if (e.key === "Enter" && searchProps.onEnter) {
|
|
378
377
|
searchProps.onEnter(searchProps.value);
|
|
379
378
|
}
|
|
380
|
-
}, placeholder:
|
|
379
|
+
}, placeholder: searchProps.placeholder ?? t("assetFilters.searchPlaceholder"), suffix: jsxRuntime.jsx(reactComponents.Text, { size: "small", subtle: true, children: searchProps.count }), value: searchProps.value })) : null, children] }));
|
|
381
380
|
};
|
|
382
381
|
|
|
383
382
|
/**
|
|
@@ -406,7 +405,6 @@ const EmptyResults = ({ loading }) => {
|
|
|
406
405
|
* @param {DefaultFilterProps<string[]>} props - The properties required for the `DefaultCheckboxFilter` component.
|
|
407
406
|
*/
|
|
408
407
|
const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, loading, setValue, filterName, customSearch, showRequestMoreUseSearch = false, showUndefinedOptionWithCountAtBottom = true, }) => {
|
|
409
|
-
var _a, _b, _c, _d, _e;
|
|
410
408
|
const [undefinedCount, setUndefinedCount] = react.useState(null);
|
|
411
409
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
412
410
|
const [hasSelectedAll, setHasSelectedAll] = react.useState(false);
|
|
@@ -414,7 +412,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
414
412
|
const [selectedCount, setSelectedCount] = react.useState(0);
|
|
415
413
|
const handleSetValue = (value) => {
|
|
416
414
|
logEvent("Filters Applied - V2", {
|
|
417
|
-
type: filterName
|
|
415
|
+
type: filterName ?? `${stringTs.capitalize(filterDefinition.filterKey)}Filter`,
|
|
418
416
|
value: value.key,
|
|
419
417
|
});
|
|
420
418
|
if (filterDefinition.type === "stringArray") {
|
|
@@ -468,10 +466,9 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
468
466
|
return result;
|
|
469
467
|
}, [customSearch, options, filteredOptions, showUndefinedOptionWithCountAtBottom]);
|
|
470
468
|
react.useEffect(() => {
|
|
471
|
-
var _a, _b;
|
|
472
469
|
const index = results.findIndex(option => option.key === "UNDEFINED");
|
|
473
470
|
if (index !== -1) {
|
|
474
|
-
setUndefinedCount({ count:
|
|
471
|
+
setUndefinedCount({ count: results[index]?.count ?? 0, index });
|
|
475
472
|
}
|
|
476
473
|
}, [results]);
|
|
477
474
|
react.useEffect(() => {
|
|
@@ -505,22 +502,21 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
505
502
|
}
|
|
506
503
|
};
|
|
507
504
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(FilterHeader, { ...filterDefinition, ...filterBarActions, loading: loading, searchEnabled: true, searchProps: {
|
|
508
|
-
value:
|
|
509
|
-
onChange:
|
|
505
|
+
value: customSearch?.value ?? searchText,
|
|
506
|
+
onChange: customSearch?.onChange ?? setSearchText,
|
|
510
507
|
count: undefinedCount ? filteredOptions.length - 1 : filteredOptions.length,
|
|
511
508
|
} }), options.length >= 2 ? (jsxRuntime.jsxs(reactComponents.Button, { className: "mb-1 ml-1 mt-1", dataTestId: "selectAllButton", onClick: handleSelectAll, size: "small", variant: "ghost", children: [hasSelectedAll ? t("filtersBar.deselectAll") : t("filtersBar.selectAll"), " (", selectedCount || (undefinedCount ? options.length - 1 : options.length), ")"] })) : null, jsxRuntime.jsx(FilterResults, { ignoreUndefined: undefinedCount !== null, loading: loading, results: results, children: res => (jsxRuntime.jsx(DynamicFilterList, { checked: index => {
|
|
512
|
-
var _a, _b;
|
|
513
509
|
return filterDefinition.type === "valueNameArray"
|
|
514
|
-
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey,
|
|
515
|
-
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey,
|
|
516
|
-
}, count: index =>
|
|
510
|
+
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, res[index]?.key || "")
|
|
511
|
+
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, res[index]?.key || "");
|
|
512
|
+
}, count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", onChange: index => {
|
|
517
513
|
const result = res[index];
|
|
518
514
|
if (result) {
|
|
519
515
|
handleSetValue(result);
|
|
520
516
|
}
|
|
521
517
|
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsxRuntime.jsx("div", { className: "m-1", children: jsxRuntime.jsx(reactFilterComponents.CheckBoxFilterItem, { checked: filterDefinition.type === "valueNameArray"
|
|
522
|
-
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey,
|
|
523
|
-
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey,
|
|
518
|
+
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, results[undefinedCount.index]?.key || "")
|
|
519
|
+
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, results[undefinedCount.index]?.key || ""), className: "rounded-none border-t-2", dataTestId: "dynamic-filter-check-box-undefined", itemCount: undefinedCount.count, label: results[undefinedCount.index]?.label, name: "dynamic-filter-check-box-undefined", onChange: () => {
|
|
524
520
|
const result = results[undefinedCount.index];
|
|
525
521
|
if (result) {
|
|
526
522
|
handleSetValue(result);
|
|
@@ -545,17 +541,14 @@ const formatToJustDate = (date) => {
|
|
|
545
541
|
*/
|
|
546
542
|
const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue, showQuickOptions, }) => {
|
|
547
543
|
const [t] = useTranslation();
|
|
548
|
-
const hasSelection = [value
|
|
544
|
+
const hasSelection = [value?.from, value?.to].some(val => sharedUtils.nonNullable(val));
|
|
549
545
|
const reset = () => {
|
|
550
546
|
// The Types for DefaultFilterProps and FilterDefinition could probably be improved to avoid this check
|
|
551
547
|
if (filterDefinition.type === "dateRange") {
|
|
552
|
-
setValue(() => {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
to: (_b = filterDefinition.defaultValue) === null || _b === void 0 ? void 0 : _b.to,
|
|
557
|
-
});
|
|
558
|
-
});
|
|
548
|
+
setValue(() => ({
|
|
549
|
+
from: filterDefinition.defaultValue?.from,
|
|
550
|
+
to: filterDefinition.defaultValue?.to,
|
|
551
|
+
}));
|
|
559
552
|
}
|
|
560
553
|
else {
|
|
561
554
|
setValue(() => ({ from: undefined, to: undefined }));
|
|
@@ -564,16 +557,16 @@ const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue,
|
|
|
564
557
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
565
558
|
const handleApply = (fromDateValue, toDateValue) => {
|
|
566
559
|
logEvent("Filters Applied - V2", {
|
|
567
|
-
type: filterName
|
|
560
|
+
type: filterName ?? `${sharedUtils.capitalize(filterDefinition.filterKey)}Filter`,
|
|
568
561
|
value: JSON.stringify({ from: fromDateValue, to: toDateValue }),
|
|
569
562
|
});
|
|
570
563
|
setValue(() => ({ from: fromDateValue, to: toDateValue }));
|
|
571
564
|
};
|
|
572
565
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactFilterComponents.FilterHeader, { onReset: reset, resetLabel: t("filtersBar.resetFilter"), showReset: hasSelection, title: filterDefinition.title }), jsxRuntime.jsx(reactFilterComponents.FilterBody, { children: jsxRuntime.jsx("div", { className: "flex gap-4 px-1", children: jsxRuntime.jsx(reactDateAndTimeComponents.DayRangePicker, { language: "en", onRangeSelect: dateRange => {
|
|
573
|
-
handleApply(formatToJustDate(dateRange
|
|
566
|
+
handleApply(formatToJustDate(dateRange?.from), formatToJustDate(dateRange?.to));
|
|
574
567
|
}, selectedDays: {
|
|
575
|
-
from:
|
|
576
|
-
to:
|
|
568
|
+
from: value?.from ? new Date(value.from) : undefined,
|
|
569
|
+
to: value?.to ? new Date(value.to) : undefined,
|
|
577
570
|
}, showQuickOptions: showQuickOptions }) }) })] }));
|
|
578
571
|
};
|
|
579
572
|
|
|
@@ -584,27 +577,26 @@ const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue,
|
|
|
584
577
|
* @returns {ReactElement} The rendered `DefaultMinMaxFilter` component.
|
|
585
578
|
*/
|
|
586
579
|
const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, filterBarActions, unit, }) => {
|
|
587
|
-
var _a, _b;
|
|
588
580
|
const [t] = useTranslation();
|
|
589
|
-
const [minValue, setMinValue] = react.useState(
|
|
590
|
-
const [maxValue, setMaxValue] = react.useState(
|
|
581
|
+
const [minValue, setMinValue] = react.useState(value?.min ?? undefined);
|
|
582
|
+
const [maxValue, setMaxValue] = react.useState(value?.max ?? undefined);
|
|
591
583
|
react.useEffect(() => {
|
|
592
|
-
setMinValue(value
|
|
593
|
-
setMaxValue(value
|
|
584
|
+
setMinValue(value?.min);
|
|
585
|
+
setMaxValue(value?.max);
|
|
594
586
|
}, [value]);
|
|
595
587
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
596
588
|
const handleApply = () => {
|
|
597
|
-
const realMinValue = minValue === 0 ? undefined : minValue
|
|
598
|
-
const realMaxValue = maxValue === 0 ? undefined : maxValue
|
|
589
|
+
const realMinValue = minValue === 0 ? undefined : minValue ?? undefined;
|
|
590
|
+
const realMaxValue = maxValue === 0 ? undefined : maxValue ?? undefined;
|
|
599
591
|
logEvent("Filters Applied - V2", {
|
|
600
|
-
type: filterName
|
|
592
|
+
type: filterName ?? `${stringTs.capitalize(filterDefinition.filterKey)}Filter`,
|
|
601
593
|
value: JSON.stringify({ min: realMinValue, max: realMaxValue }),
|
|
602
594
|
});
|
|
603
595
|
setValue(() => {
|
|
604
596
|
return realMinValue || realMaxValue ? { min: realMinValue, max: realMaxValue } : {};
|
|
605
597
|
});
|
|
606
598
|
};
|
|
607
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactFilterComponents.FilterHeader, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.filterHasChanged(filterDefinition.filterKey), title: filterDefinition.title }), jsxRuntime.jsxs(reactFilterComponents.FilterBody, { children: [jsxRuntime.jsxs("div", { className: "flex gap-4 px-1", children: [jsxRuntime.jsx(reactFormComponents.NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue
|
|
599
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactFilterComponents.FilterHeader, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.filterHasChanged(filterDefinition.filterKey), title: filterDefinition.title }), jsxRuntime.jsxs(reactFilterComponents.FilterBody, { children: [jsxRuntime.jsxs("div", { className: "flex gap-4 px-1", children: [jsxRuntime.jsx(reactFormComponents.NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue ?? "" }), jsxRuntime.jsx(reactFormComponents.NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.max"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMaxValue(e.target.value === "" ? undefined : Number(e.target.value)), value: maxValue ?? "" })] }), jsxRuntime.jsx(reactFilterComponents.FilterFooter, { children: jsxRuntime.jsx(reactComponents.Button, { onClick: handleApply, size: "small", variant: "ghost", children: t("filtersBar.defaultMinMaxFilters.apply") }) })] })] }));
|
|
608
600
|
};
|
|
609
601
|
|
|
610
602
|
/**
|
|
@@ -613,28 +605,26 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
|
|
|
613
605
|
* @returns {JSX.Element} - Returns the DefaultRadioFilter component.
|
|
614
606
|
*/
|
|
615
607
|
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, setValue, }) => {
|
|
616
|
-
var _a, _b;
|
|
617
608
|
const { logEvent } = reactCoreHooks.useAnalytics(FilterEvents);
|
|
618
609
|
const [filteredOptions, searchText, setSearchText] = reactCoreHooks.useTextSearch(options, item => [item.label]);
|
|
619
610
|
const handleClick = (selectedId) => {
|
|
620
|
-
|
|
621
|
-
const { key, label } = (_a = filteredOptions.find(({ key: id }) => id === selectedId)) !== null && _a !== void 0 ? _a : {};
|
|
611
|
+
const { key, label } = filteredOptions.find(({ key: id }) => id === selectedId) ?? {};
|
|
622
612
|
if (key && label) {
|
|
623
613
|
setValue(() => ({ value: key, name: label }));
|
|
624
614
|
logEvent("Filters Applied - V2", {
|
|
625
|
-
type: filterName
|
|
615
|
+
type: filterName ?? `${stringTs.capitalize(filterDefinition.filterKey)}Filter`,
|
|
626
616
|
value: String(label),
|
|
627
617
|
});
|
|
628
618
|
}
|
|
629
619
|
};
|
|
630
620
|
const selectedRadioId = filteredOptions.find(option => filterBarActions.objectIncludesValue(filterDefinition.filterKey, option.key));
|
|
631
621
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(FilterHeader, { ...filterBarActions, ...filterDefinition, loading: loading, searchEnabled: true, searchProps: {
|
|
632
|
-
value:
|
|
633
|
-
onChange:
|
|
622
|
+
value: customSearch?.value ?? searchText,
|
|
623
|
+
onChange: customSearch?.onChange ?? setSearchText,
|
|
634
624
|
count: filteredOptions.length,
|
|
635
625
|
} }), jsxRuntime.jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsxRuntime.jsx(reactFormComponents.RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
|
|
636
626
|
handleClick(e.currentTarget.value);
|
|
637
|
-
}, value:
|
|
627
|
+
}, value: selectedRadioId?.key || "", children: jsxRuntime.jsx(DynamicFilterList, { checked: index => filterBarActions.objectIncludesValue(filterDefinition.filterKey, res[index]?.key || ""), count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
|
|
638
628
|
};
|
|
639
629
|
|
|
640
630
|
/**
|
|
@@ -741,7 +731,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
741
731
|
setValue,
|
|
742
732
|
filterBarActions,
|
|
743
733
|
filterState,
|
|
744
|
-
}) })) : (jsxRuntime.jsx(reactFilterComponents.Filter, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text
|
|
734
|
+
}) })) : (jsxRuntime.jsx(reactFilterComponents.Filter, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text?.length), popoverProps: { placement: "right-start" }, title: filter.title, withStickyHeader: true, children: filter.component({
|
|
745
735
|
filterDefinition: filter,
|
|
746
736
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
747
737
|
value: values,
|
|
@@ -761,7 +751,7 @@ const ResetFiltersButton = ({ filtersHaveBeenApplied, resetFiltersToInitialState
|
|
|
761
751
|
if (!filtersHaveBeenApplied) {
|
|
762
752
|
return null;
|
|
763
753
|
}
|
|
764
|
-
return (jsxRuntime.jsx(reactComponents.Button, { className: className, dataTestId: dataTestId
|
|
754
|
+
return (jsxRuntime.jsx(reactComponents.Button, { className: className, dataTestId: dataTestId ?? "reset-filters-button", onClick: () => {
|
|
765
755
|
resetFiltersToInitialState();
|
|
766
756
|
}, size: "small", variant: "ghost-neutral", children: t("filtersBar.resetFilters") }));
|
|
767
757
|
};
|
|
@@ -802,7 +792,7 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
802
792
|
return t("filtersBar.hiddenFilters.plural", { count: hiddenFiltersCount });
|
|
803
793
|
}
|
|
804
794
|
};
|
|
805
|
-
return (jsxRuntime.jsxs(reactComponents.Popover, { placement: "bottom-start", children: [jsxRuntime.jsx(reactComponents.PopoverTrigger, { children: jsxRuntime.jsx(reactComponents.Button, { className: className, dataTestId: dataTestId
|
|
795
|
+
return (jsxRuntime.jsxs(reactComponents.Popover, { placement: "bottom-start", children: [jsxRuntime.jsx(reactComponents.PopoverTrigger, { children: jsxRuntime.jsx(reactComponents.Button, { className: className, dataTestId: dataTestId ?? "starred-filters-menu", size: "small", variant: "ghost", children: getHiddenFiltersLabel() }) }), jsxRuntime.jsx(reactComponents.PopoverContent, { children: jsxRuntime.jsx(reactComponents.MenuList, { className: "overflow-hidden", dataTestId: "starred-filters-menu-popover", children: jsxRuntime.jsx("div", { className: "max-h-[55dvh] w-72 overflow-y-auto px-3 pb-2", children: filtersGrouped.map((group, idx) => {
|
|
806
796
|
const isLast = idx === filtersGrouped.length - 1;
|
|
807
797
|
return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(reactComponents.Text, { className: "pb-1 pt-2", dataTestId: "starred-filters-group-title", size: "small", subtle: true, uppercase: true, children: group.title }), jsxRuntime.jsx("div", { className: "grid gap-2", children: group.filters.map(filter => {
|
|
808
798
|
return !filter.isHidden ? (jsxRuntime.jsxs("div", { className: "grid-cols-min-fr grid cursor-pointer items-center gap-2 rounded-sm transition hover:bg-neutral-50", "data-testid": `${filter.filterKey}-star-filter`, onClick: () => {
|
|
@@ -829,7 +819,7 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
829
819
|
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], compact, dataTestId, className, }) => {
|
|
830
820
|
const [t] = useTranslation();
|
|
831
821
|
const { isLg } = reactComponents.useViewportBreakpoints();
|
|
832
|
-
const isCompactMode = compact
|
|
822
|
+
const isCompactMode = compact ?? !isLg;
|
|
833
823
|
const hideInMenu = react.useMemo(() => {
|
|
834
824
|
return sharedUtils.objectValues(filterBarDefinition)
|
|
835
825
|
.map(filter => {
|
|
@@ -966,13 +956,12 @@ const createInitialState = (name, mainFilters, initialState, setValue) => {
|
|
|
966
956
|
.filter(f => f.default)
|
|
967
957
|
.map(f => f.filterKey);
|
|
968
958
|
const values = mainFilters.reduce((prev, curr) => {
|
|
969
|
-
var _a, _b;
|
|
970
959
|
const key = curr.filterKey;
|
|
971
960
|
const type = curr.type;
|
|
972
961
|
return {
|
|
973
962
|
...prev,
|
|
974
963
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
975
|
-
[key]:
|
|
964
|
+
[key]: initialState[key] ?? curr.defaultValue ?? getInitialValueFromType(type),
|
|
976
965
|
};
|
|
977
966
|
}, {});
|
|
978
967
|
const setters = mainFilters.reduce((prev, curr) => {
|
|
@@ -983,13 +972,12 @@ const createInitialState = (name, mainFilters, initialState, setValue) => {
|
|
|
983
972
|
};
|
|
984
973
|
}, {});
|
|
985
974
|
const updatedInitialState = mainFilters.reduce((prev, curr) => {
|
|
986
|
-
var _a, _b;
|
|
987
975
|
const key = curr.filterKey;
|
|
988
976
|
const type = curr.type;
|
|
989
977
|
return {
|
|
990
978
|
...prev,
|
|
991
979
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
992
|
-
[key]:
|
|
980
|
+
[key]: initialState[key] ?? curr.defaultValue ?? getInitialValueFromType(type),
|
|
993
981
|
};
|
|
994
982
|
}, {});
|
|
995
983
|
const newFilter = {
|
|
@@ -1100,7 +1088,7 @@ const validateFilter = (filter, filterDefinitions) => {
|
|
|
1100
1088
|
const stateKeys = [];
|
|
1101
1089
|
let inBadState = false;
|
|
1102
1090
|
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1103
|
-
for (const key of Object.keys(
|
|
1091
|
+
for (const key of Object.keys(filter?.values || {})) {
|
|
1104
1092
|
if (filterDefinitions.find(filterDefinition => filterDefinition.filterKey === key)) {
|
|
1105
1093
|
stateKeys.push(key);
|
|
1106
1094
|
}
|
|
@@ -1109,7 +1097,7 @@ const validateFilter = (filter, filterDefinitions) => {
|
|
|
1109
1097
|
}
|
|
1110
1098
|
}
|
|
1111
1099
|
filterDefinitions.forEach(filterDefinition => {
|
|
1112
|
-
const foundFilter =
|
|
1100
|
+
const foundFilter = filter?.values && filter.values[filterDefinition.filterKey];
|
|
1113
1101
|
if (filter) {
|
|
1114
1102
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1115
1103
|
if (foundFilter && hasValue(foundFilter) && isNotRightType(filterDefinition, foundFilter)) {
|
|
@@ -1161,15 +1149,12 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1161
1149
|
//To do this for a changing default value as in customers and sites we would need to recreate the initialFilterBarConfig every time the default value changes.
|
|
1162
1150
|
//This mean that filterbars that have this functionality wouldn't be able to save the state of the filterbar.
|
|
1163
1151
|
//Another option would be to create a new filterbar for each customer or site. This also has its drawbacks. Would raise it with the frontend community.
|
|
1164
|
-
const hasNonVisibleDefaultValues = filterDefinitionsValues.some(value =>
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
((_a = value.defaultValue) === null || _a === void 0 ? void 0 : _a.toString) &&
|
|
1171
|
-
value.defaultValue.toString().length > 0;
|
|
1172
|
-
});
|
|
1152
|
+
const hasNonVisibleDefaultValues = filterDefinitionsValues.some(value => value.showInStarredMenu &&
|
|
1153
|
+
!value.showInStarredMenu() &&
|
|
1154
|
+
value.showInFilterBar &&
|
|
1155
|
+
!value.showInFilterBar() &&
|
|
1156
|
+
value.defaultValue?.toString &&
|
|
1157
|
+
value.defaultValue.toString().length > 0);
|
|
1173
1158
|
if (initialFilterBarConfig === undefined || hasNonVisibleDefaultValues) {
|
|
1174
1159
|
initialFilterBarConfig = createInitialState(name, filterDefinitionsValues, initialState || {}, setValue);
|
|
1175
1160
|
}
|
|
@@ -1181,7 +1166,7 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1181
1166
|
return initialFilterBarConfig;
|
|
1182
1167
|
});
|
|
1183
1168
|
react.useEffect(() => {
|
|
1184
|
-
onValuesChange
|
|
1169
|
+
onValuesChange?.(filterBarConfig.values);
|
|
1185
1170
|
}, [filterBarConfig.values, filterBarConfig, onValuesChange]);
|
|
1186
1171
|
react.useEffect(() => {
|
|
1187
1172
|
localStorage.setItem(`filter-${name}`, JSON.stringify(filterBarConfig));
|
|
@@ -1192,12 +1177,11 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1192
1177
|
return filterBarConfig.name;
|
|
1193
1178
|
},
|
|
1194
1179
|
getFilterTitle(key) {
|
|
1195
|
-
|
|
1196
|
-
return (_b = (_a = filterBarDefinition[key]) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : key;
|
|
1180
|
+
return filterBarDefinition[key]?.title ?? key;
|
|
1197
1181
|
},
|
|
1198
1182
|
arrayIncludesValue(key, value) {
|
|
1199
1183
|
const filter = filterBarConfig.values[key];
|
|
1200
|
-
return
|
|
1184
|
+
return filter?.includes(value) || false;
|
|
1201
1185
|
},
|
|
1202
1186
|
getValuesByKey(key) {
|
|
1203
1187
|
return filterBarConfig.values[key];
|
|
@@ -1231,11 +1215,11 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1231
1215
|
},
|
|
1232
1216
|
objectArrayIncludesValue(key, value) {
|
|
1233
1217
|
const filter = filterBarConfig.values[key];
|
|
1234
|
-
return
|
|
1218
|
+
return filter?.find(f => f.value === value) !== undefined || false;
|
|
1235
1219
|
},
|
|
1236
1220
|
objectIncludesValue(key, value) {
|
|
1237
1221
|
const filter = filterBarConfig.values[key];
|
|
1238
|
-
return
|
|
1222
|
+
return filter?.value === value || false;
|
|
1239
1223
|
},
|
|
1240
1224
|
};
|
|
1241
1225
|
}, [filterBarConfig.initialState, filterBarConfig.name, filterBarConfig.values, filterBarDefinition]);
|
|
@@ -1277,7 +1261,7 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1277
1261
|
toggleArrayValue(key, value) {
|
|
1278
1262
|
setFilterBarConfig(prevState => {
|
|
1279
1263
|
const filterValue = prevState.values[key];
|
|
1280
|
-
if (filterValue
|
|
1264
|
+
if (filterValue?.includes(value)) {
|
|
1281
1265
|
return {
|
|
1282
1266
|
...prevState,
|
|
1283
1267
|
values: {
|
package/index.esm.js
CHANGED
|
@@ -354,7 +354,7 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
|
|
|
354
354
|
const updatedRowCount = useMemo(() => (showRequestMoreUseSearch ? rowCount + 1 : rowCount), [rowCount, showRequestMoreUseSearch]);
|
|
355
355
|
return (jsx(FilterBody, { limitSize: true, ref: parentRef, children: jsx(VirtualizedList, { count: updatedRowCount, rowHeight: 40, separator: "space", children: index => {
|
|
356
356
|
return (jsx("div", { children: showRequestMoreUseSearch && index === rowCount ? (jsxs("div", { className: "p-3 pt-2", children: [jsx("span", { className: "text-sm text-gray-600", children: t("filter.more.options.if.you.search.title", { count: rowCount }) }), jsx("br", {}), jsx("span", { className: "text-sm italic text-gray-400", children: t("filter.more.options.if.you.search.description") })] })) : type === "Radio" ? (jsx(RadioFilterItem, { dataTestId: "dynamic-filter-radio-" + keyMapper(index), itemCount: count(index), label: labelMapper(index), selected: checked(index), value: keyMapper(index) }, keyMapper(index))) : (jsx(CheckBoxFilterItem, { checked: checked(index), dataTestId: "dynamic-filter-check-box-" + keyMapper(index), itemCount: count(index), label: labelMapper(index), name: keyMapper(index), onChange: () => {
|
|
357
|
-
onChange
|
|
357
|
+
onChange?.(index);
|
|
358
358
|
} }, keyMapper(index))) }));
|
|
359
359
|
} }) }));
|
|
360
360
|
};
|
|
@@ -365,17 +365,16 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
|
|
|
365
365
|
* @returns {JSX.Element} - Returns the FilterHeader component.
|
|
366
366
|
*/
|
|
367
367
|
const FilterHeader = ({ filterKey, title, searchEnabled, searchProps, filterHasChanged, resetIndividualFilterToInitialState, onResetFilter, loading = false, children, className, dataTestId, }) => {
|
|
368
|
-
var _a;
|
|
369
368
|
const [t] = useTranslation();
|
|
370
369
|
const handleResetFilter = () => {
|
|
371
370
|
resetIndividualFilterToInitialState(filterKey);
|
|
372
|
-
onResetFilter
|
|
371
|
+
onResetFilter?.();
|
|
373
372
|
};
|
|
374
|
-
return (jsxs(FilterHeader$1, { className: className, dataTestId: dataTestId
|
|
373
|
+
return (jsxs(FilterHeader$1, { className: className, dataTestId: dataTestId ?? `${filterKey}-filter-header`, loading: loading, onReset: handleResetFilter, resetLabel: t("filtersBar.resetFilter"), showReset: filterHasChanged(filterKey), title: title, children: [searchEnabled ? (jsx(Search, { autoFocus: true, fieldSize: "small", id: `${filterKey}-search`, onChange: e => searchProps.onChange(e.currentTarget.value), onKeyDown: e => {
|
|
375
374
|
if (e.key === "Enter" && searchProps.onEnter) {
|
|
376
375
|
searchProps.onEnter(searchProps.value);
|
|
377
376
|
}
|
|
378
|
-
}, placeholder:
|
|
377
|
+
}, placeholder: searchProps.placeholder ?? t("assetFilters.searchPlaceholder"), suffix: jsx(Text, { size: "small", subtle: true, children: searchProps.count }), value: searchProps.value })) : null, children] }));
|
|
379
378
|
};
|
|
380
379
|
|
|
381
380
|
/**
|
|
@@ -404,7 +403,6 @@ const EmptyResults = ({ loading }) => {
|
|
|
404
403
|
* @param {DefaultFilterProps<string[]>} props - The properties required for the `DefaultCheckboxFilter` component.
|
|
405
404
|
*/
|
|
406
405
|
const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, loading, setValue, filterName, customSearch, showRequestMoreUseSearch = false, showUndefinedOptionWithCountAtBottom = true, }) => {
|
|
407
|
-
var _a, _b, _c, _d, _e;
|
|
408
406
|
const [undefinedCount, setUndefinedCount] = useState(null);
|
|
409
407
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
410
408
|
const [hasSelectedAll, setHasSelectedAll] = useState(false);
|
|
@@ -412,7 +410,7 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
412
410
|
const [selectedCount, setSelectedCount] = useState(0);
|
|
413
411
|
const handleSetValue = (value) => {
|
|
414
412
|
logEvent("Filters Applied - V2", {
|
|
415
|
-
type: filterName
|
|
413
|
+
type: filterName ?? `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
416
414
|
value: value.key,
|
|
417
415
|
});
|
|
418
416
|
if (filterDefinition.type === "stringArray") {
|
|
@@ -466,10 +464,9 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
466
464
|
return result;
|
|
467
465
|
}, [customSearch, options, filteredOptions, showUndefinedOptionWithCountAtBottom]);
|
|
468
466
|
useEffect(() => {
|
|
469
|
-
var _a, _b;
|
|
470
467
|
const index = results.findIndex(option => option.key === "UNDEFINED");
|
|
471
468
|
if (index !== -1) {
|
|
472
|
-
setUndefinedCount({ count:
|
|
469
|
+
setUndefinedCount({ count: results[index]?.count ?? 0, index });
|
|
473
470
|
}
|
|
474
471
|
}, [results]);
|
|
475
472
|
useEffect(() => {
|
|
@@ -503,22 +500,21 @@ const DefaultCheckboxFilter = ({ filterDefinition, filterBarActions, options, lo
|
|
|
503
500
|
}
|
|
504
501
|
};
|
|
505
502
|
return (jsxs(Fragment, { children: [jsx(FilterHeader, { ...filterDefinition, ...filterBarActions, loading: loading, searchEnabled: true, searchProps: {
|
|
506
|
-
value:
|
|
507
|
-
onChange:
|
|
503
|
+
value: customSearch?.value ?? searchText,
|
|
504
|
+
onChange: customSearch?.onChange ?? setSearchText,
|
|
508
505
|
count: undefinedCount ? filteredOptions.length - 1 : filteredOptions.length,
|
|
509
506
|
} }), options.length >= 2 ? (jsxs(Button, { className: "mb-1 ml-1 mt-1", dataTestId: "selectAllButton", onClick: handleSelectAll, size: "small", variant: "ghost", children: [hasSelectedAll ? t("filtersBar.deselectAll") : t("filtersBar.selectAll"), " (", selectedCount || (undefinedCount ? options.length - 1 : options.length), ")"] })) : null, jsx(FilterResults, { ignoreUndefined: undefinedCount !== null, loading: loading, results: results, children: res => (jsx(DynamicFilterList, { checked: index => {
|
|
510
|
-
var _a, _b;
|
|
511
507
|
return filterDefinition.type === "valueNameArray"
|
|
512
|
-
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey,
|
|
513
|
-
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey,
|
|
514
|
-
}, count: index =>
|
|
508
|
+
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, res[index]?.key || "")
|
|
509
|
+
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, res[index]?.key || "");
|
|
510
|
+
}, count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", onChange: index => {
|
|
515
511
|
const result = res[index];
|
|
516
512
|
if (result) {
|
|
517
513
|
handleSetValue(result);
|
|
518
514
|
}
|
|
519
515
|
}, rowCount: undefinedCount ? res.length - 1 : res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "CheckBox" })) }), showUndefinedOptionWithCountAtBottom && undefinedCount ? (jsx("div", { className: "m-1", children: jsx(CheckBoxFilterItem, { checked: filterDefinition.type === "valueNameArray"
|
|
520
|
-
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey,
|
|
521
|
-
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey,
|
|
516
|
+
? filterBarActions.objectArrayIncludesValue(filterDefinition.filterKey, results[undefinedCount.index]?.key || "")
|
|
517
|
+
: filterBarActions.arrayIncludesValue(filterDefinition.filterKey, results[undefinedCount.index]?.key || ""), className: "rounded-none border-t-2", dataTestId: "dynamic-filter-check-box-undefined", itemCount: undefinedCount.count, label: results[undefinedCount.index]?.label, name: "dynamic-filter-check-box-undefined", onChange: () => {
|
|
522
518
|
const result = results[undefinedCount.index];
|
|
523
519
|
if (result) {
|
|
524
520
|
handleSetValue(result);
|
|
@@ -543,17 +539,14 @@ const formatToJustDate = (date) => {
|
|
|
543
539
|
*/
|
|
544
540
|
const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue, showQuickOptions, }) => {
|
|
545
541
|
const [t] = useTranslation();
|
|
546
|
-
const hasSelection = [value
|
|
542
|
+
const hasSelection = [value?.from, value?.to].some(val => nonNullable(val));
|
|
547
543
|
const reset = () => {
|
|
548
544
|
// The Types for DefaultFilterProps and FilterDefinition could probably be improved to avoid this check
|
|
549
545
|
if (filterDefinition.type === "dateRange") {
|
|
550
|
-
setValue(() => {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
to: (_b = filterDefinition.defaultValue) === null || _b === void 0 ? void 0 : _b.to,
|
|
555
|
-
});
|
|
556
|
-
});
|
|
546
|
+
setValue(() => ({
|
|
547
|
+
from: filterDefinition.defaultValue?.from,
|
|
548
|
+
to: filterDefinition.defaultValue?.to,
|
|
549
|
+
}));
|
|
557
550
|
}
|
|
558
551
|
else {
|
|
559
552
|
setValue(() => ({ from: undefined, to: undefined }));
|
|
@@ -562,16 +555,16 @@ const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue,
|
|
|
562
555
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
563
556
|
const handleApply = (fromDateValue, toDateValue) => {
|
|
564
557
|
logEvent("Filters Applied - V2", {
|
|
565
|
-
type: filterName
|
|
558
|
+
type: filterName ?? `${capitalize$1(filterDefinition.filterKey)}Filter`,
|
|
566
559
|
value: JSON.stringify({ from: fromDateValue, to: toDateValue }),
|
|
567
560
|
});
|
|
568
561
|
setValue(() => ({ from: fromDateValue, to: toDateValue }));
|
|
569
562
|
};
|
|
570
563
|
return (jsxs(Fragment, { children: [jsx(FilterHeader$1, { onReset: reset, resetLabel: t("filtersBar.resetFilter"), showReset: hasSelection, title: filterDefinition.title }), jsx(FilterBody, { children: jsx("div", { className: "flex gap-4 px-1", children: jsx(DayRangePicker, { language: "en", onRangeSelect: dateRange => {
|
|
571
|
-
handleApply(formatToJustDate(dateRange
|
|
564
|
+
handleApply(formatToJustDate(dateRange?.from), formatToJustDate(dateRange?.to));
|
|
572
565
|
}, selectedDays: {
|
|
573
|
-
from:
|
|
574
|
-
to:
|
|
566
|
+
from: value?.from ? new Date(value.from) : undefined,
|
|
567
|
+
to: value?.to ? new Date(value.to) : undefined,
|
|
575
568
|
}, showQuickOptions: showQuickOptions }) }) })] }));
|
|
576
569
|
};
|
|
577
570
|
|
|
@@ -582,27 +575,26 @@ const DefaultDateRangeFilter = ({ filterDefinition, filterName, value, setValue,
|
|
|
582
575
|
* @returns {ReactElement} The rendered `DefaultMinMaxFilter` component.
|
|
583
576
|
*/
|
|
584
577
|
const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, filterBarActions, unit, }) => {
|
|
585
|
-
var _a, _b;
|
|
586
578
|
const [t] = useTranslation();
|
|
587
|
-
const [minValue, setMinValue] = useState(
|
|
588
|
-
const [maxValue, setMaxValue] = useState(
|
|
579
|
+
const [minValue, setMinValue] = useState(value?.min ?? undefined);
|
|
580
|
+
const [maxValue, setMaxValue] = useState(value?.max ?? undefined);
|
|
589
581
|
useEffect(() => {
|
|
590
|
-
setMinValue(value
|
|
591
|
-
setMaxValue(value
|
|
582
|
+
setMinValue(value?.min);
|
|
583
|
+
setMaxValue(value?.max);
|
|
592
584
|
}, [value]);
|
|
593
585
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
594
586
|
const handleApply = () => {
|
|
595
|
-
const realMinValue = minValue === 0 ? undefined : minValue
|
|
596
|
-
const realMaxValue = maxValue === 0 ? undefined : maxValue
|
|
587
|
+
const realMinValue = minValue === 0 ? undefined : minValue ?? undefined;
|
|
588
|
+
const realMaxValue = maxValue === 0 ? undefined : maxValue ?? undefined;
|
|
597
589
|
logEvent("Filters Applied - V2", {
|
|
598
|
-
type: filterName
|
|
590
|
+
type: filterName ?? `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
599
591
|
value: JSON.stringify({ min: realMinValue, max: realMaxValue }),
|
|
600
592
|
});
|
|
601
593
|
setValue(() => {
|
|
602
594
|
return realMinValue || realMaxValue ? { min: realMinValue, max: realMaxValue } : {};
|
|
603
595
|
});
|
|
604
596
|
};
|
|
605
|
-
return (jsxs(Fragment, { children: [jsx(FilterHeader$1, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.filterHasChanged(filterDefinition.filterKey), title: filterDefinition.title }), jsxs(FilterBody, { children: [jsxs("div", { className: "flex gap-4 px-1", children: [jsx(NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue
|
|
597
|
+
return (jsxs(Fragment, { children: [jsx(FilterHeader$1, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.filterHasChanged(filterDefinition.filterKey), title: filterDefinition.title }), jsxs(FilterBody, { children: [jsxs("div", { className: "flex gap-4 px-1", children: [jsx(NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue ?? "" }), jsx(NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.max"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMaxValue(e.target.value === "" ? undefined : Number(e.target.value)), value: maxValue ?? "" })] }), jsx(FilterFooter, { children: jsx(Button, { onClick: handleApply, size: "small", variant: "ghost", children: t("filtersBar.defaultMinMaxFilters.apply") }) })] })] }));
|
|
606
598
|
};
|
|
607
599
|
|
|
608
600
|
/**
|
|
@@ -611,28 +603,26 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
|
|
|
611
603
|
* @returns {JSX.Element} - Returns the DefaultRadioFilter component.
|
|
612
604
|
*/
|
|
613
605
|
const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loading, filterName, customSearch, showRequestMoreUseSearch = false, setValue, }) => {
|
|
614
|
-
var _a, _b;
|
|
615
606
|
const { logEvent } = useAnalytics(FilterEvents);
|
|
616
607
|
const [filteredOptions, searchText, setSearchText] = useTextSearch(options, item => [item.label]);
|
|
617
608
|
const handleClick = (selectedId) => {
|
|
618
|
-
|
|
619
|
-
const { key, label } = (_a = filteredOptions.find(({ key: id }) => id === selectedId)) !== null && _a !== void 0 ? _a : {};
|
|
609
|
+
const { key, label } = filteredOptions.find(({ key: id }) => id === selectedId) ?? {};
|
|
620
610
|
if (key && label) {
|
|
621
611
|
setValue(() => ({ value: key, name: label }));
|
|
622
612
|
logEvent("Filters Applied - V2", {
|
|
623
|
-
type: filterName
|
|
613
|
+
type: filterName ?? `${capitalize(filterDefinition.filterKey)}Filter`,
|
|
624
614
|
value: String(label),
|
|
625
615
|
});
|
|
626
616
|
}
|
|
627
617
|
};
|
|
628
618
|
const selectedRadioId = filteredOptions.find(option => filterBarActions.objectIncludesValue(filterDefinition.filterKey, option.key));
|
|
629
619
|
return (jsxs(Fragment, { children: [jsx(FilterHeader, { ...filterBarActions, ...filterDefinition, loading: loading, searchEnabled: true, searchProps: {
|
|
630
|
-
value:
|
|
631
|
-
onChange:
|
|
620
|
+
value: customSearch?.value ?? searchText,
|
|
621
|
+
onChange: customSearch?.onChange ?? setSearchText,
|
|
632
622
|
count: filteredOptions.length,
|
|
633
623
|
} }), jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsx(RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
|
|
634
624
|
handleClick(e.currentTarget.value);
|
|
635
|
-
}, value:
|
|
625
|
+
}, value: selectedRadioId?.key || "", children: jsx(DynamicFilterList, { checked: index => filterBarActions.objectIncludesValue(filterDefinition.filterKey, res[index]?.key || ""), count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
|
|
636
626
|
};
|
|
637
627
|
|
|
638
628
|
/**
|
|
@@ -739,7 +729,7 @@ const Filter = ({ filter, filterBarActions, filterState, }) => {
|
|
|
739
729
|
setValue,
|
|
740
730
|
filterBarActions,
|
|
741
731
|
filterState,
|
|
742
|
-
}) })) : (jsx(Filter$1, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text
|
|
732
|
+
}) })) : (jsx(Filter$1, { activeLabel: activeFilterText, dataTestId: `${filter.filterKey}-filter-button`, isActive: Boolean(text?.length), popoverProps: { placement: "right-start" }, title: filter.title, withStickyHeader: true, children: filter.component({
|
|
743
733
|
filterDefinition: filter,
|
|
744
734
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
745
735
|
value: values,
|
|
@@ -759,7 +749,7 @@ const ResetFiltersButton = ({ filtersHaveBeenApplied, resetFiltersToInitialState
|
|
|
759
749
|
if (!filtersHaveBeenApplied) {
|
|
760
750
|
return null;
|
|
761
751
|
}
|
|
762
|
-
return (jsx(Button, { className: className, dataTestId: dataTestId
|
|
752
|
+
return (jsx(Button, { className: className, dataTestId: dataTestId ?? "reset-filters-button", onClick: () => {
|
|
763
753
|
resetFiltersToInitialState();
|
|
764
754
|
}, size: "small", variant: "ghost-neutral", children: t("filtersBar.resetFilters") }));
|
|
765
755
|
};
|
|
@@ -800,7 +790,7 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
800
790
|
return t("filtersBar.hiddenFilters.plural", { count: hiddenFiltersCount });
|
|
801
791
|
}
|
|
802
792
|
};
|
|
803
|
-
return (jsxs(Popover, { placement: "bottom-start", children: [jsx(PopoverTrigger, { children: jsx(Button, { className: className, dataTestId: dataTestId
|
|
793
|
+
return (jsxs(Popover, { placement: "bottom-start", children: [jsx(PopoverTrigger, { children: jsx(Button, { className: className, dataTestId: dataTestId ?? "starred-filters-menu", size: "small", variant: "ghost", children: getHiddenFiltersLabel() }) }), jsx(PopoverContent, { children: jsx(MenuList, { className: "overflow-hidden", dataTestId: "starred-filters-menu-popover", children: jsx("div", { className: "max-h-[55dvh] w-72 overflow-y-auto px-3 pb-2", children: filtersGrouped.map((group, idx) => {
|
|
804
794
|
const isLast = idx === filtersGrouped.length - 1;
|
|
805
795
|
return (jsxs("div", { children: [jsx(Text, { className: "pb-1 pt-2", dataTestId: "starred-filters-group-title", size: "small", subtle: true, uppercase: true, children: group.title }), jsx("div", { className: "grid gap-2", children: group.filters.map(filter => {
|
|
806
796
|
return !filter.isHidden ? (jsxs("div", { className: "grid-cols-min-fr grid cursor-pointer items-center gap-2 rounded-sm transition hover:bg-neutral-50", "data-testid": `${filter.filterKey}-star-filter`, onClick: () => {
|
|
@@ -827,7 +817,7 @@ const StarredFiltersMenu = ({ filterBarDefinition, updateStarredFilters, starred
|
|
|
827
817
|
const StarredFilters = ({ filterBarDefinition, filterBarConfig, hiddenFilters = [], compact, dataTestId, className, }) => {
|
|
828
818
|
const [t] = useTranslation();
|
|
829
819
|
const { isLg } = useViewportBreakpoints();
|
|
830
|
-
const isCompactMode = compact
|
|
820
|
+
const isCompactMode = compact ?? !isLg;
|
|
831
821
|
const hideInMenu = useMemo(() => {
|
|
832
822
|
return objectValues(filterBarDefinition)
|
|
833
823
|
.map(filter => {
|
|
@@ -964,13 +954,12 @@ const createInitialState = (name, mainFilters, initialState, setValue) => {
|
|
|
964
954
|
.filter(f => f.default)
|
|
965
955
|
.map(f => f.filterKey);
|
|
966
956
|
const values = mainFilters.reduce((prev, curr) => {
|
|
967
|
-
var _a, _b;
|
|
968
957
|
const key = curr.filterKey;
|
|
969
958
|
const type = curr.type;
|
|
970
959
|
return {
|
|
971
960
|
...prev,
|
|
972
961
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
973
|
-
[key]:
|
|
962
|
+
[key]: initialState[key] ?? curr.defaultValue ?? getInitialValueFromType(type),
|
|
974
963
|
};
|
|
975
964
|
}, {});
|
|
976
965
|
const setters = mainFilters.reduce((prev, curr) => {
|
|
@@ -981,13 +970,12 @@ const createInitialState = (name, mainFilters, initialState, setValue) => {
|
|
|
981
970
|
};
|
|
982
971
|
}, {});
|
|
983
972
|
const updatedInitialState = mainFilters.reduce((prev, curr) => {
|
|
984
|
-
var _a, _b;
|
|
985
973
|
const key = curr.filterKey;
|
|
986
974
|
const type = curr.type;
|
|
987
975
|
return {
|
|
988
976
|
...prev,
|
|
989
977
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
990
|
-
[key]:
|
|
978
|
+
[key]: initialState[key] ?? curr.defaultValue ?? getInitialValueFromType(type),
|
|
991
979
|
};
|
|
992
980
|
}, {});
|
|
993
981
|
const newFilter = {
|
|
@@ -1098,7 +1086,7 @@ const validateFilter = (filter, filterDefinitions) => {
|
|
|
1098
1086
|
const stateKeys = [];
|
|
1099
1087
|
let inBadState = false;
|
|
1100
1088
|
// eslint-disable-next-line no-autofix/local-rules/prefer-custom-object-keys
|
|
1101
|
-
for (const key of Object.keys(
|
|
1089
|
+
for (const key of Object.keys(filter?.values || {})) {
|
|
1102
1090
|
if (filterDefinitions.find(filterDefinition => filterDefinition.filterKey === key)) {
|
|
1103
1091
|
stateKeys.push(key);
|
|
1104
1092
|
}
|
|
@@ -1107,7 +1095,7 @@ const validateFilter = (filter, filterDefinitions) => {
|
|
|
1107
1095
|
}
|
|
1108
1096
|
}
|
|
1109
1097
|
filterDefinitions.forEach(filterDefinition => {
|
|
1110
|
-
const foundFilter =
|
|
1098
|
+
const foundFilter = filter?.values && filter.values[filterDefinition.filterKey];
|
|
1111
1099
|
if (filter) {
|
|
1112
1100
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1113
1101
|
if (foundFilter && hasValue(foundFilter) && isNotRightType(filterDefinition, foundFilter)) {
|
|
@@ -1159,15 +1147,12 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1159
1147
|
//To do this for a changing default value as in customers and sites we would need to recreate the initialFilterBarConfig every time the default value changes.
|
|
1160
1148
|
//This mean that filterbars that have this functionality wouldn't be able to save the state of the filterbar.
|
|
1161
1149
|
//Another option would be to create a new filterbar for each customer or site. This also has its drawbacks. Would raise it with the frontend community.
|
|
1162
|
-
const hasNonVisibleDefaultValues = filterDefinitionsValues.some(value =>
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
((_a = value.defaultValue) === null || _a === void 0 ? void 0 : _a.toString) &&
|
|
1169
|
-
value.defaultValue.toString().length > 0;
|
|
1170
|
-
});
|
|
1150
|
+
const hasNonVisibleDefaultValues = filterDefinitionsValues.some(value => value.showInStarredMenu &&
|
|
1151
|
+
!value.showInStarredMenu() &&
|
|
1152
|
+
value.showInFilterBar &&
|
|
1153
|
+
!value.showInFilterBar() &&
|
|
1154
|
+
value.defaultValue?.toString &&
|
|
1155
|
+
value.defaultValue.toString().length > 0);
|
|
1171
1156
|
if (initialFilterBarConfig === undefined || hasNonVisibleDefaultValues) {
|
|
1172
1157
|
initialFilterBarConfig = createInitialState(name, filterDefinitionsValues, initialState || {}, setValue);
|
|
1173
1158
|
}
|
|
@@ -1179,7 +1164,7 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1179
1164
|
return initialFilterBarConfig;
|
|
1180
1165
|
});
|
|
1181
1166
|
useEffect(() => {
|
|
1182
|
-
onValuesChange
|
|
1167
|
+
onValuesChange?.(filterBarConfig.values);
|
|
1183
1168
|
}, [filterBarConfig.values, filterBarConfig, onValuesChange]);
|
|
1184
1169
|
useEffect(() => {
|
|
1185
1170
|
localStorage.setItem(`filter-${name}`, JSON.stringify(filterBarConfig));
|
|
@@ -1190,12 +1175,11 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1190
1175
|
return filterBarConfig.name;
|
|
1191
1176
|
},
|
|
1192
1177
|
getFilterTitle(key) {
|
|
1193
|
-
|
|
1194
|
-
return (_b = (_a = filterBarDefinition[key]) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : key;
|
|
1178
|
+
return filterBarDefinition[key]?.title ?? key;
|
|
1195
1179
|
},
|
|
1196
1180
|
arrayIncludesValue(key, value) {
|
|
1197
1181
|
const filter = filterBarConfig.values[key];
|
|
1198
|
-
return
|
|
1182
|
+
return filter?.includes(value) || false;
|
|
1199
1183
|
},
|
|
1200
1184
|
getValuesByKey(key) {
|
|
1201
1185
|
return filterBarConfig.values[key];
|
|
@@ -1229,11 +1213,11 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1229
1213
|
},
|
|
1230
1214
|
objectArrayIncludesValue(key, value) {
|
|
1231
1215
|
const filter = filterBarConfig.values[key];
|
|
1232
|
-
return
|
|
1216
|
+
return filter?.find(f => f.value === value) !== undefined || false;
|
|
1233
1217
|
},
|
|
1234
1218
|
objectIncludesValue(key, value) {
|
|
1235
1219
|
const filter = filterBarConfig.values[key];
|
|
1236
|
-
return
|
|
1220
|
+
return filter?.value === value || false;
|
|
1237
1221
|
},
|
|
1238
1222
|
};
|
|
1239
1223
|
}, [filterBarConfig.initialState, filterBarConfig.name, filterBarConfig.values, filterBarDefinition]);
|
|
@@ -1275,7 +1259,7 @@ const useFilterBar = ({ name, onValuesChange, filterBarDefinition, initialState,
|
|
|
1275
1259
|
toggleArrayValue(key, value) {
|
|
1276
1260
|
setFilterBarConfig(prevState => {
|
|
1277
1261
|
const filterValue = prevState.values[key];
|
|
1278
|
-
if (filterValue
|
|
1262
|
+
if (filterValue?.includes(value)) {
|
|
1279
1263
|
return {
|
|
1280
1264
|
...prevState,
|
|
1281
1265
|
values: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/filters-filter-bar",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"tailwind-merge": "^2.0.0",
|
|
15
15
|
"string-ts": "^2.0.0",
|
|
16
16
|
"zod": "3.22.4",
|
|
17
|
-
"@trackunit/react-components": "^1.0
|
|
17
|
+
"@trackunit/react-components": "^1.1.0",
|
|
18
18
|
"@trackunit/react-core-hooks": "^1.0.5",
|
|
19
|
-
"@trackunit/react-filter-components": "^1.0.
|
|
20
|
-
"@trackunit/react-date-and-time-components": "^1.0.
|
|
19
|
+
"@trackunit/react-filter-components": "^1.0.18",
|
|
20
|
+
"@trackunit/react-date-and-time-components": "^1.0.17",
|
|
21
21
|
"@trackunit/shared-utils": "^1.0.3",
|
|
22
|
-
"@trackunit/react-form-components": "^1.0.
|
|
22
|
+
"@trackunit/react-form-components": "^1.0.17",
|
|
23
23
|
"@trackunit/react-core-contexts-api": "^1.0.5",
|
|
24
24
|
"@trackunit/geo-json-utils": "^1.0.2",
|
|
25
25
|
"@trackunit/i18n-library-translation": "^1.0.7"
|