fix(core): filters edge cases
This commit is contained in:
@@ -191,15 +191,16 @@ export const CheckboxTree = (props: CheckboxTreeProps) => {
|
||||
dispatch({ type: 'openCategory', payload: value });
|
||||
};
|
||||
|
||||
const handleChange = () => {
|
||||
useEffect(() => {
|
||||
const values = Object.values(state).map(category => ({
|
||||
category: category.label,
|
||||
selected: Object.values(category.options)
|
||||
category: category.isChecked ? category.label : null,
|
||||
selectedChilds: Object.values(category.options)
|
||||
.filter(option => option.isChecked)
|
||||
.map(option => option.value),
|
||||
}));
|
||||
onChange(values);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [state]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -213,13 +214,12 @@ export const CheckboxTree = (props: CheckboxTreeProps) => {
|
||||
<ListItem
|
||||
dense
|
||||
button
|
||||
onClick={async () => {
|
||||
await dispatch({
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: 'checkCategory',
|
||||
payload: item.label,
|
||||
});
|
||||
handleChange();
|
||||
}}
|
||||
})
|
||||
}
|
||||
>
|
||||
<ListItemIcon className={classes.listItemIcon}>
|
||||
<Checkbox
|
||||
@@ -253,16 +253,15 @@ export const CheckboxTree = (props: CheckboxTreeProps) => {
|
||||
button
|
||||
key={option.label}
|
||||
className={classes.nested}
|
||||
onClick={async () => {
|
||||
await dispatch({
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: 'checkOption',
|
||||
payload: {
|
||||
subCategoryLabel: item.label,
|
||||
optionLabel: option.label,
|
||||
},
|
||||
});
|
||||
handleChange();
|
||||
}}
|
||||
})
|
||||
}
|
||||
>
|
||||
<ListItemIcon className={classes.listItemIcon}>
|
||||
<Checkbox
|
||||
|
||||
@@ -24,17 +24,18 @@ import {
|
||||
|
||||
import {
|
||||
FormControl,
|
||||
InputLabel,
|
||||
Select,
|
||||
MenuItem,
|
||||
InputBase,
|
||||
Chip,
|
||||
Typography,
|
||||
Checkbox,
|
||||
ClickAwayListener
|
||||
} from '@material-ui/core';
|
||||
|
||||
import ClosedDropdown from './static/ClosedDropdown';
|
||||
import OpenedDropdown from './static/OpenedDropdown';
|
||||
import { idea } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
|
||||
|
||||
const BootstrapInput = withStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -118,9 +119,20 @@ export const SelectComponent = (props: SelectProps) => {
|
||||
};
|
||||
|
||||
const selectHandleOnOpen = () => {
|
||||
setCanOpen(!canOpen);
|
||||
setCanOpen(previous => {
|
||||
if (multiple) {
|
||||
return true
|
||||
}
|
||||
return !previous
|
||||
});
|
||||
};
|
||||
|
||||
const handleClickAway = (event: React.ChangeEvent<any>) => {
|
||||
if (event.target.id !== "menu-item") {
|
||||
setCanOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = (selectedValue: string | number) => () => {
|
||||
const newValue = (value as any[]).filter(chip => chip !== selectedValue)
|
||||
setValue(newValue);
|
||||
@@ -130,9 +142,9 @@ export const SelectComponent = (props: SelectProps) => {
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Typography variant="button">{label}</Typography>
|
||||
<ClickAwayListener onClickAway={handleClickAway}>
|
||||
<FormControl className={classes.formControl}>
|
||||
<Select
|
||||
id="select"
|
||||
value={value}
|
||||
displayEmpty
|
||||
multiple={multiple}
|
||||
@@ -177,13 +189,13 @@ export const SelectComponent = (props: SelectProps) => {
|
||||
}}
|
||||
>
|
||||
{placeholder && (
|
||||
<MenuItem value="" disabled>
|
||||
<MenuItem value={[]}>
|
||||
{placeholder}
|
||||
</MenuItem>
|
||||
)}
|
||||
{items &&
|
||||
items.map(item => (
|
||||
<MenuItem key={item.value} value={item.value}>
|
||||
<MenuItem id="menu-item" key={item.value} value={item.value}>
|
||||
{multiple && (
|
||||
<Checkbox
|
||||
color="primary"
|
||||
@@ -196,6 +208,7 @@ export const SelectComponent = (props: SelectProps) => {
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</ClickAwayListener>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -80,7 +80,7 @@ export const Filters = (props: Props) => {
|
||||
|
||||
useEffect(() => {
|
||||
onChangeFilters(selectedFilters);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedFilters]);
|
||||
|
||||
// As material table doesn't provide a way to add a column filter tab we will make our own filter logic
|
||||
@@ -99,12 +99,25 @@ export const Filters = (props: Props) => {
|
||||
<CheckboxTree
|
||||
key={filter.element.label}
|
||||
{...(filter.element as CheckboxTreeProps)}
|
||||
onChange={
|
||||
el => ({})
|
||||
// setSelectedFilters({
|
||||
// ...selectedFilters,
|
||||
// [filter.element.label]: el,
|
||||
// })
|
||||
onChange={el =>
|
||||
setSelectedFilters({
|
||||
...selectedFilters,
|
||||
[filter.element.label]: el
|
||||
.filter(
|
||||
(checkboxFilter: any) =>
|
||||
checkboxFilter.category ||
|
||||
checkboxFilter.selectedChilds.length,
|
||||
)
|
||||
.map((checkboxFilter: any) =>
|
||||
checkboxFilter.category
|
||||
? [
|
||||
...checkboxFilter.selectedChilds,
|
||||
checkboxFilter.category,
|
||||
]
|
||||
: checkboxFilter.selectedChilds,
|
||||
)
|
||||
.flat(),
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -138,6 +138,7 @@ const useFilterStyles = makeStyles<BackstageTheme>(() => ({
|
||||
const useTableStyles = makeStyles<BackstageTheme>(() => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
alignItems: 'start',
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -212,23 +213,20 @@ export function Table<T extends object = {}>({
|
||||
const getFieldByTitle = (titleValue: string | keyof T) =>
|
||||
columns.find(el => el.title === titleValue)?.field;
|
||||
|
||||
|
||||
const onChangeFilters = (selectedFilters: any) => {
|
||||
const onChangeFilters = (selectedFilters: any) => {
|
||||
const selectedFiltersArray = Object.values(selectedFilters);
|
||||
if (selectedFiltersArray.flat().length) {
|
||||
const newData = (props.data as any[]).filter(
|
||||
el =>
|
||||
!!Object.entries(selectedFilters).find(
|
||||
([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.includes(el[getFieldByTitle(key)])
|
||||
}
|
||||
return el[getFieldByTitle(key)] === value
|
||||
},
|
||||
),
|
||||
!!Object.entries(selectedFilters).find(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.includes(el[getFieldByTitle(key)]);
|
||||
}
|
||||
return el[getFieldByTitle(key)] === value;
|
||||
}),
|
||||
);
|
||||
setTableData(newData);
|
||||
setSelectedFiltersLength(selectedFiltersArray.flat().length)
|
||||
setSelectedFiltersLength(selectedFiltersArray.flat().length);
|
||||
} else {
|
||||
setTableData(props.data as any[]);
|
||||
}
|
||||
@@ -283,7 +281,9 @@ export function Table<T extends object = {}>({
|
||||
>
|
||||
<FilterList />
|
||||
</IconButton>
|
||||
<Typography variant="h6">Filters ({ selectedFiltersLength })</Typography>
|
||||
<Typography variant="h6">
|
||||
Filters ({selectedFiltersLength})
|
||||
</Typography>
|
||||
</div>
|
||||
<MTableToolbar classes={toolbarClasses} {...toolbarProps} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user