getAllNested for collections too. added treenodeobject interface

This commit is contained in:
Kyle Spearrin 2018-10-25 12:09:22 -04:00
parent 6aba4550a4
commit 59f0549072
7 changed files with 70 additions and 39 deletions

View File

@ -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>;

37
src/misc/serviceUtils.ts Normal file
View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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; }>(

View File

@ -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);
}
}
}