@syncfusion/ej2-filemanager 29.2.4 → 30.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 (163) hide show
  1. package/.eslintrc.json +2 -0
  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 +181 -20
  6. package/dist/es6/ej2-filemanager.es2015.js.map +1 -1
  7. package/dist/es6/ej2-filemanager.es5.js +182 -20
  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/dist/ts/file-manager/actions/breadcrumb-bar.d.ts +60 -0
  13. package/dist/ts/file-manager/actions/breadcrumb-bar.ts +423 -0
  14. package/dist/ts/file-manager/actions/index.d.ts +6 -0
  15. package/dist/ts/file-manager/actions/index.ts +6 -0
  16. package/dist/ts/file-manager/actions/toolbar.d.ts +54 -0
  17. package/dist/ts/file-manager/actions/toolbar.ts +609 -0
  18. package/dist/ts/file-manager/actions/virtualization.d.ts +93 -0
  19. package/dist/ts/file-manager/actions/virtualization.ts +324 -0
  20. package/dist/ts/file-manager/base/classes.d.ts +224 -0
  21. package/dist/ts/file-manager/base/classes.ts +225 -0
  22. package/dist/ts/file-manager/base/constant.d.ts +136 -0
  23. package/dist/ts/file-manager/base/constant.ts +137 -0
  24. package/dist/ts/file-manager/base/file-manager-model.d.ts +520 -0
  25. package/dist/ts/file-manager/base/file-manager.d.ts +867 -0
  26. package/dist/ts/file-manager/base/file-manager.ts +2061 -0
  27. package/dist/ts/file-manager/base/index.d.ts +8 -0
  28. package/dist/ts/file-manager/base/index.ts +8 -0
  29. package/dist/ts/file-manager/base/interface.d.ts +952 -0
  30. package/dist/ts/file-manager/base/interface.ts +931 -0
  31. package/dist/ts/file-manager/common/index.d.ts +5 -0
  32. package/dist/ts/file-manager/common/index.ts +5 -0
  33. package/dist/ts/file-manager/common/operations.d.ts +122 -0
  34. package/dist/ts/file-manager/common/operations.ts +1369 -0
  35. package/dist/ts/file-manager/common/utility.d.ts +644 -0
  36. package/dist/ts/file-manager/common/utility.ts +1728 -0
  37. package/dist/ts/file-manager/index.d.ts +9 -0
  38. package/dist/ts/file-manager/index.ts +9 -0
  39. package/dist/ts/file-manager/layout/details-view.d.ts +152 -0
  40. package/dist/ts/file-manager/layout/details-view.ts +1990 -0
  41. package/dist/ts/file-manager/layout/index.d.ts +6 -0
  42. package/dist/ts/file-manager/layout/index.ts +6 -0
  43. package/dist/ts/file-manager/layout/large-icons-view.d.ts +157 -0
  44. package/dist/ts/file-manager/layout/large-icons-view.ts +1684 -0
  45. package/dist/ts/file-manager/layout/navigation-pane.d.ts +104 -0
  46. package/dist/ts/file-manager/layout/navigation-pane.ts +919 -0
  47. package/dist/ts/file-manager/models/ajax-settings-model.d.ts +36 -0
  48. package/dist/ts/file-manager/models/ajax-settings.d.ts +30 -0
  49. package/dist/ts/file-manager/models/ajax-settings.ts +39 -0
  50. package/dist/ts/file-manager/models/column-model.d.ts +155 -0
  51. package/dist/ts/file-manager/models/column.d.ts +179 -0
  52. package/dist/ts/file-manager/models/column.ts +216 -0
  53. package/dist/ts/file-manager/models/contextMenu-settings-model.d.ts +36 -0
  54. package/dist/ts/file-manager/models/contextMenu-settings.d.ts +33 -0
  55. package/dist/ts/file-manager/models/contextMenu-settings.ts +44 -0
  56. package/dist/ts/file-manager/models/default-locale.d.ts +4 -0
  57. package/dist/ts/file-manager/models/default-locale.ts +101 -0
  58. package/dist/ts/file-manager/models/details-view-settings-model.d.ts +30 -0
  59. package/dist/ts/file-manager/models/details-view-settings.d.ts +31 -0
  60. package/dist/ts/file-manager/models/details-view-settings.ts +54 -0
  61. package/dist/ts/file-manager/models/index.d.ts +19 -0
  62. package/dist/ts/file-manager/models/index.ts +19 -0
  63. package/dist/ts/file-manager/models/navigation-pane-settings-model.d.ts +40 -0
  64. package/dist/ts/file-manager/models/navigation-pane-settings.d.ts +34 -0
  65. package/dist/ts/file-manager/models/navigation-pane-settings.ts +42 -0
  66. package/dist/ts/file-manager/models/search-settings-model.d.ts +42 -0
  67. package/dist/ts/file-manager/models/search-settings.d.ts +44 -0
  68. package/dist/ts/file-manager/models/search-settings.ts +53 -0
  69. package/dist/ts/file-manager/models/toolbar-settings-model.d.ts +197 -0
  70. package/dist/ts/file-manager/models/toolbar-settings.d.ts +174 -0
  71. package/dist/ts/file-manager/models/toolbar-settings.ts +198 -0
  72. package/dist/ts/file-manager/models/upload-settings-model.d.ts +70 -0
  73. package/dist/ts/file-manager/models/upload-settings.d.ts +61 -0
  74. package/dist/ts/file-manager/models/upload-settings.ts +75 -0
  75. package/dist/ts/file-manager/pop-up/context-menu.d.ts +64 -0
  76. package/dist/ts/file-manager/pop-up/context-menu.ts +693 -0
  77. package/dist/ts/file-manager/pop-up/dialog.d.ts +31 -0
  78. package/dist/ts/file-manager/pop-up/dialog.ts +1009 -0
  79. package/dist/ts/file-manager/pop-up/index.d.ts +5 -0
  80. package/dist/ts/file-manager/pop-up/index.ts +5 -0
  81. package/dist/ts/index.d.ts +4 -0
  82. package/dist/ts/index.ts +4 -0
  83. package/package.json +16 -17
  84. package/src/file-manager/base/interface.d.ts +10 -0
  85. package/src/file-manager/common/operations.d.ts +18 -1
  86. package/src/file-manager/common/operations.js +59 -0
  87. package/src/file-manager/common/utility.d.ts +3 -3
  88. package/src/file-manager/common/utility.js +20 -6
  89. package/src/file-manager/layout/details-view.js +4 -3
  90. package/src/file-manager/layout/large-icons-view.d.ts +3 -0
  91. package/src/file-manager/layout/large-icons-view.js +67 -9
  92. package/src/file-manager/layout/navigation-pane.js +2 -0
  93. package/src/file-manager/pop-up/dialog.d.ts +3 -3
  94. package/src/file-manager/pop-up/dialog.js +34 -6
  95. package/styles/bds-lite.css +51 -1
  96. package/styles/bds.css +51 -1
  97. package/styles/bootstrap-dark-lite.css +51 -0
  98. package/styles/bootstrap-dark.css +51 -0
  99. package/styles/bootstrap-lite.css +51 -0
  100. package/styles/bootstrap.css +51 -0
  101. package/styles/bootstrap4-lite.css +51 -0
  102. package/styles/bootstrap4.css +51 -0
  103. package/styles/bootstrap5-dark-lite.css +51 -1
  104. package/styles/bootstrap5-dark.css +51 -1
  105. package/styles/bootstrap5-lite.css +51 -1
  106. package/styles/bootstrap5.3-lite.css +51 -0
  107. package/styles/bootstrap5.3.css +51 -0
  108. package/styles/bootstrap5.css +51 -1
  109. package/styles/fabric-dark-lite.css +51 -0
  110. package/styles/fabric-dark.css +51 -0
  111. package/styles/fabric-lite.css +51 -0
  112. package/styles/fabric.css +51 -0
  113. package/styles/file-manager/_bds-definition.scss +1 -0
  114. package/styles/file-manager/_bootstrap5-definition.scss +1 -0
  115. package/styles/file-manager/_layout.scss +46 -4
  116. package/styles/file-manager/_material3-definition.scss +2 -2
  117. package/styles/file-manager/_tailwind-definition.scss +1 -0
  118. package/styles/file-manager/_tailwind3-definition.scss +1 -0
  119. package/styles/file-manager/bds.css +51 -1
  120. package/styles/file-manager/bootstrap-dark.css +51 -0
  121. package/styles/file-manager/bootstrap.css +51 -0
  122. package/styles/file-manager/bootstrap4.css +51 -0
  123. package/styles/file-manager/bootstrap5-dark.css +51 -1
  124. package/styles/file-manager/bootstrap5.3.css +51 -0
  125. package/styles/file-manager/bootstrap5.css +51 -1
  126. package/styles/file-manager/fabric-dark.css +51 -0
  127. package/styles/file-manager/fabric.css +51 -0
  128. package/styles/file-manager/fluent-dark.css +51 -0
  129. package/styles/file-manager/fluent.css +51 -0
  130. package/styles/file-manager/fluent2.css +51 -0
  131. package/styles/file-manager/highcontrast-light.css +51 -0
  132. package/styles/file-manager/highcontrast.css +51 -0
  133. package/styles/file-manager/material-dark.css +51 -0
  134. package/styles/file-manager/material.css +51 -0
  135. package/styles/file-manager/material3-dark.css +53 -2
  136. package/styles/file-manager/material3.css +53 -2
  137. package/styles/file-manager/tailwind-dark.css +51 -1
  138. package/styles/file-manager/tailwind.css +51 -1
  139. package/styles/file-manager/tailwind3.css +51 -0
  140. package/styles/fluent-dark-lite.css +51 -0
  141. package/styles/fluent-dark.css +51 -0
  142. package/styles/fluent-lite.css +51 -0
  143. package/styles/fluent.css +51 -0
  144. package/styles/fluent2-lite.css +51 -0
  145. package/styles/fluent2.css +51 -0
  146. package/styles/highcontrast-light-lite.css +51 -0
  147. package/styles/highcontrast-light.css +51 -0
  148. package/styles/highcontrast-lite.css +51 -0
  149. package/styles/highcontrast.css +51 -0
  150. package/styles/material-dark-lite.css +51 -0
  151. package/styles/material-dark.css +51 -0
  152. package/styles/material-lite.css +51 -0
  153. package/styles/material.css +51 -0
  154. package/styles/material3-dark-lite.css +51 -0
  155. package/styles/material3-dark.css +53 -2
  156. package/styles/material3-lite.css +51 -0
  157. package/styles/material3.css +53 -2
  158. package/styles/tailwind-dark-lite.css +51 -1
  159. package/styles/tailwind-dark.css +51 -1
  160. package/styles/tailwind-lite.css +51 -1
  161. package/styles/tailwind.css +51 -1
  162. package/styles/tailwind3-lite.css +51 -0
  163. package/styles/tailwind3.css +51 -0
@@ -0,0 +1,1369 @@
1
+ import { Ajax, Fetch, createElement, select, extend } from '@syncfusion/ej2-base';
2
+ import { isNullOrUndefined as isNOU, setValue, getValue } from '@syncfusion/ej2-base';
3
+ import { IFileManager, ReadArgs, BeforeSendEventArgs, BeforeDownloadEventArgs } from '../base/interface';
4
+ import * as events from '../base/constant';
5
+ import { createDialog, createExtDialog } from '../pop-up/dialog';
6
+ import { FileDetails, FileDragEventArgs, FailureEventArgs, SuccessEventArgs, FolderCreateEventArgs, DeleteEventArgs, RenameEventArgs, MoveEventArgs, SearchEventArgs } from '../../index';
7
+ import { fileType, setNodeId, getLocaleText, setDateObject, doPasteUpdate, getPathObject } from '../common/utility';
8
+ import { generatePath, getAccessDetails, getTargetPath } from '../common/utility';
9
+ import { getUid } from '@syncfusion/ej2-grids';
10
+
11
+ /* eslint-disable @typescript-eslint/no-explicit-any */
12
+ /**
13
+ * Function to read the content from given path in File Manager.
14
+ *
15
+ * @param {IFileManager} parent - specifies the parent element.
16
+ * @param {string} event - specifies the event.
17
+ * @param {string} path - specifies the path.
18
+ * @returns {void}
19
+ * @private
20
+ */
21
+ export function read(parent: IFileManager, event: string, path: string): void {
22
+ const itemData: Object[] = parent.itemData;
23
+ for (let i: number = 0; i < itemData.length; i++) {
24
+ if (isNOU(getValue('hasChild', itemData[i as number]))) { setValue('hasChild', false, itemData[i as number]); }
25
+ }
26
+ const data: Object = { action: 'read', path: path, showHiddenItems: parent.showHiddenItems, data: itemData };
27
+ createAjax(parent, data, readSuccess, event);
28
+ }
29
+
30
+ /**
31
+ * Function to create new folder in File Manager.
32
+ *
33
+ * @param {IFileManager} parent - specifies the parent element.
34
+ * @param {string} itemName - specifies the item name.
35
+ * @returns {void}
36
+ * @private
37
+ */
38
+ export function createFolder(parent: IFileManager, itemName: string): void {
39
+ const data: Object = { action: 'create', path: parent.path, name: itemName, data: parent.itemData };
40
+ createAjax(parent, data, createSuccess, itemName);
41
+ }
42
+
43
+ /**
44
+ * Function to filter the files in File Manager.
45
+ *
46
+ * @param {IFileManager} parent - specifies the parent element.
47
+ * @param {string} event - specifies the event.
48
+ * @returns {void}
49
+ * @private
50
+ */
51
+ export function filter(parent: IFileManager, event: string): void {
52
+ const data: Object = { action: 'filter', path: parent.path, showHiddenItems: parent.showHiddenItems, data: [getPathObject(parent)] };
53
+ let filterData: Object;
54
+ const filterDataVal: Object = parent.filterData ? extend(filterData, data, parent.filterData) : data;
55
+ createAjax(parent, filterDataVal, filterSuccess, event, getValue('action', filterDataVal));
56
+ }
57
+
58
+ /**
59
+ * Function to rename the folder/file in File Manager.
60
+ *
61
+ * @param {IFileManager} parent - specifies the parent element.
62
+ * @param {string} path - specifies the path.
63
+ * @param {string} itemNewName - specifies the item's new name.
64
+ * @returns {void}
65
+ * @private
66
+ */
67
+ export function rename(parent: IFileManager, path: string, itemNewName: string): void {
68
+ let name: string;
69
+ let newName: string;
70
+ if (parent.breadcrumbbarModule.searchObj.element.value === '' && !parent.isFiltered) {
71
+ name = parent.currentItemText;
72
+ newName = itemNewName;
73
+ } else {
74
+ let fPath: string = parent.filterPath;
75
+ if (parent.hasId) {
76
+ name = parent.currentItemText;
77
+ newName = itemNewName;
78
+ } else {
79
+ fPath = fPath.replace(/\\/g, '/');
80
+ name = fPath.replace(path, '') + parent.currentItemText;
81
+ newName = fPath.replace(path, '') + itemNewName;
82
+ }
83
+ }
84
+ const data: Object = {
85
+ action: 'rename', path: path, name: name, newName: newName, data: parent.itemData, showFileExtension: parent.showFileExtension
86
+ };
87
+ createAjax(parent, data, renameSuccess, path);
88
+ }
89
+
90
+
91
+ /**
92
+ * Function to paste file's and folder's in File Manager.
93
+ *
94
+ * @param {IFileManager} parent - specifies the parent element.
95
+ * @param {string} path - specifies the path.
96
+ * @param {string[]} names - specifies the names.
97
+ * @param {string} targetPath - specifies the target path.
98
+ * @param {string} pasteOperation - specifies the paste operation.
99
+ * @param {string[]} renameItems - specifies the rename items.
100
+ * @param {Object[]} actionRecords - specifies the action records.
101
+ * @returns {void}
102
+ * @private
103
+ */
104
+ export function paste(
105
+ parent: IFileManager, path: string, names: string[], targetPath: string, pasteOperation: string,
106
+ renameItems?: string[], actionRecords?: Object[]): void {
107
+ const data: Object = {
108
+ action: pasteOperation, path: path, targetData: parent.itemData[0],
109
+ targetPath: targetPath, names: names, renameFiles: renameItems, data: actionRecords
110
+ };
111
+ parent.destinationPath = targetPath;
112
+ createAjax(parent, data, pasteSuccess, path, pasteOperation, targetPath);
113
+ }
114
+
115
+ /**
116
+ * Function to delete file's and folder's in File Manager.
117
+ *
118
+ * @param {IFileManager} parent - specifies the parent element.
119
+ * @param {string[]} items - specifies the items.
120
+ * @param {string} path - specifies the path.
121
+ * @param {string} operation - specifies the operation.
122
+ * @returns {void}
123
+ * @private
124
+ */
125
+ export function Delete(parent: IFileManager, items: string[], path: string, operation: string): void {
126
+ const data: Object = { action: operation, path: path, names: items, data: parent.itemData };
127
+ createAjax(parent, data, deleteSuccess, path);
128
+ }
129
+
130
+ /* istanbul ignore next */
131
+ /**
132
+ * Function to get details of file's and folder's in File Manager.
133
+ *
134
+ * @param {IFileManager} parent - specifies the parent element.
135
+ * @param {string[]} names - specifies the names.
136
+ * @param {string} path - specifies the path.
137
+ * @param {string} operation - specifies the operation data.
138
+ * @returns {void}
139
+ * @private
140
+ */
141
+ export function GetDetails(parent: IFileManager, names: string[], path: string, operation: string): void {
142
+ const data: Object = { action: operation, path: path, names: names, data: parent.itemData };
143
+ createAjax(parent, data, detailsSuccess, path, operation);
144
+ }
145
+
146
+ /**
147
+ * Checks whether fileSystemData is enabled.
148
+ *
149
+ * @param {IFileManager} parent - specifies the parent element.
150
+ * @returns {boolean} - returns the boolean value.
151
+ */
152
+ export function isFileSystemData(parent: IFileManager): boolean {
153
+ const isFileSystemData: boolean = parent.fileSystemData.length >= 0 && isNOU(parent.ajaxSettings.url);
154
+ return isFileSystemData;
155
+ }
156
+
157
+ /**
158
+ * Function to check whether file already exist or not.
159
+ *
160
+ * @param {Record<string, any>} fileSystemData - specifies the file data.
161
+ * @param {string} name - specifies the name.
162
+ * @returns {boolean} - returns the boolean value.
163
+ * @private
164
+ */
165
+ function isFileExists(fileSystemData: Record<string, any>, name: string): boolean {
166
+ const isExists: boolean = fileSystemData.some((item: { [key: string]: Object; }) => item.name === name);
167
+ return isExists;
168
+ }
169
+
170
+ /**
171
+ * Function to find the index value of a file or folder.
172
+ *
173
+ * @param {IFileManager} parent - specifies the parent element.
174
+ * @param {number} id - specifies the id.
175
+ * @returns {number} - returns the index value.
176
+ * @private
177
+ */
178
+ function findIndexById(parent: IFileManager, id: number): number {
179
+ const index: number = parent.fileSystemData.findIndex(
180
+ (item: { [key: string]: Object; }) =>
181
+ !isNOU(item) && String(item.id) === String(id)
182
+ );
183
+ return index;
184
+ }
185
+
186
+ /**
187
+ * Function to get the entire data of a file or folder using id value.
188
+ *
189
+ * @param {IFileManager} parent - specifies the parent element.
190
+ * @param {number | string} id - specifies the id.
191
+ * @returns {Object} - returns the data.
192
+ * @private
193
+ */
194
+ function filterById(parent: IFileManager, id: number | string): Object {
195
+ const data: Object = parent.fileSystemData.filter((item: { [key: string]: Object; }) => String(item.id) === String(id))[0];
196
+ return data;
197
+ }
198
+
199
+ /**
200
+ * Function to get the entire data of a file or folder for a parent.
201
+ *
202
+ * @param {IFileManager} parent - specifies the parent element.
203
+ * @param {number | string} parentId - specifies the parent id.
204
+ * @returns {Object[]} - returns the data.
205
+ * @private
206
+ */
207
+ function filterByParent(parent: IFileManager, parentId: number | string): Object[] {
208
+ const data: Object[] = parent.fileSystemData.filter((item: { [key: string]: Object; }) => String(item.parentId) === String(parentId));
209
+ return data;
210
+ }
211
+
212
+ /**
213
+ * Function to create a new copied file or folder.
214
+ *
215
+ * @param {Record<string, any>} data - specifies the file or folder data.
216
+ * @param {Record<string, any>} target - specifies the target data.
217
+ * @param {string} itemName - specifies the item name.
218
+ * @param {boolean} isCopy - specifies the copy operation.
219
+ * @returns {Record<string, Object>} - returns the data.
220
+ * @private
221
+ */
222
+ function createNewItem(data: { [key: string]: any }, target: { [key: string]: any },
223
+ itemName: string, isCopy: boolean): Record<string, any> {
224
+ const newItem: Record<string, any> = {};
225
+ //Construct the new folder details.
226
+ for (const key in data) {
227
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
228
+ newItem[key as string] = null;
229
+ }
230
+ }
231
+ const currentDate: Date = new Date();
232
+ const folderPath: string = String(target.id) !== String(0) && !isNOU(target.parentId) ? target.filterPath + target.name + '\\' : '\\';
233
+ Object.assign(newItem, {
234
+ dateCreated: currentDate,
235
+ dateModified: currentDate,
236
+ filterPath: folderPath,
237
+ hasChild: isCopy ? data.hasChild : false,
238
+ id: getUid(itemName === null ? data.name : itemName),
239
+ isFile: isCopy ? data.isFile : false,
240
+ name: itemName === null ? data.name : itemName,
241
+ parentId: target.id,
242
+ size: isCopy ? data.size : 0,
243
+ type: isCopy ? data.type : ''
244
+ });
245
+ if (!isNOU(target.filterId)) {
246
+ Object.assign(newItem, {
247
+ filterId: target.filterId + target.id + '/'
248
+ });
249
+ }
250
+ return newItem;
251
+ }
252
+
253
+ /**
254
+ * Function to create an error response.
255
+ *
256
+ * @param {IFileManager} parent - specifies the parent element.
257
+ * @param {string} message - specifies the error message.
258
+ * @param {string} code - specifies the error code.
259
+ * @param {Object[]} fileName - specifies the file name.
260
+ * @returns {void}
261
+ * @private
262
+ */
263
+ function createErrorObject(parent: IFileManager, message: string, code: string, fileName: Object[]): void {
264
+ parent.responseData = {
265
+ cwd: null,
266
+ details: null,
267
+ error: {
268
+ code: code,
269
+ message: message,
270
+ fileExists: fileName != null ? fileName : null
271
+ },
272
+ files: null
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Function to trigger folder creation.
278
+ *
279
+ * @param {IFileManager} parent - specifies the parent element.
280
+ * @param {Object} data - specifies the data.
281
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
282
+ * @returns {void}
283
+ * @private
284
+ */
285
+ function triggerFolderCreation(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
286
+ const createEventArgs: FolderCreateEventArgs = {
287
+ folderName: getValue('name', data),
288
+ cancel: false,
289
+ path: getValue('path', data),
290
+ parentFolder: getValue('data', data)
291
+ };
292
+ parent.trigger('beforeFolderCreate', createEventArgs, function (args: FolderCreateEventArgs): void {
293
+ if (args.cancel) {
294
+ eventArgs.cancel = true; return;
295
+ }
296
+ if (isFileSystemData(parent)) {
297
+ if (!isFileExists(parent.fileSystemData, args.folderName)) {
298
+ const data: { [key: string]: Object; } = args.parentFolder[0];
299
+ const newObject: { [key: string]: Object; } = createNewItem(data, data, args.folderName, false);
300
+ parent.fileSystemData.push(newObject);
301
+ }
302
+ else {
303
+ const message: string = 'A file or folder with the name ' + args.folderName + ' already exists.';
304
+ createErrorObject(parent, message, '400', null);
305
+ }
306
+ }
307
+ });
308
+ }
309
+
310
+ /**
311
+ * Function to trigger delete operation.
312
+ *
313
+ * @param {IFileManager} parent - specifies the parent element.
314
+ * @param {Object} data - specifies the data.
315
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
316
+ * @returns {void}
317
+ * @private
318
+ */
319
+ function triggerDeleteOperation(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
320
+ const deleteEventArgs: DeleteEventArgs = {
321
+ cancel: false,
322
+ itemData: getValue('data', data),
323
+ path: getValue('path', data)
324
+ };
325
+ parent.trigger('beforeDelete', deleteEventArgs, function (args: DeleteEventArgs): void {
326
+ if (args.cancel) {
327
+ eventArgs.cancel = true; return;
328
+ }
329
+ if (isFileSystemData(parent)) {
330
+ args.itemData.forEach((itemData: any) => {
331
+ const index: number = findIndexById(parent, itemData.id);
332
+ if (index !== -1) {
333
+ parent.fileSystemData.splice(index, 1);
334
+ }
335
+ if (!itemData.isFile) {
336
+ const subItems: { [key: string]: any; } = parent.fileSystemData.filter(function (obj: { [key: string]: any; }): void
337
+ { return obj.filterPath.includes(itemData.name); });
338
+ subItems.forEach((subItem: any) => {
339
+ const index: number = findIndexById(parent, subItem.id);
340
+ if (index !== -1) {
341
+ parent.fileSystemData.splice(index, 1);
342
+ }
343
+ });
344
+ }
345
+ });
346
+ }
347
+ });
348
+ }
349
+
350
+ /**
351
+ * Function to trigger rename operation.
352
+ *
353
+ * @param {IFileManager} parent - specifies the parent element.
354
+ * @param {Object} data - specifies the data.
355
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
356
+ * @returns {void}
357
+ * @private
358
+ */
359
+ function triggerRenameOperation(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
360
+ const renameEventArgs: RenameEventArgs = {
361
+ cancel: false,
362
+ newName: getValue('newName', data),
363
+ itemData: getValue('data', data),
364
+ path: getValue('path', data)
365
+ };
366
+ parent.trigger('beforeRename', renameEventArgs, function (args: RenameEventArgs): void {
367
+ if (args.cancel) {
368
+ eventArgs.cancel = true; return;
369
+ }
370
+ if (isFileSystemData(parent)) {
371
+ if (!isFileExists(parent.fileSystemData, args.newName)) {
372
+ const fileData: { [key: string]: any; } = filterById(parent, (args.itemData[0] as any).id);
373
+ const oldName: string = fileData.name;
374
+ fileData.name = args.newName;
375
+ updateChildrenFilterPath(parent, fileData.id, oldName, args.newName);
376
+ }
377
+ else {
378
+ const message: string = 'Cannot rename' + (args.itemData[0] as { [key: string]: Object; }).name + 'to' + args.newName + ': destination already exists.';
379
+ createErrorObject(parent, message, '400', null);
380
+ }
381
+ }
382
+ });
383
+ }
384
+
385
+ /**
386
+ * Function to update child item filter path.
387
+ *
388
+ * @param {IFileManager} parent - specifies the parent element.
389
+ * @param {string | number} parentId - specifies the parent id.
390
+ * @param {string} oldName - specifies the previous name.
391
+ * @param {string} newName - specifies the new name.
392
+ * @returns {void}
393
+ * @private
394
+ */
395
+ function updateChildrenFilterPath(parent: IFileManager, parentId: string | number, oldName: string, newName: string): void {
396
+ parent.fileSystemData.forEach((item: { [key: string]: any; }) => {
397
+ if (String(item.parentId) === String(parentId)) {
398
+ const oldPath: string = item.filterPath;
399
+ const newPath: string = oldPath.replace(oldName + '\\', newName + '\\');
400
+ item.filterPath = newPath;
401
+ updateChildrenFilterPath(parent, item.id, oldName, newName);
402
+ }
403
+ });
404
+ }
405
+
406
+ /**
407
+ * Function to trigger move or copy operation.
408
+ *
409
+ * @param {IFileManager} parent - specifies the parent element.
410
+ * @param {Object} data - specifies the data.
411
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
412
+ * @returns {void}
413
+ * @private
414
+ */
415
+ function triggerMoveOrCopyOperation(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
416
+ const moveEventArgs: MoveEventArgs = {
417
+ cancel: false,
418
+ itemData: getValue('data', data),
419
+ isCopy: getValue('action', data) === 'copy' ? true : false,
420
+ path: getValue('path', data),
421
+ targetData: getValue('targetData', data),
422
+ targetPath: getValue('targetPath', data)
423
+ };
424
+ parent.trigger('beforeMove', moveEventArgs, function (args: MoveEventArgs): void {
425
+ if (args.cancel) {
426
+ eventArgs.cancel = true; return;
427
+ }
428
+ if (isFileSystemData(parent)) {
429
+ const message: string = 'File Already Exists';
430
+ const action: string = getValue('action', data);
431
+ const itemPermission: string = getAccessDetails(parent, args.itemData, action, false);
432
+ const pathPermission: string = getAccessDetails(parent, [args.targetData], action, true);
433
+ const file: Object[] = [];
434
+ parent.pasteNodes = [];
435
+ if (itemPermission === '' && pathPermission === '') {
436
+ if (args.isCopy) {
437
+ const folderSubItems: Object[] = filterByParent(parent, (args.targetData as any).id);
438
+ const copiedFolders: { [key: string]: Object; }[] = args.itemData;
439
+ copiedFolders.forEach((itemData: any) => {
440
+ if (!isFileExists(folderSubItems, itemData.name) || getValue('renameFiles', data).length > 0) {
441
+ if (getValue('renameFiles', data).length > 0) {
442
+ const names: string[] = itemData.name.split('.');
443
+ const name: string = itemData.name.includes('.') ? names[0] + '(' + parent.existingFileCount + ').' + names[1] : names[0] + '(' + parent.existingFileCount + ')';
444
+ copyFolderItems(parent, itemData, args.targetData, name);
445
+ parent.responseData.error = null;
446
+ parent.existingFileCount++;
447
+ return;
448
+ }
449
+ copyFolderItems(parent, itemData, args.targetData, null);
450
+ }
451
+ else {
452
+ file.push(itemData.name);
453
+ }
454
+ });
455
+ if (file.length > 0) {
456
+ createErrorObject(parent, message, '400', file);
457
+ }
458
+ return;
459
+ }
460
+ let target: { [key: string]: any; } = args.targetData;
461
+ const getTargetFiles: Object[] = filterByParent(parent, target.id);
462
+ for (let i: number = 0; i < args.itemData.length; i++) {
463
+ const currItem: { [key: string]: any; } = args.itemData[i as number];
464
+ if (!isFileExists(getTargetFiles, currItem.name) || getValue('renameFiles', data).length > 0) {
465
+ if (!target.hasChild) {
466
+ target.hasChild = !currItem.isFile;
467
+ const targetItem: { [key: string]: Object; }[] = parent.fileSystemData
468
+ .filter((item: { [key: string]: Object; }) => String(item.id) === String(target.id));
469
+ if (targetItem.length > 0) {
470
+ targetItem[0].hasChild = target.hasChild;
471
+ }
472
+ }
473
+ if (!currItem.isFile) {
474
+ //Check whether the source folder include other sub folders or not.
475
+ const subItems: Object[] = currItem.parentId !== 0
476
+ ? filterByParent(parent, currItem.parentId) : [];
477
+ const itemData: any = filterById(parent, currItem.parentId);
478
+ itemData.hasChild = subItems.length > 1 ? true : false;
479
+ }
480
+ const fileData: any = filterById(parent, currItem.id);
481
+ if (getValue('renameFiles', data).length > 0) {
482
+ const names: string[] = currItem.name.split('.');
483
+ currItem.name = currItem.name.includes('.') ? names[0] + '(' + parent.existingFileCount + ').' + names[1] : names[0] + '(' + parent.existingFileCount + ')';
484
+ fileData.name = currItem.name;
485
+ parent.responseData.error = null;
486
+ parent.existingFileCount++;
487
+ parent.dropData = target;
488
+ parent.dropPath = args.path;
489
+ const pathArray: string[] = args.targetPath.replace(/^\/|\/$/g, '').split('/');
490
+ target = filterById(parent, pathArray[pathArray.length - 1]);
491
+ }
492
+ fileData.parentId = target.id;
493
+ fileData.filterPath = target.id === 0 ? '\\' : target.filterPath + target.name + '\\';
494
+ if (!isNOU(target.filterId)) {
495
+ fileData.filterId = target.filterId + target.id + '/';
496
+ }
497
+ if (!currItem.isFile) {
498
+ updateMovedItemChildren(parent, fileData);
499
+ }
500
+ }
501
+ else {
502
+ file.push(currItem.name);
503
+ }
504
+ }
505
+ if (file.length > 0) {
506
+ createErrorObject(parent, message, '400', file);
507
+ }
508
+ }
509
+ }
510
+ });
511
+ }
512
+
513
+ /**
514
+ * Function to trigger search operation.
515
+ *
516
+ * @param {IFileManager} parent - specifies the parent element.
517
+ * @param {Object} data - specifies the data.
518
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
519
+ * @returns {void}
520
+ * @private
521
+ */
522
+ function triggerSearchOperation(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
523
+ const searchEventArgs: SearchEventArgs = {
524
+ searchResults: getValue('data', data),
525
+ cancel: false,
526
+ path: getValue('path', data),
527
+ searchText: getValue('searchString', data),
528
+ caseSensitive: getValue('caseSensitive', data),
529
+ showHiddenItems: getValue('showHiddenItems', data)
530
+ };
531
+ parent.trigger('search', searchEventArgs, function (args: SearchEventArgs): void {
532
+ setValue('data', args.searchResults, data);
533
+ if (args.cancel) {
534
+ eventArgs.cancel = true;
535
+ }
536
+ });
537
+ }
538
+
539
+ /**
540
+ * Function to trigger client side events.
541
+ *
542
+ * @param {IFileManager} parent - specifies the parent element.
543
+ * @param {Object} data - specifies the data.
544
+ * @param {BeforeSendEventArgs} eventArgs - specifies the eventArgs.
545
+ * @returns {void}
546
+ * @private
547
+ */
548
+ function triggerClientEvents(parent: IFileManager, data: Object, eventArgs: BeforeSendEventArgs): void {
549
+ switch (getValue('action', data)) {
550
+ case 'create': {
551
+ triggerFolderCreation(parent, data, eventArgs);
552
+ break;
553
+ }
554
+ case 'delete': {
555
+ triggerDeleteOperation(parent, data, eventArgs);
556
+ break;
557
+ }
558
+ case 'rename': {
559
+ triggerRenameOperation(parent, data, eventArgs);
560
+ break;
561
+ }
562
+ case 'move':
563
+ case 'copy': {
564
+ triggerMoveOrCopyOperation(parent, data, eventArgs);
565
+ break;
566
+ }
567
+ case 'search': {
568
+ triggerSearchOperation(parent, data, eventArgs);
569
+ break;
570
+ }
571
+ }
572
+ }
573
+ /**
574
+ * Creates an AJAX request for the file manager.
575
+ *
576
+ * @param {IFileManager} parent - The parent file manager instance.
577
+ * @param {Object} data - The data object for the AJAX request.
578
+ * @param {Function} fn - The callback function to be executed after the AJAX request.
579
+ * @param {string} [event] - The event type for the AJAX request.
580
+ * @param {string} [operation] - The operation type for the AJAX request.
581
+ * @param {string} [targetPath] - The target path for the AJAX request.
582
+ * @returns {void}
583
+ * @private
584
+ */
585
+ function createAjax(
586
+ parent: IFileManager, data: Object, fn: Function, event?: string,
587
+ operation?: string, targetPath?: string): void {
588
+ const ajaxSettings: Object = {
589
+ url: parent.ajaxSettings.url,
590
+ type: 'POST',
591
+ mode: true,
592
+ dataType: 'json',
593
+ contentType: 'application/json',
594
+ data: JSON.stringify(data),
595
+ onSuccess: null,
596
+ onFailure: null,
597
+ beforeSend: null
598
+ };
599
+ const eventArgs: BeforeSendEventArgs = { action: getValue('action', data), ajaxSettings: ajaxSettings, cancel: false };
600
+ triggerClientEvents(parent, data, eventArgs);
601
+ parent.trigger('beforeSend', eventArgs, (beforeSendArgs: BeforeSendEventArgs) => {
602
+ if (!beforeSendArgs.cancel) {
603
+ parent.notify(events.beforeRequest, {});
604
+ if (isFileSystemData(parent)) {
605
+ const filePath: string = event === 'node-expand' || event === 'finalize-end' || event === 'rename-end-parent'
606
+ ? getValue('path', data) : parent.path;
607
+ const pathArray: string[] = filePath.replace(/^\/|\/$/g, '').split('/');
608
+ const idValue: string = event === 'rename-end-parent' || (event === 'path-changed' && getValue('data', data).length !== 0 && isNOU(parent.renamedItem))
609
+ ? getValue('data', data)[0].id : pathArray[pathArray.length - 1];
610
+ const action: string = getValue('action', data);
611
+ const isFileOperation: boolean = (action === 'move' || action === 'rename' || action === 'copy' || action === 'delete' || action === 'search') && event !== 'rename-end';
612
+ if (action === 'read' || action === 'create' || event === 'rename-end') {
613
+ const rootId: number | string = parent.fileSystemData
614
+ .filter((item: { [key: string]: Object; }) => isNOU(item.parentId))
615
+ .length > 0
616
+ ? parent.fileSystemData
617
+ .filter((item: { [key: string]: Object; }) => isNOU(item.parentId))[0].id as number | string
618
+ : 0;
619
+ parent.responseData = {
620
+ cwd: filterById(parent, parent.path === '/' && event !== 'node-expand' && event !== 'rename-end-parent' ? rootId : idValue),
621
+ details: null,
622
+ error: null,
623
+ files: filterByParent(parent, parent.path === '/' && event !== 'node-expand' && event !== 'rename-end-parent' ? rootId : idValue)
624
+ };
625
+ if (isNOU(parent.responseData.cwd)) {
626
+ const message: string = 'Cannot load empty data within the File Manager.';
627
+ createErrorObject(parent, message, '400', null);
628
+ }
629
+ }
630
+ else if (isFileOperation && parent.responseData.error === null) {
631
+ let itemData: Object[] = action === 'search' || action === 'delete' ? getValue('data', data) : [];
632
+ if (itemData.length === 0) {
633
+ if (action === 'copy') {
634
+ itemData = parent.pasteNodes.map((item: number | string) => filterById(parent, item));
635
+ }
636
+ else {
637
+ itemData = getValue('data', data).map((item: any) => filterById(parent, item.id));
638
+ }
639
+ }
640
+ parent.responseData = {
641
+ cwd: null,
642
+ details: null,
643
+ error: null,
644
+ files: itemData
645
+ };
646
+ }
647
+ else if (getValue('action', data) === 'details') {
648
+ const itemData: { [key: string]: any } = getValue('data', data);
649
+ const details: { [key: string]: any } = itemData[0];
650
+ const isMultipleFiles: boolean = itemData.length > 1;
651
+ const itemNames: string[] = itemData.map((item: { [key: string]: any }) => item.name);
652
+ const totalSize: string = isMultipleFiles ? getSize(itemData.reduce(
653
+ (accumulator: number, currentObject: any) => accumulator + (currentObject.size || 0), 0)) : getSize(details.size);
654
+ const path: string | string[] = ((parent.pathNames as any).includes(details.name) || isMultipleFiles ? parent.pathNames.join('/') : parent.pathNames.join('/') + '/' + details.name);
655
+ parent.responseData.details = Object.assign({
656
+ location: path,
657
+ multipleFiles: isMultipleFiles,
658
+ name: itemNames.join(', '),
659
+ size: totalSize
660
+ }, isMultipleFiles ? {} : {
661
+ created: details.dateCreated,
662
+ isFile: details.isFile,
663
+ modified: details.dateModified,
664
+ permission: details.permission
665
+ });
666
+ }
667
+ performReadOperation(parent, parent.responseData, fn, data, event, operation, targetPath, beforeSendArgs);
668
+ return;
669
+ }
670
+ const ajax: Ajax = new Ajax({
671
+ url: getValue('url', beforeSendArgs.ajaxSettings),
672
+ type: getValue('type', beforeSendArgs.ajaxSettings),
673
+ mode: getValue('mode', beforeSendArgs.ajaxSettings),
674
+ dataType: getValue('dataType', beforeSendArgs.ajaxSettings),
675
+ contentType: getValue('contentType', beforeSendArgs.ajaxSettings),
676
+ data: getValue('data', beforeSendArgs.ajaxSettings),
677
+ beforeSend: getValue('beforeSend', beforeSendArgs.ajaxSettings),
678
+ onSuccess: (result: ReadArgs) => {
679
+ if (isNOU(result)) {
680
+ const result: ReadArgs = {
681
+ error: {
682
+ fileExists: null,
683
+ message: getLocaleText(parent, 'Server-Error') + ' ' + parent.ajaxSettings.url,
684
+ code: '406'
685
+ },
686
+ files: null
687
+ };
688
+ triggerAjaxFailure(parent, beforeSendArgs, fn, result, event, operation, targetPath);
689
+ return;
690
+ }
691
+ if (typeof (result) === 'string') {
692
+ result = JSON.parse(result);
693
+ }
694
+ performReadOperation(parent, result, fn, data, event, operation, targetPath, beforeSendArgs);
695
+ },
696
+ onFailure: () => {
697
+ const result: ReadArgs = {
698
+ files: null,
699
+ error: {
700
+ code: '404',
701
+ message: getLocaleText(parent, 'Network-Error') + ' ' + parent.ajaxSettings.url,
702
+ fileExists: null
703
+ }
704
+ };
705
+ triggerAjaxFailure(parent, beforeSendArgs, fn, result, event, operation, targetPath);
706
+ }
707
+ });
708
+ ajax.send();
709
+ }
710
+ });
711
+ }
712
+
713
+ /**
714
+ * Function to get file size.
715
+ *
716
+ * @param {number} size - specifies the size.
717
+ * @returns {string} - returns the size.
718
+ * @private
719
+ */
720
+ function getSize(size: number): string {
721
+ let hz: string;
722
+ if (size < 1024) {hz = size + ' B'; }
723
+ else if (size < 1024 * 1024) {hz = (size / 1024).toFixed(2) + ' KB'; }
724
+ else if (size < 1024 * 1024 * 1024) {hz = (size / 1024 / 1024).toFixed(2) + ' MB'; }
725
+ else {hz = (size / 1024 / 1024 / 1024).toFixed(2) + ' GB'; }
726
+ return hz;
727
+ }
728
+
729
+ /**
730
+ * Function to perform read operation.
731
+ *
732
+ * @param {IFileManager} parent - specifies the parent element.
733
+ * @param {ReadArgs} result - specifies the result.
734
+ * @param {Function} fn - specifies the function.
735
+ * @param {Object} data - specifies the data.
736
+ * @param {string} event - specifies the event.
737
+ * @param {string} operation - specifies the operation.
738
+ * @param {string} targetPath - specifies the targetPath.
739
+ * @param {BeforeSendEventArgs} beforeSendArgs - specifies the eventArgs.
740
+ * @returns {void}
741
+ * @private
742
+ */
743
+ function performReadOperation(
744
+ parent: IFileManager, result: ReadArgs, fn: Function, data: Object, event?: string,
745
+ operation?: string, targetPath?: string, beforeSendArgs?: BeforeSendEventArgs): void {
746
+ parent.notify(events.afterRequest, { action: 'success' });
747
+ const id: string = parent.expandedId ? parent.expandedId : parent.pathId[parent.pathId.length - 1];
748
+ if (!isNOU(result.cwd) && (getValue('action', data) === 'read')) {
749
+ result.cwd.name = (parent.pathId.length === 1) ? (parent.rootAliasName || result.cwd.name) : result.cwd.name;
750
+ setValue('_fm_id', id, result.cwd);
751
+ setValue(id, result.cwd, parent.feParent);
752
+ if (!isNOU(result.files) || result.error.code === '401') {
753
+ if ((event === 'finalize-end' || event === 'initial-end') && parent.pathNames.length === 0) {
754
+ const root: Object = getValue(parent.pathId[0], parent.feParent);
755
+ parent.pathNames[0] = getValue('name', root);
756
+ parent.hasId = !isNOU(getValue('id', root));
757
+ }
758
+ if (event === 'finalize-end') {
759
+ generatePath(parent);
760
+ }
761
+ }
762
+ }
763
+ if (!isNOU(result.files)) {
764
+ setDateObject(result.files);
765
+ for (let i: number = 0, len: number = result.files.length; i < len; i++) {
766
+ const item: Object = result.files[i as number];
767
+ setValue('_fm_iconClass', fileType(item), item);
768
+ }
769
+ if (getValue('action', data) === 'read') {
770
+ setNodeId(result, id);
771
+ setValue(id, result.files, parent.feFiles);
772
+ }
773
+ }
774
+ if (!isNOU(result.details) && !isNOU(parent.rootAliasName)) {
775
+ const rootName: string = parent.rootAliasName || getValue('name', result.details);
776
+ let location: string = getValue('location', result.details).replace(new RegExp('/', 'g'), '\\');
777
+ if ((getValue('path', data) === '/') || (parent.hasId && getValue('path', data).match(/[/]/g).length === 1)) {
778
+ if (getValue('names', data).length === 0) {
779
+ setValue('name', rootName, result.details);
780
+ }
781
+ if (location.indexOf('\\') === -1) {
782
+ location = rootName;
783
+ }
784
+ else {
785
+ location = location.replace(location.substring(0, location.indexOf('\\')), rootName);
786
+ }
787
+ } else {
788
+ location = location.replace(location.substring(0, location.indexOf('\\')), rootName);
789
+ }
790
+ setValue('location', location, result.details);
791
+ }
792
+ fn(parent, result, event, operation, targetPath);
793
+ if (!isNOU(result.files) && (event === 'path-changed' || event === 'finalize-end' || event === 'open-end' || event === 'drop-path')) {
794
+ parent.notify(events.searchTextChange, result);
795
+ }
796
+ if (typeof getValue('onSuccess', beforeSendArgs.ajaxSettings) === 'function') {
797
+ getValue('onSuccess', beforeSendArgs.ajaxSettings)();
798
+ }
799
+ }
800
+
801
+ /**
802
+ * Function to copy operation.
803
+ *
804
+ * @param {IFileManager} parent - specifies the parent element.
805
+ * @param {Object} data - specifies the data.
806
+ * @param {string} target - specifies the target.
807
+ * @param {string} itemName - specifies the item name.
808
+ * @returns {void}
809
+ * @private
810
+ */
811
+ function copyFolderItems(parent: IFileManager, data: { [key: string]: any }, target: { [key: string]: any }, itemName: string): void {
812
+ const newObject: { [key: string]: any } = createNewItem(data, target, itemName, true);
813
+ parent.fileSystemData.push(newObject);
814
+ parent.pasteNodes.push(newObject.id);
815
+ const copiedItems: Object[] = filterByParent(parent, data.id);
816
+ for (let i: number = 0; i < copiedItems.length; i++) {
817
+ copyFolderItems(parent, copiedItems[i as number], newObject, null);
818
+ }
819
+ }
820
+ /**
821
+ * Function to move operation.
822
+ *
823
+ * @param {IFileManager} parent - specifies the parent element.
824
+ * @param {Object} itemData - specifies the data.
825
+ * @returns {void}
826
+ * @private
827
+ */
828
+ function updateMovedItemChildren(parent: IFileManager, itemData: { [key: string]: any }): void {
829
+ const childItems: Object[] = filterByParent(parent, itemData.id);
830
+ childItems.forEach((childItem: any) => {
831
+ childItem.filterPath = itemData.filterPath + itemData.name + '\\';
832
+ if (!isNOU(itemData.filterId)) {
833
+ childItem.filterId = itemData.filterId + itemData.id + '/';
834
+ }
835
+ if (!childItem.isFile) {
836
+ updateMovedItemChildren(parent, childItem);
837
+ }
838
+ });
839
+ }
840
+ /**
841
+ * Function for trigger Ajax failure in File Manager.
842
+ *
843
+ * @param {IFileManager} parent - specifies the parent element.
844
+ * @param {BeforeSendEventArgs} beforeSendArgs - specifies the beforeSendArgs.
845
+ * @param {Function} fn - specifies the function.
846
+ * @param {ReadArgs} result - specifies the result.
847
+ * @param {string} event - specifies the event.
848
+ * @param {string} operation - specifies the operation.
849
+ * @param {string} targetPath - specifies the targetPath.
850
+ * @returns {void}
851
+ * @private
852
+ */
853
+ function triggerAjaxFailure(
854
+ parent: IFileManager, beforeSendArgs: BeforeSendEventArgs, fn: Function,
855
+ result: ReadArgs, event?: string, operation?: string, targetPath?: string): void {
856
+ parent.notify(events.afterRequest, { action: 'failure' });
857
+ fn(parent, result, event, operation, targetPath);
858
+ if (typeof getValue('onFailure', beforeSendArgs.ajaxSettings) === 'function') {
859
+ getValue('onFailure', beforeSendArgs.ajaxSettings)();
860
+ }
861
+ }
862
+
863
+ /**
864
+ * Function for read success in File Manager.
865
+ *
866
+ * @param {IFileManager} parent - specifies the parent element.
867
+ * @param {ReadArgs} result - specifies the result.
868
+ * @param {string} event - specifies the event.
869
+ * @returns {void}
870
+ * @private
871
+ */
872
+ function readSuccess(parent: IFileManager, result: ReadArgs, event: string): void {
873
+ try {
874
+ if (!isNOU(result.files)) {
875
+ parent.notify(event, result);
876
+ parent.notify(events.selectionChanged, {});
877
+ const args: SuccessEventArgs = { action: 'read', result: result };
878
+ parent.trigger('success', args);
879
+ } else {
880
+ if (!isNOU(result.error) && result.error.code === '401') {
881
+ result.files = [];
882
+ parent.notify(event, result);
883
+ parent.notify(events.selectionChanged, {});
884
+ }
885
+ onFailure(parent, result, 'read');
886
+ parent.setProperties({ path: parent.oldPath }, true);
887
+ parent.pathNames.pop();
888
+ }
889
+ }
890
+ catch (error) {
891
+ handleCatchError(parent, error, 'read');
892
+ parent.setProperties({ path: parent.oldPath }, true);
893
+ parent.pathNames.pop();
894
+ }
895
+ if (parent.isDragDrop && parent.isDropEnd) {
896
+ if (parent.droppedObjects.length !== 0) {
897
+ const args: FileDragEventArgs = { fileDetails: parent.droppedObjects };
898
+ parent.trigger('fileDropped', args);
899
+ }
900
+ parent.isDropEnd = parent.isDragDrop = false;
901
+ }
902
+ }
903
+
904
+ /**
905
+ * Function for filter success in File Manager.
906
+ *
907
+ * @param {IFileManager} parent - specifies the parent element.
908
+ * @param {ReadArgs} result - specifies the result.
909
+ * @param {string} event - specifies the event.
910
+ * @param {string} action - specifies the action.
911
+ * @returns {void}
912
+ * @private
913
+ */
914
+ function filterSuccess(parent: IFileManager, result: ReadArgs, event: string, action: string): void {
915
+ try {
916
+ if (!isNOU(result.files)) {
917
+ parent.notify(event, result);
918
+ const args: SuccessEventArgs = { action: action, result: result };
919
+ parent.trigger('success', args);
920
+ } else {
921
+ onFailure(parent, result, action);
922
+ }
923
+ }
924
+ catch (error) {
925
+ handleCatchError(parent, error, action);
926
+ }
927
+ }
928
+
929
+ /* istanbul ignore next */
930
+ /**
931
+ * Function for create success in File Manager.
932
+ *
933
+ * @param {IFileManager} parent - specifies the parent element.
934
+ * @param {ReadArgs} result - specifies the result.
935
+ * @param {string} itemName - specifies the item name.
936
+ * @returns {void}
937
+ * @private
938
+ */
939
+ function createSuccess(parent: IFileManager, result: ReadArgs, itemName: string): void {
940
+ try {
941
+ if (!isNOU(result.files)) {
942
+ if (parent.dialogObj && parent.dialogObj.visible) { parent.dialogObj.hide(); }
943
+ parent.createdItem = isFileSystemData(parent) ? result.files[result.files.length - 1] : result.files[0];
944
+ parent.breadcrumbbarModule.searchObj.value = '';
945
+ const createEventArgs: FolderCreateEventArgs = {
946
+ folderName: itemName,
947
+ path: parent.path,
948
+ parentFolder: parent.itemData as { [key: string]: Object }[]
949
+ };
950
+ parent.trigger('folderCreate', createEventArgs);
951
+ const args: SuccessEventArgs = { action: 'create', result: result };
952
+ parent.trigger('success', args);
953
+ parent.itemData = [getPathObject(parent)];
954
+ read(parent, events.createEnd, parent.path);
955
+ } else {
956
+ if (result.error.code === '400') {
957
+ if (parent.dialogObj && parent.dialogObj.visible) {
958
+ const ele: HTMLInputElement = select('#newname', parent.dialogObj.element) as HTMLInputElement;
959
+ const error: string = getLocaleText(parent, 'Validation-NewFolder-Exists').replace('{0}', '"' + ele.value + '"');
960
+ ele.parentElement.nextElementSibling.innerHTML = error;
961
+ } else {
962
+ const result: ReadArgs = {
963
+ files: null,
964
+ error: {
965
+ code: '400',
966
+ message: getLocaleText(parent, 'Validation-NewFolder-Exists').replace('{0}', '"' + itemName + '"'),
967
+ fileExists: null
968
+ }
969
+ };
970
+ createDialog(parent, 'Error', result);
971
+ }
972
+ const args: FailureEventArgs = { action: 'create', error: result.error };
973
+ parent.trigger('failure', args);
974
+ } else {
975
+ if (parent.dialogObj && parent.dialogObj.visible) { parent.dialogObj.hide(); }
976
+ onFailure(parent, result, 'create');
977
+ }
978
+ }
979
+ }
980
+ catch (error) {
981
+ if (parent.dialogObj && parent.dialogObj.visible) { parent.dialogObj.hide(); }
982
+ handleCatchError(parent, error, 'create');
983
+ }
984
+ }
985
+
986
+ /* istanbul ignore next */
987
+ /**
988
+ * Function to rename the folder/file in File Manager.
989
+ *
990
+ * @param {IFileManager} parent - specifies the parent element.
991
+ * @param {ReadArgs} result - specifies the result.
992
+ * @returns {void}
993
+ * @private
994
+ */
995
+ function renameSuccess(parent: IFileManager, result: ReadArgs): void {
996
+ try {
997
+ if (!isNOU(result.files)) {
998
+ if (!isNOU(parent.dialogObj)) { parent.dialogObj.hide(); }
999
+ const args: SuccessEventArgs = { action: 'rename', result: result };
1000
+ parent.trigger('success', args);
1001
+ parent.renamedItem = Array.isArray(result.files) ? result.files[0] : result.files;
1002
+ const renameEventArgs: RenameEventArgs = {
1003
+ newName: parent.renamedItem.name as string,
1004
+ itemData: [parent.renamedItem as { [key: string]: Object; }],
1005
+ path: parent.path
1006
+ };
1007
+ parent.trigger('rename', renameEventArgs);
1008
+ if (parent.activeModule === 'navigationpane') {
1009
+ const pathObject: Object = getPathObject(parent);
1010
+ const pathLevel: number = parent.pathId[parent.pathId.length - 1].split('_').length - 2;
1011
+ parent.pathId.pop();
1012
+ parent.itemData = [getValue(parent.pathId[parent.pathId.length - 1], parent.feParent)];
1013
+ const renamePath: string = getTargetPath(parent, parent.renamedItem);
1014
+ read(parent, events.renameEndParent, renamePath);
1015
+ if (!isNOU(pathObject) && parent.pathNames.length > 1 && pathLevel <= parent.pathNames.length - 1) {
1016
+ parent.pathNames[pathLevel as number] = parent.renameText;
1017
+ if (!parent.hasId) {
1018
+ parent.setProperties({ path: `/${parent.pathNames.slice(1).join('/')}/` }, true);
1019
+ }
1020
+ }
1021
+ parent.itemData = parent.navigationpaneModule.previousSelected.length > 0
1022
+ ? parent.navigationpaneModule.treeObj.getTreeData(parent.navigationpaneModule.previousSelected[0]) : parent.itemData;
1023
+ read(parent, events.pathChanged, parent.path);
1024
+ parent.itemData[0] = parent.renamedItem;
1025
+ parent.renamedItem = null;
1026
+ } else {
1027
+ parent.itemData = [getPathObject(parent)];
1028
+ if (parent.breadcrumbbarModule.searchObj.value !== '') {
1029
+ Search(
1030
+ parent, events.renameEnd, parent.path, parent.searchWord,
1031
+ parent.showHiddenItems, !parent.searchSettings.ignoreCase
1032
+ );
1033
+ } else {
1034
+ if (parent.isFiltered) {
1035
+ filter(parent, events.renameEnd);
1036
+ } else {
1037
+ read(parent, events.renameEnd, parent.path);
1038
+ }
1039
+ }
1040
+ }
1041
+ } else {
1042
+ if (result.error.code === '400' && parent.dialogObj && parent.dialogObj.visible) {
1043
+ const ele: HTMLInputElement = select('#rename', parent.dialogObj.element) as HTMLInputElement;
1044
+ let error: string = getLocaleText(parent, 'Validation-Rename-Exists').replace('{0}', '"' + parent.currentItemText + '"');
1045
+ error = error.replace('{1}', '"' + ele.value + '"');
1046
+ ele.parentElement.nextElementSibling.innerHTML = error;
1047
+ const args: FailureEventArgs = { action: 'rename', error: result.error };
1048
+ parent.trigger('failure', args);
1049
+ } else {
1050
+ if (!isNOU(parent.dialogObj)) { parent.dialogObj.hide(); }
1051
+ onFailure(parent, result, 'rename');
1052
+ }
1053
+ }
1054
+ }
1055
+ catch (error) {
1056
+ if (!isNOU(parent.dialogObj)) { parent.dialogObj.hide(); }
1057
+ handleCatchError(parent, error, 'rename');
1058
+ }
1059
+ }
1060
+
1061
+ /* istanbul ignore next */
1062
+ /**
1063
+ * Function to create new folder in File Manager.
1064
+ *
1065
+ * @param {IFileManager} parent - specifies the parent element.
1066
+ * @param {ReadArgs} result - specifies the result.
1067
+ * @param {string} path - specifies the path.
1068
+ * @param {string} operation - specifies the operation.
1069
+ * @returns {void}
1070
+ * @private
1071
+ */
1072
+ function pasteSuccess(
1073
+ parent: IFileManager, result: ReadArgs, path: string, operation: string): void {
1074
+ try {
1075
+ const moveorcopyEventArgs: MoveEventArgs = {
1076
+ itemData: result.files,
1077
+ isCopy: operation === 'copy' ? true : false,
1078
+ path: path,
1079
+ targetData: parent.itemData[0] as { [key: string]: Object},
1080
+ targetPath: parent.path
1081
+ };
1082
+ parent.trigger('move', moveorcopyEventArgs);
1083
+ if (result.error && result.error.fileExists) {
1084
+ parent.fileLength = 0;
1085
+ if (!isNOU(result.files)) {
1086
+ parent.isPasteError = true;
1087
+ doPasteUpdate(parent, operation, result);
1088
+ }
1089
+ createExtDialog(parent, 'DuplicateItems', result.error.fileExists);
1090
+ if (result.error.code === '404') {
1091
+ createDialog(parent, 'Error', result);
1092
+ }
1093
+ } else if (!result.error && !isNOU(result.files)) {
1094
+ parent.isPasteError = false;
1095
+ doPasteUpdate(parent, operation, result);
1096
+ } else if (result.error && !isNOU(result.files)) {
1097
+ parent.isPasteError = true;
1098
+ doPasteUpdate(parent, operation, result);
1099
+ createDialog(parent, 'Error', result);
1100
+ } else {
1101
+ onFailure(parent, result, operation);
1102
+ }
1103
+ }
1104
+ catch (error) {
1105
+ handleCatchError(parent, error, operation);
1106
+ }
1107
+ }
1108
+
1109
+ /**
1110
+ * Function to delete success in File Manager.
1111
+ *
1112
+ * @param {IFileManager} parent - specifies the parent element.
1113
+ * @param {ReadArgs} result - specifies the result.
1114
+ * @param {string} path - specifies the path.
1115
+ * @returns {void}
1116
+ * @private
1117
+ */
1118
+ function deleteSuccess(parent: IFileManager, result: ReadArgs, path: string): void {
1119
+ try {
1120
+ const deleteEventArgs: DeleteEventArgs = {
1121
+ itemData: result.files,
1122
+ path: path
1123
+ };
1124
+ parent.trigger('delete', deleteEventArgs);
1125
+ if (!isNOU(result.files)) {
1126
+ parent.setProperties({ path: path }, true);
1127
+ parent.itemData = [getPathObject(parent)];
1128
+ read(parent, events.deleteEnd, parent.path);
1129
+ if (result.error) {
1130
+ onFailure(parent, result, 'delete');
1131
+ } else {
1132
+ const args: SuccessEventArgs = { action: 'delete', result: result };
1133
+ parent.trigger('success', args);
1134
+ }
1135
+ } else {
1136
+ onFailure(parent, result, 'delete');
1137
+ }
1138
+ }
1139
+ catch (error) {
1140
+ handleCatchError(parent, error, 'delete');
1141
+ }
1142
+ }
1143
+ /**
1144
+ * Function for details success in File Manager.
1145
+ *
1146
+ * @param {IFileManager} parent - specifies the parent element.
1147
+ * @param {ReadArgs} result - specifies the result.
1148
+ * @param {string} path - specifies the path.
1149
+ * @param {string} operation - specifies the operation.
1150
+ * @returns {void}
1151
+ * @private
1152
+ */
1153
+ function detailsSuccess(
1154
+ // eslint:disable-next-line
1155
+ parent: IFileManager, result: ReadArgs, path: string, operation: string): void {
1156
+ try {
1157
+ if (!isNOU(result.details)) {
1158
+ createDialog(parent, operation, null, <FileDetails>result.details);
1159
+ const args: SuccessEventArgs = { action: 'details', result: result };
1160
+ parent.trigger('success', args);
1161
+ } else {
1162
+ onFailure(parent, result, 'details');
1163
+ }
1164
+ }
1165
+ catch (error) {
1166
+ handleCatchError(parent, error, 'details');
1167
+ }
1168
+ }
1169
+ /**
1170
+ * Function for on failure event in File Manager.
1171
+ *
1172
+ * @param {IFileManager} parent - specifies the parent element.
1173
+ * @param {ReadArgs} result - specifies the result.
1174
+ * @param {string} action - specifies the action.
1175
+ * @returns {void}
1176
+ * @private
1177
+ */
1178
+ function onFailure(parent: IFileManager, result: ReadArgs, action: string): void {
1179
+ createDialog(parent, 'Error', result);
1180
+ const args: FailureEventArgs = { action: action, error: result.error };
1181
+ parent.trigger('failure', args);
1182
+ }
1183
+ /**
1184
+ * Function for search in File Manager.
1185
+ *
1186
+ * @param {IFileManager} parent - specifies the parent element.
1187
+ * @param {string} event - specifies the event.
1188
+ * @param {string} path - specifies the path.
1189
+ * @param {string} searchString - specifies the search string.
1190
+ * @param {boolean} showHiddenItems - specifies the hidden items.
1191
+ * @param {boolean} caseSensitive - specifies the casing of search text.
1192
+ * @returns {void}
1193
+ * @private
1194
+ */
1195
+ export function Search(
1196
+ parent: IFileManager, event: string, path: string, searchString: string, showHiddenItems?: boolean, caseSensitive?: boolean): void {
1197
+ const data: Object = {
1198
+ action: 'search', path: path, searchString: searchString, showHiddenItems: showHiddenItems, caseSensitive: caseSensitive,
1199
+ data: parent.itemData
1200
+ };
1201
+ createAjax(parent, data, searchSuccess, event);
1202
+ }
1203
+
1204
+ /* istanbul ignore next */
1205
+ /**
1206
+ * Function for search success in File Manager.
1207
+ *
1208
+ * @param {IFileManager} parent - specifies the parent element.
1209
+ * @param {ReadArgs} result - specifies the result.
1210
+ * @param {string} event - specifies the event.
1211
+ * @returns {void}
1212
+ * @private
1213
+ */
1214
+ function searchSuccess(parent: IFileManager, result: ReadArgs, event: string): void {
1215
+ try {
1216
+ if (!isNOU(result.files)) {
1217
+ parent.notify(event, result);
1218
+ const args: SuccessEventArgs = { action: 'search', result: result };
1219
+ parent.trigger('success', args);
1220
+ } else {
1221
+ onFailure(parent, result, 'search');
1222
+ }
1223
+ }
1224
+ catch (error) {
1225
+ handleCatchError(parent, error, 'search');
1226
+ }
1227
+ }
1228
+ /* istanbul ignore next */
1229
+ /**
1230
+ * Function for download in File Manager.
1231
+ *
1232
+ * @param {IFileManager} parent - specifies the parent element.
1233
+ * @param {string} path - specifies the path.
1234
+ * @param {string[]} items - specifies the items.
1235
+ * @returns {void}
1236
+ * @private
1237
+ */
1238
+ export function Download(parent: IFileManager, path: string, items: string[]): void {
1239
+ const downloadUrl: string = parent.ajaxSettings.downloadUrl ? parent.ajaxSettings.downloadUrl : parent.ajaxSettings.url;
1240
+ const data: Object = { 'action': 'download', 'path': path, 'names': items, 'data': parent.itemData };
1241
+ const ajaxSettings: Object = {
1242
+ url: downloadUrl,
1243
+ type: 'POST',
1244
+ contentType: 'application/json',
1245
+ responseType: 'blob',
1246
+ data: JSON.stringify(data),
1247
+ onSuccess: null,
1248
+ onFailure: null,
1249
+ beforeSend: null
1250
+ };
1251
+ const eventArgs: BeforeDownloadEventArgs = { data: data, cancel: false, useFormPost: true, ajaxSettings: ajaxSettings };
1252
+ parent.trigger('beforeDownload', eventArgs, (downloadArgs: BeforeDownloadEventArgs) => {
1253
+ if (!downloadArgs.cancel) {
1254
+ if (downloadArgs.useFormPost) {
1255
+ const form: HTMLElement = createElement('form', {
1256
+ id: parent.element.id + '_downloadForm',
1257
+ attrs: { action: downloadUrl, method: 'post', name: 'downloadForm', 'download': '' }
1258
+ });
1259
+ const input: HTMLElement =
1260
+ createElement('input', {
1261
+ id: parent.element.id + '_hiddenForm',
1262
+ attrs: { name: 'downloadInput', value: JSON.stringify(downloadArgs.data), type: 'hidden' }
1263
+ });
1264
+ form.appendChild(input);
1265
+ parent.element.appendChild(form);
1266
+ document.forms.namedItem('downloadForm').submit();
1267
+ parent.element.removeChild(form);
1268
+ }
1269
+ else {
1270
+ try {
1271
+ let contentDisposition: string | null;
1272
+ let fileName: string;
1273
+ const fetch: Fetch = new Fetch({
1274
+ url: getValue('url', downloadArgs.ajaxSettings),
1275
+ type: getValue('type', downloadArgs.ajaxSettings),
1276
+ contentType: getValue('contentType', downloadArgs.ajaxSettings),
1277
+ responseType: getValue('responseType', downloadArgs.ajaxSettings),
1278
+ beforeSend: getValue('beforeSend', downloadArgs.ajaxSettings),
1279
+ onLoad: (e: Response) => {
1280
+ contentDisposition = e.headers.get('Content-Disposition');
1281
+ if (contentDisposition) {
1282
+ const filenameMatch: RegExpMatchArray | null = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
1283
+ const extractedFilename: string | null = filenameMatch && filenameMatch[1];
1284
+ fileName = extractedFilename ? extractedFilename.replace(/['"]/g, '') : fileName;
1285
+ }
1286
+ else {
1287
+ fileName = parent.itemData.length > 1 ? 'files.zip' : getValue('isFile', parent.itemData[0]) ? getValue('name', parent.itemData[0]) : getValue('name', parent.itemData[0]) + '.zip';
1288
+ }
1289
+ },
1290
+ onSuccess: (e: Blob) => {
1291
+ parent.trigger('success', downloadArgs);
1292
+ const blob: Blob = e;
1293
+ const blobUrl: string = URL.createObjectURL(blob);
1294
+ const link: HTMLAnchorElement = document.createElement('a');
1295
+ link.href = blobUrl;
1296
+ link.download = fileName;
1297
+ document.body.appendChild(link);
1298
+ link.click();
1299
+ document.body.removeChild(link);
1300
+ },
1301
+ onFailure: (e: Response) => {
1302
+ const result: ReadArgs = {
1303
+ error: {
1304
+ code: e.status.toString(),
1305
+ message: getLocaleText(parent, 'Network-Error') + ' ' + parent.ajaxSettings.downloadUrl
1306
+ }
1307
+ };
1308
+ createDialog(parent, 'Error', result);
1309
+ parent.trigger('failure', downloadArgs);
1310
+ }
1311
+ });
1312
+ fetch.send(JSON.stringify(downloadArgs.data));
1313
+ }
1314
+ catch (error) {
1315
+ handleCatchError(parent, error, 'download');
1316
+ }
1317
+ }
1318
+ }
1319
+ });
1320
+ }
1321
+
1322
+ /**
1323
+ * Function for on catch handler in File Manager.
1324
+ *
1325
+ * @param {IFileManager} parent - specifies the parent element.
1326
+ * @param {any} error - specifies the catch error.
1327
+ * @param {string} action - specifies the action.
1328
+ * @returns {void}
1329
+ * @private
1330
+ */
1331
+ function handleCatchError(parent: IFileManager, error: any, action: string): void {
1332
+ const errorResult: ReadArgs = {
1333
+ files: null,
1334
+ error: {
1335
+ message: error.message,
1336
+ fileExists: null
1337
+ }
1338
+ };
1339
+ onFailure(parent, errorResult, action);
1340
+ }
1341
+ /**
1342
+ * Function for trigger Fetch success in File Manager.
1343
+ *
1344
+ * @param {IFileManager} parent - specifies the parent element.
1345
+ * @param {Object} ajaxSettings - specifies the ajax settings.
1346
+ * @returns {void}
1347
+ */
1348
+ export function triggerFetchSuccess(parent: IFileManager, ajaxSettings: Object): void {
1349
+ parent.notify(events.afterRequest, { action: 'success' });
1350
+ if (ajaxSettings && typeof getValue('onSuccess', ajaxSettings) === 'function') {
1351
+ getValue('onSuccess', ajaxSettings)();
1352
+ }
1353
+ }
1354
+
1355
+ /**
1356
+ * Function for trigger Fetch failure in File Manager.
1357
+ *
1358
+ * @param {IFileManager} parent - specifies the parent element.
1359
+ * @param {Object} ajaxSettings - specifies the ajax settings.
1360
+ * @param {ReadArgs} result - specifies the result.
1361
+ * @returns {void}
1362
+ */
1363
+ export function triggerFetchFailure(parent: IFileManager, ajaxSettings: Object, result: ReadArgs): void {
1364
+ parent.notify(events.afterRequest, { action: 'failure' });
1365
+ createDialog(parent, 'Error', result);
1366
+ if (typeof getValue('onFailure', ajaxSettings) === 'function') {
1367
+ getValue('onFailure', ajaxSettings)();
1368
+ }
1369
+ }