filters: DataTableFilters;
onChange?: (filters: DataTableFilters) => void;
+ /**
+ * When set to true, only one filter can be selected at a time.
+ */
+ mutuallyExclusive?: boolean;
+
/**
* By default `all` filters selection means that label should be grayed out.
* Use `none` when label is supposed to be grayed out when no filter is selected.
onClick={this.open}
disableRipple>
{children}
- <IconButton component='span' classes={{root: classes.iconButton}} tabIndex={-1}>
+ <IconButton component='span' classes={{ root: classes.iconButton }} tabIndex={-1}>
<i className={classnames(["fas fa-filter", classes.icon])}
data-fa-transform="shrink-3"
ref={this.icon} />
</CardContent>
<DataTableFiltersTree
filters={this.state.filters}
- onChange={filters => this.setState({ filters })} />
+ mutuallyExclusive={this.props.mutuallyExclusive}
+ onChange={filters => {
+ this.setState({ filters });
+ }} />
<CardActions>
<Button
color="primary"
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
-import { Tree, toggleNodeSelection, getNode, initTreeNode, getNodeChildrenIds } from '~/models/tree';
+import { Tree, toggleNodeSelection, getNode, initTreeNode, getNodeChildrenIds, selectNode, deselectNodes } from '~/models/tree';
import { Tree as TreeComponent, TreeItem, TreeItemStatus } from '~/components/tree/tree';
import { noop, map } from "lodash/fp";
import { toggleNodeCollapse } from '~/models/tree';
export interface DataTableFilterProps {
filters: DataTableFilters;
onChange?: (filters: DataTableFilters) => void;
+
+ /**
+ * When set to true, only one filter can be selected at a time.
+ */
+ mutuallyExclusive?: boolean;
}
export class DataTableFiltersTree extends React.Component<DataTableFilterProps> {
items={filtersToTree(filters)}
render={renderItem}
showSelection
+ useRadioButtons={this.props.mutuallyExclusive}
+ toggleItemRadioButton={this.toggleRadioButtonFilter}
disableRipple
onContextMenu={noop}
toggleItemActive={noop}
/>;
}
+ /**
+ * Handler for when a tree item is toggled via a radio button.
+ * Ensures mutual exclusivity among filter tree items.
+ */
+ toggleRadioButtonFilter = (item: TreeItem<DataTableFilterItem>) => {
+ const { onChange = noop } = this.props;
+
+ // If the filter is already selected, do nothing.
+ if (item.selected) { return; }
+
+ // Otherwise select this node and deselect the others
+ const filters = selectNode(item.id)(this.props.filters);
+ const toDeselect = Object.keys(this.props.filters).filter((id) => (id !== item.id));
+ onChange(deselectNodes(toDeselect)(filters));
+ }
+
toggleFilter = (_: React.MouseEvent, item: TreeItem<DataTableFilterItem>) => {
const { onChange = noop } = this.props;
onChange(toggleNodeSelection(item.id)(this.props.filters));