getAllNested for collections too. added treenodeobject interface
This commit is contained in:
parent
6aba4550a4
commit
59f0549072
|
@ -1,6 +1,7 @@
|
|||
import { CollectionData } from '../models/data/collectionData';
|
||||
|
||||
import { Collection } from '../models/domain/collection';
|
||||
import { TreeNode } from '../models/domain/treeNode';
|
||||
|
||||
import { CollectionView } from '../models/view/collectionView';
|
||||
|
||||
|
@ -13,6 +14,7 @@ export abstract class CollectionService {
|
|||
get: (id: string) => Promise<Collection>;
|
||||
getAll: () => Promise<Collection[]>;
|
||||
getAllDecrypted: () => Promise<CollectionView[]>;
|
||||
getAllNested: (collections?: CollectionView[]) => Promise<Array<TreeNode<CollectionView>>>;
|
||||
upsert: (collection: CollectionData | CollectionData[]) => Promise<any>;
|
||||
replace: (collections: { [id: string]: CollectionData; }) => Promise<any>;
|
||||
clear: (userId: string) => Promise<any>;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import {
|
||||
ITreeNodeObject,
|
||||
TreeNode,
|
||||
} from '../models/domain/treeNode';
|
||||
|
||||
export class ServiceUtils {
|
||||
static nestedTraverse(nodeTree: Array<TreeNode<ITreeNodeObject>>, partIndex: number, parts: string[],
|
||||
obj: ITreeNodeObject, delimiter: string) {
|
||||
if (parts.length <= partIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
const end = partIndex === parts.length - 1;
|
||||
const partName = parts[partIndex];
|
||||
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.name === parts[partIndex]) {
|
||||
if (end && nodeTree[i].node.id !== obj.id) {
|
||||
// Another node with the same name.
|
||||
nodeTree.push(new TreeNode(obj, partName));
|
||||
return;
|
||||
}
|
||||
this.nestedTraverse(nodeTree[i].children, partIndex + 1, parts, obj, delimiter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeTree.filter((n) => n.node.name === partName).length === 0) {
|
||||
if (end) {
|
||||
nodeTree.push(new TreeNode(obj, partName));
|
||||
return;
|
||||
}
|
||||
const newPartName = parts[partIndex] + delimiter + parts[partIndex + 1];
|
||||
this.nestedTraverse(nodeTree, 0, [newPartName, ...parts.slice(partIndex + 2)], obj, delimiter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
export class TreeNode<T> {
|
||||
export class TreeNode<T extends ITreeNodeObject> {
|
||||
node: T;
|
||||
children: Array<TreeNode<T>> = [];
|
||||
|
||||
constructor(node: T) {
|
||||
constructor(node: T, name: string) {
|
||||
this.node = node;
|
||||
this.node.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITreeNodeObject {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { View } from './view';
|
||||
|
||||
import { Collection } from '../domain/collection';
|
||||
import { ITreeNodeObject } from '../domain/treeNode';
|
||||
|
||||
export class CollectionView implements View {
|
||||
export class CollectionView implements View, ITreeNodeObject {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
name: string;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { View } from './view';
|
||||
|
||||
import { Folder } from '../domain/folder';
|
||||
import { ITreeNodeObject } from '../domain/treeNode';
|
||||
|
||||
export class FolderView implements View {
|
||||
export class FolderView implements View, ITreeNodeObject {
|
||||
id: string = null;
|
||||
name: string;
|
||||
revisionDate: Date;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { CollectionData } from '../models/data/collectionData';
|
||||
|
||||
import { Collection } from '../models/domain/collection';
|
||||
import { TreeNode } from '../models/domain/treeNode';
|
||||
|
||||
import { CollectionView } from '../models/view/collectionView';
|
||||
|
||||
|
@ -10,11 +11,13 @@ import { I18nService } from '../abstractions/i18n.service';
|
|||
import { StorageService } from '../abstractions/storage.service';
|
||||
import { UserService } from '../abstractions/user.service';
|
||||
|
||||
import { ServiceUtils } from '../misc/serviceUtils';
|
||||
import { Utils } from '../misc/utils';
|
||||
|
||||
const Keys = {
|
||||
collectionsPrefix: 'collections_',
|
||||
};
|
||||
const NestingDelimiter = '/';
|
||||
|
||||
export class CollectionService implements CollectionServiceAbstraction {
|
||||
decryptedCollectionCache: CollectionView[];
|
||||
|
@ -95,6 +98,19 @@ export class CollectionService implements CollectionServiceAbstraction {
|
|||
return this.decryptedCollectionCache;
|
||||
}
|
||||
|
||||
async getAllNested(collections: CollectionView[] = null): Promise<Array<TreeNode<CollectionView>>> {
|
||||
if (collections == null) {
|
||||
collections = await this.getAllDecrypted();
|
||||
}
|
||||
const nodes: Array<TreeNode<CollectionView>> = [];
|
||||
collections.forEach((f) => {
|
||||
const collectionCopy = new CollectionView();
|
||||
collectionCopy.id = f.id;
|
||||
ServiceUtils.nestedTraverse(nodes, 0, f.name.split(NestingDelimiter), collectionCopy, NestingDelimiter);
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
||||
async upsert(collection: CollectionData | CollectionData[]): Promise<any> {
|
||||
const userId = await this.userService.getUserId();
|
||||
let collections = await this.storageService.get<{ [id: string]: CollectionData; }>(
|
||||
|
|
|
@ -2,6 +2,7 @@ import { FolderData } from '../models/data/folderData';
|
|||
|
||||
import { Folder } from '../models/domain/folder';
|
||||
import { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';
|
||||
import { TreeNode } from '../models/domain/treeNode';
|
||||
|
||||
import { FolderRequest } from '../models/request/folderRequest';
|
||||
|
||||
|
@ -18,8 +19,8 @@ import { StorageService } from '../abstractions/storage.service';
|
|||
import { UserService } from '../abstractions/user.service';
|
||||
import { CipherData } from '../models/data/cipherData';
|
||||
|
||||
import { ServiceUtils } from '../misc/serviceUtils';
|
||||
import { Utils } from '../misc/utils';
|
||||
import { TreeNode } from '../models/domain/treeNode';
|
||||
|
||||
const Keys = {
|
||||
foldersPrefix: 'folders_',
|
||||
|
@ -104,7 +105,7 @@ export class FolderService implements FolderServiceAbstraction {
|
|||
const folderCopy = new FolderView();
|
||||
folderCopy.id = f.id;
|
||||
folderCopy.revisionDate = f.revisionDate;
|
||||
this.nestedTraverse(nodes, 0, f.name.split(NestingDelimiter), folderCopy);
|
||||
ServiceUtils.nestedTraverse(nodes, 0, f.name.split(NestingDelimiter), folderCopy, NestingDelimiter);
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
@ -199,37 +200,4 @@ export class FolderService implements FolderServiceAbstraction {
|
|||
await this.apiService.deleteFolder(id);
|
||||
await this.delete(id);
|
||||
}
|
||||
|
||||
private nestedTraverse(nodeTree: Array<TreeNode<FolderView>>, partIndex: number,
|
||||
parts: string[], folder: FolderView) {
|
||||
if (parts.length <= partIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
const end = partIndex === parts.length - 1;
|
||||
const partName = parts[partIndex];
|
||||
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.name === parts[partIndex]) {
|
||||
if (end && nodeTree[i].node.id !== folder.id) {
|
||||
// Another node with the same name.
|
||||
folder.name = partName;
|
||||
nodeTree.push(new TreeNode(folder));
|
||||
return;
|
||||
}
|
||||
this.nestedTraverse(nodeTree[i].children, partIndex + 1, parts, folder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeTree.filter((n) => n.node.name === partName).length === 0) {
|
||||
if (end) {
|
||||
folder.name = partName;
|
||||
nodeTree.push(new TreeNode(folder));
|
||||
return;
|
||||
}
|
||||
const newPartName = parts[partIndex] + NestingDelimiter + parts[partIndex + 1];
|
||||
this.nestedTraverse(nodeTree, 0, [newPartName, ...parts.slice(partIndex + 2)], folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue