@syncfusion/ej2-filemanager 32.2.7 → 33.1.45

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 (45) hide show
  1. package/dist/ej2-filemanager.min.js +2 -2
  2. package/dist/ej2-filemanager.umd.min.js +2 -2
  3. package/dist/ej2-filemanager.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-filemanager.es2015.js +133 -4
  5. package/dist/es6/ej2-filemanager.es2015.js.map +1 -1
  6. package/dist/es6/ej2-filemanager.es5.js +137 -4
  7. package/dist/es6/ej2-filemanager.es5.js.map +1 -1
  8. package/dist/global/ej2-filemanager.min.js +2 -2
  9. package/dist/global/ej2-filemanager.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +11 -11
  12. package/src/file-manager/actions/toolbar.js +8 -0
  13. package/src/file-manager/base/file-manager.d.ts +1 -0
  14. package/src/file-manager/base/file-manager.js +14 -0
  15. package/src/file-manager/base/interface.d.ts +1 -0
  16. package/src/file-manager/layout/details-view.d.ts +10 -1
  17. package/src/file-manager/layout/details-view.js +37 -0
  18. package/src/file-manager/layout/large-icons-view.d.ts +26 -3
  19. package/src/file-manager/layout/large-icons-view.js +68 -0
  20. package/src/file-manager/models/default-locale.js +2 -2
  21. package/src/file-manager/pop-up/context-menu.js +5 -2
  22. package/src/file-manager/pop-up/dialog.js +3 -0
  23. package/styles/bootstrap4-lite.css +5 -1
  24. package/styles/bootstrap4.css +5 -1
  25. package/styles/bootstrap5-dark-lite.css +4 -0
  26. package/styles/bootstrap5-dark.css +4 -0
  27. package/styles/bootstrap5-lite.css +5 -1
  28. package/styles/bootstrap5.css +5 -1
  29. package/styles/file-manager/_bootstrap4-definition.scss +3 -0
  30. package/styles/file-manager/_bootstrap5-dark-definition.scss +3 -0
  31. package/styles/file-manager/_bootstrap5-definition.scss +3 -0
  32. package/styles/file-manager/_fluent2-definition.scss +1 -0
  33. package/styles/file-manager/_theme.scss +10 -1
  34. package/styles/file-manager/bootstrap4.css +5 -1
  35. package/styles/file-manager/bootstrap5-dark.css +4 -0
  36. package/styles/file-manager/bootstrap5.css +5 -1
  37. package/styles/file-manager/fluent2.css +1 -0
  38. package/styles/file-manager/material3-dark.css +0 -5
  39. package/styles/file-manager/material3.css +0 -5
  40. package/styles/fluent2-lite.css +1 -0
  41. package/styles/fluent2.css +1 -0
  42. package/styles/material3-dark-lite.css +0 -5
  43. package/styles/material3-dark.css +0 -5
  44. package/styles/material3-lite.css +0 -5
  45. package/styles/material3.css +0 -5
@@ -3935,6 +3935,9 @@ function triggerPopupOpen(parent, dlgModule, dialogName) {
3935
3935
  function triggerPopupClose(parent, dlgModule, dialogName) {
3936
3936
  const args = { popupModule: dlgModule, element: dlgModule.element, popupName: dialogName };
3937
3937
  parent.trigger('popupClose', args);
3938
+ if (dialogName !== 'Duplicate Items') {
3939
+ parent.restoreFocus();
3940
+ }
3938
3941
  }
3939
3942
  /**
3940
3943
  *
@@ -4815,6 +4818,7 @@ class LargeIconsView {
4815
4818
  this.isInteracted = true;
4816
4819
  this.imageEventArgsMap = new Map();
4817
4820
  this.imageUrlCache = new Map();
4821
+ this.nextFocusIndex = null;
4818
4822
  this.parent = parent;
4819
4823
  this.element = select('#' + this.parent.element.id + LARGEICON_ID, this.parent.element);
4820
4824
  addClass([this.element], LARGE_ICONS);
@@ -5221,6 +5225,13 @@ class LargeIconsView {
5221
5225
  }
5222
5226
  onDeleteInit() {
5223
5227
  if (this.parent.activeModule === 'largeiconsview') {
5228
+ const activeItem = this.getFocusedItem() || this.getActiveItem();
5229
+ if (activeItem) {
5230
+ const index = this.itemList.indexOf(activeItem);
5231
+ if (index !== -1) {
5232
+ this.nextFocusIndex = index;
5233
+ }
5234
+ }
5224
5235
  Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete');
5225
5236
  }
5226
5237
  }
@@ -5231,6 +5242,16 @@ class LargeIconsView {
5231
5242
  }
5232
5243
  this.onLayoutChange(args);
5233
5244
  this.parent.setProperties({ selectedItems: [] }, true);
5245
+ if (typeof this.nextFocusIndex === 'number') {
5246
+ const items = this.element.querySelectorAll('li.e-list-item');
5247
+ if (items.length > 0) {
5248
+ const focusIndex = this.nextFocusIndex >= items.length
5249
+ ? (this.nextFocusIndex === items.length ? items.length - 1 : 0) : this.nextFocusIndex;
5250
+ // eslint-disable-next-line security/detect-object-injection
5251
+ this.addFocus(items[focusIndex]);
5252
+ }
5253
+ this.nextFocusIndex = null;
5254
+ }
5234
5255
  this.clearSelect();
5235
5256
  }
5236
5257
  onRefreshEnd(args) {
@@ -5258,6 +5279,30 @@ class LargeIconsView {
5258
5279
  this.clearSelect();
5259
5280
  this.addSelection(this.parent.renamedItem);
5260
5281
  }
5282
+ let mappedItem = null;
5283
+ if (this.parent._lastFocused && this.parent.pathId && this.parent.pathId.length && this.items && this.itemList) {
5284
+ const key = this.parent.pathId[this.parent.pathId.length - 1];
5285
+ // eslint-disable-next-line security/detect-object-injection
5286
+ const mappedId = this.parent._lastFocused[key];
5287
+ if (mappedId) {
5288
+ let foundIndex = -1;
5289
+ for (let i = 0; i < this.items.length; i++) {
5290
+ // eslint-disable-next-line security/detect-object-injection
5291
+ if (getValue('_fm_id', this.items[i]) === mappedId || (this.parent.hasId && getValue('id', this.items[i]) === mappedId) || getValue('name', this.items[i]) === mappedId) {
5292
+ foundIndex = i;
5293
+ break;
5294
+ }
5295
+ }
5296
+ // eslint-disable-next-line security/detect-object-injection
5297
+ if (foundIndex > -1 && this.itemList[foundIndex]) {
5298
+ mappedItem = this.itemList[foundIndex];
5299
+ }
5300
+ }
5301
+ }
5302
+ const targetItem = this.getFocusedItem() || mappedItem || this.parent.visitedItem || this.getFirstItem();
5303
+ if (targetItem) {
5304
+ this.addFocus(targetItem);
5305
+ }
5261
5306
  }
5262
5307
  }
5263
5308
  onOpenInit(args) {
@@ -5715,6 +5760,9 @@ class LargeIconsView {
5715
5760
  if (!this.parent.isFile) {
5716
5761
  const val = this.parent.breadcrumbbarModule.searchObj.element.value;
5717
5762
  if (val === '' && !this.parent.isFiltered) {
5763
+ if (this.parent.pathId && this.parent.pathId.length) {
5764
+ this.parent._lastFocused = Object.assign(this.parent._lastFocused || {}, { [this.parent.pathId[this.parent.pathId.length - 1]]: getValue('_fm_id', details) || getValue('id', details) || text });
5765
+ }
5718
5766
  const id = getValue('id', details);
5719
5767
  this.parent.oldPath = this.parent.path;
5720
5768
  const newPath = this.parent.path + (isNullOrUndefined(id) ? text : id) + '/';
@@ -5954,12 +6002,26 @@ class LargeIconsView {
5954
6002
  const indexes = this.getIndexes([item], this.parent.hasId);
5955
6003
  return this.itemList[indexes[0]];
5956
6004
  }
6005
+ /**
6006
+ *
6007
+ * Gets the currently focused item element in the large icon view.
6008
+ *
6009
+ * @returns {Element} - The DOM element of the focused item, or null if none is focused.
6010
+ * @hidden
6011
+ */
5957
6012
  getFocusedItem() {
5958
6013
  return select('.' + LIST_ITEM + '.' + FOCUS, this.element);
5959
6014
  }
5960
6015
  getActiveItem() {
5961
6016
  return select('.' + LIST_ITEM + '.' + ACTIVE, this.element);
5962
6017
  }
6018
+ /**
6019
+ *
6020
+ * Gets the first item element in the large icon view.
6021
+ *
6022
+ * @returns {Element} - The DOM element representing the first item in the list.
6023
+ * @hidden
6024
+ */
5963
6025
  getFirstItem() {
5964
6026
  return this.itemList[0];
5965
6027
  }
@@ -6164,6 +6226,14 @@ class LargeIconsView {
6164
6226
  const data = this.getItemObject(item);
6165
6227
  return getItemName(this.parent, data);
6166
6228
  }
6229
+ /**
6230
+ *
6231
+ * Adds focus to the specified item element in the large icon view.
6232
+ *
6233
+ * @param {Element} item - The DOM element representing the item to focus.
6234
+ * @returns {void} - If null or invalid, no focus is applied.
6235
+ * @hidden
6236
+ */
6167
6237
  addFocus(item) {
6168
6238
  this.element.setAttribute('tabindex', '-1');
6169
6239
  const fItem = this.getFocusedItem();
@@ -6918,6 +6988,9 @@ class ContextMenu {
6918
6988
  return;
6919
6989
  }
6920
6990
  });
6991
+ if (!this.isMenuItemClicked && this.menuTarget) {
6992
+ this.parent.restoreFocus();
6993
+ }
6921
6994
  this.menuTarget = null;
6922
6995
  if (!this.isMenuItemClicked && this.parent.pathId.length > 1 && this.parent.activeModule === 'navigationpane') {
6923
6996
  this.parent.pathId.pop();
@@ -7435,11 +7508,11 @@ class ContextMenu {
7435
7508
  id: itemId, text: itemText, iconCss: ICON_UPLOAD,
7436
7509
  items: [
7437
7510
  {
7438
- id: this.getMenuId('folderupload'), text: getLocaleText(this.parent, 'Upload-Folder'),
7511
+ id: this.getMenuId('folderupload'), text: getLocaleText(this.parent, 'Folder'),
7439
7512
  iconCss: !this.parent.uploadObj.directoryUpload ? null : TB_OPTION_TICK
7440
7513
  },
7441
7514
  {
7442
- id: this.getMenuId('fileupload'), text: getLocaleText(this.parent, 'Upload-File'),
7515
+ id: this.getMenuId('fileupload'), text: getLocaleText(this.parent, 'File'),
7443
7516
  iconCss: this.parent.uploadObj.directoryUpload ? null : TB_OPTION_TICK
7444
7517
  }
7445
7518
  ]
@@ -7587,8 +7660,8 @@ const defaultLocale = {
7587
7660
  'None': 'None',
7588
7661
  'View-LargeIcons': 'Large icons',
7589
7662
  'View-Details': 'Details',
7590
- 'Upload-File': 'File',
7591
- 'Upload-Folder': 'Folder',
7663
+ 'File': 'File',
7664
+ 'Folder': 'Folder',
7592
7665
  'Search': 'Search',
7593
7666
  'Button-Ok': 'OK',
7594
7667
  'Button-Cancel': 'Cancel',
@@ -9017,6 +9090,20 @@ let FileManager = FileManager_1 = class FileManager extends Component {
9017
9090
  this.uploadObj.enableRtl = rtl;
9018
9091
  }
9019
9092
  }
9093
+ restoreFocus() {
9094
+ if (this.activeModule === 'detailsview') {
9095
+ if (this.detailsviewModule.gridObj) {
9096
+ this.detailsviewModule.addFocus(this.detailsviewModule.gridObj.selectedRowIndex > -1
9097
+ ? this.detailsviewModule.gridObj.selectedRowIndex : 0);
9098
+ }
9099
+ return;
9100
+ }
9101
+ const targetItem = this.largeiconsviewModule.getFocusedItem()
9102
+ || this.visitedItem || this.largeiconsviewModule.getFirstItem();
9103
+ if (targetItem && this.largeiconsviewModule) {
9104
+ this.largeiconsviewModule.addFocus(targetItem);
9105
+ }
9106
+ }
9020
9107
  };
9021
9108
  __decorate$8([
9022
9109
  Complex({}, AjaxSettings)
@@ -9589,6 +9676,12 @@ class Toolbar {
9589
9676
  items.push(item);
9590
9677
  }
9591
9678
  }
9679
+ for (const item of items) {
9680
+ if (typeof item === 'object' && item !== null && typeof item.template === 'string') {
9681
+ const template = item.template;
9682
+ item.template = template.replace(/>((?:Upload|SortBy|View|Refresh|NewFolder|Cut|Copy|Paste|Delete|Rename|Download|SelectAll|Details))</g, (_match, key) => '>' + getLocaleText(this.parent, key) + '<');
9683
+ }
9684
+ }
9592
9685
  return items;
9593
9686
  }
9594
9687
  getItemModel(propItem) {
@@ -10987,6 +11080,7 @@ class DetailsView {
10987
11080
  this.isMultiSelect = false;
10988
11081
  this.pasteOperation = false;
10989
11082
  this.uploadOperation = false;
11083
+ this.nextFocusIndex = null;
10990
11084
  Grid.Inject(Resize, ContextMenu$2, Sort, VirtualScroll);
10991
11085
  this.parent = parent;
10992
11086
  this.element = select('#' + this.parent.element.id + GRID_ID, this.parent.element);
@@ -11437,6 +11531,13 @@ class DetailsView {
11437
11531
  sortIconElement.classList.remove('e-icon-ascending', 'e-ascending', 'e-icon-descending', 'e-descending');
11438
11532
  }
11439
11533
  }
11534
+ if (typeof this.nextFocusIndex === 'number') {
11535
+ const rowCount = this.gridObj.getRows().length;
11536
+ if (rowCount > 0) {
11537
+ this.addFocus(this.nextFocusIndex >= rowCount ? rowCount : this.nextFocusIndex);
11538
+ }
11539
+ this.nextFocusIndex = null;
11540
+ }
11440
11541
  }
11441
11542
  selectRecords(nodes) {
11442
11543
  const gridRecords = this.gridObj.getCurrentViewRecords();
@@ -11570,6 +11671,21 @@ class DetailsView {
11570
11671
  showSpinner(this.parent.element);
11571
11672
  this.parent.setProperties({ selectedItems: [] }, true);
11572
11673
  this.gridObj.dataSource = getSortedData(this.parent, args.files);
11674
+ if (this.parent._lastFocused && this.parent.pathId && this.parent.pathId.length) {
11675
+ const key = this.parent.pathId[this.parent.pathId.length - 1];
11676
+ // eslint-disable-next-line security/detect-object-injection
11677
+ const mappedId = this.parent._lastFocused[key];
11678
+ if (mappedId) {
11679
+ const gridItems = getSortedData(this.parent, args.files);
11680
+ for (let i = 0; i < gridItems.length; i++) {
11681
+ // eslint-disable-next-line security/detect-object-injection
11682
+ if (getValue('_fm_id', gridItems[i]) === mappedId || (this.parent.hasId && getValue('id', gridItems[i]) === mappedId) || getValue('name', gridItems[i]) === mappedId) {
11683
+ this.nextFocusIndex = i;
11684
+ break;
11685
+ }
11686
+ }
11687
+ }
11688
+ }
11573
11689
  this.gridObj.freezeRefresh();
11574
11690
  if (this.parent.isReact) {
11575
11691
  this.gridObj.on('reactTemplateRender', this.reactTemplateRender, this);
@@ -11640,6 +11756,9 @@ class DetailsView {
11640
11756
  else {
11641
11757
  const val = this.parent.breadcrumbbarModule.searchObj.element.value;
11642
11758
  if (val === '' && !this.parent.isFiltered) {
11759
+ if (this.parent.pathId && this.parent.pathId.length) {
11760
+ this.parent._lastFocused = Object.assign(this.parent._lastFocused || {}, { [this.parent.pathId[this.parent.pathId.length - 1]]: getValue('_fm_id', data) || getValue('id', data) || name });
11761
+ }
11643
11762
  const id = getValue('id', data);
11644
11763
  this.parent.oldPath = this.parent.path;
11645
11764
  const newPath = this.parent.path + (isNullOrUndefined(id) ? name : id) + '/';
@@ -11760,6 +11879,8 @@ class DetailsView {
11760
11879
  }
11761
11880
  onDeleteInit() {
11762
11881
  if (this.parent.activeModule === 'detailsview') {
11882
+ const selectedIndex = this.gridObj.selectedRowIndex;
11883
+ this.nextFocusIndex = selectedIndex >= 0 ? selectedIndex : this.nextFocusIndex;
11763
11884
  Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete');
11764
11885
  }
11765
11886
  }
@@ -12707,6 +12828,14 @@ class DetailsView {
12707
12828
  }
12708
12829
  this.startIndex = this.gridObj.selectedRowIndex;
12709
12830
  }
12831
+ /**
12832
+ * Adds focus to the specified grid row.
12833
+ *
12834
+ * @param {number | null} item - The row index of the item to focus.
12835
+ * If null or invalid, no focus is applied.
12836
+ * @returns {void}
12837
+ * @hidden
12838
+ */
12710
12839
  addFocus(item) {
12711
12840
  const fItem = this.getFocusedItem();
12712
12841
  const itemElement = this.gridObj.getRowByIndex(item);