X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/1c7242e61e9d71c7a37483ec0583dd0256f8ee7e..HEAD:/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.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-state.ts index 953f4c01..298a5a1e 100644 --- a/src/store/collection-panel/collection-panel-files/collection-panel-files-state.ts +++ b/src/store/collection-panel/collection-panel-files/collection-panel-files-state.ts @@ -2,14 +2,62 @@ // // SPDX-License-Identifier: AGPL-3.0 -export type CollectionPanelFilesState = Array; +import { Tree, TreeNode, mapTreeValues, getNodeValue, getNodeDescendants } from 'models/tree'; +import { CollectionFile, CollectionDirectory, CollectionFileType } from 'models/collection-file'; +import { ContextMenuResource } from 'store/context-menu/context-menu-actions'; +import { CollectionResource } from 'models/collection'; -export interface CollectionPanelFile { - parentId?: string; - id: string; - name: string; - size?: number; +export type CollectionPanelFilesState = Tree; + +export interface CollectionPanelDirectory extends CollectionDirectory { collapsed: boolean; selected: boolean; - type: string; -} \ No newline at end of file +} + +export interface CollectionPanelFile extends CollectionFile { + selected: boolean; +} + +export interface CollectionFileSelection { + collection: CollectionResource; + selectedPaths: string[]; +} + +export const mapCollectionFileToCollectionPanelFile = (node: TreeNode): TreeNode => { + return { + ...node, + value: node.value.type === CollectionFileType.DIRECTORY + ? { ...node.value, selected: false, collapsed: true } + : { ...node.value, selected: false } + }; +}; + +export const mergeCollectionPanelFilesStates = (oldState: CollectionPanelFilesState, newState: CollectionPanelFilesState) => { + return mapTreeValues((value: CollectionPanelDirectory | CollectionPanelFile) => { + const oldValue = getNodeValue(value.id)(oldState); + return oldValue + ? oldValue.type === CollectionFileType.DIRECTORY + ? { ...value, collapsed: oldValue.collapsed, selected: oldValue.selected } + : { ...value, selected: oldValue.selected } + : value; + })(newState); +}; + +export const filterCollectionFilesBySelection = (tree: CollectionPanelFilesState, selected: boolean): (CollectionPanelFile | CollectionPanelDirectory)[] => { + const allFiles = getNodeDescendants('')(tree).map(node => node.value); + const selectedDirectories = allFiles.filter(file => file.selected === selected && file.type === CollectionFileType.DIRECTORY); + const selectedFiles = allFiles.filter(file => file.selected === selected && !selectedDirectories.some(dir => dir.id === file.path)); + return [...selectedDirectories, ...selectedFiles] + .filter((value, index, array) => ( + array.indexOf(value) === index + )); +}; + +export const getCollectionSelection = (sourceCollection: CollectionResource, selectedItems: (CollectionPanelDirectory | CollectionPanelFile | ContextMenuResource)[]) => ({ + collection: sourceCollection, + selectedPaths: selectedItems.map(itemsToPaths).map(trimPathUuids(sourceCollection.uuid)), +}) + +const itemsToPaths = (item: (CollectionPanelDirectory | CollectionPanelFile | ContextMenuResource)): string => ('uuid' in item) ? item.uuid : item.id; + +const trimPathUuids = (parentCollectionUuid: string) => (path: string) => path.replace(new RegExp(`(^${parentCollectionUuid})`), '');