UNPKG

ntk-cms-filemanager

Version:

Ntk Cms Api And Model For Typscript

1 lines 171 kB
{"version":3,"file":"ntk-cms-filemanager.mjs","sources":["../../../projects/ntk-cms-filemanager/src/lib/models/componentOptionModel.ts","../../../projects/ntk-cms-filemanager/src/lib/models/tree.model.ts","../../../projects/ntk-cms-filemanager/src/lib/enums/download-mode.enum.ts","../../../projects/ntk-cms-filemanager/src/lib/services/file-manager-store.service.ts","../../../projects/ntk-cms-filemanager/src/lib/services/node.service.ts","../../../projects/ntk-cms-filemanager/src/lib/services/node-clicked.service.ts","../../../projects/ntk-cms-filemanager/src/lib/services/translateUi.service.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/node/node.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/node/node.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/folder-content/folder-content.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/folder-content/folder-content.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/tree/node-lister/node-lister.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/tree/node-lister/node-lister.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/tree/tree.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/tree/tree.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/nav-bar/nav-bar.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/nav-bar/nav-bar.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/navigation/navigation.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/navigation/navigation.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/functions/loading-overlay/loading-overlay.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/loading-overlay/loading-overlay.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/functions/upload/fileUploaderPickerAdapter.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/upload/upload.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/upload/upload.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/functions/new-folder/new-folder.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/functions/new-folder/new-folder.component.html","../../../projects/ntk-cms-filemanager/src/lib/components/side-view/side-view.component.ts","../../../projects/ntk-cms-filemanager/src/lib/components/side-view/side-view.component.html","../../../projects/ntk-cms-filemanager/src/lib/cms-filemanager.component.ts","../../../projects/ntk-cms-filemanager/src/lib/cms-filemanager.component.html","../../../projects/ntk-cms-filemanager/src/lib/pipes/file-size.pipe.ts","../../../projects/ntk-cms-filemanager/src/lib/pipes/map-to-iterable.pipe.ts","../../../projects/ntk-cms-filemanager/src/lib/cms-filemanager.module.ts","../../../projects/ntk-cms-filemanager/src/ntk-cms-filemanager.ts"],"sourcesContent":["export class ComponentOptionModel {\r\n childMethods: any;\r\n parentMethods: any;\r\n data: any;\r\n}\r\n","import { ConfigInterface } from '../interfaces/config.interface';\r\nimport { NodeInterface } from '../interfaces/node.interface';\r\n\r\nexport class TreeModel {\r\n private _currentPath: string;\r\n private _nodes: NodeInterface;\r\n private _selectedNodeId: string;\r\n public config: ConfigInterface;\r\n\r\n constructor(config: ConfigInterface) {\r\n // this._currentPath = config.startingFolder; // todo implement (config.interfce.ts)\r\n this._currentPath = '';\r\n this.config = config;\r\n\r\n this.nodes = ({\r\n id: 0,\r\n pathToNode: '',\r\n pathToParent: null,\r\n isFolder: true,\r\n isExpanded: true,\r\n stayOpen: true,\r\n name: 'root',\r\n children: {},\r\n isRoot: true\r\n } as NodeInterface);\r\n }\r\n\r\n get currentPath(): string {\r\n return this._currentPath;\r\n }\r\n\r\n set currentPath(value: string) {\r\n this._currentPath = value;\r\n }\r\n\r\n get nodes(): NodeInterface {\r\n return this._nodes;\r\n }\r\n\r\n set nodes(value: NodeInterface) {\r\n this._nodes = value;\r\n }\r\n\r\n get selectedNodeId(): string {\r\n return this._selectedNodeId;\r\n }\r\n\r\n set selectedNodeId(value: string) {\r\n this._selectedNodeId = value;\r\n }\r\n\r\n // todo implement (config.interfce.ts)\r\n // get isCache(): boolean {\r\n // return this.config.offlineMode;\r\n // }\r\n //\r\n // set isCache(value: boolean) {\r\n // this.config.offlineMode = value;\r\n // }\r\n}\r\n","export enum DownloadModeEnum {\r\n DOWNLOAD_DISABLED, DOWNLOAD_FILES, DOWNLOAD_ALL\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\nimport { distinctUntilChanged, map } from 'rxjs/operators';\r\nimport { NodeInterface } from '../interfaces/node.interface';\r\nimport { StateInterface } from '../interfaces/state.interface';\r\nimport { AppStore } from '../reducers/reducer.factory';\r\n\r\nconst initialState: StateInterface = {\r\n path: '',\r\n isLoading: true,\r\n selectedNode: null,\r\n inProcessingList: []\r\n};\r\n\r\n@Injectable()\r\nexport class FileManagerStoreService {\r\n private state: AppStore;\r\n\r\n private sub: Subject<AppStore> = new Subject<AppStore>();\r\n\r\n constructor() {\r\n this.state = {\r\n fileManagerState: initialState\r\n };\r\n\r\n // @ts-ignore\r\n window.getInfo = () => this.state;\r\n }\r\n\r\n dispatch(param: Actions) {\r\n Object.assign(this.state.fileManagerState, stateReducer(this.state.fileManagerState, param));\r\n this.sub.next(this.state);\r\n // if (isDevMode()) console.warn('[FileManagerStoreService] dispatch', param, JSON.parse(JSON.stringify(this.state)));\r\n }\r\n\r\n getState<R>(mapFn: (value: AppStore, index: number) => R): Observable<R> {\r\n if (typeof mapFn !== 'function') {\r\n throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');\r\n }\r\n\r\n return this.sub.asObservable()\r\n .pipe(map(mapFn))\r\n .pipe(distinctUntilChanged());\r\n }\r\n processStart(name: string): void {\r\n if (this.state?.fileManagerState?.inProcessingList) {\r\n const index = this.state.fileManagerState.inProcessingList.indexOf(name);\r\n if (index < 0) {\r\n // console.log('processStart 1', this.state.fileManagerState.inProcessingList);\r\n const list = [...this.state.fileManagerState.inProcessingList];\r\n list.push(name);\r\n // console.log('processStart 2', this.state.fileManagerState.inProcessingList);\r\n this.dispatch({ type: SET_IN_PROCESSING_LIST, payload: list });\r\n }\r\n }\r\n }\r\n processStop(name: string): void {\r\n if (this.state?.fileManagerState?.inProcessingList) {\r\n const index = this.state.fileManagerState.inProcessingList.indexOf(name);\r\n if (index >= 0) {\r\n // console.log('processStop 1', this.state.fileManagerState.inProcessingList);\r\n const list = [...this.state.fileManagerState.inProcessingList];\r\n list.splice(index, 1);\r\n // console.log('processStop 2', this.state.fileManagerState.inProcessingList);\r\n this.dispatch({ type: SET_IN_PROCESSING_LIST, payload: list });\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n// REDUCERS\r\nexport function stateReducer(state: StateInterface = initialState, action: Actions): StateInterface {\r\n switch (action.type) {\r\n case SET_PATH:\r\n if (action.payload === '/') {\r\n action.payload = '';\r\n }\r\n if (state.path === action.payload) {\r\n return state;\r\n }\r\n return { ...state, path: action.payload, isLoading: true };\r\n case SET_LOADING_STATE:\r\n return { ...state, isLoading: action.payload };\r\n case SET_IN_PROCESSING_LIST:\r\n return { ...state, inProcessingList: action.payload };\r\n case SET_SELECTED_NODE:\r\n return { ...state, selectedNode: action.payload };\r\n default:\r\n return initialState;\r\n }\r\n}\r\n\r\n\r\n// ACTIONS\r\nexport interface ActionInterface {\r\n readonly type: string;\r\n payload?: any;\r\n}\r\n\r\nexport const SET_PATH = 'SET_PATH';\r\nexport const SET_LOADING_STATE = 'SET_LOADING_STATE';\r\nexport const SET_IN_PROCESSING_LIST = 'SET_IN_PROCESSING_LIST';\r\nexport const SET_SELECTED_NODE = 'SET_SELECTED_NODE';\r\n\r\nexport class SetPath implements ActionInterface {\r\n readonly type = SET_PATH;\r\n payload: string;\r\n}\r\n\r\nexport class SetLoadingState implements ActionInterface {\r\n readonly type = SET_LOADING_STATE;\r\n payload: boolean;\r\n}\r\n\r\nexport class SetInProcessingList implements ActionInterface {\r\n readonly type = SET_IN_PROCESSING_LIST;\r\n payload: Array<string>;\r\n}\r\n\r\n\r\nexport class SetSelectedNode implements ActionInterface {\r\n readonly type = SET_SELECTED_NODE;\r\n payload: NodeInterface;\r\n}\r\n\r\nexport type Actions = SetPath | SetLoadingState | SetSelectedNode | SetInProcessingList;\r\n","import { HttpClient, HttpParams } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { FileCategoryService, FileContentService } from 'ntk-cms-api';\r\nimport { Observable } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\nimport { NodeInterface } from '../interfaces/node.interface';\r\nimport { TreeModel } from '../models/tree.model';\r\nimport { FileManagerStoreService, SET_LOADING_STATE, SET_PATH, SET_SELECTED_NODE } from './file-manager-store.service';\r\n\r\n/*\r\n{\r\n size: string // e.g. '3 KB'\r\n url?: string // download url\r\n id: string | number; // id can be path or database id\r\n dir: bool // is current node dir?\r\n path: string // path to current item (e.g. /folder1/someFile.txt)\r\n name?: string // optional (but we are using id as name if name is not present) (e.g. someFile.txt)\r\n}\r\nhttps://github.com/Chiff/ng6-file-man-express/blob/master/index.js\r\n*/\r\n// @Injectable({\r\n// providedIn: 'root'\r\n// })\r\n@Injectable()\r\nexport class NodeService {\r\n public serviceTree: TreeModel;\r\n private privatePath: string;\r\n\r\n constructor(\r\n private http: HttpClient,\r\n private store: FileManagerStoreService,\r\n private fileContentService: FileContentService,\r\n private fileCategoryService: FileCategoryService,\r\n ) {\r\n /** GUID */\r\n this.guid = this.newGuid();\r\n /** GUID */\r\n // console.log('NodeService Constructor:', this.guid);\r\n }\r\n /** GUID */\r\n private guid = '';\r\n private S4(): string {\r\n const ran = (1 + Math.random()) * 0x10000;\r\n return (ran | 0).toString(16).substring(1);\r\n }\r\n newGuid(): string {\r\n const isString = `${this.S4()}${this.S4()}-${this.S4()}-${this.S4()}-${this.S4()}-${this.S4()}${this.S4()}${this.S4()}`;\r\n return isString;\r\n }\r\n /** GUID */\r\n // todo ask server to get parent structure\r\n public startManagerAt(path: string): void {\r\n this.currentPath = path;\r\n this.refreshCurrentPath();\r\n }\r\n public refreshCurrentPath_orginal(): void {\r\n this.findNodeByPath_orginal(this.currentPath).children = {};\r\n this.getNodes_orginal(this.currentPath).then(() => {\r\n this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.serviceTree.nodes });\r\n this.store.dispatch({ type: SET_PATH, payload: this.currentPath });\r\n });\r\n }\r\n public refreshCurrentPath(): void {\r\n this.findNodeByPath(this.currentPath).children = {};\r\n this.getNodes(this.currentPath).then(() => {\r\n this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.serviceTree.nodes });\r\n this.store.dispatch({ type: SET_PATH, payload: this.currentPath });\r\n });\r\n }\r\n getNodes_orginal(path: string): Promise<Array<NodeInterface>> {\r\n return new Promise((resolve => {\r\n this.parseNodes_orginal(path).subscribe((data: Array<NodeInterface>) => {\r\n for (let i = 0; i < data.length; i++) {\r\n const parentPath = this.getParentPath(data[i].pathToNode);\r\n this.findNodeByPath_orginal(parentPath).children[data[i].name] = data[i];\r\n }\r\n resolve(null);\r\n });\r\n }));\r\n }\r\n getNodes(path: string): Promise<Array<NodeInterface>> {\r\n //console.log('getNodes Run:', this.guid);\r\n const prosses = 'getNodes';\r\n this.store.processStart(prosses);\r\n return new Promise((resolve => {\r\n this.parseNodes(path).subscribe((data: Array<NodeInterface>) => {\r\n for (let i = 0; i < data.length; i++) {\r\n const parentPath = this.getParentPath(data[i].pathToNode);\r\n this.findNodeByPath(parentPath).children[data[i].id] = data[i];\r\n }\r\n this.store.processStop(prosses);\r\n resolve(null);\r\n });\r\n }));\r\n }\r\n private getParentPath_orginal(path: string): string {\r\n let parentPath = path.split('/');\r\n parentPath = parentPath.slice(0, parentPath.length - 1);\r\n return parentPath.join('/');\r\n }\r\n private getParentPath(path: string): string {\r\n let parentPath = path.split('/');\r\n parentPath = parentPath.slice(0, parentPath.length - 1);\r\n return parentPath.join('/');\r\n }\r\n private parseNodes_orginal(path: string): Observable<NodeInterface[]> {\r\n return new Observable(observer => {\r\n this.getNodesFromServer_orginal(path).subscribe((data: Array<any>) => {\r\n observer.next(data.map(node => this.createNode_orginal(path, node)));\r\n this.store.dispatch({ type: SET_LOADING_STATE, payload: false });\r\n });\r\n });\r\n }\r\n private parseNodes(path: string): Observable<NodeInterface[]> {\r\n return new Observable(observer => {\r\n this.getNodesFromServer(path).subscribe((data: Array<any>) => {\r\n\r\n observer.next(data.map(node => this.createNode(path, node)));\r\n this.store.dispatch({ type: SET_LOADING_STATE, payload: false });\r\n\r\n });\r\n });\r\n }\r\n private createNode_orginal(path: string, node: any): NodeInterface {\r\n if (node.path[0] !== '/') {\r\n console.warn('[Node Service] Server should return initial path with \"/\"');\r\n node.path = '/' + node.path;\r\n }\r\n\r\n const ids = node.path.split('/');\r\n if (ids.length > 2 && ids[ids.length - 1] === '') {\r\n ids.splice(-1, 1);\r\n node.path = ids.join('/');\r\n }\r\n\r\n const cachedNode = this.findNodeByPath_orginal(node.path);\r\n return {\r\n id: node.id,\r\n isFolder: node.dir,\r\n isExpanded: cachedNode ? cachedNode.isExpanded : false,\r\n pathToNode: node.path,\r\n pathToParent: this.getParentPath_orginal(node.path),\r\n name: node.name || node.id,\r\n children: cachedNode ? cachedNode.children : {}\r\n } as NodeInterface;\r\n\r\n\r\n\r\n }\r\n private createNode(path: string, node: NodeInterface): NodeInterface {\r\n\r\n // if (node.parentId && node.parentId > 0) {\r\n // console.warn('[Node Service] Server should return initial path with \"/\"');\r\n // node.pathToNode = '/' + node.pathToNode;\r\n // }\r\n\r\n const ids = node.pathToNode.split('/');\r\n if (ids.length > 2 && ids[ids.length - 1] === '') {\r\n ids.splice(-1, 1);\r\n node.pathToNode = ids.join('/');\r\n }\r\n\r\n const cachedNode = this.findNodeByPath(node.pathToNode);\r\n const pathToParentVar = this.getParentPath(node.pathToNode);\r\n // node.isExpanded = cachedNode ? cachedNode.isExpanded : false;\r\n // node.pathToParent = pathToParentVar;\r\n // node.children = cachedNode ? cachedNode.children : {};\r\n // node.name = node.name ? node.name : node.id + '';\r\n // return node;\r\n return {\r\n id: node.id,\r\n isFolder: node.isFolder,\r\n isExpanded: cachedNode ? cachedNode.isExpanded : false,\r\n pathToNode: node.pathToNode,\r\n pathToParent: pathToParentVar,\r\n name: node.name || node.id,\r\n children: cachedNode ? cachedNode.children : {},\r\n createdDate: node.createdDate,\r\n updatedDate: node.updatedDate,\r\n size: node.size,\r\n extension: node.extension,\r\n downloadLinksrc: node.downloadLinksrc,\r\n downloadThumbnailSrc: node.downloadThumbnailSrc,\r\n } as NodeInterface;\r\n }\r\n private getNodesFromServer_orginal(path: string): Observable<any> {\r\n let folderId: any = this.findNodeByPath_orginal(path).id;\r\n folderId = folderId === 0 ? '' : folderId;\r\n\r\n return this.http.get(\r\n this.serviceTree.config.baseURL + this.serviceTree.config.api.listFile,\r\n { params: new HttpParams().set('parentPath', folderId) }\r\n );\r\n\r\n }\r\n private getNodesFromServer(path: string): Observable<Array<NodeInterface>> {\r\n this.store.dispatch({ type: SET_LOADING_STATE, payload: true });\r\n\r\n const findN = this.findNodeByPath(path);\r\n const folderId = findN ? findN.id : 0;\r\n // folderId = folderId === 0 ? '' : folderId;\r\n const retOut = new Observable<Array<NodeInterface>>(observer => {\r\n return this.getCategoryList(folderId, path).subscribe(\r\n xCat => {\r\n return this.getFileList(folderId, path).subscribe(\r\n (\r\n xfile => {\r\n xfile = xfile.concat(xCat);\r\n observer.next(xfile);\r\n })\r\n );\r\n });\r\n });\r\n\r\n return retOut;\r\n }\r\n public findNodeByPath_orginal(nodePath: string): NodeInterface {\r\n const ids = nodePath.split('/');\r\n ids.splice(0, 1);\r\n\r\n return ids.length === 0 ? this.serviceTree.nodes : ids.reduce((value, index) => value.children[index], this.serviceTree.nodes);\r\n }\r\n public findNodeByPath(nodePath: string): NodeInterface {\r\n const ids = nodePath.split('/');\r\n ids.splice(0, 1);\r\n if (ids.length === 0) {\r\n return this.serviceTree.nodes;\r\n }\r\n const retOut = ids.reduce((value, index) => value.children[index], this.serviceTree.nodes);\r\n return retOut;\r\n }\r\n\r\n public findNodeById_orginal(id: number): NodeInterface {\r\n const result = this.findNodeByIdHelper_orginal(id);\r\n\r\n if (result === null) {\r\n console.warn('[Node Service] Cannot find node by id. Id not existing or not fetched. Returning root.');\r\n return this.serviceTree.nodes;\r\n }\r\n\r\n return result;\r\n }\r\n public findNodeById(id: number): NodeInterface {\r\n\r\n const result = this.findNodeByIdHelper(id);\r\n\r\n if (result === null) {\r\n console.warn('[Node Service] Cannot find node by id. Id not existing or not fetched. Returning root.');\r\n return this.serviceTree.nodes;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n public findNodeByIdHelper_orginal(id: number, node: NodeInterface = this.serviceTree.nodes): any {\r\n if (node.id === id) {\r\n return node;\r\n }\r\n\r\n const keys = Object.keys(node.children);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n if (typeof node.children[keys[i]] === 'object') {\r\n const obj = this.findNodeByIdHelper_orginal(id, node.children[keys[i]]);\r\n if (obj != null) {\r\n return obj;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n public findNodeByIdHelper(id: number, node: NodeInterface = this.serviceTree.nodes): any {\r\n if (node.id === id) {\r\n return node;\r\n }\r\n\r\n const keys = Object.keys(node.children);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n if (typeof node.children[keys[i]] === 'object') {\r\n const obj = this.findNodeByIdHelper(id, node.children[keys[i]]);\r\n if (obj != null) {\r\n return obj;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n public foldRecursively_orginal(node: NodeInterface): void {\r\n // console.log('folding ', node);\r\n const children = node.children;\r\n\r\n Object.keys(children).map((child: string) => {\r\n if (!children.hasOwnProperty(child) || !children[child].isExpanded) {\r\n return null;\r\n }\r\n\r\n this.foldRecursively_orginal(children[child]);\r\n // todo put this getElById into one func (curr inside node.component.ts + fm.component.ts) - this won't be maintainable\r\n document.getElementById('tree_' + children[child].pathToNode).classList.add('deselected');\r\n children[child].isExpanded = false;\r\n });\r\n }\r\n public foldRecursively(node: NodeInterface): void {\r\n // console.log('folding ', node);\r\n const children = node.children;\r\n\r\n Object.keys(children).map((child: string) => {\r\n if (!children.hasOwnProperty(child) || !children[child].isExpanded) {\r\n return null;\r\n }\r\n\r\n this.foldRecursively(children[child]);\r\n // todo put this getElById into one func (curr inside node.component.ts + fm.component.ts) - this won't be maintainable\r\n document.getElementById('tree_' + children[child].pathToNode).classList.add('deselected');\r\n children[child].isExpanded = false;\r\n });\r\n }\r\n\r\n public foldAll_orginal(): void {\r\n this.foldRecursively_orginal(this.serviceTree.nodes);\r\n }\r\n public foldAll(refresh = false): void {\r\n if (refresh) {\r\n this.refreshCurrentPath();\r\n // this.foldRecursively(this.serviceTree.nodes);\r\n } else {\r\n this.foldRecursively(this.serviceTree.nodes);\r\n }\r\n }\r\n\r\n get currentPath(): string {\r\n return this.privatePath;\r\n }\r\n\r\n set currentPath(value: string) {\r\n this.privatePath = value;\r\n }\r\n getCategoryList(folderId: number, path: string): Observable<Array<NodeInterface>> {\r\n return this.fileCategoryService.ServiceGetAllInCategoryById(folderId).pipe(\r\n map((x) => {\r\n const retList: NodeInterface[] = [];\r\n\r\n x.listItems.forEach(element => {\r\n const item: NodeInterface = {\r\n name: element.title,\r\n isRoot: true,\r\n id: element.id,\r\n parentId: element.linkParentId ? element.linkParentId : null,\r\n pathToNode: path + '/' + element.id,\r\n pathToParent: '',\r\n isFolder: true,\r\n isExpanded: false,\r\n createdDate: element.createdDate,\r\n updatedDate: element.updatedDate,\r\n downloadLinksrc: element.linkMainImageIdSrc,\r\n };\r\n item.pathToNode = '/' + item.pathToNode;\r\n item.pathToNode = item.pathToNode.replace('//', '/');\r\n // if (retList.length < 4) {\r\n retList.push(item);\r\n // }\r\n });\r\n return retList;\r\n })\r\n );\r\n\r\n }\r\n getFileList(folderId: number, path: string): Observable<Array<NodeInterface>> {\r\n return this.fileContentService.ServiceGetAllInCategoryById(folderId).pipe(\r\n map((x) => {\r\n const retList: NodeInterface[] = [];\r\n x.listItems.forEach(element => {\r\n const item: NodeInterface = {\r\n name: element.fileName,\r\n isRoot: false,\r\n id: element.id,\r\n parentId: element.linkCategoryId ? element.linkCategoryId : null,\r\n pathToNode: path + '/' + element.id,\r\n pathToParent: '',\r\n isFolder: false,\r\n isExpanded: false,\r\n createdDate: element.createdDate,\r\n updatedDate: element.updatedDate,\r\n downloadLinksrc: element.downloadLinksrc,\r\n downloadThumbnailSrc: element.downloadThumbnailSrc,\r\n size: element.fileSize,\r\n extension: element.extension\r\n };\r\n item.pathToNode = '/' + item.pathToNode;\r\n item.pathToNode = item.pathToNode.replace('//', '/');\r\n // if (retList.length < 2) {\r\n retList.push(item);\r\n // }\r\n });\r\n return retList;\r\n })\r\n );\r\n }\r\n}\r\n\r\n","import { HttpClient, HttpParams } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { NtkSmartModalService } from 'ngx-ntk-smart-module';\r\nimport { FileCategoryModel, FileCategoryService, FileContentModel, FileContentService } from 'ntk-cms-api';\r\nimport { Observable } from 'rxjs';\r\nimport { first } from 'rxjs/operators';\r\nimport { NodeInterface } from '../interfaces/node.interface';\r\nimport { TreeModel } from '../models/tree.model';\r\nimport { FileManagerStoreService } from './file-manager-store.service';\r\nimport { NodeService } from './node.service';\r\n\r\n@Injectable()\r\nexport class NodeClickedService {\r\n public serviceTree: TreeModel;\r\n\r\n constructor(\r\n public ngxSmartModalService: NtkSmartModalService,\r\n private nodeService: NodeService,\r\n private store: FileManagerStoreService,\r\n private http: HttpClient,\r\n private fileContentService: FileContentService,\r\n private fileCategoryService: FileCategoryService,\r\n ) {\r\n }\r\n\r\n public startDownload_orginal(node: NodeInterface): void {\r\n const parameters = new HttpParams().append('path', node.id + '');\r\n this.reachServer('download', this.serviceTree.config.api.downloadFile, parameters);\r\n }\r\n public startDownload(node: NodeInterface): void {\r\n window.open(node.downloadLinksrc, '_blank');\r\n }\r\n public initDelete_orginal(node: NodeInterface): void {\r\n this.sideEffectHelper(\r\n 'Delete',\r\n new HttpParams().append('path', node.id + ''),\r\n 'delete',\r\n this.serviceTree.config.api.deleteFile,\r\n () => this.successWithSideViewClose()\r\n );\r\n }\r\n public initDelete(node: NodeInterface): void {\r\n const prosses = 'initDelete';\r\n this.store.processStart(prosses);\r\n if (node.isFolder) {\r\n this.fileCategoryService.ServiceDelete(node.id).subscribe(\r\n (next) => {\r\n if (next.isSuccess) {\r\n this.successWithSideViewClose();\r\n }\r\n else {\r\n this.actionFailed('Delete Folder Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('Delete Folder Error', error);\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n } else {\r\n this.fileContentService.ServiceDelete(node.id).subscribe(\r\n (next) => {\r\n if (next.isSuccess) {\r\n this.successWithSideViewClose();\r\n }\r\n else {\r\n this.actionFailed('Delete File Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('Delete File Error', error);\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n }\r\n }\r\n\r\n public searchForString_orginal(input: string): void {\r\n this.sideEffectHelper(\r\n 'Search',\r\n new HttpParams().append('query', input),\r\n 'get',\r\n this.serviceTree.config.api.searchFiles,\r\n (res) => this.searchSuccess(input, res)\r\n );\r\n }\r\n public searchForString(input: string): void {\r\n\r\n\r\n\r\n }\r\n\r\n\r\n\r\n\r\n\r\n public createFolder_orginal(currentParent: number, newDirName: string): void {\r\n this.sideEffectHelper(\r\n 'Create Folder',\r\n (() => {\r\n let httpParams = new HttpParams().append('dirName', newDirName);\r\n if (currentParent !== 0) {\r\n httpParams = httpParams.append('parentPath', currentParent + '');\r\n }\r\n\r\n console.log(currentParent, httpParams.get('dirName'), httpParams.get('parentPath'));\r\n return httpParams;\r\n })(),\r\n 'post',\r\n this.serviceTree.config.api.createFolder\r\n );\r\n }\r\n\r\n public createFolder(currentParent: number, newDirName: string): void {\r\n const model = new FileCategoryModel();\r\n model.title = newDirName;\r\n if (currentParent > 0) {\r\n model.linkParentId = currentParent;\r\n }\r\n const prosses = 'createFolder';\r\n this.store.processStart(prosses);\r\n this.fileCategoryService.ServiceAdd(model).subscribe(\r\n (next) => {\r\n if (next.isSuccess) {\r\n this.successWithSideViewClose();\r\n }\r\n else {\r\n this.actionFailed('Create Folder Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('Create Folder Error', error);\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n }\r\n public createFile(\r\n currentParent: number, fileName: string, uploadFileGUID: string,\r\n successMethod: any,\r\n failMethod: any\r\n ): void {\r\n const model = new FileContentModel();\r\n model.fileName = fileName;\r\n model.uploadFileGUID = uploadFileGUID;\r\n if (currentParent > 0) {\r\n model.linkCategoryId = currentParent;\r\n }\r\n const prosses = 'createFile';\r\n this.store.processStart(prosses);\r\n this.fileContentService.ServiceAdd(model).subscribe(\r\n (next) => {\r\n if (next.isSuccess) {\r\n this.successWithSideViewClose();\r\n if (successMethod) {\r\n successMethod(next);\r\n }\r\n }\r\n else {\r\n this.actionFailed('Create File Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('Create File Error', error);\r\n if (failMethod) {\r\n failMethod(error);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n }\r\n public rename_orginal(node: NodeInterface, newName: string): void {\r\n this.sideEffectHelper(\r\n 'Rename',\r\n new HttpParams().append('path', node.id + '').append('newName', newName),\r\n 'post',\r\n this.serviceTree.config.api.renameFile,\r\n () => this.successWithSideViewClose()\r\n );\r\n }\r\n public rename(node: NodeInterface, newName: string): void {\r\n const prosses = 'rename';\r\n this.store.processStart(prosses);\r\n if (node.isFolder) {\r\n this.fileCategoryService.ServiceGetOneById(node.id).subscribe((next) => {\r\n if (next.isSuccess) {\r\n next.item.title = newName;\r\n /** update */\r\n this.fileCategoryService.ServiceEdit(next.item).subscribe(\r\n (next2) => {\r\n if (next2.isSuccess) {\r\n this.successWithSideViewClose();\r\n }\r\n else {\r\n this.actionFailed('rename Folder Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('rename Folder Error', error);\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n /** update */\r\n } else {\r\n this.actionFailed('rename Folder Error', next.errorMessage);\r\n this.store.processStop(prosses);\r\n }\r\n }\r\n , (error) => {\r\n this.actionFailed('rename Folder Error', error);\r\n this.store.processStop(prosses);\r\n });\r\n\r\n } else {\r\n this.fileContentService.ServiceGetOneById(node.id).subscribe((next) => {\r\n if (next.isSuccess) {\r\n next.item.fileName = newName;\r\n /** update */\r\n this.fileContentService.ServiceEdit(next.item).subscribe(\r\n (next2) => {\r\n if (next2.isSuccess) {\r\n this.successWithSideViewClose();\r\n }\r\n else {\r\n this.actionFailed('rename File Error', next.errorMessage);\r\n }\r\n this.store.processStop(prosses);\r\n }\r\n , (error) => {\r\n this.actionFailed('rename File Error', error);\r\n this.store.processStop(prosses);\r\n }\r\n );\r\n /** update */\r\n } else {\r\n this.actionFailed('rename File Error', next.errorMessage);\r\n this.store.processStop(prosses);\r\n }\r\n }\r\n , (error) => {\r\n this.actionFailed('rename File Error', error);\r\n this.store.processStop(prosses);\r\n });\r\n }\r\n }\r\n\r\n private sideEffectHelper(\r\n name: string, parameters: HttpParams, httpMethod: string, apiURL: string,\r\n successMethod = (a: any) => this.actionSuccess(a),\r\n failMethod = (a: any, b: any) => this.actionFailed(a, b)\r\n ): void {\r\n this.ngxSmartModalService.getModal('waitModal').open();\r\n\r\n this.reachServer(httpMethod, apiURL, parameters)\r\n .subscribe(\r\n (a) => successMethod(a),\r\n (err) => failMethod(name, err)\r\n );\r\n }\r\n\r\n private reachServer(method: string, apiUrl: string, parameters: HttpParams, data: any = {}): Observable<any> {\r\n switch (method.toLowerCase()) {\r\n case 'get':\r\n return this.http.get(this.serviceTree.config.baseURL + apiUrl, { params: parameters });\r\n case 'post':\r\n return this.http.post(this.serviceTree.config.baseURL + apiUrl, data, { params: parameters });\r\n case 'delete':\r\n return this.http.delete(this.serviceTree.config.baseURL + apiUrl, { params: parameters });\r\n case 'download':\r\n window.open(this.serviceTree.config.baseURL + apiUrl + '?path=' + parameters.get('path'), '_blank');\r\n return null;\r\n default:\r\n console.warn('[NodeClickedService] Incorrect params for this side-effect');\r\n return null;\r\n }\r\n }\r\n\r\n private successWithSideViewClose(): void {\r\n this.actionSuccess();\r\n document.getElementById('side-view').classList.remove('selected');\r\n }\r\n\r\n private searchSuccess(input: string, data: any): void {\r\n const obj = {\r\n searchString: input,\r\n response: data\r\n };\r\n\r\n this.actionSuccess();\r\n\r\n this.ngxSmartModalService.setModalData(obj, 'searchModal', true);\r\n this.ngxSmartModalService.getModal('searchModal').open();\r\n }\r\n\r\n private actionSuccess(response: string = ''): void {\r\n document.body.classList.remove('dialog-open');\r\n\r\n this.nodeService.refreshCurrentPath();\r\n\r\n const modal = this.ngxSmartModalService.getModal('waitModal');\r\n modal.onOpenFinished.pipe(first()).subscribe(() => modal.close());\r\n modal.close();\r\n }\r\n\r\n private actionFailed(name: string, error: any): void {\r\n document.body.classList.remove('dialog-open');\r\n\r\n this.ngxSmartModalService.getModal('waitModal').close();\r\n this.ngxSmartModalService.getModal('errorModal').open();\r\n console.warn('[NodeClickedService] Action \"' + name + '\" failed', error);\r\n }\r\n\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { forkJoin, Observable, of } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class TranslateUiService {\r\n private availableLanguages = ['en', 'fa', 'fr', 'ru'];\r\n private translationPath = './assets/i18n/ntk-cms-filemanager/';\r\n\r\n constructor(\r\n private translateService: TranslateService,\r\n private http: HttpClient\r\n ) {}\r\n\r\n public init(language: string = null): void {\r\n if (language) {\r\n // Initialize one specific language\r\n this.loadTranslation(language).subscribe(\r\n (translations) => {\r\n this.translateService.setTranslation(language, translations, true);\r\n this.translateService.use(language);\r\n },\r\n (error) => {\r\n console.warn(\r\n `Failed to load translation for ${language}, falling back to English`\r\n );\r\n this.loadTranslation('en').subscribe((enTranslations) => {\r\n this.translateService.setTranslation(\r\n language,\r\n enTranslations,\r\n true\r\n );\r\n this.translateService.use(language);\r\n });\r\n }\r\n );\r\n } else {\r\n // Initialize all languages\r\n const loadPromises = this.availableLanguages.map((lang) =>\r\n this.loadTranslation(lang).pipe(\r\n catchError((error) => {\r\n console.warn(`Failed to load translation for ${lang}`);\r\n return of(null);\r\n })\r\n )\r\n );\r\n\r\n forkJoin(loadPromises).subscribe((results) => {\r\n results.forEach((translations, index) => {\r\n if (translations) {\r\n const lang = this.availableLanguages[index];\r\n this.translateService.setTranslation(lang, translations, true);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n private loadTranslation(language: string): Observable<any> {\r\n return this.http.get(`${this.translationPath}${language}.json`);\r\n }\r\n\r\n public setLanguage(language: string): void {\r\n this.translateService.use(language);\r\n }\r\n\r\n public getCurrentLanguage(): string {\r\n return this.translateService.currentLang;\r\n }\r\n\r\n public getAvailableLanguages(): string[] {\r\n return this.availableLanguages;\r\n }\r\n}\r\n","import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';\r\n\r\nimport { NodeInterface } from '../../../interfaces/node.interface';\r\n\r\nimport { DownloadModeEnum } from '../../../enums/download-mode.enum';\r\nimport { FileManagerStoreService, SET_PATH, SET_SELECTED_NODE } from '../../../services/file-manager-store.service';\r\nimport { NodeClickedService } from '../../../services/node-clicked.service';\r\nimport { NodeService } from '../../../services/node.service';\r\n\r\n@Component({\r\n selector: 'lib-filemanager-node',\r\n templateUrl: './node.component.html',\r\n styleUrls: ['./node.component.scss'],\r\n standalone: false\r\n})\r\nexport class NodeComponent implements OnInit {\r\n @Input() node: NodeInterface;\r\n isSingleClick = true;\r\n\r\n constructor(\r\n private store: FileManagerStoreService,\r\n private nodeService: NodeService,\r\n private nodeClickedService: NodeClickedService,\r\n private cdr: ChangeDetectorRef\r\n ) {\r\n this.store\r\n .getState(state => state.fileManagerState.selectedNode)\r\n .subscribe((value: NodeInterface) => {\r\n this.selectedNode = value;\r\n this.cdr.detectChanges();\r\n });\r\n }\r\n selectedNode: NodeInterface;\r\n public method1CallForClick(event: MouseEvent) {\r\n event.preventDefault();\r\n\r\n this.isSingleClick = true;\r\n setTimeout(() => {\r\n if (this.isSingleClick) {\r\n this.showMenu();\r\n }\r\n }, 200);\r\n }\r\n\r\n // todo event.preventDefault for double click\r\n public method2CallForDblClick(event: any) {\r\n event.preventDefault();\r\n\r\n this.isSingleClick = false;\r\n this.open();\r\n }\r\n\r\n ngOnInit() {\r\n }\r\n\r\n private open() {\r\n if (!this.node.isFolder) {\r\n if (this.nodeService?.serviceTree?.config?.options?.allowFolderDownload === DownloadModeEnum.DOWNLOAD_DISABLED) {\r\n this.isSingleClick = true;\r\n this.showMenu();\r\n return;\r\n }\r\n\r\n this.nodeClickedService.startDownload(this.node);\r\n return;\r\n }\r\n\r\n if (this.node.stayOpen) {\r\n if (this.node.name === 'root') {\r\n if (this.selectedNode && this.selectedNode.id === this.node.id) {\r\n this.nodeService.foldAll(true);\r\n }\r\n else {\r\n this.nodeService.foldAll();\r\n }\r\n }\r\n\r\n this.store.dispatch({ type: SET_PATH, payload: this.node.pathToNode });\r\n return;\r\n }\r\n\r\n this.toggleNodeExpanded();\r\n\r\n if (this.node.isExpanded) {\r\n this.store.dispatch({ type: SET_PATH, payload: this.node.pathToNode });\r\n }\r\n\r\n this.setNodeSelectedState();\r\n }\r\n\r\n private showMenu() {\r\n this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.node });\r\n this.cdr.detectChanges();\r\n }\r\n\r\n private toggleNodeExpanded() {\r\n this.node.isExpanded = !this.node.isExpanded;\r\n }\r\n\r\n private setNodeSelectedState() {\r\n if (!this.node.isExpanded) {\r\n document.getElementById('tree_' + this.node.pathToNode).classList.add('deselected');\r\n\r\n this.nodeService.foldRecursively(this.node);\r\n\r\n this.store.dispatch({ type: SET_PATH, payload: this.node.pathToParent });\r\n } else {\r\n document.getElementById('tree_' + this.node.pathToNode).classList.remove('deselected');\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n","<div #customTemplate (dblclick)=\"method2CallForDblClick($event)\" (click)=\"method1CallForClick($event)\">\r\n <ng-content></ng-content>\r\n</div>","import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core';\r\n\r\nimport { NodeInterface } from '../../interfaces/node.interface';\r\nimport { FileManagerStoreService } from '../../services/file-manager-store.service';\r\nimport { NodeService } from '../../services/node.service';\r\n\r\n\r\n@Component({\r\n selector: 'lib-filemanager-folder-content',\r\n templateUrl: './folder-content.component.html',\r\n styleUrls: ['./folder-content.component.scss'],\r\n standalone: false\r\n})\r\nexport class FolderContentComponent implements OnInit {\r\n @Input() folderContentTemplate: TemplateRef<any>;\r\n @Input() folderContentBackTemplate: TemplateRef<any>;\r\n @Input() folderContentNewFolderTemplate: TemplateRef<any>;\r\n @Input() folderContentNewFileTemplate: TemplateRef<any>;\r\n @Input() folderContentReloadTemplate: TemplateRef<any>; // karavi\r\n\r\n @Output() openUploadDialog = new EventEmitter();\r\n @Output() openNewFolderDialog = new EventEmitter();\r\n\r\n nodes: NodeInterface;\r\n obj = Object;\r\n\r\n constructor(\r\n private nodeService: NodeService,\r\n private store: FileManagerStoreService,\r\n private cdr: ChangeDetectorRef\r\n ) {\r\n this.store\r\n .getState(state => state.fileManagerState.inProcessingList)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n this.store\r\n .getState(state => state.fileManagerState.selectedNode)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n }\r\n\r\n ngOnInit() {\r\n this.nodes = this.nodeService.serviceTree.nodes;\r\n\r\n this.store\r\n .getState(state => state.fileManagerState.path)\r\n .subscribe((path: string) => {\r\n this.nodes = this.nodeService.findNodeByPath(path);\r\n });\r\n }\r\n\r\n newFileClickedAction() {\r\n this.openUploadDialog.emit(true);\r\n }\r\n newFolderClickedAction() {\r\n this.openNewFolderDialog.emit(true);\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n","<div class=\"item-holder\" style=\"direction: ltr;\" *ngIf=\"nodes\">\r\n <ng-container *ngIf=\"nodes.id !== 0\">\r\n <lib-filemanager-node [node]=nodes id=\"{{nodes.pathToNode}}\">\r\n <ng-container [ngTemplateOutletContext]=\"{$implicit: nodes}\" [ngTemplateOutlet]=\"folderContentBackTemplate\">\r\n </ng-container>\r\n </lib-filemanager-node>\r\n </ng-container>\r\n <ng-container *ngIf=\"nodes.id === 0\">\r\n <lib-filemanager-node [node]=\"nodes\" id=\"{{ nodes.id }}\" >\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: nodes }\" [ngTemplateOutlet]=\"folderContentReloadTemplate\">\r\n </ng-container>\r\n </lib-filemanager-node>\r\n </ng-container>\r\n\r\n <ng-container *ngFor=\"let node of obj.keys(nodes.children)\">\r\n <lib-filemanager-node [node]=\"nodes.children[node]\" id=\"fc_{{nodes.children[node].pathToNode}}\">\r\n <ng-container [ngTemplateOutletContext]=\"{$implicit: nodes.children[node]}\"\r\n [ngTemplateOutlet]=\"folderContentTemplate\">\r\n </ng-container>\r\n </lib-filemanager-node>\r\n </ng-container>\r\n\r\n <div class=\"new\" (click)=\"newFolderClickedAction()\" *ngIf=\"nodes?.children\">\r\n <ng-container [ngTemplateOutlet]=\"folderContentNewFolderTemplate\"></ng-container>\r\n </div>\r\n <div class=\"new\" (click)=\"newFileClickedAction()\" *ngIf=\"nodes?.children && nodes.id !== 0\">\r\n <ng-container [ngTemplateOutlet]=\"folderContentNewFileTemplate\"></ng-container>\r\n </div>\r\n</div>\r\n","import { ChangeDetectorRef, Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/core';\r\n\r\nimport { NodeInterface } from '../../../interfaces/node.interface';\r\nimport { FileManagerStoreService } from '../../../services/file-manager-store.service';\r\n\r\n\r\n@Component({\r\n selector: 'lib-filemanager-node-lister',\r\n templateUrl: './node-lister.component.html',\r\n styleUrls: ['./node-lister.component.scss'],\r\n standalone: false\r\n})\r\nexport class NodeListerComponent implements OnInit {\r\n @ContentChild(TemplateRef, { static: false }) templateRef: TemplateRef<any>;\r\n @Input() nodes: NodeInterface;\r\n @Input() showFiles: boolean;\r\n\r\n obj = Object;\r\n\r\n constructor(\r\n private store: FileManagerStoreService,\r\n private cdr: ChangeDetectorRef) {\r\n this.store\r\n .getState(state => state.fileManagerState.inProcessingList)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n this.store\r\n .getState(state => state.fileManagerState.selectedNode)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n }\r\n\r\n ngOnInit() {\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n","<ul class=\"node-lister-flist\" style=\"direction: ltr;text-align: left;\">\r\n <!--In order to avoid having to create that extra div, we can instead use ng-container directive-->\r\n <ng-container *ngFor=\"let node of obj.keys(nodes)\">\r\n <li class=\"node-lister-list-item\" *ngIf=\"nodes[node].isFolder || showFiles\">\r\n\r\n <lib-filemanager-node class=\"node-lister-app-node\" [node]=\"nodes[node]\" id=\"tree_{{nodes[node].isRoot ? 'root' : nodes[node].pathToNode}}\">\r\n <ng-container [ngTemplateOutletContext]=\"{$implicit: (nodes[node])}\"\r\n [ngTemplateOutlet]=\"templateRef\">\r\n </ng-container>\r\n </lib-filemanager-node>\r\n\r\n <lib-filemanager-node-lister class=\"node-lister\" *ngIf=\"obj.keys(nodes[node].children).length > 0\"\r\n [showFiles]=\"showFiles\" [nodes]=\"nodes[node].children\">\r\n <ng-template let-nodes>\r\n <ng-container [ngTemplateOutletContext]=\"{$implicit: (nodes)}\"\r\n [ngTemplateOutlet]=\"templateRef\">\r\n </ng-container>\r\n </ng-template>\r\n </lib-filemanager-node-lister>\r\n </li>\r\n </ng-container>\r\n</ul>\r\n","import { AfterViewInit, ChangeDetectorRef, Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/core';\r\n\r\nimport { first } from 'rxjs/operators';\r\nimport { ConfigInterface } from '../../interfaces/config.interface';\r\nimport { NodeInterface } from '../../interfaces/node.interface';\r\nimport { TreeModel } from '../../models/tree.model';\r\nimport { FileManagerStoreService, SET_SELECTED_NODE } from '../../services/file-manager-store.service';\r\nimport { NodeService } from '../../services/node.service';\r\n\r\n\r\n@Component({\r\n selector: 'lib-filemanager-tree',\r\n templateUrl: './tree.component.html',\r\n styleUrls: ['./tree.component.scss'],\r\n standalone: false\r\n})\r\nexport class TreeComponent implements AfterViewInit, OnInit {\r\n @ContentChild(TemplateRef, { static: false }) templateRef: TemplateRef<any>;\r\n\r\n @Input() treeModel: TreeModel;\r\n @Input() config: ConfigInterface;\r\n\r\n nodes: NodeInterface;\r\n currentTreeLevel = '';\r\n\r\n constructor(\r\n private nodeService: NodeService,\r\n private store: FileManagerStoreService,\r\n private cdr: ChangeDetectorRef\r\n ) {\r\n this.store\r\n .getState(state => state.fileManagerState.inProcessingList)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n this.store\r\n .getState(state => state.fileManagerState.selectedNode)\r\n .subscribe(() => {\r\n this.cdr.detectChanges();\r\n });\r\n }\r\n\r\n ngOnInit() {\r\n this.nodes = this.treeModel.nodes;\r\n\r\n // todo move this store to proper place\r\n this.store\r\n .getState(state => state.fileManagerState.path)\r\n .subscribe((path: string) => {\r\n this.nodeService.getNodes(path);\r\n this.currentTreeLevel = this.treeModel.currentPath;\r\n return this.treeModel.currentPath = path;\r\n });\r\n }\r\n\r\n ngAfterViewInit() {\r\n this.store\r\n .getState(state => state.fileManagerState.path)\r\n .pipe(first())\r\n .subscribe((path: string) => {\r\n const nodes = this.nodeService.findNodeByPath(path);\r\n this.store.dispatch({ type: SET_SELECTED_NODE, payload: nodes });\r\n this.cdr.detectChanges();\r\n });\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n","<lib-filemanager-node-lister [showFiles]=\"treeModel.config.options.showFilesInsideTree\"\r\n [nodes]=\"{children: nodes}\">\r\n <ng-template let-nodes>\r\n <ng-container [ngTemplateOutletContext]=\"{$impli