Add collection-panel manifest map utils
[arvados-workbench2.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 { uniqBy } from 'lodash';
6 import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "../../../models/keep-manifest";
7
8 export type CollectionPanelFilesState = Array<CollectionPanelItem>;
9
10 export type CollectionPanelItem = CollectionPanelDirectory | CollectionPanelFile;
11
12 export interface CollectionPanelDirectory {
13     parentId?: string;
14     id: string;
15     name: string;
16     collapsed: boolean;
17     selected: boolean;
18     type: 'directory';
19 }
20
21 export interface CollectionPanelFile {
22     parentId?: string;
23     id: string;
24     name: string;
25     selected: boolean;
26     size: number;
27     type: 'file';
28 }
29
30 export const mapManifestToItems = (manifest: KeepManifest): CollectionPanelItem[] => ([
31     ...mapManifestToDirectories(manifest),
32     ...mapManifestToFiles(manifest)
33 ]);
34
35 export const mapManifestToDirectories = (manifest: KeepManifest): CollectionPanelDirectory[] =>
36     uniqBy(
37         manifest
38             .map(mapStreamDirectory)
39             .map(splitDirectory)
40             .reduce((all, splitted) => ([...all, ...splitted]), []),
41         directory => directory.id);
42
43 export const mapManifestToFiles = (manifest: KeepManifest): CollectionPanelFile[] =>
44     manifest
45         .map(stream => stream.files.map(mapStreamFile(stream)))
46         .reduce((all, current) => ([...all, ...current]), []);
47
48 const splitDirectory = (directory: CollectionPanelDirectory): CollectionPanelDirectory[] => {
49     return directory.name
50         .split('/')
51         .slice(1)
52         .map(mapPathComponentToDirectory);
53 };
54
55 const mapPathComponentToDirectory = (component: string, index: number, components: string[]): CollectionPanelDirectory =>
56     createDirectory({
57         parentId: index === 0 ? '' : joinPathComponents(components, index),
58         id: joinPathComponents(components, index + 1),
59         name: component,
60     });
61
62 const joinPathComponents = (components: string[], index: number) =>
63     `/${components.slice(0, index).join('/')}`;
64
65 const mapStreamDirectory = (stream: KeepManifestStream): CollectionPanelDirectory =>
66     createDirectory({
67         parentId: '',
68         id: stream.name,
69         name: stream.name,
70     });
71
72 const mapStreamFile = (stream: KeepManifestStream) =>
73     (file: KeepManifestStreamFile): CollectionPanelFile =>
74         createFile({
75             parentId: stream.name,
76             id: `${stream.name}/${file.name}`,
77             name: file.name,
78             size: file.size,
79         });
80
81 const createDirectory = (data: { parentId: string, id: string, name: string }): CollectionPanelDirectory => ({
82     ...data,
83     collapsed: true,
84     selected: false,
85     type: 'directory'
86 });
87
88 const createFile = (data: { parentId: string, id: string, name: string, size: number }): CollectionPanelFile => ({
89     ...data,
90     selected: false,
91     type: 'file'
92 });