@oat-sa/tao-core-ui 1.57.0 → 1.58.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.
Files changed (171) hide show
  1. package/dist/actionbar.js +386 -395
  2. package/dist/adder.js +21 -19
  3. package/dist/animable/absorbable/absorbable.js +204 -213
  4. package/dist/animable/absorbable/css/absorb.css +1 -0
  5. package/dist/animable/absorbable/css/absorb.css.map +1 -1
  6. package/dist/animable/pulsable/pulsable.js +168 -177
  7. package/dist/autocomplete/css/autocomplete.css +1 -0
  8. package/dist/autocomplete/css/autocomplete.css.map +1 -1
  9. package/dist/autocomplete.js +68 -66
  10. package/dist/badge/badge.js +188 -197
  11. package/dist/badge/css/badge.css +1 -0
  12. package/dist/badge/css/badge.css.map +1 -1
  13. package/dist/breadcrumbs.js +275 -284
  14. package/dist/btngrouper.js +5 -5
  15. package/dist/bulkActionPopup.js +490 -495
  16. package/dist/button.js +283 -291
  17. package/dist/cascadingComboBox.js +249 -258
  18. package/dist/ckeditor/ckConfigurator.js +42 -20
  19. package/dist/ckeditor/dtdHandler.js +11 -9
  20. package/dist/class/selector.js +441 -450
  21. package/dist/component/resizable.js +1 -1
  22. package/dist/component/windowed.js +285 -294
  23. package/dist/component.js +419 -428
  24. package/dist/contextualPopup.js +417 -426
  25. package/dist/dashboard.js +300 -309
  26. package/dist/datalist.js +753 -762
  27. package/dist/datatable/filterStrategy/multiple.js +1 -1
  28. package/dist/datatable/filterStrategy/single.js +1 -1
  29. package/dist/datatable.js +1527 -1550
  30. package/dist/dateRange/dateRange.js +393 -402
  31. package/dist/datetime/picker.js +665 -672
  32. package/dist/deleter.js +368 -377
  33. package/dist/destination/selector.js +286 -295
  34. package/dist/dialog/alert.js +3 -3
  35. package/dist/dialog/confirm.js +1 -1
  36. package/dist/dialog/confirmDelete.js +216 -225
  37. package/dist/dialog.js +650 -654
  38. package/dist/disabler.js +8 -8
  39. package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +166 -175
  40. package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +518 -527
  41. package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +380 -389
  42. package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +539 -548
  43. package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +369 -378
  44. package/dist/documentViewer/providers/pdfViewer.js +184 -193
  45. package/dist/documentViewer.js +292 -301
  46. package/dist/dropdown.js +383 -392
  47. package/dist/durationer.js +5 -5
  48. package/dist/dynamicComponent.js +597 -598
  49. package/dist/feedback.js +356 -362
  50. package/dist/figure/FigureStateActive.js +117 -108
  51. package/dist/filesender.js +2 -2
  52. package/dist/filter.js +230 -239
  53. package/dist/form/dropdownForm.js +355 -357
  54. package/dist/form/form.js +919 -690
  55. package/dist/form/simpleForm.js +1 -1
  56. package/dist/form/validator/renderer.js +233 -235
  57. package/dist/form/validator/validator.js +257 -189
  58. package/dist/form/widget/definitions.js +1 -1
  59. package/dist/form/widget/providers/checkBox.js +254 -259
  60. package/dist/form/widget/providers/comboBox.js +187 -192
  61. package/dist/form/widget/providers/default.js +8 -9
  62. package/dist/form/widget/providers/hidden.js +170 -179
  63. package/dist/form/widget/providers/hiddenBox.js +262 -267
  64. package/dist/form/widget/providers/radioBox.js +216 -225
  65. package/dist/form/widget/providers/textArea.js +187 -196
  66. package/dist/form/widget/providers/textBox.js +2 -3
  67. package/dist/form/widget/widget.js +473 -475
  68. package/dist/formValidator/formValidator.js +1 -1
  69. package/dist/formValidator/highlighters/message.js +1 -1
  70. package/dist/generis/form/form.js +314 -323
  71. package/dist/generis/validator/validator.js +209 -218
  72. package/dist/generis/widget/checkBox/checkBox.js +218 -227
  73. package/dist/generis/widget/comboBox/comboBox.js +179 -188
  74. package/dist/generis/widget/hiddenBox/hiddenBox.js +220 -229
  75. package/dist/generis/widget/textBox/textBox.js +169 -178
  76. package/dist/generis/widget/widget.js +246 -255
  77. package/dist/groupedComboBox.js +222 -231
  78. package/dist/groupvalidator.js +2 -2
  79. package/dist/highlighter.js +967 -958
  80. package/dist/image/ImgStateActive/helper.js +7 -5
  81. package/dist/image/ImgStateActive/initHelper.js +49 -43
  82. package/dist/image/ImgStateActive/initMediaEditor.js +24 -20
  83. package/dist/image/ImgStateActive/mediaSizer.js +14 -12
  84. package/dist/image/ImgStateActive.js +72 -70
  85. package/dist/incrementer.js +6 -6
  86. package/dist/inplacer.js +6 -6
  87. package/dist/itemButtonList/css/item-button-list.css +1 -0
  88. package/dist/itemButtonList/css/item-button-list.css.map +1 -1
  89. package/dist/itemButtonList.js +439 -435
  90. package/dist/keyNavigation/navigableDomElement.js +51 -38
  91. package/dist/keyNavigation/navigator.js +85 -70
  92. package/dist/listbox.js +460 -469
  93. package/dist/liststyler.js +8 -8
  94. package/dist/loadingButton/loadingButton.js +209 -218
  95. package/dist/lock.js +476 -485
  96. package/dist/login/login.js +475 -484
  97. package/dist/maths/calculator/basicCalculator.js +235 -244
  98. package/dist/maths/calculator/calculatorComponent.js +3 -3
  99. package/dist/maths/calculator/core/board.js +772 -781
  100. package/dist/maths/calculator/core/expression.js +476 -485
  101. package/dist/maths/calculator/core/labels.js +228 -237
  102. package/dist/maths/calculator/core/tokenizer.js +1 -1
  103. package/dist/maths/calculator/core/tokens.js +163 -170
  104. package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +244 -253
  105. package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +279 -288
  106. package/dist/maths/calculator/scientificCalculator.js +327 -336
  107. package/dist/mediaEditor/mediaEditorComponent.js +238 -245
  108. package/dist/mediaEditor/plugins/mediaAlignment/helper.js +7 -7
  109. package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +229 -235
  110. package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +580 -589
  111. package/dist/mediaplayer/players/html5.js +666 -675
  112. package/dist/mediaplayer/players/youtube.js +419 -424
  113. package/dist/mediaplayer/support.js +11 -10
  114. package/dist/mediaplayer/utils/reminder.js +14 -13
  115. package/dist/mediaplayer/utils/timeObserver.js +10 -11
  116. package/dist/mediaplayer/youtubeManager.js +164 -145
  117. package/dist/mediaplayer.js +1565 -1520
  118. package/dist/mediasizer.js +669 -678
  119. package/dist/modal.js +10 -17
  120. package/dist/pageSizeSelector.js +219 -228
  121. package/dist/pagination/providers/pages.js +280 -289
  122. package/dist/pagination/providers/simple.js +192 -201
  123. package/dist/previewer.js +30 -30
  124. package/dist/progressbar.js +4 -4
  125. package/dist/report.js +347 -356
  126. package/dist/resource/filters.js +271 -280
  127. package/dist/resource/list.js +1264 -1273
  128. package/dist/resource/selector.js +865 -874
  129. package/dist/resource/tree.js +1483 -1492
  130. package/dist/resourcemgr/fileBrowser.js +564 -569
  131. package/dist/resourcemgr/filePreview.js +16 -16
  132. package/dist/resourcemgr/fileSelector.js +515 -524
  133. package/dist/resourcemgr/util/updatePermissions.js +2 -2
  134. package/dist/resourcemgr.js +306 -315
  135. package/dist/searchModal/advancedSearch.js +796 -767
  136. package/dist/searchModal.js +597 -549
  137. package/dist/switch/switch.js +298 -307
  138. package/dist/tabs.js +598 -575
  139. package/dist/taskQueue/status.js +312 -321
  140. package/dist/taskQueue/table.js +375 -384
  141. package/dist/taskQueue/taskQueueModel.js +488 -472
  142. package/dist/taskQueueButton/taskable.js +264 -273
  143. package/dist/taskQueueButton/treeButton.js +189 -198
  144. package/dist/themeLoader.js +24 -23
  145. package/dist/themes.js +1 -1
  146. package/dist/toggler.js +3 -3
  147. package/dist/tooltip.js +295 -304
  148. package/dist/transformer.js +2 -2
  149. package/dist/tristateCheckboxGroup.js +311 -320
  150. package/dist/uploader.js +687 -696
  151. package/dist/validator/Report.js +1 -1
  152. package/dist/validator/Validator.js +3 -3
  153. package/dist/validator/validators.js +9 -9
  154. package/dist/validator.js +240 -230
  155. package/dist/waitForMedia.js +1 -1
  156. package/package.json +3 -3
  157. package/scss/ckeditor/skins/tao/scss/inc/_menu.scss +51 -27
  158. package/scss/ckeditor/skins/tao/scss/inc/_panel.scss +16 -5
  159. package/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -2
  160. package/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +15 -3
  161. package/src/animable/absorbable/css/absorb.css +1 -0
  162. package/src/animable/absorbable/css/absorb.css.map +1 -1
  163. package/src/autocomplete/css/autocomplete.css +1 -0
  164. package/src/autocomplete/css/autocomplete.css.map +1 -1
  165. package/src/badge/css/badge.css +1 -0
  166. package/src/badge/css/badge.css.map +1 -1
  167. package/src/ckeditor/ckConfigurator.js +24 -1
  168. package/src/itemButtonList/css/item-button-list.css +1 -0
  169. package/src/itemButtonList/css/item-button-list.css.map +1 -1
  170. package/scss/.DS_Store +0 -0
  171. package/src/.DS_Store +0 -0
@@ -1,638 +1,686 @@
1
1
  define(['jquery', 'lodash', 'i18n', 'context', 'handlebars', 'lib/dompurify/purify', 'css!ui/searchModal/css/searchModal.css', 'ui/component', 'ui/modal', 'ui/datatable', 'core/store', 'ui/resource/selector', 'ui/searchModal/advancedSearch', 'core/dataProvider/request', 'util/url', 'select2', 'util/shortcut/registry'], function ($$1, _, __, context, Handlebars, DOMPurify, searchModal_css, component, modal, datatable, store, resourceSelectorFactory, advancedSearchFactory, request, urlUtil, select2, shortcutRegistry) { 'use strict';
2
2
 
3
- $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
- _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
- __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
- context = context && Object.prototype.hasOwnProperty.call(context, 'default') ? context['default'] : context;
7
- Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
8
- DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
9
- component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;
10
- store = store && Object.prototype.hasOwnProperty.call(store, 'default') ? store['default'] : store;
11
- resourceSelectorFactory = resourceSelectorFactory && Object.prototype.hasOwnProperty.call(resourceSelectorFactory, 'default') ? resourceSelectorFactory['default'] : resourceSelectorFactory;
12
- advancedSearchFactory = advancedSearchFactory && Object.prototype.hasOwnProperty.call(advancedSearchFactory, 'default') ? advancedSearchFactory['default'] : advancedSearchFactory;
13
- request = request && Object.prototype.hasOwnProperty.call(request, 'default') ? request['default'] : request;
14
- urlUtil = urlUtil && Object.prototype.hasOwnProperty.call(urlUtil, 'default') ? urlUtil['default'] : urlUtil;
15
- shortcutRegistry = shortcutRegistry && Object.prototype.hasOwnProperty.call(shortcutRegistry, 'default') ? shortcutRegistry['default'] : shortcutRegistry;
3
+ $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
+ _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
+ __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
+ context = context && Object.prototype.hasOwnProperty.call(context, 'default') ? context['default'] : context;
7
+ Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
8
+ DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
9
+ component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;
10
+ store = store && Object.prototype.hasOwnProperty.call(store, 'default') ? store['default'] : store;
11
+ resourceSelectorFactory = resourceSelectorFactory && Object.prototype.hasOwnProperty.call(resourceSelectorFactory, 'default') ? resourceSelectorFactory['default'] : resourceSelectorFactory;
12
+ advancedSearchFactory = advancedSearchFactory && Object.prototype.hasOwnProperty.call(advancedSearchFactory, 'default') ? advancedSearchFactory['default'] : advancedSearchFactory;
13
+ request = request && Object.prototype.hasOwnProperty.call(request, 'default') ? request['default'] : request;
14
+ urlUtil = urlUtil && Object.prototype.hasOwnProperty.call(urlUtil, 'default') ? urlUtil['default'] : urlUtil;
15
+ shortcutRegistry = shortcutRegistry && Object.prototype.hasOwnProperty.call(shortcutRegistry, 'default') ? shortcutRegistry['default'] : shortcutRegistry;
16
+
17
+ function ownKeys(object, enumerableOnly) {
18
+ var keys = Object.keys(object);
19
+
20
+ if (Object.getOwnPropertySymbols) {
21
+ var symbols = Object.getOwnPropertySymbols(object);
22
+ enumerableOnly && (symbols = symbols.filter(function (sym) {
23
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
24
+ })), keys.push.apply(keys, symbols);
25
+ }
16
26
 
17
- /**
18
- * This program is free software; you can redistribute it and/or
19
- * modify it under the terms of the GNU General Public License
20
- * as published by the Free Software Foundation; under version 2
21
- * of the License (non-upgradable).
22
- *
23
- * This program is distributed in the hope that it will be useful,
24
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
- * GNU General Public License for more details.
27
- *
28
- * You should have received a copy of the GNU General Public License
29
- * along with this program; if not, write to the Free Software
30
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31
- *
32
- * Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
33
- *
34
- *
35
- */
36
- function Helpers0 (hb) {
37
- //register a i18n helper
38
- hb.registerHelper('__', function (key) {
39
- return __(key);
40
- });
41
- /**
42
- * Register dompurify helper
43
- *
44
- * https://github.com/cure53/DOMPurify
45
- * with config SAFE_FOR_TEMPLATES: true
46
- * to make output safe for template systems
47
- */
27
+ return keys;
28
+ }
48
29
 
49
- hb.registerHelper('dompurify', function (context) {
50
- return DOMPurify.sanitize(context);
30
+ function _objectSpread2(target) {
31
+ for (var i = 1; i < arguments.length; i++) {
32
+ var source = null != arguments[i] ? arguments[i] : {};
33
+ i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
34
+ _defineProperty(target, key, source[key]);
35
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
36
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
51
37
  });
52
- /**
53
- * Register join helper
54
- *
55
- * Example :
56
- * var values = {a:v1, b:v2, c:v3};
57
- * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
58
- * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
59
- */
38
+ }
60
39
 
61
- hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
62
- var fragments = [];
63
- keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
64
- fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
65
- wrapper = typeof wrapper === 'string' ? wrapper : '"';
40
+ return target;
41
+ }
42
+
43
+ function _typeof(obj) {
44
+ "@babel/helpers - typeof";
45
+
46
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
47
+ return typeof obj;
48
+ } : function (obj) {
49
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
50
+ }, _typeof(obj);
51
+ }
52
+
53
+ function _defineProperty(obj, key, value) {
54
+ if (key in obj) {
55
+ Object.defineProperty(obj, key, {
56
+ value: value,
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true
60
+ });
61
+ } else {
62
+ obj[key] = value;
63
+ }
66
64
 
67
- _.forIn(arr, function (value, key) {
68
- var fragment = '';
65
+ return obj;
66
+ }
69
67
 
70
- if (value !== null || value !== undefined) {
71
- if (typeof value === 'boolean') {
72
- value = value ? 'true' : 'false';
73
- } else if (typeof value === 'object') {
74
- value = _.values(value).join(' ');
75
- }
76
- } else {
77
- value = '';
78
- }
68
+ function Helpers0 (hb) {
69
+ //register a i18n helper
70
+ hb.registerHelper('__', function (key) {
71
+ return __(key);
72
+ });
73
+ /**
74
+ * Register dompurify helper
75
+ *
76
+ * https://github.com/cure53/DOMPurify
77
+ * with config SAFE_FOR_TEMPLATES: true
78
+ * to make output safe for template systems
79
+ */
79
80
 
80
- if (keyValueGlue !== undefined) {
81
- fragment += key + keyValueGlue;
82
- }
81
+ hb.registerHelper('dompurify', function (context) {
82
+ return DOMPurify.sanitize(context);
83
+ });
84
+ /**
85
+ * Register join helper
86
+ *
87
+ * Example :
88
+ * var values = {a:v1, b:v2, c:v3};
89
+ * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
90
+ * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
91
+ */
83
92
 
84
- fragment += wrapper + value + wrapper;
85
- fragments.push(fragment);
86
- });
93
+ hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
94
+ var fragments = [];
95
+ keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
96
+ fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
97
+ wrapper = typeof wrapper === 'string' ? wrapper : '"';
87
98
 
88
- return fragments.join(fragmentGlue);
89
- }); //register a classic "for loop" helper
90
- //it also adds a local variable "i" as the index in each iteration loop
99
+ _.forIn(arr, function (value, key) {
100
+ var fragment = '';
91
101
 
92
- hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
93
- var ret = '';
94
- startIndex = parseInt(startIndex);
95
- stopIndex = parseInt(stopIndex);
96
- increment = parseInt(increment);
102
+ if (value !== null || value !== undefined) {
103
+ if (typeof value === 'boolean') {
104
+ value = value ? 'true' : 'false';
105
+ } else if (_typeof(value) === 'object') {
106
+ value = _.values(value).join(' ');
107
+ }
108
+ } else {
109
+ value = '';
110
+ }
97
111
 
98
- for (var i = startIndex; i < stopIndex; i += increment) {
99
- ret += options.fn(_.extend({}, this, {
100
- i: i
101
- }));
112
+ if (keyValueGlue !== undefined) {
113
+ fragment += key + keyValueGlue;
102
114
  }
103
115
 
104
- return ret;
116
+ fragment += wrapper + value + wrapper;
117
+ fragments.push(fragment);
105
118
  });
106
- hb.registerHelper('equal', function (var1, var2, options) {
107
- if (var1 == var2) {
108
- return options.fn(this);
109
- } else {
110
- return options.inverse(this);
111
- }
112
- }); // register a "get property" helper
113
- // it gets the named property from the provided context
114
119
 
115
- hb.registerHelper('property', function (name, context) {
116
- return context[name] || '';
117
- }); // register an 'includes' helper
118
- // it checks if value is in array
120
+ return fragments.join(fragmentGlue);
121
+ }); //register a classic "for loop" helper
122
+ //it also adds a local variable "i" as the index in each iteration loop
119
123
 
120
- hb.registerHelper('includes', function (haystack, needle, options) {
121
- if (_.contains(haystack, needle)) {
122
- return options.fn(this);
123
- }
124
- });
125
- }
124
+ hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
125
+ var ret = '';
126
+ startIndex = parseInt(startIndex);
127
+ stopIndex = parseInt(stopIndex);
128
+ increment = parseInt(increment);
126
129
 
127
- if (!Helpers0.__initialized) {
128
- Helpers0(Handlebars);
129
- Helpers0.__initialized = true;
130
- }
131
- var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
132
- this.compilerInfo = [4,'>= 1.0.0'];
133
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
134
- var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing;
135
-
136
-
137
- buffer += "<div class=\"search-modal section-container\">\n <div class=\"clear content-wrapper content-panel\">\n <div class=\"ui-container\">\n <div class=\"filters-container\">\n <div class=\"basic-search-container\">\n <div class=\"filter-container\">\n <span class=\"icon-find\"></span>\n <input class=\"generic-search-input\" type=\"text\" placeholder=\"";
138
- if (helper = helpers.placeholder) { stack1 = helper.call(depth0, {hash:{},data:data}); }
139
- else { helper = (depth0 && depth0.placeholder); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
140
- buffer += escapeExpression(stack1)
141
- + "\">\n </div>\n <div class=\"filter-container class-filter-container\">\n <span class=\"icon-folder\"></span>\n <span class=\"icon-down\"></span>\n <textarea class=\"class-filter\" cols=\"40\" rows=\"1\" readonly></textarea>\n <div class=\"class-tree\"></div>\n </div>\n </div>\n </div>\n <div class=\"buttons-container\">\n <button class=\"btn-clear btn-transparent small\">"
142
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Clear", options) : helperMissing.call(depth0, "__", "Clear", options)))
143
- + "</button>\n <button class=\"btn-search btn-info small\">"
144
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search", options) : helperMissing.call(depth0, "__", "Search", options)))
145
- + "</button>\n </div>\n </div>\n <div class=\"content-container\" style=\"padding:40px 20px\">\n </div>\n </div>\n</div>";
146
- return buffer;
147
- });
148
- function layoutTpl(data, options, asString) {
149
- var html = Template(data, options);
150
- return (asString || true) ? html : $(html);
151
- }
130
+ for (var i = startIndex; i < stopIndex; i += increment) {
131
+ ret += options.fn(_.extend({}, this, {
132
+ i: i
133
+ }));
134
+ }
152
135
 
153
- if (!Helpers0.__initialized) {
154
- Helpers0(Handlebars);
155
- Helpers0.__initialized = true;
156
- }
157
- var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
158
- this.compilerInfo = [4,'>= 1.0.0'];
159
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
160
- var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
161
-
162
-
163
- buffer += "<div class='no-datatable-container'>\n <span class=\"no-datatable-icon ";
164
- if (helper = helpers.icon) { stack1 = helper.call(depth0, {hash:{},data:data}); }
165
- else { helper = (depth0 && depth0.icon); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
166
- buffer += escapeExpression(stack1)
167
- + "\"></span>\n <p class=\"no-datatable-message\">";
168
- if (helper = helpers.message) { stack1 = helper.call(depth0, {hash:{},data:data}); }
169
- else { helper = (depth0 && depth0.message); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
170
- buffer += escapeExpression(stack1)
171
- + "</p>\n</div>";
172
- return buffer;
173
- });
174
- function infoMessageTpl(data, options, asString) {
175
- var html = Template$1(data, options);
176
- return (asString || true) ? html : $(html);
177
- }
136
+ return ret;
137
+ });
138
+ hb.registerHelper('equal', function (var1, var2, options) {
139
+ if (var1 == var2) {
140
+ return options.fn(this);
141
+ } else {
142
+ return options.inverse(this);
143
+ }
144
+ }); // register a "get property" helper
145
+ // it gets the named property from the provided context
178
146
 
147
+ hb.registerHelper('property', function (name, context) {
148
+ return context[name] || '';
149
+ }); // register an 'includes' helper
150
+ // it checks if value is in array
151
+
152
+ hb.registerHelper('includes', function (haystack, needle, options) {
153
+ if (_.contains(haystack, needle)) {
154
+ return options.fn(this);
155
+ }
156
+ });
157
+ }
158
+
159
+ if (!Helpers0.__initialized) {
160
+ Helpers0(Handlebars);
161
+ Helpers0.__initialized = true;
162
+ }
163
+ var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
164
+ this.compilerInfo = [4,'>= 1.0.0'];
165
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
166
+ var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing;
167
+
168
+
169
+ buffer += "<div class=\"search-modal section-container\">\n <div class=\"clear content-wrapper content-panel\">\n <div class=\"ui-container\">\n <div class=\"filters-container\">\n <div class=\"basic-search-container\">\n <div class=\"filter-container\">\n <span class=\"icon-find\"></span>\n <input class=\"generic-search-input\" type=\"text\" placeholder=\"";
170
+ if (helper = helpers.placeholder) { stack1 = helper.call(depth0, {hash:{},data:data}); }
171
+ else { helper = (depth0 && depth0.placeholder); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
172
+ buffer += escapeExpression(stack1)
173
+ + "\">\n </div>\n <div class=\"filter-container class-filter-container\">\n <span class=\"icon-folder\"></span>\n <span class=\"icon-down\"></span>\n <textarea class=\"class-filter\" cols=\"40\" rows=\"1\" readonly></textarea>\n <div class=\"class-tree\"></div>\n </div>\n </div>\n </div>\n <div class=\"buttons-container\">\n <button class=\"btn-clear btn-transparent small\">"
174
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Clear", options) : helperMissing.call(depth0, "__", "Clear", options)))
175
+ + "</button>\n <button class=\"btn-search btn-info small\">"
176
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Search", options) : helperMissing.call(depth0, "__", "Search", options)))
177
+ + "</button>\n </div>\n </div>\n <div class=\"content-container\" style=\"padding:40px 20px\">\n </div>\n </div>\n</div>";
178
+ return buffer;
179
+ });
180
+ function layoutTpl(data, options, asString) {
181
+ var html = Template(data, options);
182
+ return (asString || true) ? html : $(html);
183
+ }
184
+
185
+ if (!Helpers0.__initialized) {
186
+ Helpers0(Handlebars);
187
+ Helpers0.__initialized = true;
188
+ }
189
+ var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
190
+ this.compilerInfo = [4,'>= 1.0.0'];
191
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
192
+ var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
193
+
194
+
195
+ buffer += "<div class='no-datatable-container'>\n <span class=\"no-datatable-icon ";
196
+ if (helper = helpers.icon) { stack1 = helper.call(depth0, {hash:{},data:data}); }
197
+ else { helper = (depth0 && depth0.icon); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
198
+ buffer += escapeExpression(stack1)
199
+ + "\"></span>\n <p class=\"no-datatable-message\">";
200
+ if (helper = helpers.message) { stack1 = helper.call(depth0, {hash:{},data:data}); }
201
+ else { helper = (depth0 && depth0.message); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
202
+ buffer += escapeExpression(stack1)
203
+ + "</p>\n</div>";
204
+ return buffer;
205
+ });
206
+ function infoMessageTpl(data, options, asString) {
207
+ var html = Template$1(data, options);
208
+ return (asString || true) ? html : $(html);
209
+ }
210
+
211
+ /**
212
+ * Creates a searchModal instance
213
+ *
214
+ * @param {object} config
215
+ * @param {object} config.renderTo - DOM element where component will be rendered to
216
+ * @param {string} config.criterias - Search criteria to be set on component creation
217
+ * @param {boolean} config.searchOnInit - if init search must be triggered or not (stored results are used instead)
218
+ * @param {string} config.url - search endpoint to be set on datatable
219
+ * @param {string} config.rootClassUri - Uri for the root class of current context, required to init the class filter
220
+ * @param {bool} config.hideResourceSelector - if resourceSelector must be hidden
221
+ * @param {string} config.placeholder - placeholder for input in template
222
+ * @returns {searchModal}
223
+ */
224
+
225
+ function searchModalFactory(config) {
226
+ var defaults = {
227
+ renderTo: 'body',
228
+ criterias: {},
229
+ searchOnInit: true,
230
+ maxListSize: 5
231
+ }; // Private properties to be easily accessible by instance methods
232
+
233
+ var $container = null;
234
+ var $searchInput = null;
235
+ var $searchButton = null;
236
+ var $clearButton = null;
237
+ var running = false;
238
+ var searchStore = null;
239
+ var resourceSelector = null;
240
+ var $classFilterContainer = null;
241
+ var $classFilterInput = null;
242
+ var $classTreeContainer = null;
243
+ var advancedSearch = null; // resorce selector
244
+
245
+ var isResourceSelector = !config.hideResourceSelector;
246
+ var rootClassUri = config.rootClassUri;
179
247
  /**
180
- * This program is free software; you can redistribute it and/or
181
- * modify it under the terms of the GNU General Public License
182
- * as published by the Free Software Foundation; under version 2
183
- * of the License (non-upgradable).
184
- *
185
- * This program is distributed in the hope that it will be useful,
186
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
187
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
188
- * GNU General Public License for more details.
189
- *
190
- * You should have received a copy of the GNU General Public License
191
- * along with this program; if not, write to the Free Software
192
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
193
- *
194
- * Copyright (c) 2021 (original work) Open Assessment Technologies SA ;
248
+ * Creates search modal, inits template selectors, inits search store, and once is created triggers initial search
249
+ * rootClassUri is sent to advancedSearch factory for disabling in whitelisted sections
195
250
  */
251
+
252
+ function renderModal() {
253
+ var promises = [];
254
+ initModal();
255
+ initUiSelectors();
256
+ advancedSearch = advancedSearchFactory({
257
+ renderTo: $$1('.filters-container', $container),
258
+ advancedCriteria: instance.config.criterias.advancedCriteria,
259
+ rootClassUri: rootClassUri
260
+ });
261
+ promises.push(initClassFilter());
262
+ promises.push(initSearchStore());
263
+ Promise.all(promises).then(function () {
264
+ instance.trigger('ready');
265
+ $searchButton.trigger('click');
266
+ }).catch(function (e) {
267
+ return instance.trigger('error', e);
268
+ });
269
+ }
196
270
  /**
197
- * Creates a searchModal instance
198
- *
199
- * @param {object} config
200
- * @param {object} config.renderTo - DOM element where component will be rendered to
201
- * @param {string} config.criterias - Search criteria to be set on component creation
202
- * @param {boolean} config.searchOnInit - if init search must be triggered or not (stored results are used instead)
203
- * @param {string} config.url - search endpoint to be set on datatable
204
- * @param {string} config.rootClassUri - Uri for the root class of current context, required to init the class filter
205
- * @param {bool} config.hideResourceSelector - if resourceSelector must be hidden
206
- * @param {string} config.placeholder - placeholder for input in template
207
- * @returns {searchModal}
271
+ * Removes search modal
208
272
  */
209
273
 
210
- function searchModalFactory(config) {
211
- const defaults = {
212
- renderTo: 'body',
213
- criterias: {},
214
- searchOnInit: true,
215
- maxListSize: 5
216
- }; // Private properties to be easily accessible by instance methods
217
-
218
- let $container = null;
219
- let $searchInput = null;
220
- let $searchButton = null;
221
- let $clearButton = null;
222
- let running = false;
223
- let searchStore = null;
224
- let resourceSelector = null;
225
- let $classFilterContainer = null;
226
- let $classFilterInput = null;
227
- let $classTreeContainer = null;
228
- let advancedSearch = null; // resorce selector
229
-
230
- const isResourceSelector = !config.hideResourceSelector;
231
- const rootClassUri = config.rootClassUri;
232
- /**
233
- * Creates search modal, inits template selectors, inits search store, and once is created triggers initial search
234
- * rootClassUri is sent to advancedSearch factory for disabling in whitelisted sections
235
- */
236
274
 
237
- function renderModal() {
238
- const promises = [];
239
- initModal();
240
- initUiSelectors();
241
- advancedSearch = advancedSearchFactory({
242
- renderTo: $$1('.filters-container', $container),
243
- advancedCriteria: instance.config.criterias.advancedCriteria,
244
- rootClassUri: rootClassUri
245
- });
246
- promises.push(initClassFilter());
247
- promises.push(initSearchStore());
248
- Promise.all(promises).then(() => {
249
- instance.trigger('ready');
250
- $searchButton.trigger('click');
251
- }).catch(e => instance.trigger('error', e));
252
- }
253
- /**
254
- * Removes search modal
255
- */
275
+ function destroyModal() {
276
+ $container.removeClass('modal').modal('destroy');
277
+ $$1('.modal-bg').remove();
278
+ } // Creates new component
256
279
 
257
280
 
258
- function destroyModal() {
259
- $container.removeClass('modal').modal('destroy');
260
- $$1('.modal-bg').remove();
261
- } // Creates new component
262
-
263
-
264
- const instance = component({}, defaults).setTemplate(layoutTpl).on('render', renderModal).on('destroy', destroyModal);
265
- /**
266
- * Creates search modal
267
- */
281
+ var instance = component({}, defaults).setTemplate(layoutTpl).on('render', renderModal).on('destroy', destroyModal);
282
+ /**
283
+ * Creates search modal
284
+ */
268
285
 
269
- function initModal() {
270
- $container = instance.getElement();
271
- $container.addClass('modal').on('closed.modal', () => instance.destroy()).modal({
272
- disableEscape: false,
273
- width: $$1(window).width(),
274
- modalCloseClass: 'modal-close-left'
275
- }).focus();
276
- }
277
- /**
278
- * Inits class filter selector
279
- */
286
+ function initModal() {
287
+ $container = instance.getElement();
288
+ $container.addClass('modal').on('closed.modal', function () {
289
+ return instance.destroy();
290
+ }).modal({
291
+ disableEscape: false,
292
+ width: $$1(window).width(),
293
+ modalCloseClass: 'modal-close-left'
294
+ }).focus();
295
+ }
296
+ /**
297
+ * Inits class filter selector
298
+ */
280
299
 
281
300
 
282
- function initClassFilter() {
283
- return new Promise(resolve => {
284
- if (!isResourceSelector) {
285
- $classFilterContainer.hide();
286
- return resolve();
287
- }
301
+ function initClassFilter() {
302
+ return new Promise(function (resolve) {
303
+ if (!isResourceSelector) {
304
+ $classFilterContainer.hide();
305
+ return resolve();
306
+ }
288
307
 
289
- const initialClassUri = instance.config.criterias && instance.config.criterias.class ? instance.config.criterias.class : rootClassUri;
290
- resourceSelector = resourceSelectorFactory($$1('.class-tree', $container), {
291
- //set up the inner resource selector
292
- selectionMode: 'single',
293
- selectClass: true,
294
- classUri: rootClassUri,
295
- showContext: false,
296
- showSelection: false
297
- }); // when a class query is triggered, update selector options with received resources
298
-
299
- resourceSelector.on('query', params => {
300
- const classOnlyParams = { ...params,
301
- classOnly: true
302
- };
303
- const route = urlUtil.route('getAll', 'RestResource', 'tao');
304
- request(route, classOnlyParams).then(response => {
305
- if (response.permissions && response.permissions.data && response.permissions.supportedRights && response.permissions.supportedRights.length > 0) {
306
- manageClassTreePermissions(response);
307
- }
308
-
309
- resourceSelector.update(response.resources, classOnlyParams);
310
- }).catch(e => instance.trigger('error', e));
308
+ var initialClassUri = instance.config.criterias && instance.config.criterias.class ? instance.config.criterias.class : rootClassUri;
309
+ resourceSelector = resourceSelectorFactory($$1('.class-tree', $container), {
310
+ //set up the inner resource selector
311
+ selectionMode: 'single',
312
+ selectClass: true,
313
+ classUri: rootClassUri,
314
+ showContext: false,
315
+ showSelection: false
316
+ }); // when a class query is triggered, update selector options with received resources
317
+
318
+ resourceSelector.on('query', function (params) {
319
+ var classOnlyParams = _objectSpread2(_objectSpread2({}, params), {}, {
320
+ classOnly: true
311
321
  });
312
- /*
313
- * the first time selector opions are updated the root class is selected. Promise is
314
- * resolved so init process continues only when class input value has been set
315
- */
316
322
 
317
- resourceSelector.on('update', () => {
318
- resourceSelector.off('update');
319
- resourceSelector.select(initialClassUri);
320
- resolve();
321
- }); // then new class is selected, set its label into class filter input and hide filter container, then request class properties
322
-
323
- resourceSelector.on('change', selectedValue => {
324
- /*
325
- * on searchModal init we set manually the selector to the provided config.rootClassUri. When a selector
326
- * is set manually Selector component execs @clearSelection which triggers a change event
327
- * with an empty object as param. We catch this undesired behaviour here
328
- */
329
- if (_.isEmpty(selectedValue)) {
330
- return;
323
+ var route = urlUtil.route('getAll', 'RestResource', 'tao');
324
+ request(route, classOnlyParams).then(function (response) {
325
+ if (response.permissions && response.permissions.data && response.permissions.supportedRights && response.permissions.supportedRights.length > 0) {
326
+ manageClassTreePermissions(response);
331
327
  }
332
328
 
333
- const classUri = _.map(selectedValue, 'classUri')[0];
334
-
335
- const label = _.map(selectedValue, 'label')[0];
336
-
337
- const uri = _.map(selectedValue, 'uri')[0];
338
-
339
- const route = urlUtil.route('getWithMapping', 'ClassMetadata', 'tao', {
340
- classUri,
341
- maxListSize: instance.config.maxListSize
342
- });
343
- $classFilterInput.html(label);
344
- $classFilterInput.data('uri', uri);
345
- $classTreeContainer.hide();
346
- advancedSearch.updateCriteria(route).then(() => instance.trigger('criteriaListUpdated')).catch(e => instance.trigger('error', e));
329
+ resourceSelector.update(response.resources, classOnlyParams);
330
+ }).catch(function (e) {
331
+ return instance.trigger('error', e);
347
332
  });
348
- setResourceSelectorUIBehaviour();
349
333
  });
350
- }
351
- /**
352
- * Loops through each class in received class tree and sets access mode to 'denied' on private classes
353
- * so are disabled on class tree
354
- * @param {object} classTree - class tree received by server, containing resources (classes) and permissions
355
- */
334
+ /*
335
+ * the first time selector opions are updated the root class is selected. Promise is
336
+ * resolved so init process continues only when class input value has been set
337
+ */
356
338
 
339
+ resourceSelector.on('update', function () {
340
+ resourceSelector.off('update');
341
+ resourceSelector.select(initialClassUri);
342
+ resolve();
343
+ }); // then new class is selected, set its label into class filter input and hide filter container, then request class properties
357
344
 
358
- function manageClassTreePermissions(classTree) {
359
- const disableBlockedClasses = function (resources) {
360
- _.forEach(resources, (resource, index, array) => {
361
- if (classTree.permissions.data[resource.uri] && classTree.permissions.data[resource.uri].find(permission => permission === 'READ')) {
362
- if (resource.children) {
363
- disableBlockedClasses(resource.children);
364
- }
365
- } else {
366
- array[index].accessMode = 'denied';
367
- }
368
- });
369
- };
370
-
371
- disableBlockedClasses(classTree.resources);
372
- }
373
- /**
374
- * Inits template selectors, buttons behaviour, scroll animation,
375
- * and sets initial search query on search input
376
- */
345
+ resourceSelector.on('change', function (selectedValue) {
346
+ /*
347
+ * on searchModal init we set manually the selector to the provided config.rootClassUri. When a selector
348
+ * is set manually Selector component execs @clearSelection which triggers a change event
349
+ * with an empty object as param. We catch this undesired behaviour here
350
+ */
351
+ if (_.isEmpty(selectedValue)) {
352
+ return;
353
+ }
377
354
 
355
+ var classUri = _.map(selectedValue, 'classUri')[0];
378
356
 
379
- function initUiSelectors() {
380
- $searchButton = $$1('.btn-search', $container);
381
- $clearButton = $$1('.btn-clear', $container);
382
- $searchInput = $$1('.generic-search-input', $container);
383
- $classFilterInput = $$1('.class-filter', $container);
384
- $classTreeContainer = $$1('.class-tree', $container);
385
- $classFilterContainer = $$1('.class-filter-container', $container);
386
- $searchButton.on('click', search);
387
- $clearButton.on('click', clear);
388
- const shortcuts = shortcutRegistry($searchInput);
389
- shortcuts.clear().add('enter', search);
390
- $searchInput.val(instance.config.criterias && instance.config.criterias.search ? instance.config.criterias.search : '');
391
- }
392
- /**
393
- * Sets required listeners to properly manage resourceSelector visualization
394
- */
357
+ var label = _.map(selectedValue, 'label')[0];
395
358
 
359
+ var uri = _.map(selectedValue, 'uri')[0];
396
360
 
397
- function setResourceSelectorUIBehaviour() {
398
- $container.on('mousedown', () => {
361
+ var route = urlUtil.route('getWithMapping', 'ClassMetadata', 'tao', {
362
+ classUri: classUri,
363
+ maxListSize: instance.config.maxListSize
364
+ });
365
+ $classFilterInput.html(label);
366
+ $classFilterInput.data('uri', uri);
399
367
  $classTreeContainer.hide();
368
+ advancedSearch.updateCriteria(route).then(function () {
369
+ return instance.trigger('criteriaListUpdated');
370
+ }).catch(function (e) {
371
+ return instance.trigger('error', e);
372
+ });
400
373
  });
401
- /**
402
- * Pressing space, enter, esc, backspace
403
- * on class filter input will toggle resource selector
404
- */
374
+ setResourceSelectorUIBehaviour();
375
+ });
376
+ }
377
+ /**
378
+ * Loops through each class in received class tree and sets access mode to 'denied' on private classes
379
+ * so are disabled on class tree
380
+ * @param {object} classTree - class tree received by server, containing resources (classes) and permissions
381
+ */
405
382
 
406
- const shortcuts = shortcutRegistry($classFilterInput);
407
- shortcuts.add('enter', () => $classTreeContainer.show());
408
- shortcuts.add('space', () => $classTreeContainer.show());
409
- shortcuts.add('backspace', () => $classTreeContainer.hide());
410
- shortcuts.add('escape', () => $classTreeContainer.hide(), {
411
- propagate: false
412
- });
413
- /**
414
- * clicking on class filter container will toggle resource selector
415
- */
416
383
 
417
- $classFilterContainer.on('click', e => {
418
- $classTreeContainer.toggle();
384
+ function manageClassTreePermissions(classTree) {
385
+ var disableBlockedClasses = function disableBlockedClasses(resources) {
386
+ _.forEach(resources, function (resource, index, array) {
387
+ if (classTree.permissions.data[resource.uri] && classTree.permissions.data[resource.uri].find(function (permission) {
388
+ return permission === 'READ';
389
+ })) {
390
+ if (resource.children) {
391
+ disableBlockedClasses(resource.children);
392
+ }
393
+ } else {
394
+ array[index].accessMode = 'denied';
395
+ }
419
396
  });
420
- /**
421
- * clicking on class filter container will
422
- * stopPropagation to prevent be closed
423
- * by searchModal.mouseDown listener
424
- */
397
+ };
425
398
 
426
- $classFilterContainer.on('mousedown', e => {
427
- e.stopPropagation();
428
- }); // clicking on resource selector will stopPropagation to prevent be closed by searchModal.mouseDown listener
399
+ disableBlockedClasses(classTree.resources);
400
+ }
401
+ /**
402
+ * Inits template selectors, buttons behaviour, scroll animation,
403
+ * and sets initial search query on search input
404
+ */
429
405
 
430
- $classTreeContainer.on('mousedown', e => {
431
- e.stopPropagation();
432
- });
433
- }
434
- /**
435
- * Loads search store so it is accessible in the component
436
- * @returns {Promise}
437
- */
406
+
407
+ function initUiSelectors() {
408
+ $searchButton = $$1('.btn-search', $container);
409
+ $clearButton = $$1('.btn-clear', $container);
410
+ $searchInput = $$1('.generic-search-input', $container);
411
+ $classFilterInput = $$1('.class-filter', $container);
412
+ $classTreeContainer = $$1('.class-tree', $container);
413
+ $classFilterContainer = $$1('.class-filter-container', $container);
414
+ $searchButton.on('click', search);
415
+ $clearButton.on('click', clear);
416
+ var shortcuts = shortcutRegistry($searchInput);
417
+ shortcuts.clear().add('enter', search);
418
+ $searchInput.val(instance.config.criterias && instance.config.criterias.search ? instance.config.criterias.search : '');
419
+ }
420
+ /**
421
+ * Sets required listeners to properly manage resourceSelector visualization
422
+ */
438
423
 
439
424
 
440
- function initSearchStore() {
441
- return store('search').then(function (store) {
442
- searchStore = store;
443
- }).catch(e => instance.trigger('error', e));
444
- }
425
+ function setResourceSelectorUIBehaviour() {
426
+ $container.on('mousedown', function () {
427
+ $classTreeContainer.hide();
428
+ });
445
429
  /**
446
- * Request search results and manages its results
430
+ * Pressing space, enter, esc, backspace
431
+ * on class filter input will toggle resource selector
447
432
  */
448
433
 
434
+ var shortcuts = shortcutRegistry($classFilterInput);
435
+ shortcuts.add('enter', function () {
436
+ return $classTreeContainer.show();
437
+ });
438
+ shortcuts.add('space', function () {
439
+ return $classTreeContainer.show();
440
+ });
441
+ shortcuts.add('backspace', function () {
442
+ return $classTreeContainer.hide();
443
+ });
444
+ shortcuts.add('escape', function () {
445
+ return $classTreeContainer.hide();
446
+ }, {
447
+ propagate: false
448
+ });
449
+ /**
450
+ * clicking on class filter container will toggle resource selector
451
+ */
449
452
 
450
- function search() {
451
- const query = buildComplexQuery();
452
- const classFilterUri = isResourceSelector ? $classFilterInput.data('uri').trim() : rootClassUri; //throttle and control to prevent sending too many requests
453
-
454
- const searchHandler = _.throttle(query => {
455
- if (running === false) {
456
- running = true;
457
- $$1.ajax({
458
- url: instance.config.url,
459
- type: 'POST',
460
- data: {
461
- query: query,
462
- parentNode: classFilterUri,
463
- structure: context.shownStructure
464
- },
465
- dataType: 'json'
466
- }).done(data => {
467
- appendDefaultDatasetToDatatable(data.data).then(() => buildSearchResultsDatatable(data.data)).catch(e => instance.trigger('error', e));
468
- }).always(() => running = false);
469
- }
470
- }, 100);
471
-
472
- searchHandler(query);
473
- }
453
+ $classFilterContainer.on('click', function (e) {
454
+ $classTreeContainer.toggle();
455
+ });
474
456
  /**
475
- * build final complex query appending every filter
457
+ * clicking on class filter container will
458
+ * stopPropagation to prevent be closed
459
+ * by searchModal.mouseDown listener
476
460
  */
477
461
 
462
+ $classFilterContainer.on('mousedown', function (e) {
463
+ e.stopPropagation();
464
+ }); // clicking on resource selector will stopPropagation to prevent be closed by searchModal.mouseDown listener
478
465
 
479
- function buildComplexQuery() {
480
- const $searchInputValue = $searchInput.val().trim();
481
- let query = $searchInputValue;
482
- query += advancedSearch.getAdvancedCriteriaQuery(query !== '');
483
- return query;
484
- }
485
- /*
486
- * If search on init is not required, extends data with stored dataset
487
- * @param {object} data - search configuration including model and endpoint for datatable
488
- * @returns {Promise}
489
- */
466
+ $classTreeContainer.on('mousedown', function (e) {
467
+ e.stopPropagation();
468
+ });
469
+ }
470
+ /**
471
+ * Loads search store so it is accessible in the component
472
+ * @returns {Promise}
473
+ */
474
+
475
+
476
+ function initSearchStore() {
477
+ return store('search').then(function (store) {
478
+ searchStore = store;
479
+ }).catch(function (e) {
480
+ return instance.trigger('error', e);
481
+ });
482
+ }
483
+ /**
484
+ * Request search results and manages its results
485
+ */
490
486
 
491
487
 
492
- function appendDefaultDatasetToDatatable(data) {
493
- return new Promise(function (resolve, reject) {
494
- // If no search on init, get dataset from searchStore
495
- if (instance.config.searchOnInit === false) {
496
- searchStore.getItem('results').then(storedSearchResults => {
497
- instance.config.searchOnInit = true;
498
- data.storedSearchResults = storedSearchResults;
499
- resolve();
500
- }).catch(e => {
501
- instance.trigger('error', e);
502
- reject(new Error('Error appending default dataset from searchStore to datatable'));
488
+ function search() {
489
+ var query = buildComplexQuery();
490
+ var classFilterUri = isResourceSelector ? $classFilterInput.data('uri').trim() : rootClassUri; //throttle and control to prevent sending too many requests
491
+
492
+ var searchHandler = _.throttle(function (query) {
493
+ if (running === false) {
494
+ running = true;
495
+ $$1.ajax({
496
+ url: instance.config.url,
497
+ type: 'POST',
498
+ data: {
499
+ query: query,
500
+ parentNode: classFilterUri,
501
+ structure: context.shownStructure
502
+ },
503
+ dataType: 'json'
504
+ }).done(function (data) {
505
+ appendDefaultDatasetToDatatable(data.data).then(function () {
506
+ return buildSearchResultsDatatable(data.data);
507
+ }).catch(function (e) {
508
+ return instance.trigger('error', e);
503
509
  });
504
- } else {
505
- resolve();
506
- }
507
- });
508
- }
509
- /**
510
- * Creates a datatable with search results
511
- * @param {object} data - search configuration including model and endpoint for datatable
512
- */
510
+ }).always(function () {
511
+ return running = false;
512
+ });
513
+ }
514
+ }, 100);
513
515
 
516
+ searchHandler(query);
517
+ }
518
+ /**
519
+ * build final complex query appending every filter
520
+ */
514
521
 
515
- function buildSearchResultsDatatable(data) {
516
- //update the section container
517
- const $tableContainer = $$1('<div class="flex-container-full"></div>');
518
- const section = $$1('.content-container', $container);
519
- section.empty();
520
- section.append($tableContainer);
521
- $tableContainer.on('load.datatable', searchResultsLoaded); //create datatable
522
-
523
- $tableContainer.datatable({
524
- url: data.url,
525
- model: _.values(data.model),
526
- labels: {
527
- actions: ''
528
- },
529
- actions: [{
530
- id: 'go-to-item',
531
- label: __('View'),
532
- action: function openResource(uri, data) {
533
- instance.trigger('refresh', uri, data);
534
- instance.destroy();
535
- }
536
- }],
537
- params: {
538
- params: data.params,
539
- filters: data.filters,
540
- rows: 20
541
- }
542
- }, data.storedSearchResults);
543
- }
544
- /**
545
- * Triggered on load.datatable event, it updates searchStore and manages possible exceptions
546
- * @param {object} e - load.datatable event
547
- * @param {object} dataset - datatable dataset
548
- */
549
522
 
523
+ function buildComplexQuery() {
524
+ var $searchInputValue = $searchInput.val().trim();
525
+ var query = $searchInputValue;
526
+ query += advancedSearch.getAdvancedCriteriaQuery(query !== '');
527
+ return query;
528
+ }
529
+ /*
530
+ * If search on init is not required, extends data with stored dataset
531
+ * @param {object} data - search configuration including model and endpoint for datatable
532
+ * @returns {Promise}
533
+ */
550
534
 
551
- function searchResultsLoaded(e, dataset) {
552
- if (dataset.records === 0) {
553
- replaceSearchResultsDatatableWithMessage('no-matches');
535
+
536
+ function appendDefaultDatasetToDatatable(data) {
537
+ return new Promise(function (resolve, reject) {
538
+ // If no search on init, get dataset from searchStore
539
+ if (instance.config.searchOnInit === false) {
540
+ searchStore.getItem('results').then(function (storedSearchResults) {
541
+ instance.config.searchOnInit = true;
542
+ data.storedSearchResults = storedSearchResults;
543
+ resolve();
544
+ }).catch(function (e) {
545
+ instance.trigger('error', e);
546
+ reject(new Error('Error appending default dataset from searchStore to datatable'));
547
+ });
548
+ } else {
549
+ resolve();
554
550
  }
551
+ });
552
+ }
553
+ /**
554
+ * Creates a datatable with search results
555
+ * @param {object} data - search configuration including model and endpoint for datatable
556
+ */
555
557
 
556
- instance.trigger(`datatable-loaded`);
557
- updateSearchStore({
558
- action: 'update',
559
- dataset,
560
- context: context.shownStructure,
561
- criterias: {
562
- search: $searchInput.val(),
563
- class: isResourceSelector ? _.map(resourceSelector.getSelection(), 'uri')[0] : rootClassUri,
564
- advancedCriteria: advancedSearch.getState()
558
+
559
+ function buildSearchResultsDatatable(data) {
560
+ //update the section container
561
+ var $tableContainer = $$1('<div class="flex-container-full"></div>');
562
+ var section = $$1('.content-container', $container);
563
+ section.empty();
564
+ section.append($tableContainer);
565
+ $tableContainer.on('load.datatable', searchResultsLoaded); //create datatable
566
+
567
+ $tableContainer.datatable({
568
+ url: data.url,
569
+ model: _.values(data.model),
570
+ labels: {
571
+ actions: ''
572
+ },
573
+ actions: [{
574
+ id: 'go-to-item',
575
+ label: __('View'),
576
+ action: function openResource(uri, data) {
577
+ instance.trigger('refresh', uri, data);
578
+ instance.destroy();
565
579
  }
566
- });
567
- }
568
- /**
569
- * Updates searchStore. If action is 'clear', searchStore is claread. If not, received
570
- * data is assigned to searchStore. Once all actions have been done,
571
- * store-updated event is triggered
572
- * @param {object} data - data to store
573
- */
580
+ }],
581
+ params: {
582
+ params: data.params,
583
+ filters: data.filters,
584
+ rows: 20
585
+ }
586
+ }, data.storedSearchResults);
587
+ }
588
+ /**
589
+ * Triggered on load.datatable event, it updates searchStore and manages possible exceptions
590
+ * @param {object} e - load.datatable event
591
+ * @param {object} dataset - datatable dataset
592
+ */
574
593
 
575
594
 
576
- function updateSearchStore(data) {
577
- const promises = [];
595
+ function searchResultsLoaded(e, dataset) {
596
+ if (dataset.records === 0) {
597
+ replaceSearchResultsDatatableWithMessage('no-matches');
598
+ }
578
599
 
579
- if (data.action === 'clear') {
580
- promises.push(searchStore.clear());
581
- } else if (data.action === 'update') {
582
- promises.push(searchStore.setItem('criterias', data.criterias));
583
- promises.push(searchStore.setItem('context', data.context));
584
- promises.push(data.dataset.records === 0 ? searchStore.removeItem('results') : searchStore.setItem('results', data.dataset));
600
+ instance.trigger("datatable-loaded");
601
+ updateSearchStore({
602
+ action: 'update',
603
+ dataset: dataset,
604
+ context: context.shownStructure,
605
+ criterias: {
606
+ search: $searchInput.val(),
607
+ class: isResourceSelector ? _.map(resourceSelector.getSelection(), 'uri')[0] : rootClassUri,
608
+ advancedCriteria: advancedSearch.getState()
585
609
  }
610
+ });
611
+ }
612
+ /**
613
+ * Updates searchStore. If action is 'clear', searchStore is claread. If not, received
614
+ * data is assigned to searchStore. Once all actions have been done,
615
+ * store-updated event is triggered
616
+ * @param {object} data - data to store
617
+ */
586
618
 
587
- Promise.all(promises).then(() => instance.trigger(`store-updated`)).catch(e => instance.trigger('error', e));
588
- }
589
- /**
590
- * Clear search input, criteria and results from both, view and store.
591
- * Also sets every criterion on criteriaState to unredered and
592
- * undefined value
593
- */
594
619
 
620
+ function updateSearchStore(data) {
621
+ var promises = [];
595
622
 
596
- function clear() {
597
- $searchInput.val('');
598
- advancedSearch.clear();
599
- isResourceSelector && resourceSelector.select(rootClassUri);
600
- replaceSearchResultsDatatableWithMessage('no-query');
601
- updateSearchStore({
602
- action: 'clear'
603
- });
623
+ if (data.action === 'clear') {
624
+ promises.push(searchStore.clear());
625
+ } else if (data.action === 'update') {
626
+ promises.push(searchStore.setItem('criterias', data.criterias));
627
+ promises.push(searchStore.setItem('context', data.context));
628
+ promises.push(data.dataset.records === 0 ? searchStore.removeItem('results') : searchStore.setItem('results', data.dataset));
604
629
  }
605
- /**
606
- * Removes datatable container and displays a message instead
607
- * @param {string} reason - reason why datatable is not rendered, to display appropiate message
608
- */
609
630
 
631
+ Promise.all(promises).then(function () {
632
+ return instance.trigger("store-updated");
633
+ }).catch(function (e) {
634
+ return instance.trigger('error', e);
635
+ });
636
+ }
637
+ /**
638
+ * Clear search input, criteria and results from both, view and store.
639
+ * Also sets every criterion on criteriaState to unredered and
640
+ * undefined value
641
+ */
610
642
 
611
- function replaceSearchResultsDatatableWithMessage(reason) {
612
- const section = $$1('.content-container', $container);
613
- section.empty();
614
- let message = '';
615
- let icon = '';
616
643
 
617
- if (reason === 'no-query') {
618
- message = __('Please define your search in the search panel.');
619
- icon = 'icon-find';
620
- } else if (reason === 'no-matches') {
621
- message = __('No item found. Please try other search criteria.');
622
- icon = 'icon-info';
623
- }
644
+ function clear() {
645
+ $searchInput.val('');
646
+ advancedSearch.clear();
647
+ isResourceSelector && resourceSelector.select(rootClassUri);
648
+ replaceSearchResultsDatatableWithMessage('no-query');
649
+ updateSearchStore({
650
+ action: 'clear'
651
+ });
652
+ }
653
+ /**
654
+ * Removes datatable container and displays a message instead
655
+ * @param {string} reason - reason why datatable is not rendered, to display appropiate message
656
+ */
624
657
 
625
- const infoMessage = infoMessageTpl({
626
- message,
627
- icon
628
- });
629
- section.append(infoMessage);
630
- } // return initialized instance of searchModal
631
658
 
659
+ function replaceSearchResultsDatatableWithMessage(reason) {
660
+ var section = $$1('.content-container', $container);
661
+ section.empty();
662
+ var message = '';
663
+ var icon = '';
632
664
 
633
- return instance.init(config);
634
- }
665
+ if (reason === 'no-query') {
666
+ message = __('Please define your search in the search panel.');
667
+ icon = 'icon-find';
668
+ } else if (reason === 'no-matches') {
669
+ message = __('No item found. Please try other search criteria.');
670
+ icon = 'icon-info';
671
+ }
672
+
673
+ var infoMessage = infoMessageTpl({
674
+ message: message,
675
+ icon: icon
676
+ });
677
+ section.append(infoMessage);
678
+ } // return initialized instance of searchModal
679
+
680
+
681
+ return instance.init(config);
682
+ }
635
683
 
636
- return searchModalFactory;
684
+ return searchModalFactory;
637
685
 
638
686
  });