UNPKG

@syncfusion/ej2-filemanager

Version:
1,046 lines (995 loc) 90.4 kB
import { Grid, Resize, ContextMenu, Sort, VirtualScroll, RowSelectEventArgs, RowDeselectEventArgs, Column, GridModel } from '@syncfusion/ej2-grids'; import { select, KeyboardEvents, EventHandler, KeyboardEventArgs, getValue, isNullOrUndefined } from '@syncfusion/ej2-base'; import { isNullOrUndefined as isNOU, Touch, TapEventArgs, setValue, addClass, removeClass } from '@syncfusion/ej2-base'; import { Internationalization, closest, DragEventArgs, Draggable, initializeCSPTemplate, extend, SanitizeHtmlHelper } from '@syncfusion/ej2-base'; import { FileManager } from '../base/file-manager'; import { DataManager, Query } from '@syncfusion/ej2-data'; import { hideSpinner, showSpinner } from '@syncfusion/ej2-popups'; import * as events from '../base/constant'; import * as CLS from '../base/classes'; import { ReadArgs, SearchArgs, FileDetails, NotifyArgs, SortOrder, BeforeImageLoadEventArgs } from '../base/interface'; import { FileSelectEventArgs, FileLoadEventArgs, FileSelectionEventArgs } from '../base/interface'; import { FileOpenEventArgs } from '../base/interface'; import { createDialog, createImageDialog } from '../pop-up/dialog'; import { removeBlur, openAction, getImageUrl, fileType, getSortedData, getLocaleText, updateLayout } from '../common/utility'; import { createEmptyElement } from '../common/utility'; import { read, Download, GetDetails, Delete } from '../common/operations'; import { cutFiles, addBlur, openSearchFolder, copyFiles, removeActive, pasteHandler, getPathObject, getName } from '../common/index'; import { hasReadAccess, hasEditAccess, hasDownloadAccess, doRename, getAccessClass, createDeniedDialog, rename } from '../common/index'; import { createVirtualDragElement, dragStopHandler, dragStartHandler, draggingHandler, getModule, getFullPath } from '../common/index'; import { getDirectoryPath, updateRenamingData, getItemName, doDeleteFiles, doDownloadFiles } from '../common/index'; import { RecordDoubleClickEventArgs, RowDataBoundEventArgs, SortEventArgs, HeaderCellInfoEventArgs } from '@syncfusion/ej2-grids'; import { BeforeDataBoundArgs, ColumnModel, SortDescriptorModel, BeforeCopyEventArgs, RowSelectingEventArgs, RowDeselectingEventArgs } from '@syncfusion/ej2-grids'; /* eslint-disable @typescript-eslint/no-explicit-any */ /** * DetailsView module */ export class DetailsView { /* Internal variables */ public element: HTMLElement; private parent: FileManager; private keyboardModule: KeyboardEvents; private keyboardDownModule: KeyboardEvents; private keyConfigs: { [key: string]: string }; private sortItem: boolean; private isInteracted: boolean = true; private interaction: boolean = true; private isPasteOperation: boolean = false; private isColumnRefresh: boolean = false; private clickObj: Touch; private sortSelectedNodes: string[]; private emptyArgs: ReadArgs | SearchArgs; private dragObj: Draggable = null; private startIndex: number = null; private firstItemIndex: number = null; private isSelectionUpdate: boolean = false; private currentSelectedItem: string[] = []; private count: number = 0; private isRendered: boolean = true; private isLoaded: boolean = false; private isNameWidth: boolean = false; private isMultiSelect: boolean = false; /* public variable */ public gridObj: Grid; public pasteOperation: boolean = false; public uploadOperation: boolean = false; /** * Constructor for the GridView module * * @param {FileManager} parent - specifies the parent. * @hidden */ constructor(parent?: FileManager) { Grid.Inject(Resize, ContextMenu, Sort, VirtualScroll); this.parent = parent; this.element = <HTMLElement>select('#' + this.parent.element.id + CLS.GRID_ID, this.parent.element); this.addEventListener(); this.keyConfigs = { altEnter: 'alt+enter', esc: 'escape', tab: 'tab', moveDown: 'downarrow', ctrlEnd: 'ctrl+end', ctrlHome: 'ctrl+home', ctrlDown: 'ctrl+downarrow', ctrlLeft: 'ctrl+leftarrow', ctrlRight: 'ctrl+rightarrow', shiftEnd: 'shift+end', shiftHome: 'shift+home', shiftDown: 'shift+downarrow', shiftUp: 'shift+uparrow', ctrlUp: 'ctrl+uparrow', csEnd: 'ctrl+shift+end', csHome: 'ctrl+shift+home', csDown: 'ctrl+shift+downarrow', csUp: 'ctrl+shift+uparrow', space: 'space', ctrlSpace: 'ctrl+space', shiftSpace: 'shift+space', csSpace: 'ctrl+shift+space', end: 'end', home: 'home', moveUp: 'uparrow', 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', shiftdel: 'shift+delete', ctrlD: 'ctrl+d', f2: 'f2', ctrlA: 'ctrl+a', enter: 'enter', back: 'backspace' }; } /* istanbul ignore next */ private render(args: ReadArgs | SearchArgs): void { if (this.parent.enablePersistence) { const gridPersistenceValue: string = window.localStorage.getItem('grid' + this.parent.element.id + '_grid'); if (!isNOU(gridPersistenceValue)) { const model: GridModel = JSON.parse(gridPersistenceValue); if (!isNOU(model) && Object.keys(model).length > 0 && 'sortSettings' in model) { delete model.sortSettings; window.localStorage.setItem('grid' + this.parent.element.id + '_grid', JSON.stringify(model)); } } } showSpinner(this.parent.element); if (this.parent.view === 'Details') { removeClass([this.parent.element], CLS.MULTI_SELECT); const items: Object[] = getSortedData(this.parent, args.files); this.checkNameWidth(); const columns: ColumnModel[] = this.getColumns(); let sortSettings: SortDescriptorModel[]; const isValidSortField: boolean = !isNullOrUndefined(columns) && columns.findIndex((col: ColumnModel) => col.field === this.parent.sortBy) !== -1; if (this.parent.isMobile || !isValidSortField) { sortSettings = []; } else { if (this.parent.sortOrder !== 'None') { sortSettings = [{ direction: this.parent.sortOrder, field: this.parent.sortBy }]; } } this.gridObj = new Grid({ dataSource: items, allowSorting: true, rowSelecting: this.onSelection.bind(this, 'select'), rowDeselecting: this.onSelection.bind(this, 'unselect'), rowSelected: this.onSelected.bind(this), rowDeselected: this.onDeSelection.bind(this), allowResizing: this.parent.detailsViewSettings.columnResizing, selectionSettings: { type: this.parent.allowMultiSelection ? 'Multiple' : 'Single', checkboxMode: 'ResetOnRowClick' }, enableRtl: this.parent.enableRtl, pageSettings: { pageSize: 20 }, enableVirtualization: this.parent.enableVirtualization, enablePersistence: this.parent.enablePersistence, enableVirtualMaskRow: true, sortSettings: { allowUnsort: false, columns: sortSettings }, columns: columns, recordDoubleClick: this.DblClickEvents.bind(this), beforeDataBound: this.onBeforeDataBound.bind(this), dataBound: this.onDataBound.bind(this), rowDataBound: this.onRowDataBound.bind(this), actionBegin: this.onActionBegin.bind(this), headerCellInfo: this.onHeaderCellInfo.bind(this), width: '100%', height: (this.parent.enableVirtualization) ? this.getGridHeight() : 'auto', beforeCopy: (args: BeforeCopyEventArgs) => { args.cancel = true; }, load: function (): void { this.focusModule.destroy(); }, locale: this.parent.locale }); if ((this as any).parent.isReact) { (<{ isReact?: boolean }>this.gridObj).isReact = true; (<{ portals?: object[] }>this.gridObj).portals = []; this.gridObj.on('reactTemplateRender', this.reactTemplateRender, this); } this.gridObj.isStringTemplate = true; this.gridObj.appendTo('#' + this.parent.element.id + CLS.GRID_ID); if (this.parent.selectedItems.length !== 0 && this.parent.enableVirtualization && this.parent.enablePersistence) { this.isLoaded = true; } this.wireEvents(); this.adjustHeight(); this.emptyArgs = args; } } private reactTemplateRender(args: Object[]): void { (this.parent as any)['portals'] = args; if ((this.parent as any).portals && this.parent.toolbarModule && this.parent.toolbarModule.toolbarObj && (this.parent.toolbarModule.toolbarObj as any).portals) { (this.parent as any)['portals'] = (this.parent as any)['portals'].concat((this.parent.toolbarModule.toolbarObj as any).portals); } this.parent.notify('renderReactTemplate', (this.parent as any)['portals']); (this.parent as any)['renderReactTemplates'](); } /** * Gets the grid height. * * @returns {number} - The grid height. * @private */ private getGridHeight(): number { // Get the content pane and breadcrumb bar elements const pane: HTMLElement = <HTMLElement>select('#' + this.parent.element.id + CLS.CONTENT_ID, this.parent.element); const bar: HTMLElement = <HTMLElement>select('#' + this.parent.element.id + CLS.BREADCRUMBBAR_ID, this.parent.element); // The maximum height of the header is 36 const headerMaxHeight: number = 36; // Calculate and return the grid height return (pane.offsetHeight - bar.offsetHeight - headerMaxHeight); } private checkNameWidth(): void { const initialColumn: ColumnModel[] = this.parent.detailsViewSettings.columns; this.isNameWidth = false; for (let i: number = 0; i < initialColumn.length; i++) { if (initialColumn[i as number].field === 'name') { this.isNameWidth = !isNOU(initialColumn[i as number].width); return; } } } private adjustWidth(columns: ColumnModel[], fieldName: string): void { if (this.isNameWidth && (fieldName === 'name')) { return; } for (let i: number = 0; i < columns.length; i++) { if (columns[i as number].field === fieldName) { let nameWidth: string; if (this.parent.breadcrumbbarModule.searchObj.element.value === '' && !this.parent.isFiltered) { nameWidth = (this.element.clientWidth <= 500) ? '120px' : 'auto'; } else { nameWidth = (this.element.clientWidth <= 680) ? ((fieldName === 'name') ? '120px' : '180px') : 'auto'; } columns[i as number].width = nameWidth; } } } private getColumns(): ColumnModel[] { let columns: ColumnModel[]; const enableHtmlSanitizer: boolean = this.parent.enableHtmlSanitizer; if (this.parent.isMobile) { columns = [ { field: 'name', headerText: getLocaleText(this.parent, 'Name'), width: 'auto', minWidth: 120, headerTextAlign: 'Left', template: initializeCSPTemplate(function(data: any): string | Function { const name: string = enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(data.name) : data.name; return `<div class="e-fe-text">${name}</div><div class="e-fe-date">${data._fm_modified}</div><span class="e-fe-size">${data.size}</span>`; }) as string | Function } ]; } else { columns = extend([], this.parent.detailsViewSettings.columns, null, true) as ColumnModel[]; this.adjustWidth(columns, 'name'); for (let i: number = 0, len: number = columns.length; i < len; i++) { columns[i as number].headerText = getLocaleText(this.parent, columns[i as number].headerText); if (columns[i as number].field === 'name' && !isNOU(columns[i as number].template) && !(typeof columns[i as number].template === 'function')) { const template: string | Function = columns[i as number].template; columns[i as number].template = initializeCSPTemplate(function (data: any): string | Function { const name: string = enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(data.name) : data.name; return (template as any).replace(/\${name}/g, name); }); } } } const iWidth: string = ((this.parent.isMobile || this.parent.isBigger) ? '54' : '46'); const icon: ColumnModel = { field: 'type', width: iWidth, minWidth: iWidth, template: initializeCSPTemplate(function(data: any): string | Function { return `<span class="e-fe-icon ${data._fm_iconClass}"></span>`; }) as string | Function, allowResizing: false, allowSorting: true, customAttributes: { class: 'e-fe-grid-icon' }, headerTemplate: initializeCSPTemplate(function(): string | Function { return '<span class=\'e-fe-icon e-fe-folder\'></span>'; }) as string | Function }; columns.unshift(icon); if (this.parent.showItemCheckBoxes) { const cWidth: string = (this.parent.isBigger ? '36' : '26'); const cBox: ColumnModel = { type: 'checkbox', width: cWidth, minWidth: cWidth, customAttributes: { class: 'e-fe-checkbox' }, allowResizing: false, allowSorting: false }; if (this.parent.isMobile) { columns.push(cBox); } else { columns.unshift(cBox); } } for (let i: number = 0, len: number = columns.length; i < len; i++) { columns[i as number].disableHtmlEncode = !this.parent.enableHtmlSanitizer; } if (this.parent.enableRangeSelection) { const HiddenName: ColumnModel = { field: 'name', visible: false, customAttributes: { class: 'e-drag-text' } }; columns.push(HiddenName); } return columns; } private adjustHeight(): void { if (!this.gridObj) { return; } const pane: HTMLElement = <HTMLElement>select('#' + this.parent.element.id + CLS.CONTENT_ID, this.parent.element); const bar: HTMLElement = <HTMLElement>select('#' + this.parent.element.id + CLS.BREADCRUMBBAR_ID, this.parent.element); const gridHeader: HTMLElement = <HTMLElement>select('.' + CLS.GRID_HEADER, this.parent.element); const height: number = (pane.offsetHeight - bar.offsetHeight - gridHeader.offsetHeight); this.gridObj.height = height; this.gridObj.dataBind(); } private renderCheckBox(): void { this.gridObj.columns = this.getColumns(); this.isColumnRefresh = true; this.gridObj.refreshColumns(); } private onRowDataBound(args: RowDataBoundEventArgs): void { let td: Element = select('.e-fe-grid-name', args.row); if (!td) { const columns: ColumnModel[] = this.parent.detailsViewSettings.columns; for (let i: number = 0; i < columns.length; i++) { if (columns[i as number].field === 'name') { td = args.row.children[this.parent.allowMultiSelection ? (i + 2) : (i + 1)]; break; } } } if (td) { td.setAttribute('title', getValue('name', args.data)); } if (this.parent.isLayoutChange && this.parent.isCut && this.parent.fileAction === 'move' && this.parent.selectedNodes && this.parent.selectedNodes.length !== 0) { if (this.parent.selectedNodes.indexOf(getValue('name', args.data)) !== -1) { addBlur(args.row); } } if (!this.parent.showFileExtension && getValue('isFile', args.data)) { const text: string = getValue('name', args.data); const textEle: Element = args.row.querySelector('[title= "' + text + '"]'); if (textEle) { const name: string = getValue('name', args.data); const type: string = getValue('type', args.data); if (name.indexOf(type) !== -1) { textEle.innerHTML = name.substr(0, name.length - type.length); } } } if (getValue('size', args.data) !== undefined && args.row.querySelector('.e-fe-size')) { const sizeEle: Element = args.row.querySelector('.e-fe-size'); let modifiedSize: string; if (!getValue('isFile', args.data)) { modifiedSize = ''; } else { const sizeValue: number = getValue('size', args.data); const intl: Internationalization = new Internationalization(this.parent.locale); let sizeFormat: string; const columns: ColumnModel[] = this.parent.detailsViewSettings.columns; for (let i: number = 0; i < columns.length; i++) { if (columns[i as number].field === 'size') { sizeFormat = !isNullOrUndefined(columns[i as number].format) ? columns[i as number].format.toString() : 'n'; break; } } const value: string = intl.formatNumber((sizeValue / 1024), { format: sizeFormat }); modifiedSize = value + ' ' + getLocaleText(this.parent, 'KB'); } sizeEle.innerHTML = modifiedSize; } if (this.parent.isMobile) { if (getValue('_fm_modified', args.data) !== undefined && args.row.querySelector('.e-fe-date')) { const dateEle: Element = args.row.querySelector('.e-fe-date'); const intl: Internationalization = new Internationalization(this.parent.locale); const columns: ColumnModel[] = this.parent.detailsViewSettings.columns; let format: Object; for (let i: number = 0; i < columns.length; i++) { if (columns[i as number].field === 'dateModified') { format = columns[i as number].format; break; } } const formattedString: string = intl.formatDate(new Date(getValue('_fm_modified', args.data)), format); dateEle.innerHTML = formattedString; } } const checkWrap: Element = args.row.querySelector('.' + CLS.CB_WRAP); if (checkWrap) { checkWrap.classList.add('e-small'); } if (!hasEditAccess(args.data)) { args.row.className += ' ' + getAccessClass(args.data); } const eventArgs: FileLoadEventArgs = { element: args.row as HTMLElement, fileDetails: args.data, module: 'DetailsView' }; this.parent.trigger('fileLoad', eventArgs); } private onActionBegin(args: SortEventArgs): void { if (args.requestType === 'sorting') { this.parent.setProperties({ sortOrder: args.direction }, true); this.parent.setProperties({ sortBy: args.columnName }, true); if (this.parent.selectedItems.length !== 0) { this.sortItem = true; const rows: number[] = this.gridObj.getSelectedRowIndexes(); let len: number = rows.length; this.sortSelectedNodes = []; while (len > 0) { const data: Object = this.gridObj.getRowsObject()[rows[len - 1]].data; this.sortSelectedNodes.push(getValue(this.parent.hasId ? 'id' : 'name', data)); len--; } } this.parent.notify(events.sortByChange, {}); } } private onHeaderCellInfo(args: HeaderCellInfoEventArgs): void { const checkWrap: Element = args.node.querySelector('.' + CLS.CB_WRAP); if (checkWrap) { checkWrap.classList.add('e-small'); } } private onBeforeDataBound(args: BeforeDataBoundArgs): void { showSpinner(this.parent.element); const nameColumn: ColumnModel = this.parent.detailsViewSettings.columns.find((column: ColumnModel) => column.field === this.parent.sortBy); if (nameColumn && !('sortComparer' in nameColumn)) { const items: Object[] = getSortedData( this.parent, (this.parent.enableVirtualization) ? args.result : this.gridObj.dataSource as Object[] ); args.result = items; } } /* istanbul ignore next */ private onDataBound(): void { this.createDragObj(); if ((this.parent.selectedItems.length !== 0 && !this.parent.enableVirtualization) || this.isLoaded) { this.selectRecords(this.parent.selectedItems); } if (this.isPasteOperation === true && (!isNullOrUndefined(this.gridObj.getDataRows()) && this.gridObj.getDataRows().length > 0)) { if (!this.isColumnRefresh) { this.selectRecords(this.parent.pasteNodes); this.isPasteOperation = false; } else { this.isColumnRefresh = false; } } if (this.parent.createdItem) { this.selectRecords([getValue(this.parent.hasId ? 'id' : 'name', this.parent.createdItem)]); this.parent.createdItem = null; } if (this.parent.layoutSelectedItems.length) { this.selectRecords(this.parent.layoutSelectedItems); } if (this.parent.renamedItem && this.parent.selectedItems.length === 0) { this.gridObj.clearSelection(); this.addSelection(this.parent.renamedItem); this.parent.renamedItem = null; } if (this.sortItem === true) { this.selectRecords(this.sortSelectedNodes); this.sortItem = false; } if (this.isSelectionUpdate) { if (!this.isColumnRefresh) { this.selectRecords(this.currentSelectedItem); this.isSelectionUpdate = false; } else { this.isColumnRefresh = false; } } if (this.uploadOperation === true) { this.count++; this.selectRecords(this.parent.uploadItem); if (this.count === this.parent.uploadItem.length) { this.uploadOperation = false; this.parent.uploadItem = []; } } if (this.gridObj.currentViewData.length * this.gridObj.getRowHeight() < this.gridObj.height) { const hdTable: HTMLElement = <HTMLElement>this.gridObj.getHeaderContent(); hdTable.style.paddingRight = ''; hdTable.style.paddingLeft = ''; const hdContent: HTMLElement = <HTMLElement>select('.e-headercontent', hdTable); hdContent.style.borderRightWidth = '0'; const cnTable: HTMLElement = <HTMLElement>this.gridObj.getContent().querySelector('.e-content'); cnTable.style.overflowY = ''; cnTable.classList.add('e-scrollShow'); } else { const hdTable: HTMLElement = <HTMLElement>this.gridObj.getHeaderContent(); if (!this.parent.enableRtl) { hdTable.style.paddingRight = '16px'; } else { hdTable.style.paddingLeft = '16px'; } const cnTable: Element = this.gridObj.getContent().querySelector('.e-content'); cnTable.classList.remove('e-scrollShow'); } this.isRendered = true; this.parent.isLayoutChange = false; hideSpinner(this.parent.element); this.checkEmptyDiv(this.emptyArgs); this.isInteracted = this.isLoaded ? true : this.isInteracted; this.isLoaded = false; } private selectRecords(nodes: string[]): void { const gridRecords: Object[] = this.gridObj.getCurrentViewRecords(); const sRecords: number[] = []; for (let i: number = 0, len: number = gridRecords.length; i < len; i++) { const node: string = this.parent.hasId ? getValue('id', gridRecords[i as number]) : getName(this.parent, gridRecords[i as number]); if (nodes.indexOf(node) !== -1) { sRecords.push(i); } else if (!this.parent.showFileExtension && !this.parent.hasId && node.includes('.')){ const Str2: string = node.split('.').slice(0, -1).join('.'); if (nodes.indexOf(Str2) !== -1) { sRecords.push(i); } } } if (sRecords.length !== 0) { this.gridObj.selectRows(sRecords); this.addFocus(this.gridObj.selectedRowIndex); } } private addSelection(data: Object): void { const items: Object[] = this.gridObj.getCurrentViewRecords(); let rData: Object[] = []; if (this.parent.hasId) { rData = new DataManager(items). executeLocal(new Query().where('id', 'equal', this.parent.renamedId, false)); } else { const nData: Object[] = new DataManager(items). executeLocal(new Query().where('name', 'equal', getValue('name', data), false)); if (nData.length > 0) { rData = new DataManager(nData). executeLocal(new Query().where('filterPath', 'equal', this.parent.filterPath, false)); } } if (rData.length > 0) { const index: number = items.indexOf(rData[0]); this.gridObj.selectRows([index]); } } private onSortColumn(): void { if (this.parent.sortOrder !== 'None') { this.gridObj.sortModule.sortColumn(this.parent.sortBy, this.parent.sortOrder); } else { this.gridObj.dataSource = getSortedData(this.parent, this.gridObj.dataSource as Object[]); } if (this.element.querySelector('.e-content').scrollTop !== 0) { this.gridObj.freezeRefresh(); } } 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.createDragObj(); break; case 'height': this.adjustHeight(); break; case 'detailsViewSettings': if (!isNullOrUndefined(this.gridObj)) { this.checkNameWidth(); const columns: ColumnModel[] = this.getColumns(); this.gridObj.columns = columns; this.gridObj.allowResizing = this.parent.detailsViewSettings.columnResizing; this.gridObj.dataBind(); this.gridObj.refreshColumns(); } break; case 'selectedItems': this.interaction = false; if (this.parent.selectedItems.length !== 0) { if (!this.parent.allowMultiSelection) { const slItems: string[] = this.parent.selectedItems.slice(this.parent.selectedItems.length - 1); this.parent.setProperties({ selectedItems: slItems }, true); } this.selectRecords(this.parent.selectedItems); this.parent.setProperties({ selectedItems: this.parent.selectedItems }, true); } else if (!isNOU(this.gridObj)) { this.gridObj.clearSelection(); this.interaction = true; } break; case 'showFileExtension': read(this.parent, events.pathChanged, this.parent.path); break; case 'showHiddenItems': read(this.parent, events.pathChanged, this.parent.path); break; case 'showItemCheckBoxes': case 'allowMultiSelection': if (!isNullOrUndefined(this.gridObj)) { this.currentSelectedItem = this.parent.selectedItems; this.gridObj.selectionSettings.type = e.newProp.allowMultiSelection ? 'Multiple' : 'Single'; this.isSelectionUpdate = true; this.renderCheckBox(); } break; case 'view': updateLayout(this.parent, 'Details'); break; case 'width': this.onDetailsResize(); } } } private onPathChanged(args: ReadArgs): void { this.parent.isCut = false; const pathField: ColumnModel = this.parent.detailsViewSettings.columns.find((column: ColumnModel) => column.field === 'filterPath'); if ((this.parent.breadcrumbbarModule.searchObj.element.value.trim() === '' && this.gridObj) || (!isNullOrUndefined(pathField) && !isNullOrUndefined(pathField.hideAtMedia) && pathField.hideAtMedia !== '')) { this.parent.searchedItems = []; if (!this.parent.isFiltered) { this.removePathColumn(false); } else { this.updatePathColumn(); } } removeBlur(this.parent); if (this.parent.view === 'Details') { /* istanbul ignore next */ this.isInteracted = false; showSpinner(this.parent.element); this.parent.setProperties({ selectedItems: [] }, true); this.gridObj.dataSource = getSortedData(this.parent, args.files); this.gridObj.freezeRefresh(); if ((this as any).parent.isReact) { this.gridObj.on('reactTemplateRender', this.reactTemplateRender, this); } this.wireClickEvent(true); } this.emptyArgs = args; } private updatePathColumn(): void { const len: number = this.gridObj.columns.length; const columnData: ColumnModel[] = JSON.parse(JSON.stringify(this.gridObj.columns)); if (columnData[len - 1].field && columnData[len - 1].field !== 'filterPath' && !this.parent.isMobile) { const pathColumn: ColumnModel = { field: 'filterPath', headerText: getLocaleText(this.parent, 'Path'), minWidth: 180, width: 'auto' }; (<ColumnModel[]>this.gridObj.columns).push(pathColumn); this.adjustWidth((<Column[]>this.gridObj.columns), 'filterPath'); this.adjustWidth((<Column[]>this.gridObj.columns), 'name'); this.isColumnRefresh = true; this.gridObj.refreshColumns(); } } private checkEmptyDiv(args: ReadArgs | SearchArgs): void { const items: Object[] = getSortedData(this.parent, args.files); if (items.length === 0 && !isNOU(this.element.querySelector('.' + CLS.GRID_VIEW))) { createEmptyElement(this.parent, this.element, args); } else if (items.length !== 0 && this.element.querySelector('.' + CLS.EMPTY)) { if (this.element.querySelector('.' + CLS.GRID_VIEW).querySelector('.' + CLS.EMPTY)) { const emptyDiv: Element = this.element.querySelector('.' + CLS.GRID_VIEW).querySelector('.' + CLS.EMPTY); this.element.querySelector('.' + CLS.GRID_VIEW).removeChild(emptyDiv); } else { this.element.removeChild(this.element.querySelector('.' + CLS.EMPTY)); } } } private onOpenInit(): void { if (this.parent.activeModule === 'detailsview') { const data: Object = this.gridObj.getSelectedRecords()[0]; this.openContent(data); } } public DblClickEvents(args: RecordDoubleClickEventArgs): void { this.gridObj.selectRows([args.rowIndex]); let data: Object; if (args.rowData) { data = JSON.parse(JSON.stringify(args.rowData)); this.openContent(data); } } public openContent(data: Object): void { if (!hasReadAccess(data)) { createDeniedDialog(this.parent, data, events.permissionRead); return; } const eventArgs: FileOpenEventArgs = { cancel: false, fileDetails: data, module: 'DetailsView' }; this.parent.trigger('fileOpen', eventArgs, (fileOpenArgs: FileOpenEventArgs) => { if (!fileOpenArgs.cancel) { const name: string = getValue('name', data); if (getValue('isFile', data)) { const icon: string = fileType(data); if (icon === CLS.ICON_IMAGE) { const imageData: BeforeImageLoadEventArgs = getImageUrl(this.parent, data); createImageDialog(this.parent, name, imageData); } } else { const val: string = this.parent.breadcrumbbarModule.searchObj.element.value; if (val === '' && !this.parent.isFiltered) { const id: string = getValue('id', data); this.parent.oldPath = this.parent.path; const newPath: string = this.parent.path + (isNOU(id) ? name : id) + '/'; this.parent.setProperties({ path: newPath }, true); this.parent.pathNames.push(name); this.parent.pathId.push(getValue('_fm_id', data)); this.parent.itemData = [data]; openAction(this.parent); } else { openSearchFolder(this.parent, data); } this.parent.isFiltered = false; } this.element.focus(); if (this.parent.enableVirtualization ) { (this.parent.element.querySelector('#' + this.parent.element.id + CLS.IMG_DIALOG_ID) as HTMLElement).focus(); } } }); } /* istanbul ignore next */ private onLayoutChange(args: ReadArgs): void { if (this.parent.view === 'Details') { if (this.parent.enableVirtualization) { this.parent.setProperties({ selectedItems: [] }, true); } if (!this.gridObj) { this.render(args); } else { this.isLoaded = true; } if (this.parent.isFiltered) { this.updatePathColumn(); this.parent.setProperties({ selectedItems: [] }, true); } this.gridObj.dataSource = getSortedData(this.parent, args.files); this.parent.notify(events.hideLayout, {}); this.gridObj.element.classList.remove(CLS.DISPLAY_NONE); this.isInteracted = false; this.gridObj.clearSelection(); if (this.parent.breadcrumbbarModule.searchObj.element.value.trim() !== '') { this.onSearchFiles(args); } this.adjustHeight(); if (this.gridObj.sortSettings.columns.length > 0 && this.gridObj.sortSettings.columns[0].field !== this.parent.sortBy) { if (this.parent.sortOrder !== 'None') { this.gridObj.sortColumn(this.parent.sortBy, this.parent.sortOrder); } } } } /* istanbul ignore next */ private onSearchFiles(args: SearchArgs | ReadArgs): void { if (this.parent.view === 'Details') { this.parent.setProperties({ selectedItems: [] }, true); this.parent.notify(events.selectionChanged, {}); if (!this.parent.isLayoutChange) { this.parent.layoutSelectedItems = []; } this.updatePathColumn(); this.parent.searchedItems = args.files; this.onPathChanged(<ReadArgs>args); } } private removePathColumn(isRefresh: boolean): void { const len: number = this.gridObj.columns.length; const columnData: ColumnModel[] = JSON.parse(JSON.stringify(this.gridObj.columns)); const filterPathInSettings: boolean = this.parent.detailsViewSettings.columns.some( (col: ColumnModel) => col.field === 'filterPath' ); if (columnData[len - 1].field && (columnData[len - 1].field === 'filterPath') && !filterPathInSettings) { /* istanbul ignore next */ if (!isNullOrUndefined(this.gridObj.sortSettings.columns[0]) && this.gridObj.sortSettings.columns[0].field === 'filterPath') { if (this.parent.sortOrder !== 'None') { this.gridObj.sortColumn('name', this.parent.sortOrder); } else { this.gridObj.dataSource = getSortedData(this.parent, this.gridObj.dataSource as Object[]); } this.parent.notify(events.sortByChange, {}); } this.gridObj.columns.pop(); if (!isRefresh) { this.isColumnRefresh = true; this.gridObj.refreshColumns(); } } } private onFinalizeEnd(args: ReadArgs): void { if (this.parent.view !== 'Details') { return; } if (!this.gridObj) { this.render(args); } else { this.onPathChanged(args); } } private onCreateEnd(args: ReadArgs): void { if (this.parent.view !== 'Details') { return; } this.onPathChanged(args); } private onRenameInit(): void { if (this.parent.activeModule === 'detailsview' && this.parent.selectedItems.length === 1) { this.updateRenameData(); } } private onSelectedData(): void { if (this.parent.activeModule === 'detailsview') { this.parent.itemData = this.gridObj.getSelectedRecords(); } } private onDeleteInit(): void { if (this.parent.activeModule === 'detailsview') { Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete'); } } /* istanbul ignore next */ private onDeleteEnd(args: ReadArgs): void { if (this.parent.view !== 'Details') { return; } this.onPathChanged(args); this.parent.setProperties({ selectedItems: [] }, true); } private onRefreshEnd(args: ReadArgs): void { if (this.parent.view !== 'Details') { return; } this.isInteracted = false; this.removePathColumn(false); this.gridObj.dataSource = getSortedData(this.parent, args.files); this.emptyArgs = args; } private onHideLayout(): void { if (this.parent.view !== 'Details' && this.gridObj) { this.gridObj.element.classList.add(CLS.DISPLAY_NONE); } } private onSelectAllInit(): void { if (this.parent.view === 'Details') { this.isInteracted = false; if (this.parent.allowMultiSelection) { this.gridObj.selectionModule.selectRowsByRange(0, this.gridObj.getRows().length); } else { this.gridObj.selectRow(this.gridObj.getRows().length - 1); } this.isInteracted = true; this.interaction = true; } } private onClearAllInit(): void { if (this.parent.view === 'Details') { this.removeSelection(); this.interaction = true; } } /* istanbul ignore next */ private onSelectionChanged(): void { removeClass([this.element], CLS.HEADER_CHECK); if (this.parent.selectedItems.length > 0) { addClass([this.element], CLS.HEADER_CHECK); } } private onLayoutRefresh(): void { if (this.parent.view !== 'Details') { return; } this.adjustHeight(); } private onBeforeRequest(): void { this.isRendered = false; } private onAfterRequest(): void { this.isRendered = true; } private onUpdateSelectionData(): void { if (this.parent.view !== 'Details') { return; } this.parent.itemData = this.gridObj.getSelectedRecords(); } private addEventListener(): void { this.parent.on(events.finalizeEnd, this.onFinalizeEnd, this); this.parent.on(events.destroy, this.destroy, this); this.parent.on(events.layoutChange, this.onLayoutChange, this); this.parent.on(events.pathChanged, this.onPathChanged, this); this.parent.on(events.createEnd, this.onCreateEnd, this); this.parent.on(events.dropInit, this.onDropInit, this); this.parent.on(events.detailsInit, this.onDetailsInit, this); this.parent.on(events.refreshEnd, this.onRefreshEnd, this); this.parent.on(events.search, this.onSearchFiles, this); this.parent.on(events.methodCall, this.onMethodCall, this); this.parent.on(events.actionFailure, this.onActionFailure, this); this.parent.on(events.modelChanged, this.onPropertyChanged, this); this.parent.on(events.deleteInit, this.onDeleteInit, this); this.parent.on(events.deleteEnd, this.onDeleteEnd, this); this.parent.on(events.selectedData, this.onSelectedData, this); this.parent.on(events.renameInit, this.onRenameInit, this); this.parent.on(events.renameEnd, this.onPathChanged, this); this.parent.on(events.openInit, this.onOpenInit, this); this.parent.on(events.sortColumn, this.onSortColumn, this); this.parent.on(events.openEnd, this.onPathChanged, this); this.parent.on(events.filterEnd, this.onPathChanged, this); this.parent.on(events.pasteInit, this.onPasteInit, this); this.parent.on(events.hideLayout, this.onHideLayout, this); this.parent.on(events.selectAllInit, this.onSelectAllInit, this); this.parent.on(events.clearAllInit, this.onClearAllInit, this); this.parent.on(events.pathColumn, this.onPathColumn, this); this.parent.on(events.selectionChanged, this.onSelectionChanged, this); this.parent.on(events.beforeRequest, this.onBeforeRequest, this); this.parent.on(events.afterRequest, this.onAfterRequest, this); this.parent.on(events.pasteEnd, this.onpasteEnd, this); this.parent.on(events.cutCopyInit, this.oncutCopyInit, this); this.parent.on(events.menuItemData, this.onMenuItemData, this); this.parent.on(events.resizeEnd, this.onDetailsResizeHandler, this); this.parent.on(events.splitterResize, this.onDetailsResize, this); this.parent.on(events.layoutRefresh, this.onLayoutRefresh, this); this.parent.on(events.dropPath, this.onDropPath, this); this.parent.on(events.updateSelectionData, this.onUpdateSelectionData, this); } private removeEventListener(): void { this.parent.off(events.finalizeEnd, this.onFinalizeEnd); this.parent.off(events.destroy, this.destroy); this.parent.off(events.layoutChange, this.onLayoutChange); this.parent.off(events.pathChanged, this.onPathChanged); this.parent.off(events.pasteInit, this.onPasteInit); this.parent.off(events.createEnd, this.onCreateEnd); this.parent.off(events.refreshEnd, this.onRefreshEnd); this.parent.off(events.search, this.onSearchFiles); this.parent.off(events.methodCall, this.onMethodCall); this.parent.off(events.actionFailure, this.onActionFailure); this.parent.off(events.modelChanged, this.onPropertyChanged); this.parent.off(events.renameInit, this.onRenameInit); this.parent.off(events.renameEnd, this.onPathChanged); this.parent.off(events.filterEnd, this.onPathChanged); this.parent.off(events.openInit, this.onOpenInit); this.parent.off(events.sortColumn, this.onSortColumn); this.parent.off(events.openEnd, this.onPathChanged); this.parent.off(events.hideLayout, this.onHideLayout); this.parent.off(events.selectAllInit, this.onSelectAllInit); this.parent.off(events.clearAllInit, this.onClearAllInit); this.parent.off(events.deleteInit, this.onDeleteInit); this.parent.off(events.deleteEnd, this.onDeleteEnd); this.parent.off(events.pathColumn, this.onPathColumn); this.parent.off(events.selectionChanged, this.onSelectionChanged); this.parent.off(events.beforeRequest, this.onBeforeRequest); this.parent.off(events.afterRequest, this.onAfterRequest); this.parent.off(events.pasteEnd, this.onpasteEnd); this.parent.off(events.cutCopyInit, this.oncutCopyInit); this.parent.off(events.dropInit, this.onDropInit); this.parent.off(events.selectedData, this.onSelectedData); this.parent.off(events.detailsInit, this.onDetailsInit); this.parent.off(events.menuItemData, this.onMenuItemData); this.parent.off(events.resizeEnd, this.onDetailsResizeHandler); this.parent.off(events.splitterResize, this.onDetailsResize); this.parent.off(events.layoutRefresh, this.onLayoutRefresh); this.parent.off(events.dropPath, this.onDropPath); this.parent.off(events.updateSelectionData, this.onUpdateSelectionData); } private onActionFailure(): void { this.interaction = true; } private onMenuItemData(args: { [key: string]: Object; }): void { if (this.parent.activeModule === this.getModuleName()) { this.parent.itemData = [this.gridObj.getRowInfo(<Element>args.target).rowData]; } } private onPasteInit(): void { if (this.parent.activeModule === this.getModuleName()) { this.parent.itemData = (this.parent.folderPath !== '') ? this.gridObj.getSelectedRecords() : [getPathObject(this.parent)]; } } private onDetailsInit(): void { if (this.parent.activeModule === this.getModuleName()) { if (this.parent.selectedItems.length !== 0) { this.parent.itemData = this.gridObj.getSelectedRecords(); } else { this.parent.itemData = [getValue(this.parent.pathId[this.parent.pathId.length - 1], this.parent.feParent)]; } } } public dragHelper(args: { element: HTMLElement, sender: MouseEvent & TouchEvent }): HTMLElement { const dragTarget: Element = <Element>args.sender.target; const dragLi: Element = dragTarget.closest('tr.e-row'); if (!dragLi) { return null; } let name: string; if (<HTMLElement>dragLi.getElementsByClassName('e-fe-text')[0]) { name = this.parent.hasId ? (this.gridObj.getRowInfo(dragLi).rowData as {[key: string]: Object}).id as string : (<HTMLElement>dragLi.getElementsByClassName('e-fe-text')[0]).innerText; } else if (<HTMLElement>dragLi.getElementsByClassName('e-rowcell e-templatecell')[0].nextElementSibling) { name = this.parent.hasId ? (this.gridObj.getRowInfo(dragLi).rowData as { [key: string]: Object }).id as string : (<HTMLElement>dragLi.getElementsByClassName('e-rowcell e-templatecell')[0].nextElementSibling).innerText; } if (dragLi && !dragLi.querySelector('.e-active')) { this.selectRecords([name]); } getModule(this.parent, dragLi); this.parent.activeElements = []; this.parent.dragData = []; this.parent.dragData = <{ [key: string]: Object; }[]>this.gridObj.getSelectedRecords(); let dragRow: { [key: string]: Object; }; if (this.parent.dragData.length === 0 && dragLi) { dragRow = this.gridObj.getRowInfo(dragLi) as { [key: string]: Object; }; } if (dragRow) { this.parent.dragData.push(dragRow.rowData as { [key: string]: Object; }); } this.parent.dragPath = this.parent.path; this.parent.activeElements = this.gridObj.getSelectedRows(); createVirtualDragElement(this.parent); return this.parent.virtualDragElement; } /* istanbul ignore next */ private onDetailsResize(): void { if (this.parent.view === 'Details' && !this.parent.isMobile && !isNOU(this.gridObj)) { const gridHeader: HTMLElement = <HTMLElement>this.gridObj.getHeaderContent().querySelector('.e-headercontent'); const gridHeaderColGroup: HTMLElement = <HTMLElement>gridHeader.firstChild.childNodes[0]; const gridContentColGroup: HTMLElement = <HTMLElement>this.gridObj.getContent().querySelector('.e-content .e-table').children[0]; const gridHeaderColNames: ColumnModel[] = this.gridObj.getColumns();