1e62bad6e22a63e6bd28b0d67b875dfe524aba2b
[arvados.git] / src / store / collection-panel / collection-panel-files / collections-panel-files-reducer.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { CollectionPanelFilesState, CollectionPanelFile } from "./collection-panel-files-state";
6 import { CollectionPanelFilesAction, collectionPanelFilesAction } from "./collection-panel-files-actions";
7 import { stat } from "fs";
8
9 const initialState: CollectionPanelFilesState = [{
10     collapsed: true,
11     id: 'Directory 1',
12     name: 'Directory 1',
13     selected: false,
14     type: 'directory',
15 }, {
16     parentId: 'Directory 1',
17     collapsed: true,
18     id: 'Directory 1.1',
19     name: 'Directory 1.1',
20     selected: false,
21     type: 'directory',
22 }, {
23     parentId: 'Directory 1',
24     collapsed: true,
25     id: 'File 1.1',
26     name: 'File 1.1',
27     selected: false,
28     type: 'file',
29 }, {
30     collapsed: true,
31     id: 'Directory 2',
32     name: 'Directory 2',
33     selected: false,
34     type: 'directory',
35 }, {
36     parentId: 'Directory 2',
37     collapsed: true,
38     id: 'Directory 2.1',
39     name: 'Directory 2.1',
40     selected: false,
41     type: 'directory',
42 }, {
43     parentId: 'Directory 2.1',
44     collapsed: true,
45     id: 'Directory 2.1.1',
46     name: 'Directory 2.1.1',
47     selected: false,
48     type: 'directory',
49 }, {
50     parentId: 'Directory 2.1.1',
51     collapsed: true,
52     id: 'Directory 2.1.1.1',
53     name: 'Directory 2.1.1.1',
54     selected: false,
55     type: 'directory',
56 }];
57
58 export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = initialState, action: CollectionPanelFilesAction) => {
59     return collectionPanelFilesAction.match(action, {
60         SET_COLLECTION_FILES: data => data.files,
61         TOGGLE_COLLECTION_FILE_COLLAPSE: data => toggleCollapsed(state, data.id),
62         TOGGLE_COLLECTION_FILE_SELECTION: data => toggleSelected(state, data.id),
63         default: () => state
64     });
65 };
66
67 const toggleCollapsed = (state: CollectionPanelFilesState, id: string) =>
68     state.map(file => file.id === id
69         ? { ...file, collapsed: !file.collapsed }
70         : file);
71
72 const toggleSelected = (state: CollectionPanelFilesState, id: string) =>
73     toggleAncestors(toggleDescendants(state, id), id);
74
75 const toggleDescendants = (state: CollectionPanelFilesState, id: string) => {
76     const ids = getDescendants(state)({ id }).map(file => file.id);
77     if (ids.length > 0) {
78         const selected = !state.find(f => f.id === ids[0])!.selected;
79         return state.map(file => ids.some(id => file.id === id) ? { ...file, selected } : file);
80     }
81     return state;
82 };
83
84 const toggleAncestors = (state: CollectionPanelFilesState, id: string): CollectionPanelFile[] => {
85     const file = state.find(f => f.id === id);
86     if (file) {
87         const selected = state
88             .filter(f => f.parentId === file.parentId)
89             .every(f => f.selected);
90         if (!selected) {
91             const newState = state.map(f => f.id === file.parentId ? { ...f, selected } : f);
92             return toggleAncestors(newState, file.parentId || "");
93         }
94     }
95     return state;
96 };
97
98 const getDescendants = (state: CollectionPanelFilesState) => ({ id }: { id: string }): CollectionPanelFile[] => {
99     const root = state.find(f => f.id === id);
100     if (root) {
101         return [root].concat(...state.filter(f => f.parentId === id).map(getDescendants(state)));
102     } else { return []; }
103 };
104