1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { createTree, setNodeValueWith, TreeNode, setNode, mapTreeValues, Tree } 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 import { compose } from "redux";
11 export const treePickerReducer = (state: TreePicker = {}, action: TreePickerAction) =>
12 treePickerActions.match(action, {
13 LOAD_TREE_PICKER_NODE: ({ nodeId, pickerId }) =>
14 updateOrCreatePicker(state, pickerId, setNodeValueWith(setPending)(nodeId)),
15 LOAD_TREE_PICKER_NODE_SUCCESS: ({ nodeId, nodes, pickerId }) =>
16 updateOrCreatePicker(state, pickerId, compose(receiveNodes(nodes)(nodeId),setNodeValueWith(setLoaded)(nodeId))),
17 TOGGLE_TREE_PICKER_NODE_COLLAPSE: ({ nodeId, pickerId }) =>
18 updateOrCreatePicker(state, pickerId, setNodeValueWith(toggleCollapse)(nodeId)),
19 TOGGLE_TREE_PICKER_NODE_SELECT: ({ nodeId, pickerId }) =>
20 updateOrCreatePicker(state, pickerId, mapTreeValues(toggleSelect(nodeId))),
24 const updateOrCreatePicker = (state: TreePicker, pickerId: string, func: (value: Tree<TreePickerNode>) => Tree<TreePickerNode>) => {
25 const picker = state[pickerId] || createTree();
26 const updatedPicker = func(picker);
27 return { ...state, [pickerId]: updatedPicker };
30 const setPending = (value: TreePickerNode): TreePickerNode =>
31 ({ ...value, status: TreeItemStatus.PENDING });
33 const setLoaded = (value: TreePickerNode): TreePickerNode =>
34 ({ ...value, status: TreeItemStatus.LOADED });
36 const toggleCollapse = (value: TreePickerNode): TreePickerNode =>
37 ({ ...value, collapsed: !value.collapsed });
39 const toggleSelect = (nodeId: string) => (value: TreePickerNode): TreePickerNode =>
40 value.nodeId === nodeId
41 ? ({ ...value, selected: !value.selected })
42 : ({ ...value, selected: false });
44 const receiveNodes = (nodes: Array<TreePickerNode>) => (parent: string) => (state: Tree<TreePickerNode>) =>
45 nodes.reduce((tree, node) =>
47 createTreeNode(parent)(node)
50 const createTreeNode = (parent: string) => (node: TreePickerNode): TreeNode<TreePickerNode> => ({