@oat-sa/tao-core-ui 3.24.0 → 3.24.2
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.
- package/dist/animable/pulsable/pulsable.js +0 -1
- package/dist/autocomplete/css/autocomplete.css +1 -1
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/badge/css/badge.css +6 -6
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +2 -2
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/calculator/css/calculator.css +8 -6
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/class/css/selector.css +4 -4
- package/dist/class/css/selector.css.map +1 -1
- package/dist/component/css/components.css +5 -5
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +1 -1
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +0 -1
- package/dist/component/resizable.js +0 -1
- package/dist/contextualPopup/css/contextualPopup.css +1 -1
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/datatable/css/datatable.css +3 -3
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable.js +1 -2
- package/dist/datetime/css/picker.css +13 -13
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/documentViewer/css/documentViewer.css +10 -10
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +0 -1
- package/dist/dynamicComponent/css/dynamicComponent.css +1 -1
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +1 -4
- package/dist/figure/FigureStateActive.js +20 -23
- package/dist/form/css/dropdownForm.css +1 -1
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/widget/widget.js +1 -4
- package/dist/highlighter.js +0 -2
- package/dist/image/ImgStateActive.js +13 -15
- package/dist/interactUtils.js +7 -8
- package/dist/itemButtonList/css/item-button-list.css +9 -3
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +1 -2
- package/dist/keyNavigation/navigableDomElement.js +3 -4
- package/dist/keyNavigation/navigator.js +1 -2
- package/dist/listbox/css/listbox.css +1 -1
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/maths/calculator/core/board.js +58 -127
- package/dist/maths/calculator/core/labels.js +1 -6
- package/dist/maths/calculator/css/calculator.css +18 -18
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +1 -6
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +3 -14
- package/dist/mediaplayer/players/youtube.js +3 -12
- package/dist/mediaplayer/utils/crossOrigin.js +1 -1
- package/dist/mediaplayer/utils/timeObserver.js +1 -2
- package/dist/mediaplayer/youtubeManager.js +1 -2
- package/dist/mediaplayer.js +2 -8
- package/dist/mediasizer.js +0 -1
- package/dist/resizeObserver.js +1 -3
- package/dist/resource/css/selector.css +31 -23
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/list.js +239 -203
- package/dist/resource/selector.js +0 -1
- package/dist/resource/tree.js +239 -203
- package/dist/resourcemgr/assetSearch.js +3 -3
- package/dist/resourcemgr/assetSearchContract.js +40 -12
- package/dist/resourcemgr/css/resourcemgr.css +113 -21
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +370 -17
- package/dist/resourcemgr/filePreview.js +42 -3
- package/dist/resourcemgr/fileSelector.js +15 -0
- package/dist/resourcemgr.js +15 -10
- package/dist/searchModal/advancedSearch.js +3 -4
- package/dist/searchModal/css/searchModal.css +14 -14
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +42 -53
- package/dist/switch/css/switch.css +2 -2
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/tabs/css/tabs.css +2 -2
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/taskQueue/css/taskQueue.css +4 -4
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/taskQueueModel.js +1 -2
- package/dist/taskQueueButton/taskable.js +1 -2
- package/dist/validator/validators.js +0 -1
- package/dist/waitingDialog/css/waitingDialog.css +2 -2
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/package.json +1 -1
- package/src/autocomplete/css/autocomplete.css +1 -1
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/badge/css/badge.css +6 -6
- package/src/badge/css/badge.css.map +1 -1
- package/src/breadcrumbs/css/breadcrumbs.css +2 -2
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/calculator/css/calculator.css +8 -6
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/class/css/selector.css +4 -4
- package/src/class/css/selector.css.map +1 -1
- package/src/component/css/components.css +5 -5
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +1 -1
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/contextualPopup/css/contextualPopup.css +1 -1
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/css/basic.css +123 -113
- package/src/css/basic.css.map +1 -1
- package/src/datatable/css/datatable.css +3 -3
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datetime/css/picker.css +13 -13
- package/src/datetime/css/picker.css.map +1 -1
- package/src/documentViewer/css/documentViewer.css +10 -10
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/dynamicComponent/css/dynamicComponent.css +1 -1
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/form/css/dropdownForm.css +1 -1
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/itemButtonList/css/item-button-list.css +9 -3
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/listbox/css/listbox.css +1 -1
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/maths/calculator/css/calculator.css +18 -18
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/resource/css/selector.css +31 -23
- package/src/resource/css/selector.css.map +1 -1
- package/src/resourcemgr/assetSearch.js +3 -3
- package/src/resourcemgr/assetSearchContract.js +40 -18
- package/src/resourcemgr/css/resourcemgr.css +113 -21
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +434 -33
- package/src/resourcemgr/filePreview.js +43 -4
- package/src/resourcemgr/fileSelector.js +18 -0
- package/src/resourcemgr/scss/resourcemgr.scss +103 -5
- package/src/resourcemgr/tpl/layout.tpl +30 -18
- package/src/resourcemgr.js +9 -4
- package/src/searchModal/css/searchModal.css +14 -14
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/switch/css/switch.css +2 -2
- package/src/switch/css/switch.css.map +1 -1
- package/src/tabs/css/tabs.css +2 -2
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/taskQueue/css/taskQueue.css +4 -4
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/waitingDialog/css/waitingDialog.css +2 -2
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
|
@@ -204,7 +204,18 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
204
204
|
*/
|
|
205
205
|
const NS = 'resourcemgr';
|
|
206
206
|
const LOGGER = loggerFactory(`ui/${NS}`);
|
|
207
|
-
const DEFAULT_AJAX_TIMEOUT_MS =
|
|
207
|
+
const DEFAULT_AJAX_TIMEOUT_MS = 30000;
|
|
208
|
+
const TREE_LOADING_REF_KEY = `${NS}TreeLoadingRefCount`;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @param {Object} data
|
|
212
|
+
* @returns {Array}
|
|
213
|
+
*/
|
|
214
|
+
function folderChildrenOnly(data) {
|
|
215
|
+
return _.filter(data && data.children, function (child) {
|
|
216
|
+
return child && child.path && !child.uri;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
208
219
|
function fileBrowser (options) {
|
|
209
220
|
if (!options.browseUrl && options.url) {
|
|
210
221
|
options.browseUrl = options.url;
|
|
@@ -221,15 +232,50 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
221
232
|
// for pagination
|
|
222
233
|
let selectedClass = {
|
|
223
234
|
path: rootPath,
|
|
224
|
-
childrenLimit:
|
|
235
|
+
childrenLimit: 11,
|
|
225
236
|
total: 0,
|
|
226
237
|
page: 1
|
|
227
238
|
};
|
|
228
239
|
let searchMode = false;
|
|
229
240
|
let sort = Object.assign({}, assetSearchContract.DEFAULT_SORT);
|
|
241
|
+
const splitBrowse = options.splitBrowse !== false;
|
|
230
242
|
const ajaxTimeoutMs = Number.isFinite(Number(options.ajaxTimeoutMs)) && Number(options.ajaxTimeoutMs) > 0 ? Number(options.ajaxTimeoutMs) : DEFAULT_AJAX_TIMEOUT_MS;
|
|
243
|
+
const $treeLoadingOverlay = $$1('.file-browser-tree-loading', $fileBrowser);
|
|
244
|
+
const $treeLoadingStatus = $$1('.file-browser-tree-loading-status', $treeLoadingOverlay);
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Ref-count in-flight browse requests and toggle the tree loading overlay.
|
|
248
|
+
* @param {Boolean} increment - true when a load starts, false when it finishes
|
|
249
|
+
*/
|
|
250
|
+
function setTreeLoading(increment) {
|
|
251
|
+
let treeLoadingRefCount = Number($fileBrowser.data(TREE_LOADING_REF_KEY)) || 0;
|
|
252
|
+
treeLoadingRefCount += increment ? 1 : -1;
|
|
253
|
+
if (treeLoadingRefCount < 0) {
|
|
254
|
+
treeLoadingRefCount = 0;
|
|
255
|
+
}
|
|
256
|
+
$fileBrowser.data(TREE_LOADING_REF_KEY, treeLoadingRefCount);
|
|
257
|
+
const loading = treeLoadingRefCount > 0;
|
|
258
|
+
$fileBrowser.toggleClass('is-tree-loading', loading);
|
|
259
|
+
$fileBrowser.attr('aria-busy', loading ? 'true' : 'false');
|
|
260
|
+
$treeLoadingOverlay.toggleClass('hidden', !loading).attr('aria-hidden', loading ? 'false' : 'true');
|
|
261
|
+
$treeLoadingStatus.attr('aria-busy', loading ? 'true' : 'false');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Show or hide the asset table loading overlay (browse mode only).
|
|
266
|
+
* @param {Boolean} loading
|
|
267
|
+
*/
|
|
268
|
+
function setFilesLoading(loading) {
|
|
269
|
+
if (searchMode) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
$container.trigger(`filesloading.${NS}`, [!!loading]);
|
|
273
|
+
}
|
|
231
274
|
$container.on(`searchmode.${NS}`, function (e, enabled) {
|
|
232
275
|
searchMode = !!enabled;
|
|
276
|
+
if (searchMode) {
|
|
277
|
+
$container.trigger(`filesloading.${NS}`, [false]);
|
|
278
|
+
}
|
|
233
279
|
});
|
|
234
280
|
$container.on(`sortchange.${NS}`, function (e, nextSort) {
|
|
235
281
|
sort = Object.assign({}, assetSearchContract.DEFAULT_SORT, nextSort || {});
|
|
@@ -248,9 +294,14 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
248
294
|
return;
|
|
249
295
|
}
|
|
250
296
|
const subTree = getByExactPath(fileTree, targetPath) || getByPath(fileTree, targetPath) || fileTree;
|
|
297
|
+
if (!searchMode) {
|
|
298
|
+
setFilesLoading(true);
|
|
299
|
+
}
|
|
251
300
|
getFolderContent(subTree, targetPath, function (content) {
|
|
252
301
|
if (content) {
|
|
253
302
|
selectFolder(content, targetPath);
|
|
303
|
+
} else {
|
|
304
|
+
setFilesLoading(false);
|
|
254
305
|
}
|
|
255
306
|
});
|
|
256
307
|
});
|
|
@@ -274,8 +325,15 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
274
325
|
});
|
|
275
326
|
|
|
276
327
|
//load the content of the ROOT
|
|
328
|
+
const showInitialListLoading = !searchMode && root === 'local';
|
|
329
|
+
if (showInitialListLoading) {
|
|
330
|
+
setFilesLoading(true);
|
|
331
|
+
}
|
|
277
332
|
getFolderContent(fileTree, rootPath, function (content) {
|
|
278
333
|
if (!content) {
|
|
334
|
+
if (showInitialListLoading) {
|
|
335
|
+
setFilesLoading(false);
|
|
336
|
+
}
|
|
279
337
|
return;
|
|
280
338
|
}
|
|
281
339
|
indexTree(content);
|
|
@@ -303,6 +361,8 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
303
361
|
if (root !== 'local') {
|
|
304
362
|
options.hasAlreadySelected = true;
|
|
305
363
|
}
|
|
364
|
+
} else if (showInitialListLoading) {
|
|
365
|
+
setFilesLoading(false);
|
|
306
366
|
}
|
|
307
367
|
});
|
|
308
368
|
|
|
@@ -312,6 +372,14 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
312
372
|
const $selected = $$1(this);
|
|
313
373
|
const fullPath = $selected.data('path');
|
|
314
374
|
const subTree = getByExactPath(fileTree, fullPath);
|
|
375
|
+
const openingFolder = !searchMode && fullPath !== selectedClass.path;
|
|
376
|
+
if (openingFolder) {
|
|
377
|
+
selectedClass.page = 1;
|
|
378
|
+
}
|
|
379
|
+
if (!searchMode) {
|
|
380
|
+
setFilesLoading(true);
|
|
381
|
+
}
|
|
382
|
+
invalidateFolderFiles(fullPath);
|
|
315
383
|
|
|
316
384
|
//get the folder content
|
|
317
385
|
getFolderContent(subTree, fullPath, function (content) {
|
|
@@ -341,6 +409,8 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
341
409
|
|
|
342
410
|
//internal event to set the file-selector content
|
|
343
411
|
selectFolder(content, fullPath);
|
|
412
|
+
} else if (!searchMode) {
|
|
413
|
+
setFilesLoading(false);
|
|
344
414
|
}
|
|
345
415
|
});
|
|
346
416
|
});
|
|
@@ -361,10 +431,11 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
361
431
|
}
|
|
362
432
|
if (targetPath !== selectedClass.path) {
|
|
363
433
|
selectedClass.path = targetPath;
|
|
364
|
-
selectedClass.page = 1;
|
|
365
434
|
}
|
|
435
|
+
selectedClass.page = 1;
|
|
366
436
|
invalidateFolderFiles(targetPath);
|
|
367
|
-
|
|
437
|
+
const pendingUpload = file && !file.error && (file.uri || file.name) ? file : null;
|
|
438
|
+
reloadSortedFolder(pendingUpload ? [pendingUpload] : []);
|
|
368
439
|
});
|
|
369
440
|
$container.on(`filedelete.${NS}`, function (e, path) {
|
|
370
441
|
if (searchMode) {
|
|
@@ -494,13 +565,16 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
494
565
|
$container.data('activeFileBrowserRoot', root);
|
|
495
566
|
if (searchMode) {
|
|
496
567
|
$container.trigger(`folderpath.${NS}`, [path, content.label]);
|
|
497
|
-
$container.trigger(`folderselect.${NS}`, [content.label,
|
|
568
|
+
$container.trigger(`folderselect.${NS}`, [content.label, getFilesForDisplay(content), path, content]);
|
|
498
569
|
return;
|
|
499
570
|
}
|
|
500
571
|
updateSelectedClass(path, content.total, content.childrenLimit);
|
|
501
572
|
$container.trigger(`folderpath.${NS}`, [path, content.label]);
|
|
502
|
-
$container.trigger(`folderselect.${NS}`, [content.label,
|
|
573
|
+
$container.trigger(`folderselect.${NS}`, [content.label, getFilesForDisplay(content), path, content]);
|
|
503
574
|
renderPagination();
|
|
575
|
+
if (!searchMode) {
|
|
576
|
+
setFilesLoading(false);
|
|
577
|
+
}
|
|
504
578
|
}
|
|
505
579
|
|
|
506
580
|
/**
|
|
@@ -517,6 +591,172 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
517
591
|
}
|
|
518
592
|
return files;
|
|
519
593
|
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Files for the table (split list payload or legacy children slice).
|
|
597
|
+
* @param {Object} content
|
|
598
|
+
* @returns {Array}
|
|
599
|
+
*/
|
|
600
|
+
function getFilesForDisplay(content) {
|
|
601
|
+
if (!content) {
|
|
602
|
+
return [];
|
|
603
|
+
}
|
|
604
|
+
if (splitBrowse) {
|
|
605
|
+
return content.listItems || [];
|
|
606
|
+
}
|
|
607
|
+
return getPage(content.children || []);
|
|
608
|
+
}
|
|
609
|
+
function listCacheKey() {
|
|
610
|
+
return `${sort.field}:${sort.direction}:${selectedClass.page}`;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Snapshot list request identity (folder + page/sort) when a browse starts.
|
|
615
|
+
* @returns {{path: String, cacheKey: String}}
|
|
616
|
+
*/
|
|
617
|
+
function captureListRequestContext() {
|
|
618
|
+
return {
|
|
619
|
+
path: selectedClass.path,
|
|
620
|
+
cacheKey: listCacheKey()
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Whether navigation changed before an in-flight list response should apply.
|
|
626
|
+
* @param {{path: String, cacheKey: String}} captured
|
|
627
|
+
* @returns {Boolean}
|
|
628
|
+
*/
|
|
629
|
+
function isListRequestStale(captured) {
|
|
630
|
+
return !captured || captured.path !== selectedClass.path || captured.cacheKey !== listCacheKey();
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* @param {Object} response
|
|
635
|
+
* @returns {Object}
|
|
636
|
+
*/
|
|
637
|
+
function unwrapBrowseResponse(response) {
|
|
638
|
+
if (response && response.success === false) {
|
|
639
|
+
return Promise.reject(response);
|
|
640
|
+
}
|
|
641
|
+
let data = response && response.data ? response.data : response;
|
|
642
|
+
data = updatePermissions(data);
|
|
643
|
+
if (data.children && data.children.length > 0) {
|
|
644
|
+
data.children = data.children.map(function (child) {
|
|
645
|
+
return updatePermissions(child);
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
if (data.items && data.items.length > 0) {
|
|
649
|
+
data.items = data.items.map(function (item) {
|
|
650
|
+
return updatePermissions(item);
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
return data;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* @param {String} path
|
|
658
|
+
* @param {Object} extraData
|
|
659
|
+
* @returns {Promise}
|
|
660
|
+
*/
|
|
661
|
+
function browseRequest(path, extraData) {
|
|
662
|
+
const parameters = {};
|
|
663
|
+
parameters[options.pathParam || 'path'] = path;
|
|
664
|
+
return Promise.resolve($$1.ajax({
|
|
665
|
+
url: options.browseUrl,
|
|
666
|
+
method: 'GET',
|
|
667
|
+
dataType: 'json',
|
|
668
|
+
timeout: ajaxTimeoutMs,
|
|
669
|
+
data: _.merge(parameters, options.params, extraData)
|
|
670
|
+
})).then(unwrapBrowseResponse);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* @param {Object} tree
|
|
675
|
+
* @param {String} path
|
|
676
|
+
* @param {Object} data
|
|
677
|
+
*/
|
|
678
|
+
function applyTreePayload(tree, path, data) {
|
|
679
|
+
const folderData = Object.assign({}, data, {
|
|
680
|
+
children: folderChildrenOnly(data)
|
|
681
|
+
});
|
|
682
|
+
if (!tree.path) {
|
|
683
|
+
_.merge(tree, folderData);
|
|
684
|
+
} else if (folderData.children) {
|
|
685
|
+
setToPath(tree, path, folderData);
|
|
686
|
+
if (!_.find(folderData.children, 'path')) {
|
|
687
|
+
markFolderEmptyAtPath(tree, path);
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
setToPath(tree, path, folderData);
|
|
691
|
+
markFolderEmptyAtPath(tree, path);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* @param {Object} tree
|
|
697
|
+
* @param {String} path
|
|
698
|
+
* @param {Object} listData
|
|
699
|
+
* @param {String} cacheKey
|
|
700
|
+
*/
|
|
701
|
+
function applyListPayload(tree, path, listData, cacheKey) {
|
|
702
|
+
const node = getByExactPath(tree, path) || getByPath(tree, path);
|
|
703
|
+
if (!node || !listData) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
node.listItems = listData.items || [];
|
|
707
|
+
node.total = listData.total;
|
|
708
|
+
node.childrenLimit = listData.pageSize || listData.childrenLimit || selectedClass.childrenLimit;
|
|
709
|
+
node.listPage = listData.page;
|
|
710
|
+
node.totalIsApproximate = listData.totalIsApproximate;
|
|
711
|
+
node.listCacheKey = cacheKey;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Ensure upload responses appear in the table before Elasticsearch catches up.
|
|
716
|
+
* @param {String} path
|
|
717
|
+
* @param {Array<Object>} uploads
|
|
718
|
+
*/
|
|
719
|
+
function mergePendingUploads(path, uploads) {
|
|
720
|
+
if (!uploads || !uploads.length) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
const node = getByExactPath(fileTree, path) || getByPath(fileTree, path);
|
|
724
|
+
if (!node) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (!Array.isArray(node.listItems)) {
|
|
728
|
+
node.listItems = [];
|
|
729
|
+
}
|
|
730
|
+
let added = 0;
|
|
731
|
+
uploads.forEach(function (uploaded) {
|
|
732
|
+
if (!uploaded || uploaded.error) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const normalized = updatePermissions(uploaded);
|
|
736
|
+
if (!normalized.uri && !normalized.name) {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
const exists = _.some(node.listItems, function (item) {
|
|
740
|
+
return normalized.uri && item.uri === normalized.uri || normalized.name && item.name === normalized.name;
|
|
741
|
+
});
|
|
742
|
+
if (exists) {
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
node.listItems.push(normalized);
|
|
746
|
+
added++;
|
|
747
|
+
});
|
|
748
|
+
if (!added) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (splitBrowse) {
|
|
752
|
+
node.listItems = assetSearchContract.sortAssetItems(node.listItems, sort);
|
|
753
|
+
}
|
|
754
|
+
const total = Number(node.total);
|
|
755
|
+
if (Number.isFinite(total) && total >= 0) {
|
|
756
|
+
node.total = total + added;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
520
760
|
/**
|
|
521
761
|
* Get the content of a folder, either in the model or load it
|
|
522
762
|
* @param {Object} tree - the tree model
|
|
@@ -530,6 +770,43 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
530
770
|
}
|
|
531
771
|
}
|
|
532
772
|
function getFolderContent(tree, path, cb) {
|
|
773
|
+
if (splitBrowse) {
|
|
774
|
+
const existing = getByExactPath(tree, path) || getByPath(tree, path);
|
|
775
|
+
const needTree = !existing || !existing.children && !existing.empty;
|
|
776
|
+
const cacheKey = listCacheKey();
|
|
777
|
+
const needList = !existing || existing.listCacheKey !== cacheKey;
|
|
778
|
+
const treePromise = needTree ? (setTreeLoading(true), browseRequest(path, {
|
|
779
|
+
part: 'tree',
|
|
780
|
+
depth: 1,
|
|
781
|
+
sortBy: sort.field,
|
|
782
|
+
sortDir: sort.direction
|
|
783
|
+
}).then(function (data) {
|
|
784
|
+
setTreeLoading(false);
|
|
785
|
+
return data;
|
|
786
|
+
}, function (error) {
|
|
787
|
+
setTreeLoading(false);
|
|
788
|
+
return Promise.reject(error);
|
|
789
|
+
})) : Promise.resolve(null);
|
|
790
|
+
const listPromise = needList ? browseRequest(path, {
|
|
791
|
+
part: 'list',
|
|
792
|
+
page: selectedClass.page,
|
|
793
|
+
pageSize: selectedClass.childrenLimit || 11,
|
|
794
|
+
sortBy: sort.field,
|
|
795
|
+
sortDir: sort.direction
|
|
796
|
+
}) : Promise.resolve(null);
|
|
797
|
+
Promise.all([treePromise, listPromise]).then(function ([treeData, listData]) {
|
|
798
|
+
if (treeData) {
|
|
799
|
+
applyTreePayload(tree, path, treeData);
|
|
800
|
+
}
|
|
801
|
+
if (listData) {
|
|
802
|
+
applyListPayload(tree, path, listData, cacheKey);
|
|
803
|
+
}
|
|
804
|
+
cb(getByExactPath(tree, path) || getByPath(tree, path));
|
|
805
|
+
}).catch(function () {
|
|
806
|
+
cb(null);
|
|
807
|
+
});
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
533
810
|
let content = getByPath(tree, path);
|
|
534
811
|
if (!content || !content.children && !content.empty) {
|
|
535
812
|
loadContent(path).then(function (data) {
|
|
@@ -555,7 +832,7 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
555
832
|
});
|
|
556
833
|
// Use folder total (not selectedClass): openInitialPath runs before selectFolder.
|
|
557
834
|
const expectedTotal = Number(content.total);
|
|
558
|
-
const pageSize = Number(content.childrenLimit) || selectedClass.childrenLimit ||
|
|
835
|
+
const pageSize = Number(content.childrenLimit) || selectedClass.childrenLimit || 11;
|
|
559
836
|
const page = selectedClass.page || 1;
|
|
560
837
|
// Missing/NaN total → unknown size; refetch so invalidated cache is not treated as complete.
|
|
561
838
|
if (!Number.isFinite(expectedTotal) || files.length < expectedTotal && files.length < page * pageSize) {
|
|
@@ -592,8 +869,7 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
592
869
|
* @param {object} tree - the tree model
|
|
593
870
|
* @param {number} level - the root level
|
|
594
871
|
*/
|
|
595
|
-
function indexTree(tree) {
|
|
596
|
-
let level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
872
|
+
function indexTree(tree, level = 0) {
|
|
597
873
|
if (!tree) {
|
|
598
874
|
return;
|
|
599
875
|
}
|
|
@@ -715,7 +991,16 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
715
991
|
*/
|
|
716
992
|
function invalidateFolderFiles(path) {
|
|
717
993
|
const content = getByExactPath(fileTree, path);
|
|
718
|
-
if (content
|
|
994
|
+
if (!content) {
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
if (splitBrowse) {
|
|
998
|
+
delete content.listItems;
|
|
999
|
+
delete content.listCacheKey;
|
|
1000
|
+
delete content.listPage;
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
if (Array.isArray(content.children)) {
|
|
719
1004
|
content.children = content.children.filter(function (child) {
|
|
720
1005
|
return child.path && !child.uri;
|
|
721
1006
|
});
|
|
@@ -727,11 +1012,15 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
727
1012
|
* @param {String} path
|
|
728
1013
|
* @param {Object} data
|
|
729
1014
|
*/
|
|
730
|
-
function replaceFolderContent(path, data) {
|
|
1015
|
+
function replaceFolderContent(path, data, cacheKey) {
|
|
731
1016
|
const content = getByExactPath(fileTree, path);
|
|
732
1017
|
if (!content || !data) {
|
|
733
1018
|
return;
|
|
734
1019
|
}
|
|
1020
|
+
if (splitBrowse && Object.prototype.hasOwnProperty.call(data, 'items')) {
|
|
1021
|
+
applyListPayload(fileTree, path, data, cacheKey || listCacheKey());
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
735
1024
|
if (Object.prototype.hasOwnProperty.call(data, 'children')) {
|
|
736
1025
|
content.children = data.children;
|
|
737
1026
|
} else {
|
|
@@ -761,6 +1050,7 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
761
1050
|
function loadContent(path) {
|
|
762
1051
|
const parameters = {};
|
|
763
1052
|
parameters[options.pathParam || 'path'] = path;
|
|
1053
|
+
setTreeLoading(true);
|
|
764
1054
|
return Promise.resolve($$1.ajax({
|
|
765
1055
|
url: options.browseUrl,
|
|
766
1056
|
method: 'GET',
|
|
@@ -784,6 +1074,12 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
784
1074
|
data.children.map(responseChildren => updatePermissions(responseChildren));
|
|
785
1075
|
}
|
|
786
1076
|
return data;
|
|
1077
|
+
}).then(function (data) {
|
|
1078
|
+
setTreeLoading(false);
|
|
1079
|
+
return data;
|
|
1080
|
+
}, function (error) {
|
|
1081
|
+
setTreeLoading(false);
|
|
1082
|
+
return Promise.reject(error);
|
|
787
1083
|
});
|
|
788
1084
|
}
|
|
789
1085
|
|
|
@@ -853,7 +1149,7 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
853
1149
|
selectedClass = {
|
|
854
1150
|
path,
|
|
855
1151
|
total: Number.isFinite(normalizedTotal) && normalizedTotal >= 0 ? normalizedTotal : 0,
|
|
856
|
-
childrenLimit: Number.isFinite(normalizedChildrenLimit) && normalizedChildrenLimit > 0 ? normalizedChildrenLimit : selectedClass.childrenLimit ||
|
|
1152
|
+
childrenLimit: Number.isFinite(normalizedChildrenLimit) && normalizedChildrenLimit > 0 ? normalizedChildrenLimit : selectedClass.childrenLimit || 11,
|
|
857
1153
|
page: 1
|
|
858
1154
|
};
|
|
859
1155
|
}
|
|
@@ -890,17 +1186,35 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
890
1186
|
/**
|
|
891
1187
|
* Re-fetch the current folder with the active sort and publish files.
|
|
892
1188
|
*/
|
|
893
|
-
function reloadSortedFolder() {
|
|
894
|
-
const
|
|
895
|
-
|
|
1189
|
+
function reloadSortedFolder(pendingUploads) {
|
|
1190
|
+
const listRequest = captureListRequestContext();
|
|
1191
|
+
const path = listRequest.path;
|
|
1192
|
+
if (!searchMode && isActiveBrowser()) {
|
|
1193
|
+
setFilesLoading(true);
|
|
1194
|
+
}
|
|
1195
|
+
const loadPromise = splitBrowse ? browseRequest(path, {
|
|
1196
|
+
part: 'list',
|
|
1197
|
+
page: selectedClass.page,
|
|
1198
|
+
pageSize: selectedClass.childrenLimit || 11,
|
|
1199
|
+
sortBy: sort.field,
|
|
1200
|
+
sortDir: sort.direction
|
|
1201
|
+
}) : loadContent(path);
|
|
1202
|
+
loadPromise.then(function (data) {
|
|
896
1203
|
if (!data) {
|
|
1204
|
+
setFilesLoading(false);
|
|
897
1205
|
return;
|
|
898
1206
|
}
|
|
899
|
-
|
|
1207
|
+
if (isListRequestStale(listRequest)) {
|
|
1208
|
+
setFilesLoading(false);
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
replaceFolderContent(path, data, listRequest.cacheKey);
|
|
1212
|
+
mergePendingUploads(path, pendingUploads);
|
|
900
1213
|
const content = getByExactPath(fileTree, path) || data;
|
|
901
1214
|
selectFolder(content, content.path || path);
|
|
902
1215
|
}).catch(function (error) {
|
|
903
1216
|
LOGGER.error(error);
|
|
1217
|
+
setFilesLoading(false);
|
|
904
1218
|
});
|
|
905
1219
|
}
|
|
906
1220
|
|
|
@@ -908,14 +1222,53 @@ define(['jquery', 'lodash', 'ui/pagination', 'handlebars', 'lib/handlebars/helpe
|
|
|
908
1222
|
* Load page
|
|
909
1223
|
*/
|
|
910
1224
|
function loadPage() {
|
|
1225
|
+
const listRequest = captureListRequestContext();
|
|
1226
|
+
if (!searchMode && isActiveBrowser()) {
|
|
1227
|
+
setFilesLoading(true);
|
|
1228
|
+
}
|
|
1229
|
+
if (splitBrowse) {
|
|
1230
|
+
const path = listRequest.path;
|
|
1231
|
+
browseRequest(path, {
|
|
1232
|
+
part: 'list',
|
|
1233
|
+
page: selectedClass.page,
|
|
1234
|
+
pageSize: selectedClass.childrenLimit || 11,
|
|
1235
|
+
sortBy: sort.field,
|
|
1236
|
+
sortDir: sort.direction
|
|
1237
|
+
}).then(function (data) {
|
|
1238
|
+
if (isListRequestStale(listRequest)) {
|
|
1239
|
+
setFilesLoading(false);
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
applyListPayload(fileTree, path, data, listRequest.cacheKey);
|
|
1243
|
+
const content = getByExactPath(fileTree, path);
|
|
1244
|
+
if (content) {
|
|
1245
|
+
$container.trigger(`folderselect.${NS}`, [content.label, getFilesForDisplay(content), content.path, content]);
|
|
1246
|
+
renderPagination();
|
|
1247
|
+
}
|
|
1248
|
+
setFilesLoading(false);
|
|
1249
|
+
}).catch(function (error) {
|
|
1250
|
+
LOGGER.error(error);
|
|
1251
|
+
setFilesLoading(false);
|
|
1252
|
+
});
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
911
1255
|
const subTree = getByPath(fileTree, selectedClass.path) || fileTree;
|
|
912
1256
|
|
|
913
1257
|
//get the folder content
|
|
914
1258
|
getFolderContent(subTree, selectedClass.path, function (content) {
|
|
1259
|
+
if (isListRequestStale(listRequest)) {
|
|
1260
|
+
if (!searchMode) {
|
|
1261
|
+
setFilesLoading(false);
|
|
1262
|
+
}
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
915
1265
|
indexTree(fileTree);
|
|
916
1266
|
if (content) {
|
|
917
1267
|
//internal event to set the file-selector content
|
|
918
|
-
$container.trigger(`folderselect.${NS}`, [content.label,
|
|
1268
|
+
$container.trigger(`folderselect.${NS}`, [content.label, getFilesForDisplay(content), content.path, content]);
|
|
1269
|
+
}
|
|
1270
|
+
if (!searchMode) {
|
|
1271
|
+
setFilesLoading(false);
|
|
919
1272
|
}
|
|
920
1273
|
});
|
|
921
1274
|
}
|
|
@@ -67,6 +67,39 @@ define(['jquery', 'lodash', 'util/bytes', 'context', 'ui/previewer'], function (
|
|
|
67
67
|
}
|
|
68
68
|
return String(value);
|
|
69
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Row markup uses data-download for permission flag (boolean), not the URL.
|
|
73
|
+
* @param {*} file
|
|
74
|
+
* @returns {string}
|
|
75
|
+
*/
|
|
76
|
+
function downloadHref(file) {
|
|
77
|
+
if (typeof file.downloadUrl === 'string' && file.downloadUrl) {
|
|
78
|
+
return file.downloadUrl;
|
|
79
|
+
}
|
|
80
|
+
if (typeof file.url === 'string' && file.url) {
|
|
81
|
+
const query = file.url.split('#')[0].split('?')[1] || '';
|
|
82
|
+
const hasSvgzSupport = query.split('&').some(param => param.split('=')[0] === 'svgzsupport');
|
|
83
|
+
return hasSvgzSupport ? file.url : `${file.url}&svgzsupport=true`;
|
|
84
|
+
}
|
|
85
|
+
if (typeof file.download === 'string' && file.download) {
|
|
86
|
+
return file.download;
|
|
87
|
+
}
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {*} file
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
function downloadFilename(file) {
|
|
96
|
+
if (typeof file.display === 'string' && file.display) {
|
|
97
|
+
return file.display;
|
|
98
|
+
}
|
|
99
|
+
const path = file.file || '';
|
|
100
|
+
const idx = path.lastIndexOf('/');
|
|
101
|
+
return idx >= 0 ? path.slice(idx + 1) : path;
|
|
102
|
+
}
|
|
70
103
|
function startPreview(file, preview, download, select) {
|
|
71
104
|
if (preview) {
|
|
72
105
|
$previewer.previewer(file);
|
|
@@ -81,9 +114,15 @@ define(['jquery', 'lodash', 'util/bytes', 'context', 'ui/previewer'], function (
|
|
|
81
114
|
$propSize.text(EMPTY_META);
|
|
82
115
|
}
|
|
83
116
|
if (download) {
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
$link.
|
|
117
|
+
const href = downloadHref(file);
|
|
118
|
+
if (href) {
|
|
119
|
+
$link.attr('href', href).attr('download', downloadFilename(file));
|
|
120
|
+
if ($link.hasClass('hidden')) {
|
|
121
|
+
$link.removeClass('hidden');
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
$link.attr('href', '#').removeAttr('download');
|
|
125
|
+
$link.addClass('hidden');
|
|
87
126
|
}
|
|
88
127
|
} else {
|
|
89
128
|
$link.attr('href', '#').attr('download', '#');
|
|
@@ -312,6 +312,8 @@ define(['jquery', 'lodash', 'async', 'i18n', 'core/mimetype', 'handlebars', 'lib
|
|
|
312
312
|
let $container = options.$target;
|
|
313
313
|
let $fileSelector = $$1('.file-selector', $container);
|
|
314
314
|
let $filesWrapper = $$1('.files-wrapper', $fileSelector);
|
|
315
|
+
let $filesListLoading = $$1('.files-list-loading', $filesWrapper);
|
|
316
|
+
let $filesListLoadingStatus = $$1('.files-list-loading-status', $filesListLoading);
|
|
315
317
|
let $fileContainer = $$1('.files-list', $fileSelector);
|
|
316
318
|
let $placeholder = $$1('.empty', $fileSelector);
|
|
317
319
|
let $uploader = $$1('.file-upload-container', $fileSelector);
|
|
@@ -338,6 +340,18 @@ define(['jquery', 'lodash', 'async', 'i18n', 'core/mimetype', 'handlebars', 'lib
|
|
|
338
340
|
searchMode = !!enabled;
|
|
339
341
|
$fileSelector.toggleClass('search-mode', searchMode);
|
|
340
342
|
});
|
|
343
|
+
function applyFilesListLoading(loading) {
|
|
344
|
+
$filesWrapper.toggleClass('is-files-loading', !!loading);
|
|
345
|
+
$filesWrapper.attr('aria-busy', loading ? 'true' : 'false');
|
|
346
|
+
$filesListLoading.toggleClass('hidden', !loading).attr('aria-hidden', loading ? 'false' : 'true');
|
|
347
|
+
$filesListLoadingStatus.attr('aria-busy', loading ? 'true' : 'false');
|
|
348
|
+
}
|
|
349
|
+
$container.on(`filesloading.${ns}`, function (e, loading) {
|
|
350
|
+
if (searchMode) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
applyFilesListLoading(loading);
|
|
354
|
+
});
|
|
341
355
|
|
|
342
356
|
//update current folder
|
|
343
357
|
$container.on(`folderselect.${ns}`, function (e, fullPath, data, activePath, content) {
|
|
@@ -345,6 +359,7 @@ define(['jquery', 'lodash', 'async', 'i18n', 'core/mimetype', 'handlebars', 'lib
|
|
|
345
359
|
if (searchMode) {
|
|
346
360
|
return;
|
|
347
361
|
}
|
|
362
|
+
applyFilesListLoading(false);
|
|
348
363
|
|
|
349
364
|
//update title
|
|
350
365
|
if ($container[0].querySelector('.upload')) {
|