d195a98a6836b3f861768b703494e4c7ec5a783b
[arvados-workbench2.git] / src / store / tree-picker / tree-picker-reducer.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { createTree, setNodeValueWith, TreeNode, setNode, mapTree, mapTreeValues } from "../../models/tree";
6 import { TreePicker, TreePickerNode } from "./tree-picker";
7 import { treePickerActions, TreePickerAction } from "./tree-picker-actions";
8 import { TreeItemStatus } from "../../components/tree/tree";
9
10
11 export const treePickerReducer = (state: TreePicker = createTree(), action: TreePickerAction) =>
12     treePickerActions.match(action, {
13         LOAD_TREE_PICKER_NODE: ({ id }) =>
14             setNodeValueWith(setPending)(id)(state),
15         LOAD_TREE_PICKER_NODE_SUCCESS: ({ id, nodes }) => {
16             const [newState] = [state]
17                 .map(receiveNodes(nodes)(id))
18                 .map(setNodeValueWith(setLoaded)(id));
19             return newState;
20         },
21         TOGGLE_TREE_PICKER_NODE_COLLAPSE: ({ id }) =>
22             setNodeValueWith(toggleCollapse)(id)(state),
23         TOGGLE_TREE_PICKER_NODE_SELECT: ({ id }) =>
24             mapTreeValues(toggleSelect(id))(state),
25         default: () => state
26     });
27
28 const setPending = (value: TreePickerNode): TreePickerNode =>
29     ({ ...value, status: TreeItemStatus.PENDING });
30
31 const setLoaded = (value: TreePickerNode): TreePickerNode =>
32     ({ ...value, status: TreeItemStatus.LOADED });
33
34 const toggleCollapse = (value: TreePickerNode): TreePickerNode =>
35     ({ ...value, collapsed: !value.collapsed });
36
37 const toggleSelect = (id: string) => (value: TreePickerNode): TreePickerNode =>
38     value.id === id
39         ? ({ ...value, selected: !value.selected })
40         : ({ ...value, selected: false });
41
42 const receiveNodes = (nodes: Array<TreePickerNode>) => (parent: string) => (state: TreePicker) =>
43     nodes.reduce((tree, node) =>
44         setNode(
45             createTreeNode(parent)(node)
46         )(tree), state);
47
48 const createTreeNode = (parent: string) => (node: TreePickerNode): TreeNode<TreePickerNode> => ({
49     children: [],
50     id: node.id,
51     parent,
52     value: node
53 });