@syncfusion/ej2-filemanager
Version:
Essential JS 2 FileManager Component
920 lines (867 loc) • 41.8 kB
text/typescript
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]);
}
}