//
// SPDX-License-Identifier: AGPL-3.0
-import { uniqBy } from 'lodash';
-import { KeepManifestStream, KeepManifestStreamFile, KeepManifest } from "../../../models/keep-manifest";
+import { Tree, TreeNode, mapTreeValues, getNodeValue, getNodeDescendants } from '~/models/tree';
+import { CollectionFile, CollectionDirectory, CollectionFileType } from '~/models/collection-file';
-export type CollectionPanelFilesState = Array<CollectionPanelItem>;
+export type CollectionPanelFilesState = Tree<CollectionPanelDirectory | CollectionPanelFile>;
-export type CollectionPanelItem = CollectionPanelDirectory | CollectionPanelFile;
-
-export interface CollectionPanelDirectory {
- parentId?: string;
- id: string;
- name: string;
+export interface CollectionPanelDirectory extends CollectionDirectory {
collapsed: boolean;
selected: boolean;
- type: 'directory';
}
-export interface CollectionPanelFile {
- parentId?: string;
- id: string;
- name: string;
+export interface CollectionPanelFile extends CollectionFile {
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);
+export const mapCollectionFileToCollectionPanelFile = (node: TreeNode<CollectionDirectory | CollectionFile>): TreeNode<CollectionPanelDirectory | CollectionPanelFile> => {
+ return {
+ ...node,
+ value: node.value.type === CollectionFileType.DIRECTORY
+ ? { ...node.value, selected: false, collapsed: true }
+ : { ...node.value, selected: false }
+ };
};
-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,
- });
+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);
+};
-const createDirectory = (data: { parentId: string, id: string, name: string }): CollectionPanelDirectory => ({
- ...data,
- collapsed: true,
- selected: false,
- type: 'directory'
-});
+export const filterCollectionFilesBySelection = (tree: CollectionPanelFilesState, selected: boolean) => {
+ const allFiles = getNodeDescendants('')(tree).map(node => node.value);
-const createFile = (data: { parentId: string, id: string, name: string, size: number }): CollectionPanelFile => ({
- ...data,
- selected: false,
- type: 'file'
-});
\ No newline at end of file
+ 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];
+};