Merge pull request #7194 from ainhoaL/remove-checkboxtree
core-components: Remove CheckboxTree component (used in Table Filters)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/core-components': minor
|
||||
---
|
||||
|
||||
Checkbox tree filters are no longer available in the Table component:
|
||||
|
||||
- Deleted the `CheckboxTree` component
|
||||
- Removed the filter type `'checkbox-tree'` from the `TableFilter` types.
|
||||
@@ -1913,7 +1913,7 @@ export interface TableColumn<T extends object = {}> extends Column<T> {
|
||||
// @public (undocumented)
|
||||
export type TableFilter = {
|
||||
column: string;
|
||||
type: 'select' | 'multiple-select' | /** @deprecated */ 'checkbox-tree';
|
||||
type: 'select' | 'multiple-select';
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "TableProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { CheckboxTree } from './CheckboxTree';
|
||||
|
||||
const CHECKBOX_TREE_ITEMS = [
|
||||
{
|
||||
label: 'Generic subcategory name 1',
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Option 2',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Generic subcategory name 2',
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Option 2',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Generic subcategory name 3',
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Option 2',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default {
|
||||
title: 'Inputs/CheckboxTree',
|
||||
component: CheckboxTree,
|
||||
};
|
||||
|
||||
export const Default = () => (
|
||||
<CheckboxTree
|
||||
onChange={() => {}}
|
||||
label="default"
|
||||
subCategories={CHECKBOX_TREE_ITEMS}
|
||||
/>
|
||||
);
|
||||
|
||||
export const DynamicTree = () => {
|
||||
function generateTree(showMore: boolean = false) {
|
||||
const t = [
|
||||
{
|
||||
label: 'Show more',
|
||||
options: [],
|
||||
},
|
||||
];
|
||||
|
||||
if (showMore) {
|
||||
t.push({
|
||||
label: 'More',
|
||||
options: [],
|
||||
});
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
const [tree, setTree] = useState(generateTree());
|
||||
|
||||
return (
|
||||
<CheckboxTree
|
||||
onChange={state => {
|
||||
setTree(generateTree(state.some(c => c.category === 'Show more')));
|
||||
}}
|
||||
label="default"
|
||||
subCategories={tree}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { CheckboxTree } from './CheckboxTree';
|
||||
|
||||
const CHECKBOX_TREE_ITEMS = [
|
||||
{
|
||||
label: 'Generic subcategory name 1',
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Option 2',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const minProps = {
|
||||
onChange: jest.fn(),
|
||||
label: 'Default',
|
||||
subCategories: CHECKBOX_TREE_ITEMS,
|
||||
};
|
||||
|
||||
describe('<CheckboxTree />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByText, getByTestId } = render(<CheckboxTree {...minProps} />);
|
||||
|
||||
expect(getByText('Generic subcategory name 1')).toBeInTheDocument();
|
||||
const checkbox = await getByTestId('expandable');
|
||||
|
||||
// Simulate click on expandable arrow
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
// Simulate click on option
|
||||
const option = getByText('Option 1');
|
||||
expect(getByText('Option 1')).toBeInTheDocument();
|
||||
fireEvent.click(option);
|
||||
expect(minProps.onChange).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* eslint-disable guard-for-in */
|
||||
import {
|
||||
Checkbox,
|
||||
Collapse,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess';
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore';
|
||||
import produce from 'immer';
|
||||
import { isEqual } from 'lodash';
|
||||
import React, { useEffect, useReducer } from 'react';
|
||||
import { usePrevious } from 'react-use';
|
||||
|
||||
type IndexedObject<T> = {
|
||||
[key: string]: T;
|
||||
};
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
width: '100%',
|
||||
minWidth: 10,
|
||||
maxWidth: 360,
|
||||
backgroundColor: 'transparent',
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
'&:active': {
|
||||
animation: 'none',
|
||||
transform: 'none',
|
||||
},
|
||||
},
|
||||
nested: {
|
||||
paddingLeft: theme.spacing(5),
|
||||
height: '32px',
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
},
|
||||
listItemIcon: {
|
||||
minWidth: 10,
|
||||
},
|
||||
listItem: {
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
},
|
||||
text: {
|
||||
'& span, & svg': {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
/* SUB_CATEGORY */
|
||||
|
||||
type SubCategory = {
|
||||
label: string;
|
||||
isChecked?: boolean;
|
||||
isOpen?: boolean;
|
||||
options?: Option[];
|
||||
};
|
||||
|
||||
type SubCategoryWithIndexedOptions = {
|
||||
label: string;
|
||||
isChecked?: boolean;
|
||||
isOpen?: boolean;
|
||||
options: IndexedObject<Option>;
|
||||
};
|
||||
|
||||
/* OPTION */
|
||||
|
||||
type Option = {
|
||||
label: string;
|
||||
value: string | number;
|
||||
isChecked?: boolean;
|
||||
};
|
||||
|
||||
type Selection = { category?: string; selectedChildren?: string[] }[];
|
||||
|
||||
export type CheckboxTreeProps = {
|
||||
subCategories: SubCategory[];
|
||||
label: string;
|
||||
triggerReset?: boolean;
|
||||
selected?: Selection;
|
||||
onChange: (arg: Selection) => any;
|
||||
};
|
||||
|
||||
/* REDUCER */
|
||||
|
||||
type checkOptionPayload = {
|
||||
subCategoryLabel: string;
|
||||
optionLabel: string;
|
||||
};
|
||||
|
||||
type Action =
|
||||
| { type: 'checkOption'; payload: checkOptionPayload }
|
||||
| { type: 'checkCategory'; payload: string }
|
||||
| { type: 'toggleCategory'; payload: string }
|
||||
| {
|
||||
type: 'updateCategories';
|
||||
payload: IndexedObject<SubCategoryWithIndexedOptions>;
|
||||
}
|
||||
| { type: 'updateSelected'; payload: Selection }
|
||||
| { type: 'triggerReset' };
|
||||
|
||||
const reducer = (
|
||||
state: IndexedObject<SubCategoryWithIndexedOptions>,
|
||||
action: Action,
|
||||
) => {
|
||||
switch (action.type) {
|
||||
case 'checkOption': {
|
||||
return produce(state, newState => {
|
||||
const category = newState[action.payload.subCategoryLabel];
|
||||
const option = category.options[action.payload.optionLabel];
|
||||
option.isChecked = !option.isChecked;
|
||||
category.isChecked = Object.values(category.options).every(
|
||||
o => o.isChecked,
|
||||
);
|
||||
});
|
||||
}
|
||||
case 'checkCategory': {
|
||||
return produce(state, newState => {
|
||||
const category = newState[action.payload];
|
||||
const options = category.options;
|
||||
category.isChecked = !category.isChecked;
|
||||
for (const option in options) {
|
||||
options[option].isChecked = category.isChecked;
|
||||
}
|
||||
});
|
||||
}
|
||||
case 'toggleCategory':
|
||||
return produce(state, newState => {
|
||||
const category = newState[action.payload];
|
||||
category.isOpen = !category.isOpen;
|
||||
});
|
||||
case 'triggerReset': {
|
||||
return produce(state, newState => {
|
||||
for (const category in newState) {
|
||||
newState[category].isChecked = false;
|
||||
for (const option in newState[category].options) {
|
||||
newState[category].options[option].isChecked =
|
||||
newState[category].isChecked;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
case 'updateCategories': {
|
||||
return produce(state, newState => {
|
||||
for (const category in newState) {
|
||||
delete newState[category];
|
||||
}
|
||||
|
||||
for (const category in action.payload) {
|
||||
newState[category] = action.payload[category];
|
||||
|
||||
if (state[category]) {
|
||||
newState[category].isChecked = state[category].isChecked;
|
||||
newState[category].isOpen = state[category].isOpen;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
case 'updateSelected': {
|
||||
return produce(state, newState => {
|
||||
for (const category in newState) {
|
||||
const selection = action.payload.find(s => s.category === category);
|
||||
|
||||
if (selection) {
|
||||
newState[category].isChecked = true;
|
||||
|
||||
for (const option in newState[category].options) {
|
||||
newState[category].options[option].isChecked =
|
||||
selection.selectedChildren?.includes(option) || false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const indexer = (
|
||||
arr: SubCategory[],
|
||||
): IndexedObject<SubCategoryWithIndexedOptions> =>
|
||||
arr.reduce((accumulator, el) => {
|
||||
if (el.options) {
|
||||
return {
|
||||
...accumulator,
|
||||
[el.label]: {
|
||||
label: el.label,
|
||||
isChecked: el.isChecked || false,
|
||||
isOpen: false,
|
||||
options: indexer(el.options),
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
...accumulator,
|
||||
[el.label]: { ...el, isChecked: el.isChecked || false },
|
||||
};
|
||||
}, {});
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated CheckboxTree is no longer used in Table filters
|
||||
*/
|
||||
export function CheckboxTree(props: CheckboxTreeProps) {
|
||||
const { subCategories, label, selected, onChange, triggerReset } = props;
|
||||
const classes = useStyles();
|
||||
|
||||
const [state, dispatch] = useReducer(reducer, indexer(subCategories));
|
||||
|
||||
const handleOpen = (event: any, value: any) => {
|
||||
event.stopPropagation();
|
||||
dispatch({ type: 'toggleCategory', payload: value });
|
||||
};
|
||||
|
||||
const previousSubCategories = usePrevious(subCategories);
|
||||
|
||||
useEffect(() => {
|
||||
const values = Object.values(state).map(category => ({
|
||||
category: category.isChecked ? category.label : undefined,
|
||||
selectedChildren: Object.values(category.options)
|
||||
.filter(option => option.isChecked)
|
||||
.map(option => option.label),
|
||||
}));
|
||||
onChange(values);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [state]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({ type: 'triggerReset' });
|
||||
}, [triggerReset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selected) {
|
||||
dispatch({ type: 'updateSelected', payload: selected });
|
||||
}
|
||||
}, [selected]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEqual(subCategories, previousSubCategories)) {
|
||||
dispatch({
|
||||
type: 'updateCategories',
|
||||
payload: indexer(subCategories),
|
||||
});
|
||||
}
|
||||
}, [subCategories, previousSubCategories]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography variant="button">{label}</Typography>
|
||||
<List className={classes.root}>
|
||||
{Object.values(state).map(item => (
|
||||
<div key={item.label}>
|
||||
<ListItem
|
||||
className={classes.listItem}
|
||||
dense
|
||||
button
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: 'checkCategory',
|
||||
payload: item.label,
|
||||
})
|
||||
}
|
||||
>
|
||||
<ListItemIcon className={classes.listItemIcon}>
|
||||
<Checkbox
|
||||
color="primary"
|
||||
edge="start"
|
||||
checked={item.isChecked}
|
||||
tabIndex={-1}
|
||||
disableRipple
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText className={classes.text} primary={item.label} />
|
||||
{Object.values(item.options).length ? (
|
||||
<>
|
||||
{item.isOpen ? (
|
||||
<ExpandLess
|
||||
data-testid="expandable"
|
||||
onClick={event => handleOpen(event, item.label)}
|
||||
/>
|
||||
) : (
|
||||
<ExpandMore
|
||||
data-testid="expandable"
|
||||
onClick={event => handleOpen(event, item.label)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
</ListItem>
|
||||
<Collapse in={item.isOpen} timeout="auto" unmountOnExit>
|
||||
<List component="div" disablePadding>
|
||||
{Object.values(item.options).map(option => (
|
||||
<ListItem
|
||||
button
|
||||
key={option.label}
|
||||
className={classes.nested}
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: 'checkOption',
|
||||
payload: {
|
||||
subCategoryLabel: item.label,
|
||||
optionLabel: option.label,
|
||||
},
|
||||
})
|
||||
}
|
||||
>
|
||||
<ListItemIcon className={classes.listItemIcon}>
|
||||
<Checkbox
|
||||
color="primary"
|
||||
edge="start"
|
||||
checked={option.isChecked}
|
||||
tabIndex={-1}
|
||||
disableRipple
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
className={classes.text}
|
||||
primary={option.label}
|
||||
/>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Collapse>
|
||||
</div>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { CheckboxTree } from './CheckboxTree';
|
||||
@@ -18,8 +18,6 @@ import React, { useEffect, useState } from 'react';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Button, makeStyles } from '@material-ui/core';
|
||||
import { Select } from '../Select';
|
||||
import { CheckboxTree } from '../CheckboxTree';
|
||||
import { CheckboxTreeProps } from '../CheckboxTree/CheckboxTree';
|
||||
import { SelectProps } from '../Select/Select';
|
||||
|
||||
const useSubvalueCellStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
@@ -53,10 +51,8 @@ const useSubvalueCellStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
export type Without<T, K> = Pick<T, Exclude<keyof T, K>>;
|
||||
|
||||
export type Filter = {
|
||||
type: 'select' | /** @deprecated */ 'checkbox-tree' | 'multiple-select';
|
||||
element:
|
||||
| Without<CheckboxTreeProps, 'onChange'>
|
||||
| Without<SelectProps, 'onChange'>;
|
||||
type: 'select' | 'multiple-select';
|
||||
element: Without<SelectProps, 'onChange'>;
|
||||
};
|
||||
|
||||
export type SelectedFilters = {
|
||||
@@ -100,57 +96,20 @@ export const Filters = (props: Props) => {
|
||||
</div>
|
||||
<div className={classes.filters}>
|
||||
{props.filters?.length &&
|
||||
props.filters.map(filter =>
|
||||
filter.type === 'checkbox-tree' ? (
|
||||
<CheckboxTree
|
||||
triggerReset={reset}
|
||||
key={filter.element.label}
|
||||
{...(filter.element as CheckboxTreeProps)}
|
||||
selected={
|
||||
selectedFilters[filter.element.label]
|
||||
? (selectedFilters[filter.element.label] as string[]).map(
|
||||
s => ({
|
||||
category: s,
|
||||
}),
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
onChange={el =>
|
||||
setSelectedFilters({
|
||||
...selectedFilters,
|
||||
[filter.element.label]: el
|
||||
.filter(
|
||||
(checkboxFilter: any) =>
|
||||
checkboxFilter.category ||
|
||||
checkboxFilter.selectedChildren.length,
|
||||
)
|
||||
.map((checkboxFilter: any) =>
|
||||
checkboxFilter.category
|
||||
? [
|
||||
...checkboxFilter.selectedChildren,
|
||||
checkboxFilter.category,
|
||||
]
|
||||
: checkboxFilter.selectedChildren,
|
||||
)
|
||||
.flat(),
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
triggerReset={reset}
|
||||
key={filter.element.label}
|
||||
{...(filter.element as SelectProps)}
|
||||
selected={selectedFilters[filter.element.label]}
|
||||
onChange={el =>
|
||||
setSelectedFilters({
|
||||
...selectedFilters,
|
||||
[filter.element.label]: el as any,
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
props.filters.map(filter => (
|
||||
<Select
|
||||
triggerReset={reset}
|
||||
key={filter.element.label}
|
||||
{...(filter.element as SelectProps)}
|
||||
selected={selectedFilters[filter.element.label]}
|
||||
onChange={el =>
|
||||
setSelectedFilters({
|
||||
...selectedFilters,
|
||||
[filter.element.label]: el as any,
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -313,10 +313,6 @@ export const FilterTable = () => {
|
||||
column: 'Column 2',
|
||||
type: 'multiple-select',
|
||||
},
|
||||
{
|
||||
column: 'Numeric value',
|
||||
type: 'checkbox-tree',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -56,7 +56,6 @@ import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { CheckboxTreeProps } from '../CheckboxTree/CheckboxTree';
|
||||
import { SelectProps } from '../Select/Select';
|
||||
import { Filter, Filters, SelectedFilters, Without } from './Filters';
|
||||
|
||||
@@ -191,7 +190,7 @@ export interface TableColumn<T extends object = {}> extends Column<T> {
|
||||
|
||||
export type TableFilter = {
|
||||
column: string;
|
||||
type: 'select' | 'multiple-select' | /** @deprecated */ 'checkbox-tree';
|
||||
type: 'select' | 'multiple-select';
|
||||
};
|
||||
|
||||
export type TableState = {
|
||||
@@ -365,14 +364,6 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
|
||||
setSelectedFiltersLength(selectedFiltersArray.flat().length);
|
||||
}, [data, selectedFilters, getFieldByTitle]);
|
||||
|
||||
// Check for deprecated checkbox-tree filter
|
||||
useEffect(() => {
|
||||
if (filters?.some(filter => filter.type === 'checkbox-tree')) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('"checkbox-tree" filter type is deprecated');
|
||||
}
|
||||
}, [filters]);
|
||||
|
||||
const constructFilters = (
|
||||
filterConfig: TableFilter[],
|
||||
dataValue: any[] | undefined,
|
||||
@@ -403,16 +394,6 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
|
||||
return distinctValues;
|
||||
};
|
||||
|
||||
const constructCheckboxTree = (
|
||||
filter: TableFilter,
|
||||
): Without<CheckboxTreeProps, 'onChange'> => ({
|
||||
label: filter.column,
|
||||
subCategories: [...extractDistinctValues(filter.column)].map(v => ({
|
||||
label: v,
|
||||
options: [],
|
||||
})),
|
||||
});
|
||||
|
||||
const constructSelect = (
|
||||
filter: TableFilter,
|
||||
): Without<SelectProps, 'onChange'> => {
|
||||
@@ -429,10 +410,7 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
|
||||
|
||||
return filterConfig.map(filter => ({
|
||||
type: filter.type,
|
||||
element:
|
||||
filter.type === 'checkbox-tree'
|
||||
? constructCheckboxTree(filter)
|
||||
: constructSelect(filter),
|
||||
element: constructSelect(filter),
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user