0870497ee2ece84caeebaff670aca1855c5f4e1d
[arvados-workbench2.git] / src / components / data-table-filters / data-table-filters-tree.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from "react";
6 import { Tree, toggleNodeSelection, getNode, initTreeNode, getNodeChildrenIds } from '~/models/tree';
7 import { Tree as TreeComponent, TreeItem, TreeItemStatus } from '~/components/tree/tree';
8 import { noop, map } from "lodash/fp";
9 import { toggleNodeCollapse } from '~/models/tree';
10
11 export interface DataTableFilterItem {
12     name: string;
13 }
14
15 export type DataTableFilters = Tree<DataTableFilterItem>;
16
17 export interface DataTableFilterProps {
18     filters: DataTableFilters;
19     onChange?: (filters: DataTableFilters) => void;
20 }
21
22 export class DataTableFiltersTree extends React.Component<DataTableFilterProps> {
23
24     render() {
25         return <TreeComponent
26             items={filtersToTree(this.props.filters)}
27             render={renderItem}
28             showSelection
29             onContextMenu={noop}
30             toggleItemActive={noop}
31             toggleItemOpen={this.toggleOpen}
32             toggleItemSelection={this.toggleFilter}
33         />;
34     }
35
36     toggleFilter = (_: React.MouseEvent, item: TreeItem<DataTableFilterItem>) => {
37         const { onChange = noop } = this.props;
38         onChange(toggleNodeSelection(item.id)(this.props.filters));
39     }
40
41     toggleOpen = (_: React.MouseEvent, item: TreeItem<DataTableFilterItem>) => {
42         const { onChange = noop } = this.props;
43         onChange(toggleNodeCollapse(item.id)(this.props.filters));
44     }
45 }
46
47 const renderItem = (item: TreeItem<DataTableFilterItem>) =>
48     <span>{item.data.name}</span>;
49
50 const filterToTreeItem = (filters: DataTableFilters) =>
51     (id: string): TreeItem<any> => {
52         const node = getNode(id)(filters) || initTreeNode({ id: '', value: 'InvalidNode' });
53         const items = getNodeChildrenIds(node.id)(filters)
54             .map(filterToTreeItem(filters));
55
56         return {
57             active: node.active,
58             data: node.value,
59             id: node.id,
60             items: items.length > 0 ? items : undefined,
61             open: node.expanded,
62             selected: node.selected,
63             status: TreeItemStatus.LOADED,
64         };
65     };
66
67 const filtersToTree = (filters: DataTableFilters): TreeItem<DataTableFilterItem>[] =>
68     map(filterToTreeItem(filters), getNodeChildrenIds('')(filters));