16472: Adds parameter to commonService.get to avoid showing errors.
[arvados-workbench2.git] / src / services / collection-files-service / collection-manifest-mapper.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { uniqBy, groupBy } from 'lodash';
6 import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "~/models/keep-manifest";
7 import { TreeNode, setNode, createTree, getNodeDescendantsIds, getNodeValue, TreeNodeStatus } from '~/models/tree';
8 import { CollectionFilesTree, CollectionFile, CollectionDirectory, createCollectionDirectory, createCollectionFile, CollectionFileType } from '../../models/collection-file';
9
10 export const mapCollectionFilesTreeToManifest = (tree: CollectionFilesTree): KeepManifest => {
11     const values = getNodeDescendantsIds('')(tree).map(id => getNodeValue(id)(tree));
12     const files = values.filter(value => value && value.type === CollectionFileType.FILE) as CollectionFile[];
13     const fileGroups = groupBy(files, file => file.path);
14     return Object
15         .keys(fileGroups)
16         .map(dirName => ({
17             name: dirName,
18             locators: [],
19             files: fileGroups[dirName].map(mapCollectionFile)
20         }));
21 };
22
23 export const mapManifestToCollectionFilesTree = (manifest: KeepManifest): CollectionFilesTree =>
24     manifestToCollectionFiles(manifest)
25         .map(mapCollectionFileToTreeNode)
26         .reduce((tree, node) => setNode(node)(tree), createTree<CollectionFile>());
27
28
29 export const mapCollectionFileToTreeNode = (file: CollectionFile): TreeNode<CollectionFile> => ({
30     children: [],
31     id: file.id,
32     parent: file.path,
33     value: file,
34     active: false,
35     selected: false,
36     expanded: false,
37     status: TreeNodeStatus.INITIAL,
38 });
39
40 export const manifestToCollectionFiles = (manifest: KeepManifest): Array<CollectionDirectory | CollectionFile> => ([
41     ...mapManifestToDirectories(manifest),
42     ...mapManifestToFiles(manifest)
43 ]);
44
45 export const mapManifestToDirectories = (manifest: KeepManifest): CollectionDirectory[] =>
46     uniqBy(
47         manifest
48             .map(mapStreamDirectory)
49             .map(splitDirectory)
50             .reduce((all, splitted) => ([...all, ...splitted]), []),
51         directory => directory.id);
52
53 export const mapManifestToFiles = (manifest: KeepManifest): CollectionFile[] =>
54     manifest
55         .map(stream => stream.files.map(mapStreamFile(stream)))
56         .reduce((all, current) => ([...all, ...current]), []);
57
58 const splitDirectory = (directory: CollectionDirectory): CollectionDirectory[] => {
59     return directory.name
60         .split('/')
61         .slice(1)
62         .map(mapPathComponentToDirectory);
63 };
64
65 const mapPathComponentToDirectory = (component: string, index: number, components: string[]): CollectionDirectory =>
66     createCollectionDirectory({
67         path: index === 0 ? '' : joinPathComponents(components, index),
68         id: joinPathComponents(components, index + 1),
69         name: component,
70     });
71
72 const joinPathComponents = (components: string[], index: number) =>
73     `/${components.slice(0, index).join('/')}`;
74
75 const mapCollectionFile = (file: CollectionFile): KeepManifestStreamFile => ({
76     name: file.name,
77     position: '',
78     size: file.size
79 });
80
81 const mapStreamDirectory = (stream: KeepManifestStream): CollectionDirectory =>
82     createCollectionDirectory({
83         path: '',
84         id: stream.name,
85         name: stream.name,
86     });
87
88 const mapStreamFile = (stream: KeepManifestStream) =>
89     (file: KeepManifestStreamFile): CollectionFile =>
90         createCollectionFile({
91             path: stream.name,
92             id: `${stream.name}/${file.name}`,
93             name: file.name,
94             size: file.size,
95         });
96