Merge branch '14841-link-workbench1' refs #14841 refs #14720
[arvados.git] / src / store / collection-panel / collection-panel-files / collection-panel-files-state.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Tree, TreeNode, mapTreeValues, getNodeValue, getNodeDescendants } from '~/models/tree';
6 import { CollectionFile, CollectionDirectory, CollectionFileType } from '~/models/collection-file';
7
8 export type CollectionPanelFilesState = Tree<CollectionPanelDirectory | CollectionPanelFile>;
9
10 export interface CollectionPanelDirectory extends CollectionDirectory {
11     collapsed: boolean;
12     selected: boolean;
13 }
14
15 export interface CollectionPanelFile extends CollectionFile {
16     selected: boolean;
17 }
18
19 export const mapCollectionFileToCollectionPanelFile = (node: TreeNode<CollectionDirectory | CollectionFile>): TreeNode<CollectionPanelDirectory | CollectionPanelFile> => {
20     return {
21         ...node,
22         value: node.value.type === CollectionFileType.DIRECTORY
23             ? { ...node.value, selected: false, collapsed: true }
24             : { ...node.value, selected: false }
25     };
26 };
27
28 export const mergeCollectionPanelFilesStates = (oldState: CollectionPanelFilesState, newState: CollectionPanelFilesState) => {
29     return mapTreeValues((value: CollectionPanelDirectory | CollectionPanelFile) => {
30         const oldValue = getNodeValue(value.id)(oldState);
31         return oldValue
32             ? oldValue.type === CollectionFileType.DIRECTORY
33                 ? { ...value, collapsed: oldValue.collapsed, selected: oldValue.selected }
34                 : { ...value, selected: oldValue.selected }
35             : value;
36     })(newState);
37 };
38
39 export const filterCollectionFilesBySelection = (tree: CollectionPanelFilesState, selected: boolean) => {
40     const allFiles = getNodeDescendants('')(tree).map(node => node.value);
41
42     const selectedDirectories = allFiles.filter(file => file.selected === selected && file.type === CollectionFileType.DIRECTORY);
43     const selectedFiles = allFiles.filter(file => file.selected === selected && !selectedDirectories.some(dir => dir.id === file.path));
44     return [...selectedDirectories, ...selectedFiles];
45 };