Add collection-panel manifest map utils
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 31 Jul 2018 12:38:15 +0000 (14:38 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 31 Jul 2018 12:38:15 +0000 (14:38 +0200)
Feature #13855

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/store/collection-panel/collection-panel-files/collection-panel-files-state.test.ts [new file with mode: 0644]
src/store/collection-panel/collection-panel-files/collection-panel-files-state.ts

diff --git a/src/store/collection-panel/collection-panel-files/collection-panel-files-state.test.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-state.test.ts
new file mode 100644 (file)
index 0000000..3550bc5
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { parseKeepManifestText } from "../../../models/keep-manifest";
+import { mapManifestToFiles, mapManifestToDirectories } from './collection-panel-files-state';
+
+test('mapManifestToFiles', () => {
+    const manifestText = `. 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n./c d41d8cd98f00b204e9800998ecf8427e+0 0:0:d`;
+    const manifest = parseKeepManifestText(manifestText);
+    const files = mapManifestToFiles(manifest);
+    expect(files).toEqual([{
+        parentId: '',
+        id: '/a',
+        name: 'a',
+        size: 0,
+        selected: false,
+        type: 'file'
+    }, {
+        parentId: '',
+        id: '/b',
+        name: 'b',
+        size: 0,
+        selected: false,
+        type: 'file'
+    }, {
+        parentId: '',
+        id: '/output.txt',
+        name: 'output.txt',
+        size: 33,
+        selected: false,
+        type: 'file'
+    }, {
+        parentId: '/c',
+        id: '/c/d',
+        name: 'd',
+        size: 0,
+        selected: false,
+        type: 'file'
+    },]);
+});
+
+test('mapManifestToDirectories', () => {
+    const manifestText = `./c/user/results 930625b054ce894ac40596c3f5a0d947+33 0:0:a 0:0:b 0:33:output.txt\n`;
+    const manifest = parseKeepManifestText(manifestText);
+    const directories = mapManifestToDirectories(manifest);
+    expect(directories).toEqual([{
+        parentId: "",
+        id: '/c',
+        name: 'c',
+        collapsed: true,
+        selected: false,
+        type: 'directory'
+    }, {
+        parentId: '/c',
+        id: '/c/user',
+        name: 'user',
+        collapsed: true,
+        selected: false,
+        type: 'directory'
+    }, {
+        parentId: '/c/user',
+        id: '/c/user/results',
+        name: 'results',
+        collapsed: true,
+        selected: false,
+        type: 'directory'
+    },]);
+});
\ No newline at end of file
index 953f4c0111492863100f2aecf8b43330ff64a805..6af2550dd2ed962001e1fa86d1f61367ba0621c5 100644 (file)
@@ -2,14 +2,91 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-export type CollectionPanelFilesState = Array<CollectionPanelFile>;
+import { uniqBy } from 'lodash';
+import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "../../../models/keep-manifest";
 
-export interface CollectionPanelFile {
+export type CollectionPanelFilesState = Array<CollectionPanelItem>;
+
+export type CollectionPanelItem = CollectionPanelDirectory | CollectionPanelFile;
+
+export interface CollectionPanelDirectory {
     parentId?: string;
     id: string;
     name: string;
-    size?: number;
     collapsed: boolean;
     selected: boolean;
-    type: string;
-}
\ No newline at end of file
+    type: 'directory';
+}
+
+export interface CollectionPanelFile {
+    parentId?: string;
+    id: string;
+    name: string;
+    selected: boolean;
+    size: number;
+    type: 'file';
+}
+
+export const mapManifestToItems = (manifest: KeepManifest): CollectionPanelItem[] => ([
+    ...mapManifestToDirectories(manifest),
+    ...mapManifestToFiles(manifest)
+]);
+
+export const mapManifestToDirectories = (manifest: KeepManifest): CollectionPanelDirectory[] =>
+    uniqBy(
+        manifest
+            .map(mapStreamDirectory)
+            .map(splitDirectory)
+            .reduce((all, splitted) => ([...all, ...splitted]), []),
+        directory => directory.id);
+
+export const mapManifestToFiles = (manifest: KeepManifest): CollectionPanelFile[] =>
+    manifest
+        .map(stream => stream.files.map(mapStreamFile(stream)))
+        .reduce((all, current) => ([...all, ...current]), []);
+
+const splitDirectory = (directory: CollectionPanelDirectory): CollectionPanelDirectory[] => {
+    return directory.name
+        .split('/')
+        .slice(1)
+        .map(mapPathComponentToDirectory);
+};
+
+const mapPathComponentToDirectory = (component: string, index: number, components: string[]): CollectionPanelDirectory =>
+    createDirectory({
+        parentId: index === 0 ? '' : joinPathComponents(components, index),
+        id: joinPathComponents(components, index + 1),
+        name: component,
+    });
+
+const joinPathComponents = (components: string[], index: number) =>
+    `/${components.slice(0, index).join('/')}`;
+
+const mapStreamDirectory = (stream: KeepManifestStream): CollectionPanelDirectory =>
+    createDirectory({
+        parentId: '',
+        id: stream.name,
+        name: stream.name,
+    });
+
+const mapStreamFile = (stream: KeepManifestStream) =>
+    (file: KeepManifestStreamFile): CollectionPanelFile =>
+        createFile({
+            parentId: stream.name,
+            id: `${stream.name}/${file.name}`,
+            name: file.name,
+            size: file.size,
+        });
+
+const createDirectory = (data: { parentId: string, id: string, name: string }): CollectionPanelDirectory => ({
+    ...data,
+    collapsed: true,
+    selected: false,
+    type: 'directory'
+});
+
+const createFile = (data: { parentId: string, id: string, name: string, size: number }): CollectionPanelFile => ({
+    ...data,
+    selected: false,
+    type: 'file'
+});
\ No newline at end of file