diff --git a/package.json b/package.json
index fb5d9396d..ad03762b2 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "version": "8.1.13",
+ "version": "8.1.14",
"license": "MIT",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
diff --git a/src/components/data-grid/DataGrid.tsx b/src/components/data-grid/DataGrid.tsx
index a49c7e812..df7b0bee2 100755
--- a/src/components/data-grid/DataGrid.tsx
+++ b/src/components/data-grid/DataGrid.tsx
@@ -56,6 +56,7 @@ import {
RowModelType,
DataGridColumnValueType,
CustomFilterTypes,
+ Filter,
} from './types';
import { useTheme } from '../../providers';
import { defaultFormatSettings } from './defaultFormatSettings';
@@ -572,6 +573,22 @@ export const DataGrid = ({
onFiltering(filterModel);
};
+ const getSetFilterObject = (values: (string | number | boolean | null)[], filterObject?: Filter) => {
+ if (filterObject?.customFilterMap) {
+ return filterObject?.customFilterMap(values);
+ }
+ if (filterObject?.byId) {
+ return {
+ ids: values,
+ filterType: CustomFilterTypes.ids,
+ };
+ }
+ return {
+ values,
+ filterType: CustomFilterTypes.set,
+ };
+ };
+
const onSetFiltering = useCallback(
(columnField: string, type: FilterType, value: FilterValue['value']) => {
let currentValues;
@@ -589,22 +606,7 @@ export const DataGrid = ({
}
const filterObject = filters?.find((filter) => filter.columnField === columnField);
- let setFilter;
- if (filterObject?.customFilterMap) {
- setFilter = filterObject?.customFilterMap(values);
- } else if (filterObject?.byId) {
- setFilter = {
- ids: values,
- filterType: CustomFilterTypes.ids,
- };
- } else {
- setFilter = {
- values,
- filterType: CustomFilterTypes.set,
- };
- }
-
- filterModel[columnField] = setFilter;
+ filterModel[columnField] = getSetFilterObject(values, filterObject);
onFiltering(filterModel);
},
@@ -634,6 +636,26 @@ export const DataGrid = ({
[setSelectedFilterIds, onSetFiltering],
);
+ const filterOnMultiValues = useCallback(
+ (columnField: string, values: FilterValue['value'][]) => {
+ if (!values.length) {
+ setFilterModel((model) => ({ ...model, [columnField]: undefined }));
+ return gridApi?.onFilterChanged();
+ }
+ const filterObject = filters?.find((filter) => filter.columnField === columnField);
+
+ filterModel[columnField] = getSetFilterObject(values, filterObject);
+
+ onFiltering(filterModel);
+
+ setSelectedFilterIds((currentIds) => ({
+ ...currentIds,
+ [columnField]: values,
+ }));
+ },
+ [setSelectedFilterIds, onSetFiltering],
+ );
+
// Date format that is send as part of the query request
const getDateFormat = useCallback((date: Date) => new TcDate(date).getDateWithoutTimeAsUTC().toISOString(), []);
@@ -772,6 +794,7 @@ export const DataGrid = ({
selectedFilterIds={selectedFilterIds}
setSelectedFilterIds={setSelectedFilterIds}
filterOnValue={filterOnValue}
+ filterOnMultiValues={filterOnMultiValues}
filterOnDate={filterOnDate}
debouncedSearch={debouncedSearch}
clearFilterModel={clearFilterModel}
diff --git a/src/components/data-grid/defaultTranslations.tsx b/src/components/data-grid/defaultTranslations.tsx
index ffdbcb3a7..831ffea20 100755
--- a/src/components/data-grid/defaultTranslations.tsx
+++ b/src/components/data-grid/defaultTranslations.tsx
@@ -40,6 +40,7 @@ export const defaultTranslations: Translations = {
defaultViewTooltip: 'Default view cannot be edited.',
lessFilters: 'Less filters',
allFilters: 'All filters',
+ applyFilters: 'Apply filters',
showResultsBy: 'Show',
paginationPrevious: 'Prev',
paginationNext: 'Next',
diff --git a/src/components/data-grid/filters/ColumnFilters.tsx b/src/components/data-grid/filters/ColumnFilters.tsx
index ee45ceede..2e9cfbf1f 100755
--- a/src/components/data-grid/filters/ColumnFilters.tsx
+++ b/src/components/data-grid/filters/ColumnFilters.tsx
@@ -12,6 +12,7 @@ import { Button } from '../../button';
import { ButtonKind } from '../../../models';
import { ParagraphSmall } from 'baseui/typography';
import { FixedSizeSelect } from '../../fixed-size-select';
+import { MultiFilter } from './MultiFilter';
const LESS_FILTERS_BUTTON_TEST_ID = 'less-filters-button';
const MORE_FILTERS_BUTTON_TEST_ID = 'more-filters-button';
@@ -25,9 +26,10 @@ export const ColumnFilters = ({
setDates,
setSelectedFilterIds,
selectedFilterIds,
- translations: { search, lessFilters, allFilters, clearFilters },
+ translations: { search, lessFilters, allFilters, clearFilters, applyFilters },
datepickerTranslations,
filterOnValue,
+ filterOnMultiValues,
filterOnDate,
clearFilterModel,
showClearFilters,
@@ -205,6 +207,9 @@ export const ColumnFilters = ({
const getSelectedFilterIds = (columnField: string) => selectedFilterIds[columnField]?.map(String);
+ const handleFilterMultiValues = (columnField: string) => (values: FilterValue['value'][]) =>
+ filterOnMultiValues(columnField, values);
+
const getSelectHasValue = (columnField: string) =>
Array.isArray(selectedFilterIds[columnField])
? !!selectedFilterIds[columnField].length
@@ -244,24 +249,18 @@ export const ColumnFilters = ({
>
),
[FilterType.multi]: (
-
- }
- size={SIZE.compact}
- isActive={isSetFilterActive(columnField)}
- onClear={() => onSetFilterClear(columnField)}
- hasValue={isSetFilterActive(columnField)}
- arrows
- />
-
+ valuesLoading={valuesLoading}
+ title={getSetTitle(columnField, title)}
+ icon={Icon && }
+ isFilterActive={isSetFilterActive(columnField)}
+ onSetFilterClear={() => onSetFilterClear(columnField)}
+ onApplyFilter={handleFilterMultiValues(columnField)}
+ applyFiltersLabel={applyFilters}
+ />
),
[FilterType.multiVirtual]: (
{
+ const [selectedItems, setSelectedItems] = useState([]);
+
+ const {
+ theme: {
+ current: {
+ sizing: { scale300, scale600 },
+ customColors: { light4 },
+ },
+ },
+ } = useTheme();
+
+ useEffect(() => {
+ setSelectedItems(values.filter((value) => !!initialSelectedFilterIds?.includes(value.id as string)));
+ }, [initialSelectedFilterIds]);
+
+ const handleApplyFilter = () => {
+ onApplyFilter(selectedItems.map((item) => item.id as string));
+ };
+
+ const handleSelectItem = (item: DropdownItem) => {
+ const filteredSelectedItems = selectedItems.filter(({ id }) => id !== item.id);
+ if (filteredSelectedItems.length < selectedItems.length) {
+ setSelectedItems(filteredSelectedItems);
+ return;
+ }
+ setSelectedItems([...selectedItems, item]);
+ };
+
+ const preparedValues = values.map((value) => ({
+ ...value,
+ action: () => handleSelectItem(value),
+ isBold: !!selectedItems.find(({ id }) => id === value.id),
+ }));
+
+ return (
+ id as string)}
+ searchPlaceholder={searchPlaceholder}
+ isLoading={valuesLoading}
+ footer={
+
+
+
+ }
+ >
+
+
+ );
+};
diff --git a/src/components/data-grid/filters/types.ts b/src/components/data-grid/filters/types.ts
new file mode 100644
index 000000000..d242daaa5
--- /dev/null
+++ b/src/components/data-grid/filters/types.ts
@@ -0,0 +1,16 @@
+import { ReactNode } from 'react';
+import { DropdownItem } from '../../dropdown';
+import { FilterValue } from '../types';
+
+export interface MultiFilterProps {
+ searchPlaceholder: string;
+ valuesLoading?: boolean;
+ values: DropdownItem[];
+ icon?: ReactNode;
+ isFilterActive: boolean;
+ title: string;
+ initialSelectedFilterIds: string[];
+ applyFiltersLabel: string;
+ onSetFilterClear: () => void;
+ onApplyFilter: (selectedItems: FilterValue['value'][]) => void;
+}
diff --git a/src/components/data-grid/types.ts b/src/components/data-grid/types.ts
index 9c38a2e73..707b0322f 100755
--- a/src/components/data-grid/types.ts
+++ b/src/components/data-grid/types.ts
@@ -173,6 +173,7 @@ export interface Translations {
defaultViewTooltip: string;
lessFilters: string;
allFilters: string;
+ applyFilters: string;
showResultsBy: string;
paginationPrevious: string;
paginationNext: string;
@@ -296,6 +297,7 @@ export interface FiltersProps {
selectedFilterIds: SelectedFilterIds;
setSelectedFilterIds: Dispatch>;
filterOnValue: (columnField: string, value: FilterValue['value'], type: FilterType) => void;
+ filterOnMultiValues: (columnField: string, values: FilterValue['value'][]) => void;
filterOnDate: (columnField: string, selectedDates: Date[]) => void;
debouncedSearch?: boolean;
clearFilterModel: (columnFilter: string) => void;
@@ -317,6 +319,7 @@ export interface ColumnFiltersProps {
selectedFilterIds: SelectedFilterIds;
setSelectedFilterIds: Dispatch>;
filterOnValue: (columnField: string, value: FilterValue['value'], type: FilterType) => void;
+ filterOnMultiValues: (columnField: string, values: FilterValue['value'][]) => void;
filterOnDate: (columnField: string, selectedDates: Date[]) => void;
clearFilterModel: (columnFilter: string) => void;
showClearFilters?: boolean;