UNPKG

@syncfusion/ej2-filemanager

Version:
920 lines (867 loc) 41.8 kB
import { TreeView as BaseTreeView, NodeSelectEventArgs, NodeExpandEventArgs, DrawNodeEventArgs } from '@syncfusion/ej2-navigations'; import { NodeEditEventArgs, NodeClickEventArgs } from '@syncfusion/ej2-navigations'; import { isNullOrUndefined as isNOU, select, setValue, getValue, DragEventArgs, Draggable } from '@syncfusion/ej2-base'; import { KeyboardEvents, KeyboardEventArgs, Touch, closest } from '@syncfusion/ej2-base'; import { DataManager, Query } from '@syncfusion/ej2-data'; import * as events from '../base/constant'; import * as CLS from '../base/classes'; import { IFileManager, ReadArgs, FileLoadEventArgs, NotifyArgs, FileOpenEventArgs, FileSelectEventArgs } from '../base/interface'; import { read, Download, GetDetails, Delete, isFileSystemData } from '../common/operations'; import { createDialog } from '../pop-up/dialog'; import { updatePath, getPath, getDirectories } from '../common/utility'; import { createVirtualDragElement, dragStopHandler, dragStartHandler, draggingHandler, getDirectoryPath, getModule, getPathId } from '../common/index'; import { copyFiles, cutFiles, removeActive, pasteHandler, getParentPath, readDropPath } from '../common/index'; import { hasEditAccess, createDeniedDialog, hasDownloadAccess, getAccessClass } from '../common/index'; /** * NavigationPane module */ export class NavigationPane { /* Internal variables */ private parent: IFileManager; public treeObj: BaseTreeView; public activeNode: Element; private keyboardModule: KeyboardEvents; private keyConfigs: { [key: string]: string }; private expandNodeTarget: string; public removeNodes: string[] = []; public moveNames: string[] = []; public touchClickObj: Touch; // Specifies the previously selected nodes in the treeview control. public previousSelected: string[] = []; private isDrag: boolean = false; private dragObj: Draggable; private isPathDragged: boolean = false; private isRenameParent: boolean = false; private isRightClick: boolean = false; private isSameNodeClicked: boolean = false; private isNodeExpandCalled: boolean = false; private renameParent: string = null; // Specifies whether the nodeClicked event of the treeview control is triggered or not. private isNodeClickCalled: boolean = false; // Specifies whether to restrict node selection in the treeview control. private restrictSelecting: boolean = false; /** * Constructor for the TreeView module * * @param {IFileManager} parent - specifies the parent element. * @hidden */ /* istanbul ignore next */ constructor(parent?: IFileManager) { this.parent = parent; this.addEventListener(); this.keyConfigs = { altEnter: 'alt+enter', esc: 'escape', del: 'delete', ctrlX: this.parent.isMac ? 'cmd+x' : 'ctrl+x', ctrlC: this.parent.isMac ? 'cmd+c' : 'ctrl+c', ctrlV: this.parent.isMac ? 'cmd+v' : 'ctrl+v', ctrlShiftN: 'ctrl+shift+n', shiftF10: 'shift+F10', f2: 'f2' }; } private onInit(): void { if (!isNOU(this.treeObj)) { return; } const rootData: { [key: string]: Object; } = getValue(this.parent.pathId[0], this.parent.feParent); setValue('_fm_icon', 'e-fe-folder', rootData); const attr: Object = {}; const id: string = getValue('id', rootData); if (!isNOU(id)) { setValue('data-id', id, attr); } if (!hasEditAccess(rootData)) { setValue('class', getAccessClass(rootData), attr); } if (!isNOU(attr)) { setValue('_fm_htmlAttr', attr, rootData); } this.treeObj = new BaseTreeView({ fields: { dataSource: [rootData], id: '_fm_id', parentID: '_fm_pId', expanded: '_fm_expanded', selected: '_fm_selected', text: 'name', hasChildren: 'hasChild', iconCss: '_fm_icon', htmlAttributes: '_fm_htmlAttr', tooltip: 'name' }, enableHtmlSanitizer: this.parent.enableHtmlSanitizer, sortOrder: this.parent.navigationPaneSettings.sortOrder, nodeSelecting: this.onNodeSelecting.bind(this), nodeSelected: this.onNodeSelected.bind(this), nodeExpanding: this.onNodeExpand.bind(this), nodeClicked: this.onNodeClicked.bind(this), allowEditing: true, nodeEditing: this.onNodeEditing.bind(this), drawNode: this.onDrowNode.bind(this), enableRtl: this.parent.enableRtl, dataBound: this.addDragDrop.bind(this) }); this.treeObj.isStringTemplate = true; this.treeObj.appendTo('#' + this.parent.element.id + CLS.TREE_ID); this.wireEvents(); } private addDragDrop(): void { if (!this.parent.isMobile && this.treeObj) { if (this.parent.allowDragAndDrop && isNOU(this.dragObj)) { this.dragObj = new Draggable(this.treeObj.element, { cursorAt: this.parent.dragCursorPosition, dragTarget: '.' + CLS.FULLROW, distance: 5, dragArea: this.parent.element, drag: draggingHandler.bind(this, this.parent), dragStart: (args: DragEventArgs) => { dragStartHandler(this.parent, args, this.dragObj); }, dragStop: dragStopHandler.bind(this, this.parent), enableTailMode: true, enableAutoScroll: false, helper: this.dragHelper.bind(this) }); } else if (!this.parent.allowDragAndDrop && this.dragObj) { this.dragObj.destroy(); this.dragObj = null; } } } public dragHelper(args: { element: HTMLElement, sender: MouseEvent & TouchEvent }): HTMLElement { const dragTarget: Element = <Element>args.sender.target; if (!dragTarget.classList.contains(CLS.FULLROW)) { return null; } const dragLi: Element = closest(dragTarget, 'li'); this.parent.dragPath = ''; this.parent.dragData = []; this.parent.activeElements = []; this.parent.activeElements = [dragLi]; this.parent.dragNodes = []; getModule(this.parent, dragLi); this.parent.dragData = <{ [key: string]: Object; }[]>this.getTreeData(dragLi); this.parent.dragPath = this.getDragPath(dragLi, <string>this.parent.dragData[0].name); this.parent.dragNodes.push(<string>this.parent.dragData[0].name); createVirtualDragElement(this.parent); return this.parent.virtualDragElement; } private getDragPath(dragLi: Element, text: string): string { const path: string = this.getDropPath(dragLi, text); return getParentPath(path); } private getDropPath(node: Element, text: string): string { const id: string = node.getAttribute('data-id'); const newText: string = this.parent.hasId ? id : text; return getPath(node, newText, this.parent.hasId); } private onDrowNode(args: DrawNodeEventArgs): void { const eventArgs: FileLoadEventArgs = { element: args.node, fileDetails: args.nodeData, module: 'NavigationPane' }; this.parent.trigger('fileLoad', eventArgs); } private addChild(files: { [key: string]: Object; }[], target: string, prevent: boolean): void { const directories: Object[] = getDirectories(files); const targetDirectory: object[] = this.getTreeData(target); if ( directories.length > 0 && targetDirectory.length > 0 && ((directories[0] as { [key: string]: Object }).filterPath == null || isNOU(targetDirectory[0]) && (targetDirectory[0] as { [key: string]: Object }).filterPath == null || (directories[0] as { [key: string]: Object }).filterPath !== (targetDirectory[0] as { [key: string]: Object }).filterPath) ) { let length: number = 0; const folders: { [key: string]: Object; }[] = <{ [key: string]: Object; }[]>directories; while (length < directories.length) { // eslint-disable-next-line camelcase folders[parseInt(length.toString(), 10)]._fm_icon = 'e-fe-folder'; const attr: Object = {}; const id: string = getValue('id', folders[length as number]); if (!isNOU(id)) { setValue('data-id', id, attr); } if (!hasEditAccess(folders[length as number])) { setValue('class', getAccessClass(folders[length as number]), attr); } if (!isNOU(attr)) { setValue('_fm_htmlAttr', attr, folders[length as number]); } length++; } const element: Element = select('[data-uid="' + target + '"]', this.treeObj.element); const childElements: Element = select('ul', element); if (isNOU(childElements)) { this.treeObj.addNodes(directories as { [key: string]: Object; }[], target, null, prevent); } } } // Node Selecting event handler private onNodeSelecting(args: NodeSelectEventArgs): void { if (!args.isInteracted && !this.isRightClick && !this.isSameNodeClicked && !this.isPathDragged && !this.isRenameParent || this.restrictSelecting) { this.restrictSelecting = false; this.isNodeClickCalled = false; return; } if (!this.renameParent) { this.parent.activeModule = 'navigationpane'; const nodeData: Object[] = this.getTreeData(getValue('id', args.nodeData)); if (args.node.getAttribute('data-uid') !== this.parent.pathId[this.parent.pathId.length - 1] && !this.isRightClick && !this.isNodeClickCalled || this.isSameNodeClicked || this.isPathDragged) { this.isNodeClickCalled = false; if (!this.isSameNodeClicked) { this.isSameNodeClicked = true; const selecEventArgs: FileSelectEventArgs = { action: args.action, fileDetails: nodeData[0], isInteracted: args.isInteracted }; this.parent.trigger('fileSelect', selecEventArgs); } if (!this.isRightClick) { const eventArgs: FileOpenEventArgs = { cancel: false, fileDetails: nodeData[0], module: 'NavigationPane' }; this.parent.trigger('fileOpen', eventArgs); args.cancel = eventArgs.cancel; } if (args.cancel) { this.restrictSelecting = this.isNodeClickCalled ? this.previousSelected[0] !== args.node.getAttribute('data-uid') : false; this.isNodeClickCalled = true; this.isSameNodeClicked = false; this.isPathDragged = false; this.previousSelected = this.treeObj.selectedNodes; this.treeObj.setProperties({selectedNodes: [args.node.getAttribute('data-uid')]}); } } else if (this.previousSelected[0] !== args.node.getAttribute('data-uid')){ this.isSameNodeClicked = true; const selecEventArgs: FileSelectEventArgs = { action: args.action, fileDetails: nodeData[0], isInteracted: this.isNodeClickCalled }; this.parent.trigger('fileSelect', selecEventArgs); } } } // Opens the folder while clicking open context menu item in the treeview. public openFileOnContextMenuClick(node: HTMLLIElement): void { const data: object[] = this.treeObj.getTreeData(node); this.parent.selectedItems = []; this.parent.itemData = data; this.activeNode = node; this.parent.activeModule = 'navigationpane'; const eventArgs: FileOpenEventArgs = { cancel: false, fileDetails: data[0], module: 'NavigationPane' }; this.parent.trigger('fileOpen', eventArgs); this.isNodeClickCalled = true; if (!eventArgs.cancel){ updatePath(node, this.parent.itemData[0], this.parent); read(this.parent, this.isPathDragged ? events.pasteEnd : events.pathChanged, this.parent.path); this.parent.visitedItem = node; this.isPathDragged = this.isRenameParent = this.isRightClick = false; this.treeObj.setProperties({selectedNodes: [node.getAttribute('data-uid')]}); } } private onNodeSelected(args: NodeSelectEventArgs): void { if (this.parent.breadcrumbbarModule && this.parent.breadcrumbbarModule.searchObj && !this.renameParent) { this.parent.breadcrumbbarModule.searchObj.element.value = ''; this.parent.isFiltered = false; this.isNodeClickCalled = false; } this.parent.searchedItems = []; if (!args.isInteracted && !this.isRightClick && !this.isSameNodeClicked && !this.isPathDragged && !this.isRenameParent) { this.parent.pathId = getPathId(args.node); return; } this.activeNode = args.node; this.parent.activeModule = 'navigationpane'; const nodeData: Object[] = this.getTreeData(getValue('id', args.nodeData)); this.parent.selectedItems = []; this.parent.itemData = nodeData; const previousPath: string = this.parent.path; if (!this.isRightClick && this.isSameNodeClicked ) { updatePath(args.node, this.parent.itemData[0], this.parent); } else { this.parent.pathId = getPathId(args.node); this.parent.visitedItem = args.node; } if (args.node.querySelector('.' + CLS.ICONS) && args.node.querySelector('.' + CLS.LIST_ITEM) === null) { this.expandNodeTarget = 'add'; } if (previousPath !== this.parent.path) { if (!this.isRightClick && this.isSameNodeClicked) { read(this.parent, this.isPathDragged ? events.pasteEnd : events.pathChanged, this.parent.path); this.isNodeClickCalled = true; } this.parent.visitedItem = args.node; } this.isPathDragged = this.isRenameParent = this.isRightClick = this.isSameNodeClicked = false; } /* istanbul ignore next */ private onPathDrag(args: object[]): void { this.isPathDragged = true; this.selectResultNode(args[0]); } /* istanbul ignore next */ private onNodeExpand(args: NodeExpandEventArgs): void { if (!args.isInteracted && !this.isDrag) { return; } if (args.node.querySelector('.' + CLS.LIST_ITEM) === null) { this.isNodeExpandCalled = true; const text: string = getValue('text', args.nodeData); const id: string = args.node.getAttribute('data-id'); const isId: boolean = isNOU(id) ? false : true; const newText: string = isNOU(id) ? text : id; const path: string = getPath(args.node, newText, isId); this.expandNodeTarget = args.node.getAttribute('data-uid'); this.parent.expandedId = this.expandNodeTarget; this.parent.itemData = this.getTreeData(getValue('id', args.nodeData)); this.parent.pathId.push(getValue('id', args.nodeData)); read(this.parent, events.nodeExpand, path); } } /* istanbul ignore next */ private onNodeExpanded(args: ReadArgs): void { this.addChild(args.files, this.expandNodeTarget, false); this.parent.expandedId = null; this.isNodeExpandCalled = false; } private onNodeClicked(args: NodeClickEventArgs): void { this.parent.activeModule = 'navigationpane'; this.previousSelected = this.treeObj.selectedNodes; this.activeNode = args.node; if ((args.event.which === 3) && (args.node.getAttribute('data-uid') !== this.treeObj.selectedNodes[0])) { this.isRightClick = true; this.isNodeClickCalled = true; this.treeObj.setProperties({selectedNodes: [args.node.getAttribute('data-uid')]}); } else if (args.node.getAttribute('data-uid') === this.treeObj.selectedNodes[0] && this.parent.selectedItems.length !== 0) { this.parent.setProperties({ selectedItems: [] }, true); const layout: string = (this.parent.view === 'LargeIcons') ? 'largeiconsview' : 'detailsview'; this.parent.notify(events.modelChanged, { module: layout, newProp: { selectedItems: [] } }); } else if (args.node.getAttribute('data-uid') === this.treeObj.selectedNodes[0] && !this.isNodeClickCalled && !this.isNodeExpandCalled) { if (args.event.which === 3) { this.isRightClick = true; } this.isSameNodeClicked = true; this.isNodeClickCalled = true; } } /* istanbul ignore next */ private onNodeEditing(args: NodeEditEventArgs): void { if (!isNOU(args.innerHtml)) { args.cancel = true; } } private onPathChanged(args: ReadArgs): void { this.parent.isCut = false; const currFiles: { [key: string]: Object; }[] = getValue(this.parent.pathId[this.parent.pathId.length - 1], this.parent.feFiles); if (this.expandNodeTarget === 'add') { const sNode: Element = select('[data-uid="' + this.treeObj.selectedNodes[0] + '"]', this.treeObj.element); const ul: Element = (!isNOU(sNode)) ? select('.' + CLS.LIST_PARENT, sNode) : null; if (isNOU(ul)) { this.addChild(args.files, this.treeObj.selectedNodes[0], true); } this.expandNodeTarget = ''; } if (isNOU(currFiles)) { setValue(this.parent.pathId[this.parent.pathId.length - 1], args.files, this.parent.feFiles); } if (this.parent.uploadObj.directoryUpload && !(this.parent.hasId)) { this.updateTree(args); } } private updateTree(args: ReadArgs): void { if (this.treeObj) { const id: string = this.treeObj.selectedNodes[0]; this.updateTreeNode(args, id); } } private updateTreeNode(args: ReadArgs, id: string): void { const toExpand: boolean = this.treeObj.expandedNodes.indexOf(id) === -1 ? false : true; this.removeChildNodes(id); this.addChild(args.files, id, !toExpand); } private removeChildNodes(id: string): void { const sNode: Element = select('[data-uid="' + id + '"]', this.treeObj.element); const parent: Element = select('.' + CLS.LIST_PARENT, sNode); const childs: Element[] = parent ? Array.prototype.slice.call(parent.children) : null; if (childs) { this.treeObj.removeNodes(childs); } } private onOpenEnd(args: ReadArgs): void { const sleId: string = this.parent.pathId[this.parent.pathId.length - 1]; this.treeObj.expandAll(this.treeObj.selectedNodes); this.treeObj.setProperties({selectedNodes: [sleId]}); this.expandNodeTarget = 'add'; this.onPathChanged(args); } private onOpenInit(args: NotifyArgs): void { if (this.parent.activeModule === 'navigationpane') { if (args.target.querySelector('.' + CLS.ICONS)) { this.treeObj.expandAll(this.treeObj.selectedNodes); } } } private onInitialEnd(args: ReadArgs): void { this.onInit(); this.addChild(args.files, getValue('_fm_id', args.cwd), false); } private onFinalizeEnd(args: ReadArgs): void { this.onInit(); const id: string = getValue('_fm_id', args.cwd); this.addChild(args.files, id, false); this.treeObj.setProperties({ selectedNodes: [this.parent.pathId[this.parent.pathId.length - 1]]}); } private onCreateEnd(args: ReadArgs): void { this.updateTree(args); } private onSelectedData(): void { if (this.parent.activeModule === 'navigationpane') { this.updateItemData(); } } private onDeleteInit(): void { if (this.parent.activeModule === 'navigationpane') { this.updateActionData(); const name: string = getValue('name', this.parent.itemData[0]); Delete(this.parent, [name], this.parent.path, 'delete'); } } /* istanbul ignore next */ private onDeleteEnd(args: ReadArgs): void { if (this.parent.activeModule === 'navigationpane') { const selectedNode: string = this.treeObj.selectedNodes[0]; const selcetedEle: Element = select('[data-uid="' + selectedNode + '"]', this.treeObj.element); const selectedNodeEle: HTMLElement = closest(selcetedEle, '.' + CLS.LIST_PARENT).parentElement; this.treeObj.selectedNodes = [selectedNodeEle.getAttribute('data-uid')]; this.treeObj.dataBind(); } this.updateTree(args); } private onRefreshEnd(args: ReadArgs): void { this.updateTree(args); } private onRenameInit(): void { if (this.parent.activeModule === 'navigationpane') { this.updateRenameData(); } } /* istanbul ignore next */ private onRenameEndParent(args: ReadArgs): void { const id: string = this.renameParent ? this.renameParent : this.parent.pathId[this.parent.pathId.length - 1]; this.updateTreeNode(args, id); this.parent.expandedId = null; if (this.renameParent) { this.renameParent = null; } else { let resultData: Object[] = []; if (this.parent.hasId) { resultData = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where('id', 'equal', this.parent.renamedId, false)); } else { const nData: Object[] = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where(this.treeObj.fields.text, 'equal', this.parent.renameText, false)); if (nData.length > 0) { resultData = new DataManager(nData). executeLocal(new Query().where('_fm_pId', 'equal', id, false)); } } if (resultData.length > 0) { const id: string = this.previousSelected.length > 0 && this.treeObj.getTreeData(this.previousSelected[0]).length !== 0 ? this.previousSelected[0] : getValue(this.treeObj.fields.id, resultData[0]); this.treeObj.selectedNodes = [id]; this.treeObj.dataBind(); this.updateItemData(); } } } /* istanbul ignore next */ private onRenameEnd(args: ReadArgs): void { if (this.parent.breadcrumbbarModule.searchObj.element.value === '' && !this.parent.isFiltered) { this.updateTree(args); } else { const data: { [key: string]: Object; }[] = this.treeObj.getTreeData(); let resultData: Object[] = []; if (this.parent.hasId) { resultData = new DataManager(data). executeLocal(new Query().where('id', 'equal', this.parent.renamedId, false)); } else { const nData: Object[] = new DataManager(data). executeLocal(new Query().where(this.treeObj.fields.text, 'equal', this.parent.currentItemText, false)); if (nData.length > 0) { resultData = new DataManager(nData). executeLocal(new Query().where('filterPath', 'equal', this.parent.filterPath, false)); } } if (resultData.length > 0) { this.renameParent = getValue(this.treeObj.fields.parentID, resultData[0]); this.parent.expandedId = this.renameParent; this.parent.itemData = this.getTreeData(this.renameParent); read(this.parent, events.renameEndParent, this.parent.filterPath.replace(/\\/g, '/')); } } } private onPropertyChanged(e: NotifyArgs): void { if (e.module !== this.getModuleName() && e.module !== 'common') { /* istanbul ignore next */ return; } for (const prop of Object.keys(e.newProp)) { switch (prop) { case 'allowDragAndDrop': this.addDragDrop(); break; case 'navigationPaneSettings': read(this.parent, events.finalizeEnd, this.parent.path); if (e.oldProp.navigationPaneSettings.sortOrder !== e.newProp.navigationPaneSettings.sortOrder) { this.treeObj.sortOrder = e.newProp.navigationPaneSettings.sortOrder; } break; } } } /* istanbul ignore next */ private onDownLoadInit(): void { this.doDownload(); } private onSelectionChanged(e: NotifyArgs): void { this.treeObj.setProperties({selectedNodes: [e.selectedNode]}); } private onClearPathInit(e: NotifyArgs): void { this.removeChildNodes(e.selectedNode); } private onDragEnd(args: ReadArgs): void { if (isFileSystemData(this.parent)) { this.moveNames = []; const obj: object[] = this.parent.dragData; for (let i: number = 0; i < obj.length; i++) { if (getValue('isFile', obj[i as number]) === false) { this.moveNames.push(getValue('_fm_id', obj[i as number])); } } } let moveNames: string[] = []; if (this.parent.isPasteError || this.parent.isSearchDrag) { moveNames = this.getMoveNames(args.files, this.parent.isSearchDrag, this.parent.dragPath); } else { moveNames = this.moveNames; } this.treeObj.removeNodes(moveNames); } private getMoveNames(files: { [key: string]: Object; }[], flag: boolean, path: string): string[] { const moveNames: string[] = []; for (let i: number = 0; i < files.length; i++) { if (!files[i as number].isFile) { if (!this.parent.hasId) { let name: string = <string>(files[i as number].previousName); if (flag) { path = path + files[i as number].previousName; const index: number = path.lastIndexOf('/'); name = path.substring(index + 1); path = path.substring(0, index + 1); } const resultData: Object[] = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where(this.treeObj.fields.text, 'equal', name, false)); for (let j: number = 0; j < resultData.length; j++) { let fPath: string = getValue('filterPath', resultData[j as number]); fPath = fPath.replace(/\\/g, '/'); if (fPath === path) { moveNames.push(getValue(this.treeObj.fields.id, resultData[j as number])); break; } } } } } return moveNames; } private onCutEnd(args: ReadArgs): void { let moveNames: string[] = []; if (this.parent.isPasteError || this.parent.isSearchCut) { this.moveNames = this.getMoveNames(args.files, this.parent.isSearchCut, this.parent.targetPath); } else { moveNames = this.moveNames; } this.treeObj.removeNodes(moveNames); } /* istanbul ignore next */ private selectResultNode(resultObj: object): void { if (!this.parent.hasId) { const path: string = getValue('filterPath', resultObj); const itemname: string = getValue('name', resultObj); const data: Object[] = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where(this.treeObj.fields.text, 'equal', itemname, false)); if (data.length > 0) { const resultData: Object[] = new DataManager(data). executeLocal(new Query().where('filterPath', 'equal', path, false)); if (resultData.length > 0) { const id: string = getValue(this.treeObj.fields.id, resultData[0]); this.treeObj.selectedNodes = [id]; this.treeObj.dataBind(); } } } else { const selectedNode: { [key: string]: Object; } = this.treeObj.getTreeData().filter((obj: {name: string}) => obj.name === (resultObj as {name: string}).name)[0]; this.treeObj.selectedNodes = [getValue('_fm_id', selectedNode)]; this.treeObj.dataBind(); } } private onDropPath(args: ReadArgs): void { this.onpasteEnd(args); this.selectResultNode(this.parent.dropData); this.parent.isDropEnd = !this.parent.isPasteError; } private onpasteEnd(args: ReadArgs): void { let resultData: Object[] = []; if (this.parent.hasId) { resultData = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where('id', 'equal', getValue('id', args.cwd), false)); } else { const nData: Object[] = new DataManager(this.treeObj.getTreeData()). executeLocal(new Query().where(this.treeObj.fields.text, 'equal', getValue('name', args.cwd), false)); if (nData.length > 0) { resultData = new DataManager(nData). executeLocal(new Query().where('filterPath', 'equal', getValue('filterPath', args.cwd), false)); } } if (resultData.length > 0) { const id: string = getValue(this.treeObj.fields.id, resultData[0]); const toExpand: boolean = this.treeObj.expandedNodes.indexOf(id) === -1; this.removeChildNodes(id); this.addChild(args.files, id, toExpand); } this.parent.expandedId = null; this.onPathChanged(args); if (this.parent.isDragDrop) { this.checkDropPath(args); } } /* istanbul ignore next */ private checkDropPath(args: ReadArgs): void { if (isFileSystemData(this.parent) && (this.parent.path === this.parent.dropPath || this.parent.targetModule === 'navigationpane')) { return; } if ((this.parent.dropPath.indexOf(getDirectoryPath(this.parent, args)) === -1)) { this.parent.isDropEnd = false; readDropPath(this.parent); } else { this.parent.isDropEnd = !this.parent.isPasteError; } } private onpasteInit(): void { if (this.parent.activeModule === this.getModuleName()) { this.updateItemData(); } this.moveNames = []; const obj: object[] = this.parent.isDragDrop ? this.parent.dragData : this.parent.actionRecords; for (let i: number = 0; i < obj.length; i++) { if (getValue('isFile', obj[i as number]) === false) { this.moveNames.push(getValue('_fm_id', obj[i as number])); } } } private oncutCopyInit(): void { if (this.parent.activeModule === this.getModuleName()) { this.parent.activeRecords = this.getTreeData(this.treeObj.selectedNodes[0]); this.parent.activeElements = [this.activeNode]; } } private addEventListener(): void { this.parent.on(events.modelChanged, this.onPropertyChanged, this); this.parent.on(events.downloadInit, this.onDownLoadInit, this); this.parent.on(events.initialEnd, this.onInitialEnd, this); this.parent.on(events.finalizeEnd, this.onFinalizeEnd, this); this.parent.on(events.pathChanged, this.onPathChanged, this); this.parent.on(events.pasteEnd, this.onpasteEnd, this); this.parent.on(events.cutEnd, this.onCutEnd, this); this.parent.on(events.pasteInit, this.onpasteInit, this); this.parent.on(events.nodeExpand, this.onNodeExpanded, this); this.parent.on(events.createEnd, this.onCreateEnd, this); this.parent.on(events.selectedData, this.onSelectedData, this); this.parent.on(events.deleteInit, this.onDeleteInit, this); this.parent.on(events.deleteEnd, this.onDeleteEnd, this); this.parent.on(events.refreshEnd, this.onRefreshEnd, this); this.parent.on(events.updateTreeSelection, this.onSelectionChanged, this); this.parent.on(events.openInit, this.onOpenInit, this); this.parent.on(events.openEnd, this.onOpenEnd, this); this.parent.on(events.destroy, this.destroy, this); this.parent.on(events.renameInit, this.onRenameInit, this); this.parent.on(events.renameEnd, this.onRenameEnd, this); this.parent.on(events.renameEndParent, this.onRenameEndParent, this); this.parent.on(events.clearPathInit, this.onClearPathInit, this); this.parent.on(events.cutCopyInit, this.oncutCopyInit, this); this.parent.on(events.dropInit, this.onDropInit, this); this.parent.on(events.menuItemData, this.onMenuItemData, this); this.parent.on(events.dragEnd, this.onDragEnd, this); this.parent.on(events.dragging, this.onDragging, this); this.parent.on(events.dropPath, this.onDropPath, this); this.parent.on(events.detailsInit, this.onDetailsInit, this); this.parent.on(events.pathDrag, this.onPathDrag, this); } private removeEventListener(): void { this.parent.off(events.initialEnd, this.onInitialEnd); this.parent.off(events.downloadInit, this.onDownLoadInit); this.parent.off(events.finalizeEnd, this.onFinalizeEnd); this.parent.off(events.selectedData, this.onSelectedData); this.parent.off(events.modelChanged, this.onPropertyChanged); this.parent.off(events.pathChanged, this.onPathChanged); this.parent.off(events.pasteEnd, this.onpasteEnd); this.parent.off(events.cutEnd, this.onCutEnd); this.parent.off(events.pasteInit, this.onpasteInit); this.parent.off(events.updateTreeSelection, this.onSelectionChanged); this.parent.off(events.nodeExpand, this.onNodeExpanded); this.parent.off(events.createEnd, this.onCreateEnd); this.parent.off(events.refreshEnd, this.onRefreshEnd); this.parent.off(events.openInit, this.onOpenInit); this.parent.off(events.openEnd, this.onOpenEnd); this.parent.off(events.destroy, this.destroy); this.parent.off(events.renameInit, this.onRenameInit); this.parent.off(events.renameEnd, this.onRenameEnd); this.parent.off(events.renameEndParent, this.onRenameEndParent); this.parent.off(events.clearPathInit, this.onClearPathInit); this.parent.off(events.deleteInit, this.onDeleteInit); this.parent.off(events.deleteEnd, this.onDeleteEnd); this.parent.off(events.cutCopyInit, this.oncutCopyInit); this.parent.off(events.dropInit, this.onDropInit); this.parent.off(events.dragEnd, this.onDragEnd); this.parent.off(events.dragging, this.onDragging); this.parent.off(events.dropPath, this.onDropPath); this.parent.off(events.detailsInit, this.onDetailsInit); this.parent.off(events.menuItemData, this.onMenuItemData); this.parent.off(events.pathDrag, this.onPathDrag); } /* istanbul ignore next */ private onDetailsInit(): void { if (this.parent.activeModule === this.getModuleName()) { const dataobj: Object[] = this.getTreeData(this.treeObj.selectedNodes[0]); this.parent.itemData = dataobj; } } private onMenuItemData(args: { [key: string]: Object; }): void { if (this.parent.activeModule === this.getModuleName()) { const liEle: Element = closest(<Element>args.target, 'li'); this.parent.itemData = this.getTreeData(liEle.getAttribute('data-uid')); } } /* istanbul ignore next */ private onDragging(args: DragEventArgs): void { const ele: Element = closest(args.target, 'li'); if (ele.classList.contains('e-node-collapsed')) { this.isDrag = true; const level: number = parseInt(ele.getAttribute('aria-level'), 10); this.treeObj.expandAll([ele.getAttribute('data-uid')], level + 1); this.isDrag = false; } } private onDropInit(args: DragEventArgs): void { if (this.parent.targetModule === this.getModuleName()) { const dropLi: Element = closest(args.target, 'li'); this.parent.dropData = this.getTreeData(dropLi)[0]; this.parent.dropPath = this.getDropPath(dropLi, getValue('name', this.parent.dropData)); } } /** * For internal use only - Get the module name. * * @returns {string} - returns the module name. * @private */ private getModuleName(): string { return 'navigationpane'; } public destroy(): void { if (this.parent.isDestroyed) { return; } this.removeEventListener(); if (this.treeObj) { this.unWireEvents(); this.treeObj.destroy(); } } private wireEvents(): void { this.keyboardModule = new KeyboardEvents( this.treeObj.element, { keyAction: this.keyDown.bind(this), keyConfigs: this.keyConfigs, eventName: 'keydown' } ); } private unWireEvents(): void { this.keyboardModule.destroy(); } /* istanbul ignore next */ private keyDown(e: KeyboardEventArgs): void { const action: string = e.action; switch (action) { case 'altEnter': this.parent.notify(events.detailsInit, {}); GetDetails(this.parent, [], this.parent.path, 'details'); break; case 'esc': removeActive(this.parent); break; case 'del': if (this.parent.pathId[0] !== this.activeNode.getAttribute('data-uid')) { this.updateItemData(); if (!hasEditAccess(this.parent.itemData[0])) { createDeniedDialog(this.parent, this.parent.itemData[0], events.permissionEdit); } else { this.removeNodes = []; createDialog(this.parent, 'Delete'); } } break; case 'ctrlC': copyFiles(this.parent); break; case 'ctrlV': this.parent.folderPath = ''; pasteHandler(this.parent); break; case 'ctrlX': cutFiles(this.parent); break; case 'shiftF10': this.updateItemData(); if (!hasDownloadAccess(this.parent.itemData[0])) { createDeniedDialog(this.parent, this.parent.itemData[0], events.permissionDownload); return; } if (this.parent.selectedItems.length !== 0) { this.doDownload(); } break; case 'f2': if (this.parent.selectedItems.length === 0) { const data: Object = this.getTreeData(this.treeObj.selectedNodes[0])[0]; if (!hasEditAccess(data)) { createDeniedDialog(this.parent, data, events.permissionEdit); } else { this.updateRenameData(); createDialog(this.parent, 'Rename'); } } break; } } private getTreeData(args: string | Element): object[] { const data: object[] = this.treeObj.getTreeData(args); for (let i: number = 0; i < data.length; i++) { if (isNOU(getValue('hasChild', data[i as number]))) { setValue('hasChild', false, data[i as number]); } } return data; } private updateRenameData(): void { this.updateItemData(); this.parent.currentItemText = getValue('name', this.parent.itemData[0]); } private updateItemData(): void { const data: Object = this.getTreeData(this.treeObj.selectedNodes[0])[0]; this.parent.itemData = [data]; this.parent.isFile = false; } private updateActionData(): void { this.updateItemData(); const node: HTMLLIElement = select('[data-uid="' + this.parent.pathId[this.parent.pathId.length - 1] + '"]', this.treeObj.element); updatePath(node, this.parent.itemData[0], this.parent); const newPath: string = getParentPath(this.parent.path); this.parent.setProperties({ path: newPath }, true); this.parent.pathId.pop(); this.parent.pathNames.pop(); } /* istanbul ignore next */ private doDownload(): void { const newPath: string = getParentPath(this.parent.path); const itemId: string = this.treeObj.selectedNodes[0]; const name: string = (itemId === this.parent.pathId[0]) ? '' : getValue('name', this.parent.itemData[0]); Download(this.parent, newPath, [name]); } }