import { combineLatest, Observable, of } from "rxjs";
import { concatAll, filter, map, mergeMap, take } from "rxjs/operators";
import { TranslateService } from "@ngx-translate/core";
import * as uriTemplates_ from "uri-templates";
import { AppdataStore } from "../../components/appdata/appdata.store";
import { WidgetframeService } from "../../widgets/widgetframe/widgetframe.service";
const uriTemplates = uriTemplates_;
export interface ResponseAndNodes {
nodes: any[];
response: any;
}
export class NodeLoader {
constructor(
private translateService: TranslateService,
private appstore: AppdataStore,
private widgetFrameService: WidgetframeService
) {}
public staticFolders(staticFolders: any[]): Observable<ResponseAndNodes> {
if (staticFolders == null) {
return of({
nodes: [],
response: null,
});
}
let folders = [];
staticFolders.forEach((entry) => {
entry.pimRef = entry.nameKey;
entry.id = entry.nameKey;
entry.name = this.translateService.instant(entry.nameKey);
entry.isStatic = true;
entry.folder = true;
folders.push(entry);
});
return of({
nodes: folders,
response: staticFolders,
});
}
private mapFolders(parent, folders: any[], result: any[]) {
folders.forEach((entry) => {
this.mapFolder(entry, parent);
result.push(entry);
if (entry._embedded && entry._embedded.folder) {
this.mapFolders(entry.pimRef, entry._embedded.folder, result);
}
});
}
public mapFolder(entry, parent?) {
entry.isFolder = true;
// required for app compatibility
entry.folder = true;
entry.actions = entry._actions;
entry.id = entry.pimRef;
if (parent != null) {
entry.parent = parent;
}
return entry;
}
public folders(
foldersUrl: string,
folderType: string
): Observable<ResponseAndNodes> {
return of(
of(foldersUrl),
this.appstore.getAppdata().pipe(
map((data) => (data as any).ipim._links.listfolder.href),
map((href) => uriTemplates(href).fill({ type: folderType }))
)
).pipe(
concatAll(),
filter((url) => !!url),
take(1),
mergeMap((url) => this.widgetFrameService.getData(url)),
map((response) => {
let folders = [];
this.mapFolders(null, response._embedded.folders, folders);
return {
nodes: folders,
response,
};
})
);
}
public elements(
elementsUrl: string,
elementsType: string,
elementsIdentifier: string = "identifier",
elementsDescription: string = "description"
): Observable<ResponseAndNodes> {
return of(
of(elementsUrl).pipe(filter((url) => !!url)),
this.appstore
.getAppdata()
.pipe(map((data) => (data as any).ipim._links[elementsType].href))
).pipe(
concatAll(),
filter((url) => !!url),
take(1),
mergeMap((url) => this.widgetFrameService.getData(url)),
map((data) => {
let nodes = data._embedded[elementsType].map((entry) => {
return this.mapEntry(entry, elementsIdentifier, elementsDescription);
});
return {
nodes: nodes,
response: data,
};
})
);
}
public nodes(
staticFolders: any[],
foldersUrl: string,
folderType: string,
elementsUrl: string,
elementsType: string,
elementsIdentifier?: string,
elementsDescription?: string
): Observable<any[]> {
return combineLatest([
this.staticFolders(staticFolders),
this.folders(foldersUrl, folderType),
this.elements(
elementsUrl,
elementsType,
elementsIdentifier,
elementsDescription
),
]).pipe(
map(([staticFolders, folders, elements]) => {
return [...staticFolders.nodes, ...folders.nodes, ...elements.nodes];
})
);
}
mapEntry(
entry: any,
elementsIdentifier: string,
elementsDescription: string
): any {
if (entry.folderPimRef) {
entry.parent = entry.folderPimRef;
entry._folder = entry.folder;
delete entry.folder;
}
entry.pimRef = entry[elementsIdentifier];
entry.id = entry[elementsIdentifier];
entry.name = entry[elementsDescription];
entry.actions = entry._actions;
entry.isNode = true;
return entry;
}
public static defaultStaticFolders(): any[] {
return [
{
nameKey: "dynamic-worklists",
icon: "folder-star",
},
];
}
}