UNPKG

ntk-cms-filemanager

Version:

Ntk Cms Api And Model For Typscript

974 lines (963 loc) 139 kB
import * as i0 from '@angular/core'; import { Injectable, Input, Component, EventEmitter, Output, TemplateRef, ContentChild, ViewEncapsulation, Inject, ViewChild, Pipe, NgModule } from '@angular/core'; import { Subject, Observable, of, forkJoin, timer } from 'rxjs'; import { map, distinctUntilChanged, first, catchError, delay } from 'rxjs/operators'; import * as i1 from '@angular/common/http'; import { HttpParams, HttpRequest, HttpEventType, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import * as i3 from 'ntk-cms-api'; import { FileCategoryModel, FileContentModel, FileContentService, FileCategoryService } from 'ntk-cms-api'; import * as i4 from 'ngx-ntk-smart-module'; import { NtkSmartModalModule } from 'ngx-ntk-smart-module'; import * as i1$1 from '@ngx-translate/core'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; import * as i3$1 from '@angular/common'; import { CommonModule } from '@angular/common'; import { __decorate, __param } from 'tslib'; import * as i3$2 from 'ngx-ntk-file-picker'; import { FilePickerAdapter, UploadStatus, FilePickerModule } from 'ngx-ntk-file-picker'; class ComponentOptionModel { } class TreeModel { constructor(config) { // this._currentPath = config.startingFolder; // todo implement (config.interfce.ts) this._currentPath = ''; this.config = config; this.nodes = { id: 0, pathToNode: '', pathToParent: null, isFolder: true, isExpanded: true, stayOpen: true, name: 'root', children: {}, isRoot: true }; } get currentPath() { return this._currentPath; } set currentPath(value) { this._currentPath = value; } get nodes() { return this._nodes; } set nodes(value) { this._nodes = value; } get selectedNodeId() { return this._selectedNodeId; } set selectedNodeId(value) { this._selectedNodeId = value; } } var DownloadModeEnum; (function (DownloadModeEnum) { DownloadModeEnum[DownloadModeEnum["DOWNLOAD_DISABLED"] = 0] = "DOWNLOAD_DISABLED"; DownloadModeEnum[DownloadModeEnum["DOWNLOAD_FILES"] = 1] = "DOWNLOAD_FILES"; DownloadModeEnum[DownloadModeEnum["DOWNLOAD_ALL"] = 2] = "DOWNLOAD_ALL"; })(DownloadModeEnum || (DownloadModeEnum = {})); const initialState = { path: '', isLoading: true, selectedNode: null, inProcessingList: [] }; class FileManagerStoreService { constructor() { this.sub = new Subject(); this.state = { fileManagerState: initialState }; // @ts-ignore window.getInfo = () => this.state; } dispatch(param) { Object.assign(this.state.fileManagerState, stateReducer(this.state.fileManagerState, param)); this.sub.next(this.state); // if (isDevMode()) console.warn('[FileManagerStoreService] dispatch', param, JSON.parse(JSON.stringify(this.state))); } getState(mapFn) { if (typeof mapFn !== 'function') { throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); } return this.sub.asObservable() .pipe(map(mapFn)) .pipe(distinctUntilChanged()); } processStart(name) { if (this.state?.fileManagerState?.inProcessingList) { const index = this.state.fileManagerState.inProcessingList.indexOf(name); if (index < 0) { // console.log('processStart 1', this.state.fileManagerState.inProcessingList); const list = [...this.state.fileManagerState.inProcessingList]; list.push(name); // console.log('processStart 2', this.state.fileManagerState.inProcessingList); this.dispatch({ type: SET_IN_PROCESSING_LIST, payload: list }); } } } processStop(name) { if (this.state?.fileManagerState?.inProcessingList) { const index = this.state.fileManagerState.inProcessingList.indexOf(name); if (index >= 0) { // console.log('processStop 1', this.state.fileManagerState.inProcessingList); const list = [...this.state.fileManagerState.inProcessingList]; list.splice(index, 1); // console.log('processStop 2', this.state.fileManagerState.inProcessingList); this.dispatch({ type: SET_IN_PROCESSING_LIST, payload: list }); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileManagerStoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileManagerStoreService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FileManagerStoreService, decorators: [{ type: Injectable }], ctorParameters: () => [] }); // REDUCERS function stateReducer(state = initialState, action) { switch (action.type) { case SET_PATH: if (action.payload === '/') { action.payload = ''; } if (state.path === action.payload) { return state; } return { ...state, path: action.payload, isLoading: true }; case SET_LOADING_STATE: return { ...state, isLoading: action.payload }; case SET_IN_PROCESSING_LIST: return { ...state, inProcessingList: action.payload }; case SET_SELECTED_NODE: return { ...state, selectedNode: action.payload }; default: return initialState; } } const SET_PATH = 'SET_PATH'; const SET_LOADING_STATE = 'SET_LOADING_STATE'; const SET_IN_PROCESSING_LIST = 'SET_IN_PROCESSING_LIST'; const SET_SELECTED_NODE = 'SET_SELECTED_NODE'; class SetPath { constructor() { this.type = SET_PATH; } } class SetLoadingState { constructor() { this.type = SET_LOADING_STATE; } } class SetInProcessingList { constructor() { this.type = SET_IN_PROCESSING_LIST; } } class SetSelectedNode { constructor() { this.type = SET_SELECTED_NODE; } } /* { size: string // e.g. '3 KB' url?: string // download url id: string | number; // id can be path or database id dir: bool // is current node dir? path: string // path to current item (e.g. /folder1/someFile.txt) name?: string // optional (but we are using id as name if name is not present) (e.g. someFile.txt) } https://github.com/Chiff/ng6-file-man-express/blob/master/index.js */ // @Injectable({ // providedIn: 'root' // }) class NodeService { constructor(http, store, fileContentService, fileCategoryService) { this.http = http; this.store = store; this.fileContentService = fileContentService; this.fileCategoryService = fileCategoryService; /** GUID */ this.guid = ''; /** GUID */ this.guid = this.newGuid(); /** GUID */ // console.log('NodeService Constructor:', this.guid); } S4() { const ran = (1 + Math.random()) * 0x10000; return (ran | 0).toString(16).substring(1); } newGuid() { const isString = `${this.S4()}${this.S4()}-${this.S4()}-${this.S4()}-${this.S4()}-${this.S4()}${this.S4()}${this.S4()}`; return isString; } /** GUID */ // todo ask server to get parent structure startManagerAt(path) { this.currentPath = path; this.refreshCurrentPath(); } refreshCurrentPath_orginal() { this.findNodeByPath_orginal(this.currentPath).children = {}; this.getNodes_orginal(this.currentPath).then(() => { this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.serviceTree.nodes }); this.store.dispatch({ type: SET_PATH, payload: this.currentPath }); }); } refreshCurrentPath() { this.findNodeByPath(this.currentPath).children = {}; this.getNodes(this.currentPath).then(() => { this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.serviceTree.nodes }); this.store.dispatch({ type: SET_PATH, payload: this.currentPath }); }); } getNodes_orginal(path) { return new Promise((resolve => { this.parseNodes_orginal(path).subscribe((data) => { for (let i = 0; i < data.length; i++) { const parentPath = this.getParentPath(data[i].pathToNode); this.findNodeByPath_orginal(parentPath).children[data[i].name] = data[i]; } resolve(null); }); })); } getNodes(path) { //console.log('getNodes Run:', this.guid); const prosses = 'getNodes'; this.store.processStart(prosses); return new Promise((resolve => { this.parseNodes(path).subscribe((data) => { for (let i = 0; i < data.length; i++) { const parentPath = this.getParentPath(data[i].pathToNode); this.findNodeByPath(parentPath).children[data[i].id] = data[i]; } this.store.processStop(prosses); resolve(null); }); })); } getParentPath_orginal(path) { let parentPath = path.split('/'); parentPath = parentPath.slice(0, parentPath.length - 1); return parentPath.join('/'); } getParentPath(path) { let parentPath = path.split('/'); parentPath = parentPath.slice(0, parentPath.length - 1); return parentPath.join('/'); } parseNodes_orginal(path) { return new Observable(observer => { this.getNodesFromServer_orginal(path).subscribe((data) => { observer.next(data.map(node => this.createNode_orginal(path, node))); this.store.dispatch({ type: SET_LOADING_STATE, payload: false }); }); }); } parseNodes(path) { return new Observable(observer => { this.getNodesFromServer(path).subscribe((data) => { observer.next(data.map(node => this.createNode(path, node))); this.store.dispatch({ type: SET_LOADING_STATE, payload: false }); }); }); } createNode_orginal(path, node) { if (node.path[0] !== '/') { console.warn('[Node Service] Server should return initial path with "/"'); node.path = '/' + node.path; } const ids = node.path.split('/'); if (ids.length > 2 && ids[ids.length - 1] === '') { ids.splice(-1, 1); node.path = ids.join('/'); } const cachedNode = this.findNodeByPath_orginal(node.path); return { id: node.id, isFolder: node.dir, isExpanded: cachedNode ? cachedNode.isExpanded : false, pathToNode: node.path, pathToParent: this.getParentPath_orginal(node.path), name: node.name || node.id, children: cachedNode ? cachedNode.children : {} }; } createNode(path, node) { // if (node.parentId && node.parentId > 0) { // console.warn('[Node Service] Server should return initial path with "/"'); // node.pathToNode = '/' + node.pathToNode; // } const ids = node.pathToNode.split('/'); if (ids.length > 2 && ids[ids.length - 1] === '') { ids.splice(-1, 1); node.pathToNode = ids.join('/'); } const cachedNode = this.findNodeByPath(node.pathToNode); const pathToParentVar = this.getParentPath(node.pathToNode); // node.isExpanded = cachedNode ? cachedNode.isExpanded : false; // node.pathToParent = pathToParentVar; // node.children = cachedNode ? cachedNode.children : {}; // node.name = node.name ? node.name : node.id + ''; // return node; return { id: node.id, isFolder: node.isFolder, isExpanded: cachedNode ? cachedNode.isExpanded : false, pathToNode: node.pathToNode, pathToParent: pathToParentVar, name: node.name || node.id, children: cachedNode ? cachedNode.children : {}, createdDate: node.createdDate, updatedDate: node.updatedDate, size: node.size, extension: node.extension, downloadLinksrc: node.downloadLinksrc, downloadThumbnailSrc: node.downloadThumbnailSrc, }; } getNodesFromServer_orginal(path) { let folderId = this.findNodeByPath_orginal(path).id; folderId = folderId === 0 ? '' : folderId; return this.http.get(this.serviceTree.config.baseURL + this.serviceTree.config.api.listFile, { params: new HttpParams().set('parentPath', folderId) }); } getNodesFromServer(path) { this.store.dispatch({ type: SET_LOADING_STATE, payload: true }); const findN = this.findNodeByPath(path); const folderId = findN ? findN.id : 0; // folderId = folderId === 0 ? '' : folderId; const retOut = new Observable(observer => { return this.getCategoryList(folderId, path).subscribe(xCat => { return this.getFileList(folderId, path).subscribe((xfile => { xfile = xfile.concat(xCat); observer.next(xfile); })); }); }); return retOut; } findNodeByPath_orginal(nodePath) { const ids = nodePath.split('/'); ids.splice(0, 1); return ids.length === 0 ? this.serviceTree.nodes : ids.reduce((value, index) => value.children[index], this.serviceTree.nodes); } findNodeByPath(nodePath) { const ids = nodePath.split('/'); ids.splice(0, 1); if (ids.length === 0) { return this.serviceTree.nodes; } const retOut = ids.reduce((value, index) => value.children[index], this.serviceTree.nodes); return retOut; } findNodeById_orginal(id) { const result = this.findNodeByIdHelper_orginal(id); if (result === null) { console.warn('[Node Service] Cannot find node by id. Id not existing or not fetched. Returning root.'); return this.serviceTree.nodes; } return result; } findNodeById(id) { const result = this.findNodeByIdHelper(id); if (result === null) { console.warn('[Node Service] Cannot find node by id. Id not existing or not fetched. Returning root.'); return this.serviceTree.nodes; } return result; } findNodeByIdHelper_orginal(id, node = this.serviceTree.nodes) { if (node.id === id) { return node; } const keys = Object.keys(node.children); for (let i = 0; i < keys.length; i++) { if (typeof node.children[keys[i]] === 'object') { const obj = this.findNodeByIdHelper_orginal(id, node.children[keys[i]]); if (obj != null) { return obj; } } } return null; } findNodeByIdHelper(id, node = this.serviceTree.nodes) { if (node.id === id) { return node; } const keys = Object.keys(node.children); for (let i = 0; i < keys.length; i++) { if (typeof node.children[keys[i]] === 'object') { const obj = this.findNodeByIdHelper(id, node.children[keys[i]]); if (obj != null) { return obj; } } } return null; } foldRecursively_orginal(node) { // console.log('folding ', node); const children = node.children; Object.keys(children).map((child) => { if (!children.hasOwnProperty(child) || !children[child].isExpanded) { return null; } this.foldRecursively_orginal(children[child]); // todo put this getElById into one func (curr inside node.component.ts + fm.component.ts) - this won't be maintainable document.getElementById('tree_' + children[child].pathToNode).classList.add('deselected'); children[child].isExpanded = false; }); } foldRecursively(node) { // console.log('folding ', node); const children = node.children; Object.keys(children).map((child) => { if (!children.hasOwnProperty(child) || !children[child].isExpanded) { return null; } this.foldRecursively(children[child]); // todo put this getElById into one func (curr inside node.component.ts + fm.component.ts) - this won't be maintainable document.getElementById('tree_' + children[child].pathToNode).classList.add('deselected'); children[child].isExpanded = false; }); } foldAll_orginal() { this.foldRecursively_orginal(this.serviceTree.nodes); } foldAll(refresh = false) { if (refresh) { this.refreshCurrentPath(); // this.foldRecursively(this.serviceTree.nodes); } else { this.foldRecursively(this.serviceTree.nodes); } } get currentPath() { return this.privatePath; } set currentPath(value) { this.privatePath = value; } getCategoryList(folderId, path) { return this.fileCategoryService.ServiceGetAllInCategoryById(folderId).pipe(map((x) => { const retList = []; x.listItems.forEach(element => { const item = { name: element.title, isRoot: true, id: element.id, parentId: element.linkParentId ? element.linkParentId : null, pathToNode: path + '/' + element.id, pathToParent: '', isFolder: true, isExpanded: false, createdDate: element.createdDate, updatedDate: element.updatedDate, downloadLinksrc: element.linkMainImageIdSrc, }; item.pathToNode = '/' + item.pathToNode; item.pathToNode = item.pathToNode.replace('//', '/'); // if (retList.length < 4) { retList.push(item); // } }); return retList; })); } getFileList(folderId, path) { return this.fileContentService.ServiceGetAllInCategoryById(folderId).pipe(map((x) => { const retList = []; x.listItems.forEach(element => { const item = { name: element.fileName, isRoot: false, id: element.id, parentId: element.linkCategoryId ? element.linkCategoryId : null, pathToNode: path + '/' + element.id, pathToParent: '', isFolder: false, isExpanded: false, createdDate: element.createdDate, updatedDate: element.updatedDate, downloadLinksrc: element.downloadLinksrc, downloadThumbnailSrc: element.downloadThumbnailSrc, size: element.fileSize, extension: element.extension }; item.pathToNode = '/' + item.pathToNode; item.pathToNode = item.pathToNode.replace('//', '/'); // if (retList.length < 2) { retList.push(item); // } }); return retList; })); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeService, deps: [{ token: i1.HttpClient }, { token: FileManagerStoreService }, { token: i3.FileContentService }, { token: i3.FileCategoryService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.HttpClient }, { type: FileManagerStoreService }, { type: i3.FileContentService }, { type: i3.FileCategoryService }] }); class NodeClickedService { constructor(ngxSmartModalService, nodeService, store, http, fileContentService, fileCategoryService) { this.ngxSmartModalService = ngxSmartModalService; this.nodeService = nodeService; this.store = store; this.http = http; this.fileContentService = fileContentService; this.fileCategoryService = fileCategoryService; } startDownload_orginal(node) { const parameters = new HttpParams().append('path', node.id + ''); this.reachServer('download', this.serviceTree.config.api.downloadFile, parameters); } startDownload(node) { window.open(node.downloadLinksrc, '_blank'); } initDelete_orginal(node) { this.sideEffectHelper('Delete', new HttpParams().append('path', node.id + ''), 'delete', this.serviceTree.config.api.deleteFile, () => this.successWithSideViewClose()); } initDelete(node) { const prosses = 'initDelete'; this.store.processStart(prosses); if (node.isFolder) { this.fileCategoryService.ServiceDelete(node.id).subscribe((next) => { if (next.isSuccess) { this.successWithSideViewClose(); } else { this.actionFailed('Delete Folder Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('Delete Folder Error', error); this.store.processStop(prosses); }); } else { this.fileContentService.ServiceDelete(node.id).subscribe((next) => { if (next.isSuccess) { this.successWithSideViewClose(); } else { this.actionFailed('Delete File Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('Delete File Error', error); this.store.processStop(prosses); }); } } searchForString_orginal(input) { this.sideEffectHelper('Search', new HttpParams().append('query', input), 'get', this.serviceTree.config.api.searchFiles, (res) => this.searchSuccess(input, res)); } searchForString(input) { } createFolder_orginal(currentParent, newDirName) { this.sideEffectHelper('Create Folder', (() => { let httpParams = new HttpParams().append('dirName', newDirName); if (currentParent !== 0) { httpParams = httpParams.append('parentPath', currentParent + ''); } console.log(currentParent, httpParams.get('dirName'), httpParams.get('parentPath')); return httpParams; })(), 'post', this.serviceTree.config.api.createFolder); } createFolder(currentParent, newDirName) { const model = new FileCategoryModel(); model.title = newDirName; if (currentParent > 0) { model.linkParentId = currentParent; } const prosses = 'createFolder'; this.store.processStart(prosses); this.fileCategoryService.ServiceAdd(model).subscribe((next) => { if (next.isSuccess) { this.successWithSideViewClose(); } else { this.actionFailed('Create Folder Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('Create Folder Error', error); this.store.processStop(prosses); }); } createFile(currentParent, fileName, uploadFileGUID, successMethod, failMethod) { const model = new FileContentModel(); model.fileName = fileName; model.uploadFileGUID = uploadFileGUID; if (currentParent > 0) { model.linkCategoryId = currentParent; } const prosses = 'createFile'; this.store.processStart(prosses); this.fileContentService.ServiceAdd(model).subscribe((next) => { if (next.isSuccess) { this.successWithSideViewClose(); if (successMethod) { successMethod(next); } } else { this.actionFailed('Create File Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('Create File Error', error); if (failMethod) { failMethod(error); } this.store.processStop(prosses); }); } rename_orginal(node, newName) { this.sideEffectHelper('Rename', new HttpParams().append('path', node.id + '').append('newName', newName), 'post', this.serviceTree.config.api.renameFile, () => this.successWithSideViewClose()); } rename(node, newName) { const prosses = 'rename'; this.store.processStart(prosses); if (node.isFolder) { this.fileCategoryService.ServiceGetOneById(node.id).subscribe((next) => { if (next.isSuccess) { next.item.title = newName; /** update */ this.fileCategoryService.ServiceEdit(next.item).subscribe((next2) => { if (next2.isSuccess) { this.successWithSideViewClose(); } else { this.actionFailed('rename Folder Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('rename Folder Error', error); this.store.processStop(prosses); }); /** update */ } else { this.actionFailed('rename Folder Error', next.errorMessage); this.store.processStop(prosses); } }, (error) => { this.actionFailed('rename Folder Error', error); this.store.processStop(prosses); }); } else { this.fileContentService.ServiceGetOneById(node.id).subscribe((next) => { if (next.isSuccess) { next.item.fileName = newName; /** update */ this.fileContentService.ServiceEdit(next.item).subscribe((next2) => { if (next2.isSuccess) { this.successWithSideViewClose(); } else { this.actionFailed('rename File Error', next.errorMessage); } this.store.processStop(prosses); }, (error) => { this.actionFailed('rename File Error', error); this.store.processStop(prosses); }); /** update */ } else { this.actionFailed('rename File Error', next.errorMessage); this.store.processStop(prosses); } }, (error) => { this.actionFailed('rename File Error', error); this.store.processStop(prosses); }); } } sideEffectHelper(name, parameters, httpMethod, apiURL, successMethod = (a) => this.actionSuccess(a), failMethod = (a, b) => this.actionFailed(a, b)) { this.ngxSmartModalService.getModal('waitModal').open(); this.reachServer(httpMethod, apiURL, parameters) .subscribe((a) => successMethod(a), (err) => failMethod(name, err)); } reachServer(method, apiUrl, parameters, data = {}) { switch (method.toLowerCase()) { case 'get': return this.http.get(this.serviceTree.config.baseURL + apiUrl, { params: parameters }); case 'post': return this.http.post(this.serviceTree.config.baseURL + apiUrl, data, { params: parameters }); case 'delete': return this.http.delete(this.serviceTree.config.baseURL + apiUrl, { params: parameters }); case 'download': window.open(this.serviceTree.config.baseURL + apiUrl + '?path=' + parameters.get('path'), '_blank'); return null; default: console.warn('[NodeClickedService] Incorrect params for this side-effect'); return null; } } successWithSideViewClose() { this.actionSuccess(); document.getElementById('side-view').classList.remove('selected'); } searchSuccess(input, data) { const obj = { searchString: input, response: data }; this.actionSuccess(); this.ngxSmartModalService.setModalData(obj, 'searchModal', true); this.ngxSmartModalService.getModal('searchModal').open(); } actionSuccess(response = '') { document.body.classList.remove('dialog-open'); this.nodeService.refreshCurrentPath(); const modal = this.ngxSmartModalService.getModal('waitModal'); modal.onOpenFinished.pipe(first()).subscribe(() => modal.close()); modal.close(); } actionFailed(name, error) { document.body.classList.remove('dialog-open'); this.ngxSmartModalService.getModal('waitModal').close(); this.ngxSmartModalService.getModal('errorModal').open(); console.warn('[NodeClickedService] Action "' + name + '" failed', error); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeClickedService, deps: [{ token: i4.NtkSmartModalService }, { token: NodeService }, { token: FileManagerStoreService }, { token: i1.HttpClient }, { token: i3.FileContentService }, { token: i3.FileCategoryService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeClickedService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeClickedService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i4.NtkSmartModalService }, { type: NodeService }, { type: FileManagerStoreService }, { type: i1.HttpClient }, { type: i3.FileContentService }, { type: i3.FileCategoryService }] }); class TranslateUiService { constructor(translateService, http) { this.translateService = translateService; this.http = http; this.availableLanguages = ['en', 'fa', 'fr', 'ru']; this.translationPath = './assets/i18n/ntk-cms-filemanager/'; } init(language = null) { if (language) { // Initialize one specific language this.loadTranslation(language).subscribe((translations) => { this.translateService.setTranslation(language, translations, true); this.translateService.use(language); }, (error) => { console.warn(`Failed to load translation for ${language}, falling back to English`); this.loadTranslation('en').subscribe((enTranslations) => { this.translateService.setTranslation(language, enTranslations, true); this.translateService.use(language); }); }); } else { // Initialize all languages const loadPromises = this.availableLanguages.map((lang) => this.loadTranslation(lang).pipe(catchError((error) => { console.warn(`Failed to load translation for ${lang}`); return of(null); }))); forkJoin(loadPromises).subscribe((results) => { results.forEach((translations, index) => { if (translations) { const lang = this.availableLanguages[index]; this.translateService.setTranslation(lang, translations, true); } }); }); } } loadTranslation(language) { return this.http.get(`${this.translationPath}${language}.json`); } setLanguage(language) { this.translateService.use(language); } getCurrentLanguage() { return this.translateService.currentLang; } getAvailableLanguages() { return this.availableLanguages; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslateUiService, deps: [{ token: i1$1.TranslateService }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslateUiService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TranslateUiService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i1.HttpClient }] }); class NodeComponent { constructor(store, nodeService, nodeClickedService, cdr) { this.store = store; this.nodeService = nodeService; this.nodeClickedService = nodeClickedService; this.cdr = cdr; this.isSingleClick = true; this.store .getState(state => state.fileManagerState.selectedNode) .subscribe((value) => { this.selectedNode = value; this.cdr.detectChanges(); }); } method1CallForClick(event) { event.preventDefault(); this.isSingleClick = true; setTimeout(() => { if (this.isSingleClick) { this.showMenu(); } }, 200); } // todo event.preventDefault for double click method2CallForDblClick(event) { event.preventDefault(); this.isSingleClick = false; this.open(); } ngOnInit() { } open() { if (!this.node.isFolder) { if (this.nodeService?.serviceTree?.config?.options?.allowFolderDownload === DownloadModeEnum.DOWNLOAD_DISABLED) { this.isSingleClick = true; this.showMenu(); return; } this.nodeClickedService.startDownload(this.node); return; } if (this.node.stayOpen) { if (this.node.name === 'root') { if (this.selectedNode && this.selectedNode.id === this.node.id) { this.nodeService.foldAll(true); } else { this.nodeService.foldAll(); } } this.store.dispatch({ type: SET_PATH, payload: this.node.pathToNode }); return; } this.toggleNodeExpanded(); if (this.node.isExpanded) { this.store.dispatch({ type: SET_PATH, payload: this.node.pathToNode }); } this.setNodeSelectedState(); } showMenu() { this.store.dispatch({ type: SET_SELECTED_NODE, payload: this.node }); this.cdr.detectChanges(); } toggleNodeExpanded() { this.node.isExpanded = !this.node.isExpanded; } setNodeSelectedState() { if (!this.node.isExpanded) { document.getElementById('tree_' + this.node.pathToNode).classList.add('deselected'); this.nodeService.foldRecursively(this.node); this.store.dispatch({ type: SET_PATH, payload: this.node.pathToParent }); } else { document.getElementById('tree_' + this.node.pathToNode).classList.remove('deselected'); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeComponent, deps: [{ token: FileManagerStoreService }, { token: NodeService }, { token: NodeClickedService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NodeComponent, isStandalone: false, selector: "lib-filemanager-node", inputs: { node: "node" }, ngImport: i0, template: "<div #customTemplate (dblclick)=\"method2CallForDblClick($event)\" (click)=\"method1CallForClick($event)\">\r\n <ng-content></ng-content>\r\n</div>", styles: [""] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeComponent, decorators: [{ type: Component, args: [{ selector: 'lib-filemanager-node', standalone: false, template: "<div #customTemplate (dblclick)=\"method2CallForDblClick($event)\" (click)=\"method1CallForClick($event)\">\r\n <ng-content></ng-content>\r\n</div>" }] }], ctorParameters: () => [{ type: FileManagerStoreService }, { type: NodeService }, { type: NodeClickedService }, { type: i0.ChangeDetectorRef }], propDecorators: { node: [{ type: Input }] } }); class FolderContentComponent { constructor(nodeService, store, cdr) { this.nodeService = nodeService; this.store = store; this.cdr = cdr; this.openUploadDialog = new EventEmitter(); this.openNewFolderDialog = new EventEmitter(); this.obj = Object; this.store .getState(state => state.fileManagerState.inProcessingList) .subscribe(() => { this.cdr.detectChanges(); }); this.store .getState(state => state.fileManagerState.selectedNode) .subscribe(() => { this.cdr.detectChanges(); }); } ngOnInit() { this.nodes = this.nodeService.serviceTree.nodes; this.store .getState(state => state.fileManagerState.path) .subscribe((path) => { this.nodes = this.nodeService.findNodeByPath(path); }); } newFileClickedAction() { this.openUploadDialog.emit(true); } newFolderClickedAction() { this.openNewFolderDialog.emit(true); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FolderContentComponent, deps: [{ token: NodeService }, { token: FileManagerStoreService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: FolderContentComponent, isStandalone: false, selector: "lib-filemanager-folder-content", inputs: { folderContentTemplate: "folderContentTemplate", folderContentBackTemplate: "folderContentBackTemplate", folderContentNewFolderTemplate: "folderContentNewFolderTemplate", folderContentNewFileTemplate: "folderContentNewFileTemplate", folderContentReloadTemplate: "folderContentReloadTemplate" }, outputs: { openUploadDialog: "openUploadDialog", openNewFolderDialog: "openNewFolderDialog" }, ngImport: i0, template: "<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", styles: [".item-holder{box-sizing:border-box;display:flex;flex-flow:wrap}.item-holder .new{display:inline}\n"], dependencies: [{ kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NodeComponent, selector: "lib-filemanager-node", inputs: ["node"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FolderContentComponent, decorators: [{ type: Component, args: [{ selector: 'lib-filemanager-folder-content', standalone: false, template: "<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", styles: [".item-holder{box-sizing:border-box;display:flex;flex-flow:wrap}.item-holder .new{display:inline}\n"] }] }], ctorParameters: () => [{ type: NodeService }, { type: FileManagerStoreService }, { type: i0.ChangeDetectorRef }], propDecorators: { folderContentTemplate: [{ type: Input }], folderContentBackTemplate: [{ type: Input }], folderContentNewFolderTemplate: [{ type: Input }], folderContentNewFileTemplate: [{ type: Input }], folderContentReloadTemplate: [{ type: Input }], openUploadDialog: [{ type: Output }], openNewFolderDialog: [{ type: Output }] } }); class NodeListerComponent { constructor(store, cdr) { this.store = store; this.cdr = cdr; this.obj = Object; this.store .getState(state => state.fileManagerState.inProcessingList) .subscribe(() => { this.cdr.detectChanges(); }); this.store .getState(state => state.fileManagerState.selectedNode) .subscribe(() => { this.cdr.detectChanges(); }); } ngOnInit() { } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeListerComponent, deps: [{ token: FileManagerStoreService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NodeListerComponent, isStandalone: false, selector: "lib-filemanager-node-lister", inputs: { nodes: "nodes", showFiles: "showFiles" }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: "<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", styles: [".node-lister-flist{margin:0 0 0 1em;padding:0;list-style:none;white-space:nowrap}.node-lister-list-item{list-style:none none;line-height:1.2em;font-size:1em;display:inline}.node-lister-list-item .node-lister-app-node.deselected+.node-lister ul{display:none}\n"], dependencies: [{ kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NodeComponent, selector: "lib-filemanager-node", inputs: ["node"] }, { kind: "component", type: NodeListerComponent, selector: "lib-filemanager-node-lister", inputs: ["nodes", "showFiles"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeListerComponent, decorators: [{ type: Component, args: [{ selector: 'lib-filemanager-node-lister', standalone: false, template: "<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", styles: [".node-lister-flist{margin:0 0 0 1em;padding:0;list-style:none;white-space:nowrap}.node-lister-list-item{list-style:none none;line-height:1.2em;font-size:1em;display:inline}.node-lister-list-item .node-lister-app-node.deselected+.node-lister ul{display:none}\n"] }] }], ctorParameters: () => [{ type: FileManagerStoreService }, { type: i0.ChangeDetectorRef }], propDecorators: { templateRef: [{ type: ContentChild, args: [TemplateRef, { static: false }] }], nodes: [{