@oat-sa/tao-core-ui 3.23.0 → 3.24.1
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/figure/FigureStateActive.js +64 -32
- package/dist/image/ImgStateActive/initHelper.js +64 -32
- package/dist/image/ImgStateActive.js +64 -32
- package/dist/previewer.js +1 -1
- package/dist/resourcemgr/assetSearch.js +793 -0
- package/dist/resourcemgr/assetSearchContract.js +477 -0
- package/dist/resourcemgr/css/resourcemgr.css +1230 -97
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +815 -83
- package/dist/resourcemgr/filePreview.js +82 -7
- package/dist/resourcemgr/fileSelector.js +377 -92
- package/dist/resourcemgr.js +314 -57
- package/dist/searchModal/advancedSearch.js +233 -31
- package/package.json +15 -6
- package/src/image/ImgStateActive/initHelper.js +69 -31
- package/src/previewer.js +1 -1
- package/src/resourcemgr/assetSearch.js +847 -0
- package/src/resourcemgr/assetSearchContract.js +489 -0
- package/src/resourcemgr/css/resourcemgr.css +1230 -97
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +872 -92
- package/src/resourcemgr/filePreview.js +89 -8
- package/src/resourcemgr/fileSelector.js +356 -46
- package/src/resourcemgr/scss/resourcemgr.scss +1450 -89
- package/src/resourcemgr/tpl/advanced-search.tpl +10 -0
- package/src/resourcemgr/tpl/fileSelect.tpl +25 -28
- package/src/resourcemgr/tpl/folder.tpl +4 -1
- package/src/resourcemgr/tpl/layout.tpl +125 -54
- package/src/resourcemgr/tpl/rootFolder.tpl +3 -1
- package/src/resourcemgr.js +294 -47
- package/src/searchModal/advancedSearch.js +242 -31
package/dist/resourcemgr.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'ui/resourcemgr/filePreview', 'ui/resourcemgr/fileSelector', 'handlebars', 'lib/handlebars/helpers', 'ui/modal', 'css!ui/resourcemgr/css/resourcemgr.css'], function ($$1, _, Pluginifier, fileBrowser, filePreview, fileSelector, Handlebars, Helpers0, modal, resourcemgr_css) { 'use strict';
|
|
1
|
+
define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/assetSearch', 'ui/resourcemgr/fileBrowser', 'ui/resourcemgr/filePreview', 'ui/resourcemgr/fileSelector', 'ui/feedback', 'handlebars', 'lib/handlebars/helpers', 'util/url', 'i18n', 'ui/modal', 'css!ui/resourcemgr/css/resourcemgr.css'], function ($$1, _, Pluginifier, assetSearch, fileBrowser, filePreview, fileSelector, feedback, Handlebars, Helpers0, urlUtil, __, modal, resourcemgr_css) { 'use strict';
|
|
2
2
|
|
|
3
3
|
$$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
|
|
4
4
|
_ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
|
|
5
5
|
Pluginifier = Pluginifier && Object.prototype.hasOwnProperty.call(Pluginifier, 'default') ? Pluginifier['default'] : Pluginifier;
|
|
6
|
+
assetSearch = assetSearch && Object.prototype.hasOwnProperty.call(assetSearch, 'default') ? assetSearch['default'] : assetSearch;
|
|
6
7
|
fileBrowser = fileBrowser && Object.prototype.hasOwnProperty.call(fileBrowser, 'default') ? fileBrowser['default'] : fileBrowser;
|
|
7
8
|
filePreview = filePreview && Object.prototype.hasOwnProperty.call(filePreview, 'default') ? filePreview['default'] : filePreview;
|
|
8
9
|
fileSelector = fileSelector && Object.prototype.hasOwnProperty.call(fileSelector, 'default') ? fileSelector['default'] : fileSelector;
|
|
10
|
+
feedback = feedback && Object.prototype.hasOwnProperty.call(feedback, 'default') ? feedback['default'] : feedback;
|
|
9
11
|
Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
|
|
10
12
|
Helpers0 = Helpers0 && Object.prototype.hasOwnProperty.call(Helpers0, 'default') ? Helpers0['default'] : Helpers0;
|
|
13
|
+
urlUtil = urlUtil && Object.prototype.hasOwnProperty.call(urlUtil, 'default') ? urlUtil['default'] : urlUtil;
|
|
14
|
+
__ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
|
|
11
15
|
|
|
12
16
|
if (!Helpers0.__initialized) {
|
|
13
17
|
Helpers0(Handlebars);
|
|
@@ -33,31 +37,71 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
33
37
|
if (helper = helpers.title) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
34
38
|
else { helper = (depth0 && depth0.title); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
35
39
|
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
36
|
-
buffer += "</h2>\n\n <div class=\"file-wrapper\">\n\n <!-- left section:
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
buffer += "</h2>\n\n <div class=\"file-wrapper\">\n\n <div class=\"file-panels\">\n <!-- left section: search, filters, folder tree -->\n <section class=\"file-browser\">\n <div class=\"asset-search hidden\" hidden>\n <div class=\"asset-search-header\">\n <button\n type=\"button\"\n class=\"asset-search-toggle\"\n aria-expanded=\"true\"\n aria-controls=\"";
|
|
41
|
+
if (helper = helpers.assetSearchBodyId) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
42
|
+
else { helper = (depth0 && depth0.assetSearchBodyId); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
43
|
+
buffer += escapeExpression(stack1)
|
|
44
|
+
+ "\"\n >\n <span class=\"asset-search-title\">"
|
|
45
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search", options) : helperMissing.call(depth0, "__", "Search", options)))
|
|
46
|
+
+ "</span>\n <span class=\"asset-search-applied-count hidden\" hidden></span>\n <span class=\"asset-search-scope\" aria-live=\"polite\">\n <span class=\"asset-search-scope-prefix\">"
|
|
47
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Searching in:", options) : helperMissing.call(depth0, "__", "Searching in:", options)))
|
|
48
|
+
+ "</span>\n <span class=\"asset-search-scope-name\"></span>\n <span class=\"asset-search-scope-subfolders hidden\" hidden>"
|
|
49
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "and its subfolders", options) : helperMissing.call(depth0, "__", "and its subfolders", options)))
|
|
50
|
+
+ "</span>\n </span>\n <span class=\"asset-search-chevron icon-up\" aria-hidden=\"true\"></span>\n </button>\n </div>\n <div class=\"asset-search-body\" id=\"";
|
|
51
|
+
if (helper = helpers.assetSearchBodyId) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
52
|
+
else { helper = (depth0 && depth0.assetSearchBodyId); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
53
|
+
buffer += escapeExpression(stack1)
|
|
54
|
+
+ "\">\n <div class=\"asset-search-field\">\n <span class=\"icon-find\" aria-hidden=\"true\"></span>\n <label class=\"asset-search-label\" for=\"";
|
|
55
|
+
if (helper = helpers.assetSearchInputId) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
56
|
+
else { helper = (depth0 && depth0.assetSearchInputId); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
57
|
+
buffer += escapeExpression(stack1)
|
|
58
|
+
+ "\">"
|
|
59
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search by name or label", options) : helperMissing.call(depth0, "__", "Search by name or label", options)))
|
|
60
|
+
+ "</label>\n <input\n id=\"";
|
|
61
|
+
if (helper = helpers.assetSearchInputId) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
62
|
+
else { helper = (depth0 && depth0.assetSearchInputId); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
63
|
+
buffer += escapeExpression(stack1)
|
|
64
|
+
+ "\"\n type=\"search\"\n class=\"asset-search-input\"\n placeholder=\""
|
|
65
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search by name or label", options) : helperMissing.call(depth0, "__", "Search by name or label", options)))
|
|
66
|
+
+ "\"\n autocomplete=\"off\"\n />\n </div>\n <div class=\"asset-search-filters\"></div>\n <div class=\"asset-search-actions\">\n <button type=\"button\" class=\"asset-search-clear hidden\" hidden>"
|
|
67
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Clear all", options) : helperMissing.call(depth0, "__", "Clear all", options)))
|
|
68
|
+
+ "</button>\n <button type=\"button\" class=\"btn-info small asset-search-submit\" disabled>\n <span class=\"asset-search-submit-spinner icon-loop hidden\" aria-hidden=\"true\"></span>\n <span class=\"asset-search-submit-label\">"
|
|
69
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search", options) : helperMissing.call(depth0, "__", "Search", options)))
|
|
70
|
+
+ "</span>\n </button>\n </div>\n </div>\n </div>\n\n <h1 class=\"resources-title\">"
|
|
71
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Resources", options) : helperMissing.call(depth0, "__", "Resources", options)))
|
|
72
|
+
+ "</h1>\n <div class=\"file-browser-wrapper\" aria-busy=\"false\">\n <div class=\"file-browser-tree-loading hidden\" aria-hidden=\"true\">\n <span class=\"icon-loop\" aria-hidden=\"true\"></span>\n <span class=\"file-browser-tree-loading-status\" aria-live=\"polite\" aria-atomic=\"true\" aria-busy=\"false\">"
|
|
73
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Loading", options) : helperMissing.call(depth0, "__", "Loading", options)))
|
|
74
|
+
+ "</span>\n </div>\n <div class=\"file-browser-scroll\"></div>\n </div>\n </section>\n\n <!-- center: asset listing -->\n <section class=\"file-selector\">\n\n <h1>\n <div class=\"title lft\">"
|
|
75
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Assets", options) : helperMissing.call(depth0, "__", "Assets", options)))
|
|
76
|
+
+ "</div>\n <div class=\"upload-switcher rgt\">\n <a href=\"#\" class=\"btn-info small upload hidden\"><span class=\"icon-add\"></span>"
|
|
39
77
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Add file(s)", options) : helperMissing.call(depth0, "__", "Add file(s)", options)))
|
|
40
|
-
+ "</a>\n
|
|
78
|
+
+ "</a>\n <a href=\"#\" class=\"btn-info small listing\"><span class=\"icon-undo\"></span>"
|
|
41
79
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Back to listing", options) : helperMissing.call(depth0, "__", "Back to listing", options)))
|
|
42
|
-
+ "</a>\n
|
|
80
|
+
+ "</a>\n </div>\n </h1>\n\n <div class=\"asset-search-error hidden\" hidden role=\"alert\">\n <p class=\"asset-search-error-message\"></p>\n <button type=\"button\" class=\"btn-info small asset-search-retry\">"
|
|
81
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Retry", options) : helperMissing.call(depth0, "__", "Retry", options)))
|
|
82
|
+
+ "</button>\n </div>\n\n <div class=\"empty\">\n "
|
|
43
83
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "No files", options) : helperMissing.call(depth0, "__", "No files", options)))
|
|
44
|
-
+ "\n
|
|
84
|
+
+ "\n </div>\n\n <div class=\"files-wrapper\" aria-busy=\"false\">\n <div class=\"files-list-loading hidden\" aria-hidden=\"true\">\n <span class=\"icon-loop\" aria-hidden=\"true\"></span>\n <span class=\"files-list-loading-status\" aria-live=\"polite\" aria-atomic=\"true\" aria-busy=\"false\">"
|
|
85
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Loading", options) : helperMissing.call(depth0, "__", "Loading", options)))
|
|
86
|
+
+ "</span>\n </div>\n <div class=\"files-scroll\">\n <table class=\"files\">\n <thead>\n <tr>\n <th class=\"files-label sortable sorted sorted_asc\" data-sort-by=\"label\" aria-sort=\"ascending\" tabindex=\"0\">\n <span class=\"sort-label\">"
|
|
87
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Label", options) : helperMissing.call(depth0, "__", "Label", options)))
|
|
88
|
+
+ "</span>\n </th>\n <th class=\"files-location sortable\" data-sort-by=\"location\" aria-sort=\"none\" tabindex=\"0\">\n <span class=\"sort-label\">"
|
|
89
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Location", options) : helperMissing.call(depth0, "__", "Location", options)))
|
|
90
|
+
+ "</span>\n </th>\n <th class=\"files-updated sortable\" data-sort-by=\"updatedAt\" aria-sort=\"none\" tabindex=\"0\">\n <span class=\"sort-label\">"
|
|
91
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Last modified on", options) : helperMissing.call(depth0, "__", "Last modified on", options)))
|
|
92
|
+
+ "</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"files-list\"></tbody>\n </table>\n </div>\n </div>\n\n <div class=\"file-upload-container\"></div>\n\n <div class=\"pagination-bottom\"></div>\n\n </section>\n\n <section class=\"file-preview\">\n\n <h1>"
|
|
45
93
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Preview", options) : helperMissing.call(depth0, "__", "Preview", options)))
|
|
46
|
-
+ "</h1>\n\n
|
|
47
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "File Properties", options) : helperMissing.call(depth0, "__", "File Properties", options)))
|
|
48
|
-
+ "</h2>\n\n <div class=\"file-properties\">\n\n <div class=\"grid-row\">\n <div class=\"col-2\">\n "
|
|
94
|
+
+ "</h1>\n\n <div class=\"previewer\">\n <p class=\"nopreview\"></p>\n </div>\n\n <div class=\"file-properties\">\n\n <div class=\"grid-row\">\n <div class=\"col-2\">\n "
|
|
49
95
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Type", options) : helperMissing.call(depth0, "__", "Type", options)))
|
|
50
|
-
+ "\n
|
|
96
|
+
+ "\n </div>\n <div class=\"col-10 prop-type\">—</div>\n </div>\n\n <div class=\"grid-row\">\n <div class=\"col-2\">\n "
|
|
51
97
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Size", options) : helperMissing.call(depth0, "__", "Size", options)))
|
|
52
|
-
+ "\n
|
|
98
|
+
+ "\n </div>\n <div class=\"col-10 prop-size\">—</div>\n </div>\n\n <div class=\"grid-row prop-url\">\n <div class=\"actions\">\n <a href=\"#\" download=\"\" target=\"_blank\" class=\"tlb-button-off download hidden\" title=\""
|
|
53
99
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Download this file", options) : helperMissing.call(depth0, "__", "Download this file", options)))
|
|
54
|
-
+ "\">\n
|
|
100
|
+
+ "\">\n <span class=\"icon-download\"></span>"
|
|
55
101
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Download this file", options) : helperMissing.call(depth0, "__", "Download this file", options)))
|
|
56
|
-
+ "\n </
|
|
57
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Actions", options) : helperMissing.call(depth0, "__", "Actions", options)))
|
|
58
|
-
+ "</h2>\n\n <div class=\"actions\">\n <button class=\"btn-success select-action small\" disabled>\n <span class=\"icon-move-item\"></span>"
|
|
102
|
+
+ "\n </a>\n </div>\n </div>\n </div>\n\n <div class=\"actions select-actions\">\n <button class=\"btn-success select-action small\" disabled>\n <span class=\"icon-move-item\"></span>"
|
|
59
103
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Select", options) : helperMissing.call(depth0, "__", "Select", options)))
|
|
60
|
-
+ "\n
|
|
104
|
+
+ "\n </button>\n </div>\n\n </section>\n </div>\n\n </div>\n</div>\n";
|
|
61
105
|
return buffer;
|
|
62
106
|
});
|
|
63
107
|
function layout(data, options, asString) {
|
|
@@ -74,7 +118,14 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
74
118
|
}],
|
|
75
119
|
open: true,
|
|
76
120
|
appendContainer: '.tao-scope:first',
|
|
77
|
-
title: ''
|
|
121
|
+
title: '',
|
|
122
|
+
pathParam: 'path',
|
|
123
|
+
// Advanced Search metadata filters (same endpoints as ui/searchModal)
|
|
124
|
+
rootClassUri: 'http://www.tao.lu/Ontologies/TAOMedia.rdf#Media',
|
|
125
|
+
classMappingUrl: urlUtil.route('getWithMapping', 'ClassMetadata', 'tao'),
|
|
126
|
+
statusUrl: urlUtil.route('status', 'AdvancedSearch', 'tao'),
|
|
127
|
+
maxListSize: 5,
|
|
128
|
+
ajaxTimeoutMs: 30000
|
|
78
129
|
};
|
|
79
130
|
|
|
80
131
|
/**
|
|
@@ -93,7 +144,18 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
93
144
|
* @constructor
|
|
94
145
|
* @param {Object} options - the plugin options
|
|
95
146
|
* @param {Sring|Boolean} [options.bindEvent = 'click'] - the event that trigger the toggling
|
|
96
|
-
* @param {String} options.
|
|
147
|
+
* @param {String} [options.browseUrl] - folder browse endpoint (legacy alias: options.url)
|
|
148
|
+
* @param {String} [options.url] - legacy alias for browseUrl
|
|
149
|
+
* @param {String} [options.searchUrl] - scoped asset-search endpoint; omit for browse-only
|
|
150
|
+
* @param {Boolean} [options.browseSearchFallback=false] - client filter when searchUrl returns browse-shaped `{ children }`
|
|
151
|
+
* @param {String} [options.initialPath] - folder to open on start (within the media source tree)
|
|
152
|
+
* @param {String} [options.initialSelection] - asset URI to preselect when present in results
|
|
153
|
+
* @param {String} [options.currentAsset] - asset URI/path to resolve to parent folder + selection
|
|
154
|
+
* @param {String} [options.pathParam='path'] - query parameter name for folder/asset path
|
|
155
|
+
* @param {String} [options.rootClassUri=TAOMedia#Media] - Assets class URI for Advanced Search criteria (metadata filters)
|
|
156
|
+
* @param {String} [options.classMappingUrl] - ClassMetadata mapping endpoint for criteria list
|
|
157
|
+
* @param {String} [options.statusUrl] - Advanced Search status endpoint
|
|
158
|
+
* @param {Number} [options.maxListSize=5] - max list values per criterion in filters UI
|
|
97
159
|
* @fires ResourceMgr#create.resourcemgr
|
|
98
160
|
* @returns {jQueryElement} for chaining
|
|
99
161
|
*/
|
|
@@ -102,6 +164,9 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
102
164
|
|
|
103
165
|
//get options using default
|
|
104
166
|
options = _.defaults(options, defaults);
|
|
167
|
+
if (!options.browseUrl && options.url) {
|
|
168
|
+
options.browseUrl = options.url;
|
|
169
|
+
}
|
|
105
170
|
return this.each(function () {
|
|
106
171
|
var $elt = $$1(this);
|
|
107
172
|
var $target;
|
|
@@ -112,7 +177,10 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
112
177
|
//auto bind events configured in options
|
|
113
178
|
_.functions(options).forEach(function (eventName) {
|
|
114
179
|
$elt.on(eventName + '.' + ns, function () {
|
|
115
|
-
|
|
180
|
+
const live = $elt.data(dataNs);
|
|
181
|
+
if (live && typeof live[eventName] === 'function') {
|
|
182
|
+
live[eventName].apply($elt, arguments);
|
|
183
|
+
}
|
|
116
184
|
});
|
|
117
185
|
});
|
|
118
186
|
$target = options.$target || that._createTarget($elt);
|
|
@@ -129,49 +197,236 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
129
197
|
$target.on('closed.modal', function () {
|
|
130
198
|
$elt.trigger('close.' + ns);
|
|
131
199
|
});
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
200
|
+
options.contextToken = 1;
|
|
201
|
+
const initToken = options.contextToken;
|
|
202
|
+
$elt.data(dataNs, options);
|
|
203
|
+
that._resolveCurrentAssetContext(options, initToken).always(function (resolvedOptions) {
|
|
204
|
+
const current = $elt.data(dataNs);
|
|
205
|
+
if (!current) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const ownsOpen = current.contextToken === initToken;
|
|
209
|
+
if (!ownsOpen) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
$elt.data(dataNs, resolvedOptions);
|
|
213
|
+
that._ensureBrowsersStarted($elt, resolvedOptions).always(function () {
|
|
214
|
+
const latest = $elt.data(dataNs) || resolvedOptions;
|
|
215
|
+
if (!latest._createEventEmitted) {
|
|
216
|
+
latest._createEventEmitted = true;
|
|
217
|
+
$elt.data(dataNs, latest);
|
|
218
|
+
/**
|
|
219
|
+
* The plugin have been created.
|
|
220
|
+
* @event ResourceMgr#create.resourcemgr
|
|
221
|
+
*/
|
|
222
|
+
$elt.trigger('create.' + ns, [latest.$target[0]]);
|
|
142
223
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
options.root = defaults.mediaSources[i].root;
|
|
146
|
-
options.path = defaults.mediaSources[i].path;
|
|
147
|
-
$fileBrowser.append('<div class="' + options.root + '"><ul class="folders"></ul></div>');
|
|
148
|
-
fileBrowser(options);
|
|
224
|
+
if (ownsOpen && latest.open) {
|
|
225
|
+
that._open($elt);
|
|
149
226
|
}
|
|
150
227
|
});
|
|
151
|
-
}
|
|
152
|
-
$fileBrowser.append('<div class="' + options.root + '"><ul class="folders"></ul></div>');
|
|
153
|
-
fileBrowser(options);
|
|
154
|
-
}
|
|
155
|
-
$fileBrowser.find('li.root:last').addClass('active');
|
|
156
|
-
fileSelector(options);
|
|
157
|
-
filePreview(options);
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* The plugin have been created.
|
|
161
|
-
* @event ResourceMgr#create.resourcemgr
|
|
162
|
-
*/
|
|
163
|
-
$elt.trigger('create.' + ns, [$target[0]]);
|
|
164
|
-
if (options.open) {
|
|
165
|
-
that._open($elt);
|
|
166
|
-
}
|
|
228
|
+
});
|
|
167
229
|
} else {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
that._open($elt);
|
|
171
|
-
}
|
|
230
|
+
// Reopen: consumer may pass a new currentAsset (edit/change after create).
|
|
231
|
+
that._reopenWithContext($elt, options);
|
|
172
232
|
}
|
|
173
233
|
});
|
|
174
234
|
},
|
|
235
|
+
/**
|
|
236
|
+
* Merge reopen options, re-resolve currentAsset, re-apply folder/selection, then open.
|
|
237
|
+
* @param {jQuery} $elt
|
|
238
|
+
* @param {Object} incoming - options from the latest .resourcemgr(…) call
|
|
239
|
+
*/
|
|
240
|
+
_reopenWithContext: function ($elt, incoming) {
|
|
241
|
+
const that = resourceMgr;
|
|
242
|
+
const stored = $elt.data(dataNs);
|
|
243
|
+
if (!stored) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (Object.prototype.hasOwnProperty.call(incoming, 'currentAsset')) {
|
|
247
|
+
stored.currentAsset = incoming.currentAsset;
|
|
248
|
+
stored.initialPath = null;
|
|
249
|
+
stored.initialSelection = null;
|
|
250
|
+
stored.currentAssetItem = null;
|
|
251
|
+
}
|
|
252
|
+
if (incoming.params && typeof incoming.params === 'object') {
|
|
253
|
+
stored.params = Object.assign({}, stored.params || {}, incoming.params);
|
|
254
|
+
}
|
|
255
|
+
['select', 'open', 'close'].forEach(function (key) {
|
|
256
|
+
if (typeof incoming[key] === 'function') {
|
|
257
|
+
stored[key] = incoming[key];
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
stored.contextToken = (stored.contextToken || 0) + 1;
|
|
261
|
+
const token = stored.contextToken;
|
|
262
|
+
$elt.data(dataNs, stored);
|
|
263
|
+
that._resolveCurrentAssetContext(stored, token).always(function (resolved) {
|
|
264
|
+
const current = $elt.data(dataNs);
|
|
265
|
+
if (!current || current.contextToken !== token) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
$elt.data(dataNs, resolved);
|
|
269
|
+
that._ensureBrowsersStarted($elt, resolved).always(function () {
|
|
270
|
+
that._applyResolvedContext($elt, resolved);
|
|
271
|
+
that._open($elt);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
},
|
|
275
|
+
/**
|
|
276
|
+
* Notify mounted browser/selector to open parent folder and (re)preselect.
|
|
277
|
+
* @param {jQuery} $elt
|
|
278
|
+
* @param {Object} options
|
|
279
|
+
*/
|
|
280
|
+
_applyResolvedContext: function ($elt, options) {
|
|
281
|
+
if (!options || !options.$target) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
options.$target.trigger('applycontext.' + ns, [{
|
|
285
|
+
path: options.initialPath || options.path || '/',
|
|
286
|
+
selection: options.initialSelection || null,
|
|
287
|
+
currentAssetItem: options.currentAssetItem || null
|
|
288
|
+
}]);
|
|
289
|
+
},
|
|
290
|
+
/**
|
|
291
|
+
* Resolve currentAsset via browse/search endpoint into initialPath/initialSelection.
|
|
292
|
+
* @param {Object} options
|
|
293
|
+
* @param {number} [expectedToken] - contextToken that must still match before mutating options
|
|
294
|
+
* @returns {Promise}
|
|
295
|
+
*/
|
|
296
|
+
_resolveCurrentAssetContext: function (options, expectedToken) {
|
|
297
|
+
const deferred = $$1.Deferred();
|
|
298
|
+
const isStale = function () {
|
|
299
|
+
return typeof expectedToken !== 'undefined' && expectedToken !== null && options.contextToken !== expectedToken;
|
|
300
|
+
};
|
|
301
|
+
if (!options.currentAsset || !options.browseUrl && !options.searchUrl) {
|
|
302
|
+
deferred.resolve(options);
|
|
303
|
+
return deferred.promise();
|
|
304
|
+
}
|
|
305
|
+
const endpoint = options.browseUrl || options.searchUrl;
|
|
306
|
+
const pathParam = options.pathParam || 'path';
|
|
307
|
+
const params = Object.assign({}, options.params || {}, {
|
|
308
|
+
currentAsset: options.currentAsset
|
|
309
|
+
});
|
|
310
|
+
params[pathParam] = options.path || '/';
|
|
311
|
+
$$1.ajax({
|
|
312
|
+
url: endpoint,
|
|
313
|
+
method: 'GET',
|
|
314
|
+
dataType: 'json',
|
|
315
|
+
timeout: Number(options.ajaxTimeoutMs) > 0 ? Number(options.ajaxTimeoutMs) : defaults.ajaxTimeoutMs,
|
|
316
|
+
data: params
|
|
317
|
+
}).done(function (response) {
|
|
318
|
+
if (isStale()) {
|
|
319
|
+
deferred.resolve(options);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const payload = response && response.data ? response.data : response;
|
|
323
|
+
if (payload && payload.parentPath) {
|
|
324
|
+
options.initialPath = payload.parentPath;
|
|
325
|
+
}
|
|
326
|
+
if (payload && payload.currentAsset && payload.currentAsset.uri) {
|
|
327
|
+
options.initialSelection = payload.currentAsset.uri;
|
|
328
|
+
options.currentAssetItem = payload.currentAsset;
|
|
329
|
+
} else {
|
|
330
|
+
options.initialSelection = null;
|
|
331
|
+
options.currentAssetItem = null;
|
|
332
|
+
}
|
|
333
|
+
deferred.resolve(options);
|
|
334
|
+
}).fail(function () {
|
|
335
|
+
if (isStale()) {
|
|
336
|
+
deferred.resolve(options);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
// AC6: keep RM usable without selection; surface recoverable feedback.
|
|
340
|
+
options.initialSelection = null;
|
|
341
|
+
options.currentAssetItem = null;
|
|
342
|
+
if (options.$target && options.$target.length) {
|
|
343
|
+
feedback(options.$target).warning(__('Unable to resolve the current asset. You can still browse and select another file.'));
|
|
344
|
+
}
|
|
345
|
+
deferred.resolve(options);
|
|
346
|
+
});
|
|
347
|
+
return deferred.promise();
|
|
348
|
+
},
|
|
349
|
+
/**
|
|
350
|
+
* Start browsers once and resolve when the tree wrapper is mounted.
|
|
351
|
+
* @param {jQuery} $elt
|
|
352
|
+
* @param {Object} options
|
|
353
|
+
* @returns {Promise}
|
|
354
|
+
*/
|
|
355
|
+
_ensureBrowsersStarted: function ($elt, options) {
|
|
356
|
+
const stored = $elt.data(dataNs) || options;
|
|
357
|
+
if (stored._browsersStartPromise) {
|
|
358
|
+
return stored._browsersStartPromise;
|
|
359
|
+
}
|
|
360
|
+
stored._browsersStartPromise = this._startBrowsers($elt, stored);
|
|
361
|
+
$elt.data(dataNs, stored);
|
|
362
|
+
return stored._browsersStartPromise;
|
|
363
|
+
},
|
|
364
|
+
/**
|
|
365
|
+
* Mount file browser / selector / search after options are ready.
|
|
366
|
+
* @param {jQuery} $elt
|
|
367
|
+
* @param {Object} options
|
|
368
|
+
*/
|
|
369
|
+
_startBrowsers: function ($elt, options) {
|
|
370
|
+
const $fileBrowser = $$1('.file-browser .file-browser-wrapper', options.$target);
|
|
371
|
+
const waitForTreeWrapper = function () {
|
|
372
|
+
const deferred = $$1.Deferred();
|
|
373
|
+
const isMounted = function () {
|
|
374
|
+
return $fileBrowser.children().length > 0;
|
|
375
|
+
};
|
|
376
|
+
if (isMounted()) {
|
|
377
|
+
deferred.resolve();
|
|
378
|
+
return deferred.promise();
|
|
379
|
+
}
|
|
380
|
+
let attempts = 200;
|
|
381
|
+
const poll = function () {
|
|
382
|
+
if (isMounted()) {
|
|
383
|
+
deferred.resolve();
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
attempts -= 1;
|
|
387
|
+
if (attempts <= 0) {
|
|
388
|
+
deferred.reject();
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
window.setTimeout(poll, 50);
|
|
392
|
+
};
|
|
393
|
+
poll();
|
|
394
|
+
return deferred.promise();
|
|
395
|
+
};
|
|
396
|
+
const finishMount = function () {
|
|
397
|
+
$fileBrowser.find('li.root:last').addClass('active');
|
|
398
|
+
fileSelector(options);
|
|
399
|
+
filePreview(options);
|
|
400
|
+
assetSearch(options);
|
|
401
|
+
};
|
|
402
|
+
const mountFromSources = function (mediaSources) {
|
|
403
|
+
const sources = mediaSources || defaults.mediaSources;
|
|
404
|
+
for (let i = 0; i < sources.length; i++) {
|
|
405
|
+
options.root = sources[i].root;
|
|
406
|
+
options.path = sources[i].path;
|
|
407
|
+
$fileBrowser.children('.file-browser-scroll').append('<div class="' + options.root + '"><ul class="folders"></ul></div>');
|
|
408
|
+
fileBrowser(options);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
const afterComponentsMounted = function () {
|
|
412
|
+
finishMount();
|
|
413
|
+
return waitForTreeWrapper();
|
|
414
|
+
};
|
|
415
|
+
if (options.mediaSourcesUrl) {
|
|
416
|
+
return $$1.getJSON(options.mediaSourcesUrl).then(function (data) {
|
|
417
|
+
mountFromSources(data || defaults.mediaSources);
|
|
418
|
+
return afterComponentsMounted();
|
|
419
|
+
}, function () {
|
|
420
|
+
mountFromSources(defaults.mediaSources);
|
|
421
|
+
return afterComponentsMounted();
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
if (options.path && options.root) {
|
|
425
|
+
$fileBrowser.children('.file-browser-scroll').append('<div class="' + options.root + '"><ul class="folders"></ul></div>');
|
|
426
|
+
fileBrowser(options);
|
|
427
|
+
}
|
|
428
|
+
return afterComponentsMounted();
|
|
429
|
+
},
|
|
175
430
|
_createTarget: function ($elt) {
|
|
176
431
|
var options = $elt.data(dataNs);
|
|
177
432
|
if (options) {
|
|
@@ -181,7 +436,9 @@ define(['jquery', 'lodash', 'core/pluginifier', 'ui/resourcemgr/fileBrowser', 'u
|
|
|
181
436
|
//generate
|
|
182
437
|
options.$target = $$1(layout({
|
|
183
438
|
title: options.title || '',
|
|
184
|
-
className: options.className || ''
|
|
439
|
+
className: options.className || '',
|
|
440
|
+
assetSearchInputId: options.targetId + '-asset-search',
|
|
441
|
+
assetSearchBodyId: options.targetId + '-asset-search-body'
|
|
185
442
|
}));
|
|
186
443
|
options.$target.attr('id', options.targetId).css('display', 'none').appendTo(options.appendContainer);
|
|
187
444
|
$elt.data(dataNs, options);
|