@syncfusion/ej2-filemanager 24.2.7 → 25.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +6 -25
  2. package/dist/ej2-filemanager.min.js +2 -2
  3. package/dist/ej2-filemanager.umd.min.js +2 -2
  4. package/dist/ej2-filemanager.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-filemanager.es2015.js +213 -51
  6. package/dist/es6/ej2-filemanager.es2015.js.map +1 -1
  7. package/dist/es6/ej2-filemanager.es5.js +222 -54
  8. package/dist/es6/ej2-filemanager.es5.js.map +1 -1
  9. package/dist/global/ej2-filemanager.min.js +2 -2
  10. package/dist/global/ej2-filemanager.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/package.json +16 -16
  13. package/src/file-manager/actions/toolbar.js +16 -5
  14. package/src/file-manager/base/file-manager-model.d.ts +12 -1
  15. package/src/file-manager/base/file-manager.d.ts +11 -0
  16. package/src/file-manager/base/file-manager.js +13 -5
  17. package/src/file-manager/base/interface.d.ts +18 -0
  18. package/src/file-manager/common/operations.js +70 -14
  19. package/src/file-manager/common/utility.d.ts +9 -0
  20. package/src/file-manager/common/utility.js +32 -0
  21. package/src/file-manager/index.d.ts +1 -0
  22. package/src/file-manager/index.js +1 -0
  23. package/src/file-manager/layout/details-view.d.ts +1 -1
  24. package/src/file-manager/layout/details-view.js +71 -24
  25. package/src/file-manager/layout/large-icons-view.d.ts +1 -0
  26. package/src/file-manager/layout/large-icons-view.js +16 -2
  27. package/src/file-manager/layout/navigation-pane.js +0 -1
  28. package/src/file-manager/models/column-model.d.ts +11 -1
  29. package/src/file-manager/models/column.d.ts +10 -0
  30. package/src/file-manager/models/column.js +3 -0
  31. package/src/file-manager/models/details-view-settings.js +1 -3
  32. package/styles/bootstrap-dark.css +1 -2
  33. package/styles/bootstrap.css +1 -2
  34. package/styles/bootstrap4.css +1 -2
  35. package/styles/bootstrap5-dark.css +1 -2
  36. package/styles/bootstrap5.css +1 -2
  37. package/styles/fabric-dark.css +2 -3
  38. package/styles/fabric.css +2 -3
  39. package/styles/file-manager/_bds-definition.scss +234 -0
  40. package/styles/file-manager/_layout.scss +2 -3
  41. package/styles/file-manager/bootstrap-dark.css +1 -2
  42. package/styles/file-manager/bootstrap.css +1 -2
  43. package/styles/file-manager/bootstrap4.css +1 -2
  44. package/styles/file-manager/bootstrap5-dark.css +1 -2
  45. package/styles/file-manager/bootstrap5.css +1 -2
  46. package/styles/file-manager/fabric-dark.css +2 -3
  47. package/styles/file-manager/fabric.css +2 -3
  48. package/styles/file-manager/fluent-dark.css +1 -2
  49. package/styles/file-manager/fluent.css +1 -2
  50. package/styles/file-manager/highcontrast-light.css +1 -2
  51. package/styles/file-manager/highcontrast.css +1 -2
  52. package/styles/file-manager/icons/_bds.scss +235 -0
  53. package/styles/file-manager/material-dark.css +1 -2
  54. package/styles/file-manager/material.css +1 -2
  55. package/styles/file-manager/material3-dark.css +1 -2
  56. package/styles/file-manager/material3.css +1 -2
  57. package/styles/file-manager/tailwind-dark.css +1 -2
  58. package/styles/file-manager/tailwind.css +1 -2
  59. package/styles/fluent-dark.css +1 -2
  60. package/styles/fluent.css +1 -2
  61. package/styles/highcontrast-light.css +1 -2
  62. package/styles/highcontrast.css +1 -2
  63. package/styles/material-dark.css +1 -2
  64. package/styles/material.css +1 -2
  65. package/styles/material3-dark.css +1 -2
  66. package/styles/material3.css +1 -2
  67. package/styles/tailwind-dark.css +1 -2
  68. package/styles/tailwind.css +1 -2
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * filename: index.d.ts
3
- * version : 24.2.7
3
+ * version : 25.1.37
4
4
  * Copyright Syncfusion Inc. 2001 - 2023. All rights reserved.
5
5
  * Use of this code is subject to the terms of our license.
6
6
  * A copy of the current license can be obtained at any time by e-mailing
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "_from": "@syncfusion/ej2-filemanager@*",
3
- "_id": "@syncfusion/ej2-filemanager@24.2.5",
3
+ "_id": "@syncfusion/ej2-filemanager@25.1.35",
4
4
  "_inBundle": false,
5
- "_integrity": "sha512-zyDF9WT2RgiRsPQv58YT6i8DMm09kAWaYSYq0lNqU24nQU4rH0YuoUCDgL8l7HzL7NXxS3vS3V9+yni/LfzP6w==",
5
+ "_integrity": "sha512-fol9PiIpPBAFMKP+iA/DG0Iw5IyqiQvbqbu69lxzxpnZluacXS8A4p22RCJtkYI/UlMzhw6R0Aex8TWl8ljyIg==",
6
6
  "_location": "/@syncfusion/ej2-filemanager",
7
7
  "_phantomChildren": {},
8
8
  "_requested": {
@@ -24,10 +24,10 @@
24
24
  "/@syncfusion/ej2-richtexteditor",
25
25
  "/@syncfusion/ej2-vue-filemanager"
26
26
  ],
27
- "_resolved": "https://nexus.syncfusioninternal.com/repository/ej2-hotfix-new/@syncfusion/ej2-filemanager/-/ej2-filemanager-24.2.5.tgz",
28
- "_shasum": "700c84f2f80033aef46aef2b0a5f1ac0b1d31dbf",
27
+ "_resolved": "https://nexus.syncfusioninternal.com/repository/ej2-hotfix-new/@syncfusion/ej2-filemanager/-/ej2-filemanager-25.1.35.tgz",
28
+ "_shasum": "0f8510ce10d04284efa670551e2181a2a48307e7",
29
29
  "_spec": "@syncfusion/ej2-filemanager@*",
30
- "_where": "/jenkins/workspace/elease-automation_release_24.1.1/packages/included",
30
+ "_where": "/jenkins/workspace/elease-automation_release_25.1.1/packages/included",
31
31
  "author": {
32
32
  "name": "Syncfusion Inc."
33
33
  },
@@ -36,16 +36,16 @@
36
36
  },
37
37
  "bundleDependencies": false,
38
38
  "dependencies": {
39
- "@syncfusion/ej2-base": "~24.2.7",
40
- "@syncfusion/ej2-buttons": "~24.2.7",
41
- "@syncfusion/ej2-data": "~24.2.3",
42
- "@syncfusion/ej2-grids": "~24.2.7",
43
- "@syncfusion/ej2-inputs": "~24.2.7",
44
- "@syncfusion/ej2-layouts": "~24.2.4",
45
- "@syncfusion/ej2-lists": "~24.2.4",
46
- "@syncfusion/ej2-navigations": "~24.2.4",
47
- "@syncfusion/ej2-popups": "~24.2.5",
48
- "@syncfusion/ej2-splitbuttons": "~24.2.7"
39
+ "@syncfusion/ej2-base": "~25.1.35",
40
+ "@syncfusion/ej2-buttons": "~25.1.35",
41
+ "@syncfusion/ej2-data": "~25.1.35",
42
+ "@syncfusion/ej2-grids": "~25.1.37",
43
+ "@syncfusion/ej2-inputs": "~25.1.37",
44
+ "@syncfusion/ej2-layouts": "~25.1.37",
45
+ "@syncfusion/ej2-lists": "~25.1.35",
46
+ "@syncfusion/ej2-navigations": "~25.1.37",
47
+ "@syncfusion/ej2-popups": "~25.1.35",
48
+ "@syncfusion/ej2-splitbuttons": "~25.1.37"
49
49
  },
50
50
  "deprecated": false,
51
51
  "description": "Essential JS 2 FileManager Component",
@@ -75,6 +75,6 @@
75
75
  "url": "git+https://github.com/syncfusion/ej2-javascript-ui-controls.git"
76
76
  },
77
77
  "typings": "index.d.ts",
78
- "version": "24.2.7",
78
+ "version": "25.1.37",
79
79
  "sideEffects": false
80
80
  }
@@ -167,6 +167,7 @@ var Toolbar = /** @class */ (function () {
167
167
  });
168
168
  };
169
169
  Toolbar.prototype.toolbarCreateHandler = function () {
170
+ var _this = this;
170
171
  if (!isNOU(select('#' + this.getId('SortBy'), this.parent.element))) {
171
172
  var items = [
172
173
  { id: this.getPupupId('name'), text: getLocaleText(this.parent, 'Name'),
@@ -193,15 +194,15 @@ var Toolbar = /** @class */ (function () {
193
194
  this.buttonObj.appendTo('#' + this.getId('SortBy'));
194
195
  }
195
196
  if (!isNOU(select('#' + this.getId('View'), this.parent.element))) {
196
- var gridSpan = '<span class="' + CLS.ICON_GRID + ' ' + CLS.MENU_ICON + '"></span>';
197
- var largeIconSpan = '<span class="' + CLS.ICON_LARGE + ' ' + CLS.MENU_ICON + '"></span>';
197
+ var gridSpan_1 = '<span class="' + CLS.ICON_GRID + ' ' + CLS.MENU_ICON + '"></span>';
198
+ var largeIconSpan_1 = '<span class="' + CLS.ICON_LARGE + ' ' + CLS.MENU_ICON + '"></span>';
198
199
  var layoutItems = [
199
200
  {
200
- id: this.getPupupId('large'), text: largeIconSpan + getLocaleText(this.parent, 'View-LargeIcons'),
201
+ id: this.getPupupId('large'), text: getLocaleText(this.parent, 'View-LargeIcons'),
201
202
  iconCss: this.parent.view === 'Details' ? '' : CLS.TB_OPTION_TICK
202
203
  },
203
204
  {
204
- id: this.getPupupId('details'), text: gridSpan + getLocaleText(this.parent, 'View-Details'),
205
+ id: this.getPupupId('details'), text: getLocaleText(this.parent, 'View-Details'),
205
206
  iconCss: this.parent.view === 'Details' ? CLS.TB_OPTION_TICK : ''
206
207
  }
207
208
  ];
@@ -210,7 +211,17 @@ var Toolbar = /** @class */ (function () {
210
211
  cssClass: getCssClass(this.parent, 'e-caret-hide ' + CLS.ROOT_POPUP),
211
212
  items: layoutItems, select: this.layoutChange.bind(this),
212
213
  enableRtl: this.parent.enableRtl,
213
- content: '<span class="e-tbar-btn-text">' + getLocaleText(this.parent, 'View') + '</span>'
214
+ content: '<span class="e-tbar-btn-text">' + getLocaleText(this.parent, 'View') + '</span>',
215
+ beforeItemRender: function (args) {
216
+ var tickIcon = args.item.iconCss;
217
+ var viewText = args.item.text === getLocaleText(_this.parent, 'View-LargeIcons');
218
+ var iconClass = tickIcon ? ' e-menu-icon ' + tickIcon : '';
219
+ args.element.innerHTML = '<span class="' + iconClass + '"></span>' + (viewText ? largeIconSpan_1 : gridSpan_1) + args.item.text;
220
+ var span = args.element.firstChild;
221
+ if (span && span.className === '') {
222
+ args.element.removeChild(span);
223
+ }
224
+ }
214
225
  });
215
226
  this.layoutBtnObj.isStringTemplate = true;
216
227
  this.layoutBtnObj.appendTo('#' + this.getId('View'));
@@ -1,4 +1,4 @@
1
- import { Component, EmitType, ModuleDeclaration, isNullOrUndefined, L10n, closest, Collection } from '@syncfusion/ej2-base';import { Property, INotifyPropertyChanged, NotifyPropertyChanges, Complex, select } from '@syncfusion/ej2-base';import { createElement, addClass, removeClass, setStyleAttribute as setAttr, getUniqueID } from '@syncfusion/ej2-base';import { isNullOrUndefined as isNOU, formatUnit, Browser, KeyboardEvents, KeyboardEventArgs } from '@syncfusion/ej2-base';import { Event, EventHandler, getValue, setValue } from '@syncfusion/ej2-base';import { Splitter, PanePropertiesModel } from '@syncfusion/ej2-layouts';import { Dialog, createSpinner, hideSpinner, showSpinner, BeforeOpenEventArgs, BeforeCloseEventArgs } from '@syncfusion/ej2-popups';import { createDialog, createExtDialog } from '../pop-up/dialog';import { ToolbarSettings, ToolbarSettingsModel, AjaxSettings, NavigationPaneSettings, DetailsViewSettings } from '../models/index';import { ToolbarItem, ToolbarItemModel } from'../models/index' ;import { NavigationPaneSettingsModel, DetailsViewSettingsModel } from '../models/index';import { AjaxSettingsModel, SearchSettings, SearchSettingsModel } from '../models/index';import { Toolbar } from '../actions/toolbar';import { DetailsView } from '../layout/details-view';import { LargeIconsView } from '../layout/large-icons-view';import { Uploader, UploadingEventArgs, SelectedEventArgs, FileInfo, CancelEventArgs } from '@syncfusion/ej2-inputs';import { UploadSettingsModel } from '../models/upload-settings-model';import { UploadSettings } from '../models/upload-settings';import * as events from './constant';import * as CLS from './classes';import { read, filter, createFolder } from '../common/operations';import { ITreeView, IContextMenu, ViewType, SortOrder, FileDragEventArgs, RetryArgs, ReadArgs, FileSelectionEventArgs } from './interface';import { BeforeSendEventArgs, SuccessEventArgs, FailureEventArgs, FileLoadEventArgs } from './interface';import { FileOpenEventArgs, FileSelectEventArgs, MenuClickEventArgs, MenuOpenEventArgs } from './interface';import { ToolbarClickEventArgs, ToolbarCreateEventArgs, UploadListCreateArgs } from './interface';import { PopupOpenCloseEventArgs, BeforePopupOpenCloseEventArgs, BeforeDownloadEventArgs, BeforeImageLoadEventArgs } from './interface';import { refresh, getPathObject, getLocaleText, setNextPath, createDeniedDialog, getCssClass } from '../common/utility';import { hasContentAccess, hasUploadAccess, updateLayout, createNewFolder, uploadItem } from '../common/utility';import { TreeView as BaseTreeView } from '@syncfusion/ej2-navigations';import { ContextMenuSettingsModel } from '../models/contextMenu-settings-model';import { ContextMenuSettings } from '../models/contextMenu-settings';import { BreadCrumbBar } from '../actions/breadcrumb-bar';import { ContextMenu } from '../pop-up/context-menu';import { defaultLocale } from '../models/default-locale';import { PositionModel } from '@syncfusion/ej2-base/src/draggable-model';import { Virtualization } from '../actions/virtualization';
1
+ import { Component, EmitType, ModuleDeclaration, isNullOrUndefined, L10n, closest, Collection } from '@syncfusion/ej2-base';import { Property, INotifyPropertyChanged, NotifyPropertyChanges, Complex, select } from '@syncfusion/ej2-base';import { createElement, addClass, removeClass, setStyleAttribute as setAttr, getUniqueID } from '@syncfusion/ej2-base';import { isNullOrUndefined as isNOU, formatUnit, Browser, KeyboardEvents, KeyboardEventArgs } from '@syncfusion/ej2-base';import { Event, EventHandler, getValue, setValue } from '@syncfusion/ej2-base';import { Splitter, PanePropertiesModel } from '@syncfusion/ej2-layouts';import { Dialog, createSpinner, hideSpinner, showSpinner, BeforeOpenEventArgs, BeforeCloseEventArgs } from '@syncfusion/ej2-popups';import { createDialog, createExtDialog } from '../pop-up/dialog';import { ToolbarSettings, ToolbarSettingsModel, AjaxSettings, NavigationPaneSettings, DetailsViewSettings } from '../models/index';import { ToolbarItem, ToolbarItemModel } from'../models/index' ;import { NavigationPaneSettingsModel, DetailsViewSettingsModel } from '../models/index';import { AjaxSettingsModel, SearchSettings, SearchSettingsModel } from '../models/index';import { Toolbar } from '../actions/toolbar';import { DetailsView } from '../layout/details-view';import { LargeIconsView } from '../layout/large-icons-view';import { Uploader, UploadingEventArgs, SelectedEventArgs, FileInfo, CancelEventArgs } from '@syncfusion/ej2-inputs';import { UploadSettingsModel } from '../models/upload-settings-model';import { UploadSettings } from '../models/upload-settings';import * as events from './constant';import * as CLS from './classes';import { read, filter, createFolder } from '../common/operations';import { ITreeView, IContextMenu, ViewType, SortOrder, FileDragEventArgs, RetryArgs, ReadArgs, FileSelectionEventArgs } from './interface';import { BeforeSendEventArgs, SuccessEventArgs, FailureEventArgs, FileLoadEventArgs } from './interface';import { FileOpenEventArgs, FileSelectEventArgs, MenuClickEventArgs, MenuOpenEventArgs } from './interface';import { ToolbarClickEventArgs, ToolbarCreateEventArgs, UploadListCreateArgs } from './interface';import { PopupOpenCloseEventArgs, BeforePopupOpenCloseEventArgs, BeforeDownloadEventArgs, BeforeImageLoadEventArgs } from './interface';import { refresh, getPathObject, getLocaleText, setNextPath, createDeniedDialog, getCssClass } from '../common/utility';import { hasContentAccess, hasUploadAccess, updateLayout, createNewFolder, uploadItem } from '../common/utility';import { TreeView as BaseTreeView } from '@syncfusion/ej2-navigations';import { ContextMenuSettingsModel } from '../models/contextMenu-settings-model';import { ContextMenuSettings } from '../models/contextMenu-settings';import { BreadCrumbBar } from '../actions/breadcrumb-bar';import { ContextMenu } from '../pop-up/context-menu';import { defaultLocale } from '../models/default-locale';import { PositionModel } from '@syncfusion/ej2-base/src/draggable-model';import { Virtualization } from '../actions/virtualization';import { SortComparer } from './interface';
2
2
  import {ComponentModel} from '@syncfusion/ej2-base';
3
3
 
4
4
  /**
@@ -206,6 +206,17 @@ export interface FileManagerModel extends ComponentModel{
206
206
  */
207
207
  sortBy?: string;
208
208
 
209
+ /**
210
+ * Defines the custom sorting function.
211
+ * The sort comparer function has the same functionality like
212
+ * [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) sort comparer.
213
+ * This can be used to customize the default sorting functionalities with required comparison values.
214
+ *
215
+ * @default null
216
+ * @aspType string
217
+ */
218
+ sortComparer?: SortComparer | string;
219
+
209
220
  /**
210
221
  * Specifies the group of items aligned horizontally in the toolbar.
211
222
  *
@@ -22,6 +22,7 @@ import { ContextMenuSettingsModel } from '../models/contextMenu-settings-model';
22
22
  import { BreadCrumbBar } from '../actions/breadcrumb-bar';
23
23
  import { PositionModel } from '@syncfusion/ej2-base/src/draggable-model';
24
24
  import { Virtualization } from '../actions/virtualization';
25
+ import { SortComparer } from './interface';
25
26
  /**
26
27
  * The FileManager component allows users to access and manage the file system through the web browser. It can performs the
27
28
  * functionalities like add, rename, search, sort, upload and delete files or folders. And also it
@@ -325,6 +326,16 @@ export declare class FileManager extends Component<HTMLElement> implements INoti
325
326
  * @default 'name'
326
327
  */
327
328
  sortBy: string;
329
+ /**
330
+ * Defines the custom sorting function.
331
+ * The sort comparer function has the same functionality like
332
+ * [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) sort comparer.
333
+ * This can be used to customize the default sorting functionalities with required comparison values.
334
+ *
335
+ * @default null
336
+ * @aspType string
337
+ */
338
+ sortComparer: SortComparer | string;
328
339
  /**
329
340
  * Specifies the group of items aligned horizontally in the toolbar.
330
341
  *
@@ -179,31 +179,36 @@ var FileManager = /** @class */ (function (_super) {
179
179
  if (this.toolbarSettings.visible) {
180
180
  modules.push({
181
181
  member: 'toolbar',
182
- args: [this]
182
+ args: [this],
183
+ name: 'Toolbar'
183
184
  });
184
185
  }
185
186
  if (this.navigationPaneSettings.visible) {
186
187
  modules.push({
187
188
  member: 'navigationpane',
188
- args: [this]
189
+ args: [this],
190
+ name: 'NavigationPane'
189
191
  });
190
192
  }
191
193
  if (this.view) {
192
194
  modules.push({
193
195
  member: 'detailsview',
194
- args: [this]
196
+ args: [this],
197
+ name: 'DetailsView'
195
198
  });
196
199
  }
197
200
  if (this.contextMenuSettings.visible && !this.isDevice) {
198
201
  modules.push({
199
202
  member: 'contextmenu',
200
- args: [this]
203
+ args: [this],
204
+ name: 'ContextMenu'
201
205
  });
202
206
  }
203
207
  if (this.enableVirtualization) {
204
208
  modules.push({
205
209
  member: 'virtualization',
206
- args: [this]
210
+ args: [this],
211
+ name: 'Virtualization'
207
212
  });
208
213
  }
209
214
  return modules;
@@ -1216,6 +1221,9 @@ var FileManager = /** @class */ (function (_super) {
1216
1221
  __decorate([
1217
1222
  Property('name')
1218
1223
  ], FileManager.prototype, "sortBy", void 0);
1224
+ __decorate([
1225
+ Property(null)
1226
+ ], FileManager.prototype, "sortComparer", void 0);
1219
1227
  __decorate([
1220
1228
  Complex({}, ToolbarSettings)
1221
1229
  ], FileManager.prototype, "toolbarSettings", void 0);
@@ -14,6 +14,15 @@ import { NavigationPaneSettingsModel } from '../models/navigation-pane-settings-
14
14
  import { Uploader } from '@syncfusion/ej2-inputs';
15
15
  import { BreadCrumbBar, Virtualization } from '../actions';
16
16
  import { PositionModel } from '@syncfusion/ej2-base/src/draggable-model';
17
+ /**
18
+ * ValueType is a type that can be a number, string, Date, or boolean.
19
+ */
20
+ export declare type ValueType = number | string | Date | boolean;
21
+ /**
22
+ * SortComparer is a function type that takes two ValueType arguments and returns a number.
23
+ * The function is used for comparing two values for sorting purposes.
24
+ */
25
+ export declare type SortComparer = (x: ValueType, y: ValueType) => number;
17
26
  /**
18
27
  * Defines the view type of the FileManager.
19
28
  * ```props
@@ -212,6 +221,14 @@ export interface BeforeDownloadEventArgs {
212
221
  * If you want to cancel this event then, set cancel to true. Otherwise, false.
213
222
  */
214
223
  cancel?: boolean;
224
+ /**
225
+ * Return the AJAX details, which are send to server.
226
+ */
227
+ ajaxSettings?: Object;
228
+ /**
229
+ * Specifies whether the download is performed through the form submit method or using an HTTP client instance.
230
+ */
231
+ useFormPost?: boolean;
215
232
  }
216
233
  /**
217
234
  * Interface for BeforeImageLoad event arguments.
@@ -581,6 +598,7 @@ export interface IFileManager extends Component<HTMLElement> {
581
598
  layoutSelectedItems: string[];
582
599
  sortOrder: SortOrder;
583
600
  sortBy: string;
601
+ sortComparer: SortComparer | string;
584
602
  actionRecords: Object[];
585
603
  activeRecords: Object[];
586
604
  pasteNodes: string[];
@@ -1,4 +1,4 @@
1
- import { Ajax, createElement, select, extend, Internationalization } from '@syncfusion/ej2-base';
1
+ import { Ajax, Fetch, createElement, select, extend, Internationalization } from '@syncfusion/ej2-base';
2
2
  import { isNullOrUndefined as isNOU, setValue, getValue } from '@syncfusion/ej2-base';
3
3
  import * as events from '../base/constant';
4
4
  import { createDialog, createExtDialog } from '../pop-up/dialog';
@@ -625,21 +625,77 @@ export function Download(parent, path, items) {
625
625
  var downloadUrl = parent.ajaxSettings.downloadUrl ? parent.ajaxSettings.downloadUrl : parent.ajaxSettings.url;
626
626
  // eslint-disable-next-line
627
627
  var data = { 'action': 'download', 'path': path, 'names': items, 'data': parent.itemData };
628
- var eventArgs = { data: data, cancel: false };
628
+ var ajaxSettings = {
629
+ url: downloadUrl,
630
+ type: 'POST',
631
+ contentType: 'application/json',
632
+ responseType: 'blob',
633
+ data: JSON.stringify(data),
634
+ onSuccess: null,
635
+ onFailure: null,
636
+ beforeSend: null
637
+ };
638
+ var eventArgs = { data: data, cancel: false, useFormPost: true, ajaxSettings: ajaxSettings };
629
639
  parent.trigger('beforeDownload', eventArgs, function (downloadArgs) {
630
640
  if (!downloadArgs.cancel) {
631
- var form = createElement('form', {
632
- id: parent.element.id + '_downloadForm',
633
- attrs: { action: downloadUrl, method: 'post', name: 'downloadForm', 'download': '' }
634
- });
635
- var input = createElement('input', {
636
- id: parent.element.id + '_hiddenForm',
637
- attrs: { name: 'downloadInput', value: JSON.stringify(downloadArgs.data), type: 'hidden' }
638
- });
639
- form.appendChild(input);
640
- parent.element.appendChild(form);
641
- document.forms.namedItem('downloadForm').submit();
642
- parent.element.removeChild(form);
641
+ if (downloadArgs.useFormPost) {
642
+ var form = createElement('form', {
643
+ id: parent.element.id + '_downloadForm',
644
+ attrs: { action: downloadUrl, method: 'post', name: 'downloadForm', 'download': '' }
645
+ });
646
+ var input = createElement('input', {
647
+ id: parent.element.id + '_hiddenForm',
648
+ attrs: { name: 'downloadInput', value: JSON.stringify(downloadArgs.data), type: 'hidden' }
649
+ });
650
+ form.appendChild(input);
651
+ parent.element.appendChild(form);
652
+ document.forms.namedItem('downloadForm').submit();
653
+ parent.element.removeChild(form);
654
+ }
655
+ else {
656
+ var contentDisposition_1;
657
+ var fileName_1;
658
+ var fetch_1 = new Fetch({
659
+ url: getValue('url', downloadArgs.ajaxSettings),
660
+ type: getValue('type', downloadArgs.ajaxSettings),
661
+ contentType: getValue('contentType', downloadArgs.ajaxSettings),
662
+ responseType: getValue('responseType', downloadArgs.ajaxSettings),
663
+ beforeSend: getValue('beforeSend', downloadArgs.ajaxSettings),
664
+ onLoad: function (e) {
665
+ contentDisposition_1 = e.headers.get('Content-Disposition');
666
+ if (contentDisposition_1) {
667
+ var filenameMatch = contentDisposition_1.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
668
+ var extractedFilename = filenameMatch && filenameMatch[1];
669
+ fileName_1 = extractedFilename ? extractedFilename.replace(/['"]/g, '') : fileName_1;
670
+ }
671
+ else {
672
+ fileName_1 = parent.itemData.length > 1 ? 'files.zip' : getValue('isFile', parent.itemData[0]) ? getValue('name', parent.itemData[0]) : getValue('name', parent.itemData[0]) + '.zip';
673
+ }
674
+ },
675
+ onSuccess: function (e) {
676
+ parent.trigger('success', downloadArgs);
677
+ var blob = e;
678
+ var blobUrl = URL.createObjectURL(blob);
679
+ var link = document.createElement('a');
680
+ link.href = blobUrl;
681
+ link.download = fileName_1;
682
+ document.body.appendChild(link);
683
+ link.click();
684
+ document.body.removeChild(link);
685
+ },
686
+ onFailure: function (e) {
687
+ var result = {
688
+ error: {
689
+ code: e.status.toString(),
690
+ message: getLocaleText(parent, 'Network-Error') + ' ' + parent.ajaxSettings.downloadUrl,
691
+ },
692
+ };
693
+ createDialog(parent, 'Error', result);
694
+ parent.trigger('failure', downloadArgs);
695
+ },
696
+ });
697
+ fetch_1.send(JSON.stringify(downloadArgs.data));
698
+ }
643
699
  }
644
700
  });
645
701
  }
@@ -2,6 +2,15 @@ import { IFileManager, ReadArgs, SearchArgs } from '../base/interface';
2
2
  import { Draggable, Internationalization } from '@syncfusion/ej2-base';
3
3
  import { DragEventArgs } from '@syncfusion/ej2-base';
4
4
  import { MenuEventArgs } from '@syncfusion/ej2-navigations';
5
+ /**
6
+ * Utility function to compare two strings in a way similar to Windows Explorer.
7
+ * Files and folders are sorted separately, with folders coming before files.
8
+ *
9
+ * @param {string} reference - The first string to compare. This could be a file or folder name.
10
+ * @param {string} comparer - The second string to compare. This could be a file or folder name.
11
+ * @returns {number} - A negative number if `reference` should come before `comparer`, a positive number if `comparer` should come before `reference`, and 0 if they are considered equal.
12
+ */
13
+ export declare function sortComparer(reference: string, comparer: string): number;
5
14
  /**
6
15
  * Utility file for common actions
7
16
  *
@@ -5,6 +5,38 @@ import { getValue, setValue, isNullOrUndefined as isNOU, matches, select, create
5
5
  import { closest, detach } from '@syncfusion/ej2-base';
6
6
  import { DataManager, Query } from '@syncfusion/ej2-data';
7
7
  import { createDialog } from '../pop-up/dialog';
8
+ /**
9
+ * Utility function to compare two strings in a way similar to Windows Explorer.
10
+ * Files and folders are sorted separately, with folders coming before files.
11
+ *
12
+ * @param {string} reference - The first string to compare. This could be a file or folder name.
13
+ * @param {string} comparer - The second string to compare. This could be a file or folder name.
14
+ * @returns {number} - A negative number if `reference` should come before `comparer`, a positive number if `comparer` should come before `reference`, and 0 if they are considered equal.
15
+ */
16
+ export function sortComparer(reference, comparer) {
17
+ // Check if reference and comparer are files or folders
18
+ var referenceIsFile = /\.\S+/.test(reference);
19
+ var comparerIsFile = /\.\S+/.test(comparer);
20
+ // If one is a file and the other is a folder, the folder should come first
21
+ if (referenceIsFile && !comparerIsFile)
22
+ return 1;
23
+ if (!referenceIsFile && comparerIsFile)
24
+ return -1;
25
+ var referenceParts = [];
26
+ var comparerParts = [];
27
+ (reference + '').replace(/(\d+)|(\D+)/g, function (_, $1, $2) { referenceParts.push([$1 || Infinity, $2 || ""]); return ""; });
28
+ (comparer + '').replace(/(\d+)|(\D+)/g, function (_, $1, $2) { comparerParts.push([$1 || Infinity, $2 || ""]); return ""; });
29
+ // Compare each part of reference and comparer
30
+ while (referenceParts.length && comparerParts.length) {
31
+ var referencePart = referenceParts.shift();
32
+ var comparerPart = comparerParts.shift();
33
+ var comparisonResult = referencePart[0] - comparerPart[0] ||
34
+ referencePart[1].localeCompare(comparerPart[1]);
35
+ if (comparisonResult)
36
+ return comparisonResult;
37
+ }
38
+ return referenceParts.length - comparerParts.length;
39
+ }
8
40
  /**
9
41
  * Utility file for common actions
10
42
  *
@@ -6,3 +6,4 @@ export * from './base';
6
6
  export * from './actions';
7
7
  export * from './layout';
8
8
  export * from './pop-up';
9
+ export * from './common';
@@ -6,3 +6,4 @@ export * from './base';
6
6
  export * from './actions';
7
7
  export * from './layout';
8
8
  export * from './pop-up';
9
+ export * from './common';
@@ -121,9 +121,9 @@ export declare class DetailsView {
121
121
  private wireClickEvent;
122
122
  private removeSelection;
123
123
  private removeFocus;
124
+ private onBlur;
124
125
  private getFocusedItemIndex;
125
126
  private keydownHandler;
126
- actionDivert: boolean;
127
127
  private keyupHandler;
128
128
  gridSelectNodes(): Object[];
129
129
  private doDownload;
@@ -1,7 +1,7 @@
1
1
  import { Grid, Resize, ContextMenu, Sort, VirtualScroll } from '@syncfusion/ej2-grids';
2
2
  import { select, KeyboardEvents, EventHandler, getValue, isNullOrUndefined } from '@syncfusion/ej2-base';
3
3
  import { isNullOrUndefined as isNOU, Touch, setValue, addClass, removeClass } from '@syncfusion/ej2-base';
4
- import { Internationalization, closest, Draggable, initializeCSPTemplate, extend } from '@syncfusion/ej2-base';
4
+ import { Internationalization, closest, Draggable, initializeCSPTemplate, extend, SanitizeHtmlHelper } from '@syncfusion/ej2-base';
5
5
  import { DataManager, Query } from '@syncfusion/ej2-data';
6
6
  import { hideSpinner, showSpinner } from '@syncfusion/ej2-popups';
7
7
  import * as events from '../base/constant';
@@ -40,9 +40,6 @@ var DetailsView = /** @class */ (function () {
40
40
  this.isNameWidth = false;
41
41
  this.pasteOperation = false;
42
42
  this.uploadOperation = false;
43
- /* istanbul ignore next */
44
- // eslint:disable-next-line
45
- this.actionDivert = false;
46
43
  Grid.Inject(Resize, ContextMenu, Sort, VirtualScroll);
47
44
  this.parent = parent;
48
45
  this.element = select('#' + this.parent.element.id + CLS.GRID_ID, this.parent.element);
@@ -203,12 +200,14 @@ var DetailsView = /** @class */ (function () {
203
200
  };
204
201
  DetailsView.prototype.getColumns = function () {
205
202
  var columns;
203
+ var enableHtmlSanitizer = this.parent.enableHtmlSanitizer;
206
204
  if (this.parent.isMobile) {
207
205
  columns = [
208
206
  {
209
207
  field: 'name', headerText: getLocaleText(this.parent, 'Name'), width: 'auto', minWidth: 120, headerTextAlign: 'Left',
210
208
  template: initializeCSPTemplate(function (data) {
211
- return "<div class=\"e-fe-text\">" + data.name + "</div><div class=\"e-fe-date\">" + data._fm_modified + "</div>' +\n '<span class=\"e-fe-size\">" + data.size + "</span>";
209
+ var name = enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(data.name) : data.name;
210
+ return "<div class=\"e-fe-text\">" + name + "</div><div class=\"e-fe-date\">" + data._fm_modified + "</div>' +\n '<span class=\"e-fe-size\">" + data.size + "</span>";
212
211
  })
213
212
  }
214
213
  ];
@@ -216,8 +215,19 @@ var DetailsView = /** @class */ (function () {
216
215
  else {
217
216
  columns = extend([], this.parent.detailsViewSettings.columns, null, true);
218
217
  this.adjustWidth(columns, 'name');
218
+ var _loop_1 = function (i, len) {
219
+ columns[i].headerText = getLocaleText(this_1.parent, columns[i].headerText);
220
+ if (columns[i].field === 'name' && !isNOU(columns[i].template) && !(typeof columns[i].template === 'function')) {
221
+ var template_1 = columns[i].template;
222
+ columns[i].template = initializeCSPTemplate(function (data) {
223
+ var name = enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(data.name) : data.name;
224
+ return template_1.replace(/\${name}/g, name);
225
+ });
226
+ }
227
+ };
228
+ var this_1 = this;
219
229
  for (var i = 0, len = columns.length; i < len; i++) {
220
- columns[i].headerText = getLocaleText(this.parent, columns[i].headerText);
230
+ _loop_1(i, len);
221
231
  }
222
232
  }
223
233
  var iWidth = ((this.parent.isMobile || this.parent.isBigger) ? '54' : '46');
@@ -372,10 +382,14 @@ var DetailsView = /** @class */ (function () {
372
382
  }
373
383
  };
374
384
  DetailsView.prototype.onBeforeDataBound = function (args) {
385
+ var _this = this;
375
386
  showSpinner(this.parent.element);
376
- // eslint-disable-next-line
377
- var items = getSortedData(this.parent, (this.parent.enableVirtualization) ? args.result : this.gridObj.dataSource);
378
- args.result = items;
387
+ var nameColumn = this.parent.detailsViewSettings.columns.find(function (column) { return column.field === _this.parent.sortBy; });
388
+ if (nameColumn && !('sortComparer' in nameColumn)) {
389
+ // eslint-disable-next-line
390
+ var items = getSortedData(this.parent, (this.parent.enableVirtualization) ? args.result : this.gridObj.dataSource);
391
+ args.result = items;
392
+ }
379
393
  };
380
394
  /* istanbul ignore next */
381
395
  DetailsView.prototype.onDataBound = function () {
@@ -1254,12 +1268,14 @@ var DetailsView = /** @class */ (function () {
1254
1268
  eventName: 'keydown'
1255
1269
  });
1256
1270
  EventHandler.add(this.gridObj.element, 'blur', this.removeFocus, this);
1271
+ EventHandler.add(this.parent.element, 'focusout', this.onBlur, this);
1257
1272
  };
1258
1273
  DetailsView.prototype.unWireEvents = function () {
1259
1274
  this.wireClickEvent(false);
1260
1275
  this.keyboardModule.destroy();
1261
1276
  this.keyboardDownModule.destroy();
1262
1277
  EventHandler.remove(this.gridObj.element, 'blur', this.removeFocus);
1278
+ EventHandler.remove(this.parent.element, 'focusout', this.onBlur);
1263
1279
  };
1264
1280
  DetailsView.prototype.wireClickEvent = function (toBind) {
1265
1281
  if (toBind) {
@@ -1309,6 +1325,19 @@ var DetailsView = /** @class */ (function () {
1309
1325
  DetailsView.prototype.removeFocus = function () {
1310
1326
  this.addFocus(null);
1311
1327
  };
1328
+ DetailsView.prototype.onBlur = function (e) {
1329
+ if ((e.relatedTarget !== null && closest(e.relatedTarget, '.e-grid') !== e.relatedTarget)) {
1330
+ return;
1331
+ }
1332
+ if (!isNOU(this.gridObj.element)) {
1333
+ var thElements = this.gridObj.element.querySelectorAll('th');
1334
+ for (var i = 0; i < thElements.length; i++) {
1335
+ if (thElements[i].classList.contains('e-focus')) {
1336
+ this.addFocus(null);
1337
+ }
1338
+ }
1339
+ }
1340
+ };
1312
1341
  DetailsView.prototype.getFocusedItemIndex = function () {
1313
1342
  return (!isNOU(this.getFocusedItem())) ?
1314
1343
  parseInt(this.getFocusedItem().getAttribute('data-rowindex'), 10) : null;
@@ -1357,6 +1386,8 @@ var DetailsView = /** @class */ (function () {
1357
1386
  break;
1358
1387
  }
1359
1388
  };
1389
+ /* istanbul ignore next */
1390
+ // eslint:disable-next-line
1360
1391
  DetailsView.prototype.keyupHandler = function (e) {
1361
1392
  if (!this.isRendered) {
1362
1393
  return;
@@ -1387,7 +1418,15 @@ var DetailsView = /** @class */ (function () {
1387
1418
  this.performDelete();
1388
1419
  break;
1389
1420
  case 'enter':
1390
- if (this.gridObj.selectedRowIndex === -1) {
1421
+ if (this.gridObj.selectedRowIndex === -1 && this.gridObj.allowSorting === true) {
1422
+ if (!e.target.classList.contains('e-fe-grid-icon')) {
1423
+ var direction = !e.target.getElementsByClassName('e-ascending').length ? 'Ascending' : 'Descending';
1424
+ var currentField = this.gridObj.getColumnByUid(e.target.querySelector('.e-headercelldiv').getAttribute('e-mappinguid')).field;
1425
+ this.gridObj.sortColumn(currentField, direction);
1426
+ if (!isNOU(this.getFocusedItem().nextSibling)) {
1427
+ this.getFocusedItem().nextSibling.setAttribute('tabindex', '0');
1428
+ }
1429
+ }
1391
1430
  break;
1392
1431
  }
1393
1432
  rowData = this.gridObj.getRowsObject()[this.gridObj.selectedRowIndex].data;
@@ -1434,13 +1473,8 @@ var DetailsView = /** @class */ (function () {
1434
1473
  else if (this.gridObj.selectedRowIndex !== -1 && e.action === 'tab') {
1435
1474
  return;
1436
1475
  }
1437
- else if (!this.actionDivert) {
1438
- this.addHeaderFocus();
1439
- this.actionDivert = true;
1440
- }
1441
1476
  else {
1442
- this.addFocus(0);
1443
- this.actionDivert = false;
1477
+ this.addHeaderFocus(e);
1444
1478
  }
1445
1479
  }
1446
1480
  break;
@@ -1727,16 +1761,29 @@ var DetailsView = /** @class */ (function () {
1727
1761
  addClass([itemElement], [CLS.FOCUS, CLS.FOCUSED]);
1728
1762
  }
1729
1763
  };
1730
- DetailsView.prototype.addHeaderFocus = function () {
1764
+ DetailsView.prototype.addHeaderFocus = function (e) {
1731
1765
  var treeFocus = select('.e-row', this.element);
1732
1766
  this.gridObj.element.setAttribute('tabindex', '-1');
1733
- var nameFocus = select('th.e-fe-grid-name', this.element);
1734
- nameFocus.setAttribute('tabindex', '0');
1735
- nameFocus.focus();
1736
- addClass([nameFocus], [CLS.FOCUS, CLS.FOCUSED]);
1737
- treeFocus.setAttribute('tabindex', '0');
1738
- if (treeFocus.tabIndex === 0 && nameFocus.tabIndex === 0) {
1739
- removeClass([treeFocus], [CLS.FOCUS, CLS.FOCUSED]);
1767
+ var nameFocus;
1768
+ if (!isNOU(e.target) && e.target.classList.contains('e-defaultcursor')) {
1769
+ this.addFocus(0);
1770
+ nameFocus = e.target.nextElementSibling;
1771
+ }
1772
+ else if (!isNOU(this.gridObj.element.querySelector('.e-focus')) && (this.gridObj.element.querySelector('.e-focus').tagName === 'TH')) {
1773
+ nameFocus = this.gridObj.element.querySelector('.e-focus').nextElementSibling;
1774
+ this.addFocus(0);
1775
+ }
1776
+ else {
1777
+ nameFocus = select('th.e-fe-grid-icon', this.element);
1778
+ }
1779
+ if (!isNOU(nameFocus)) {
1780
+ nameFocus.setAttribute('tabindex', '0');
1781
+ nameFocus.focus();
1782
+ addClass([nameFocus], [CLS.FOCUS, CLS.FOCUSED]);
1783
+ treeFocus.setAttribute('tabindex', '0');
1784
+ if (treeFocus.tabIndex === 0 && nameFocus.tabIndex === 0) {
1785
+ removeClass([treeFocus], [CLS.FOCUS, CLS.FOCUSED]);
1786
+ }
1740
1787
  }
1741
1788
  };
1742
1789
  DetailsView.prototype.getFocusedItem = function () {