@oat-sa/tao-core-ui 1.58.1 → 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 (233) 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 +26 -19
  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 +114 -91
  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/src/animable/absorbable/css/absorb.css +1 -0
  158. package/src/animable/absorbable/css/absorb.css.map +1 -1
  159. package/src/autocomplete/css/autocomplete.css +1 -0
  160. package/src/autocomplete/css/autocomplete.css.map +1 -1
  161. package/src/badge/css/badge.css +1 -0
  162. package/src/badge/css/badge.css.map +1 -1
  163. package/src/ckeditor/ckConfigurator.js +4 -0
  164. package/src/itemButtonList/css/item-button-list.css +1 -0
  165. package/src/itemButtonList/css/item-button-list.css.map +1 -1
  166. package/src/.DS_Store +0 -0
  167. package/src/css/basic.css +0 -7826
  168. package/src/css/basic.css.map +0 -1
  169. package/src/css/ckeditor/skins/tao/css/dialog.css +0 -950
  170. package/src/css/ckeditor/skins/tao/css/dialog.css.map +0 -1
  171. package/src/css/ckeditor/skins/tao/css/editor.css +0 -1850
  172. package/src/css/ckeditor/skins/tao/css/editor.css.map +0 -1
  173. package/src/scss/.DS_Store +0 -0
  174. package/src/scss/basic.scss +0 -16
  175. package/src/scss/ckeditor/skins/tao/scss/dialog.scss +0 -763
  176. package/src/scss/ckeditor/skins/tao/scss/editor.scss +0 -111
  177. package/src/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +0 -59
  178. package/src/scss/ckeditor/skins/tao/scss/inc/_colorpanel.scss +0 -118
  179. package/src/scss/ckeditor/skins/tao/scss/inc/_elementspath.scss +0 -69
  180. package/src/scss/ckeditor/skins/tao/scss/inc/_mainui.scss +0 -194
  181. package/src/scss/ckeditor/skins/tao/scss/inc/_menu.scss +0 -181
  182. package/src/scss/ckeditor/skins/tao/scss/inc/_panel.scss +0 -200
  183. package/src/scss/ckeditor/skins/tao/scss/inc/_presets.scss +0 -32
  184. package/src/scss/ckeditor/skins/tao/scss/inc/_reset.scss +0 -101
  185. package/src/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -213
  186. package/src/scss/ckeditor/skins/tao/scss/inc/_tao.scss +0 -59
  187. package/src/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +0 -301
  188. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
  189. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot.b64 +0 -1
  190. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
  191. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff.b64 +0 -1
  192. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
  193. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot.b64 +0 -1
  194. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
  195. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff.b64 +0 -1
  196. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot +0 -0
  197. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot.b64 +0 -1
  198. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff +0 -0
  199. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff.b64 +0 -1
  200. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
  201. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot.b64 +0 -1
  202. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
  203. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff.b64 +0 -1
  204. package/src/scss/font/tao/tao.eot +0 -0
  205. package/src/scss/font/tao/tao.svg +0 -235
  206. package/src/scss/font/tao/tao.ttf +0 -0
  207. package/src/scss/font/tao/tao.woff +0 -0
  208. package/src/scss/inc/_base.scss +0 -496
  209. package/src/scss/inc/_bootstrap.scss +0 -6
  210. package/src/scss/inc/_buttons.scss +0 -114
  211. package/src/scss/inc/_colors.scss +0 -88
  212. package/src/scss/inc/_feedback.scss +0 -150
  213. package/src/scss/inc/_flex-grid.scss +0 -15
  214. package/src/scss/inc/_fonts.scss +0 -4
  215. package/src/scss/inc/_forms.scss +0 -827
  216. package/src/scss/inc/_functions.scss +0 -283
  217. package/src/scss/inc/_grid.scss +0 -66
  218. package/src/scss/inc/_jquery.nouislider.scss +0 -254
  219. package/src/scss/inc/_normalize.scss +0 -528
  220. package/src/scss/inc/_report.scss +0 -68
  221. package/src/scss/inc/_secondary-properties.scss +0 -89
  222. package/src/scss/inc/_select2.scss +0 -634
  223. package/src/scss/inc/_toolbars.scss +0 -155
  224. package/src/scss/inc/_tooltip.scss +0 -312
  225. package/src/scss/inc/_variables.scss +0 -21
  226. package/src/scss/inc/base/_highlight.scss +0 -5
  227. package/src/scss/inc/base/_list-style.scss +0 -59
  228. package/src/scss/inc/base/_svg.scss +0 -3
  229. package/src/scss/inc/base/_table.scss +0 -63
  230. package/src/scss/inc/fonts/_source-sans-pro.scss +0 -29
  231. package/src/scss/inc/fonts/_tao-icon-classes.scss +0 -226
  232. package/src/scss/inc/fonts/_tao-icon-def.scss +0 -12
  233. package/src/scss/inc/fonts/_tao-icon-vars.scss +0 -240
@@ -1,563 +1,579 @@
1
1
  define(['jquery', 'lodash', 'i18n', 'core/eventifier', 'core/polling', 'core/dataProvider/request', 'ui/feedback', 'jquery.fileDownload'], function ($, _, __, eventifier, polling, request, feedback, jquery_fileDownload) { 'use strict';
2
2
 
3
- $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
4
- _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
- __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
- eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
7
- polling = polling && Object.prototype.hasOwnProperty.call(polling, 'default') ? polling['default'] : polling;
8
- request = request && Object.prototype.hasOwnProperty.call(request, 'default') ? request['default'] : request;
9
- feedback = feedback && Object.prototype.hasOwnProperty.call(feedback, 'default') ? feedback['default'] : feedback;
3
+ $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
4
+ _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
+ __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
+ eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
7
+ polling = polling && Object.prototype.hasOwnProperty.call(polling, 'default') ? polling['default'] : polling;
8
+ request = request && Object.prototype.hasOwnProperty.call(request, 'default') ? request['default'] : request;
9
+ feedback = feedback && Object.prototype.hasOwnProperty.call(feedback, 'default') ? feedback['default'] : feedback;
10
+
11
+ function _toConsumableArray(arr) {
12
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
13
+ }
14
+
15
+ function _arrayWithoutHoles(arr) {
16
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
17
+ }
18
+
19
+ function _iterableToArray(iter) {
20
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
21
+ }
22
+
23
+ function _unsupportedIterableToArray(o, minLen) {
24
+ if (!o) return;
25
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
26
+ var n = Object.prototype.toString.call(o).slice(8, -1);
27
+ if (n === "Object" && o.constructor) n = o.constructor.name;
28
+ if (n === "Map" || n === "Set") return Array.from(o);
29
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
30
+ }
31
+
32
+ function _arrayLikeToArray(arr, len) {
33
+ if (len == null || len > arr.length) len = arr.length;
34
+
35
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
36
+
37
+ return arr2;
38
+ }
39
+
40
+ function _nonIterableSpread() {
41
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
42
+ }
43
+
44
+ var _defaults = {
45
+ url: {
46
+ get: '',
47
+ archive: '',
48
+ all: '',
49
+ download: ''
50
+ },
51
+ pollSingleIntervals: [{
52
+ iteration: 4,
53
+ interval: 1000
54
+ }],
55
+ pollAllIntervals: [{
56
+ iteration: 10,
57
+ interval: 5000
58
+ }, {
59
+ iteration: 0,
60
+ interval: 10000
61
+ } //infinite
62
+ ]
63
+ };
64
+ /**
65
+ * Check if two tasks have equivalent task status
66
+ * @param {Object} task1 - a task object to be compared
67
+ * @param {Object} task2 - another task object to be compared
68
+ * @returns {Boolean}
69
+ */
70
+
71
+ function hasSameState(task1, task2) {
72
+ if (task1.status === task2.status) {
73
+ return true;
74
+ } else if (task1.status === 'created' || task1.status === 'in_progress') {
75
+ return task2.status === 'created' || task2.status === 'in_progress';
76
+ }
77
+
78
+ return false;
79
+ }
80
+
81
+ function translateReportMessages(taskData) {
82
+ return taskData.map(function (item) {
83
+ if (item.interpolationMessage) {
84
+ item.message = __.apply(void 0, [item.interpolationMessage].concat(_toConsumableArray(item.interpolationData)));
85
+ }
86
+
87
+ if (item.children.length > 0) {
88
+ translateReportMessages(item.children);
89
+ }
10
90
 
91
+ return item;
92
+ });
93
+ }
94
+ /**
95
+ * Create a task queue model to communicates with the server REST API
96
+ *
97
+ * @param {Object} config
98
+ * @param {Object} config.url - the list of server endpoints
99
+ * @param {String} config.url.get - the url to get the status log for a single task
100
+ * @param {String} config.url.archive - the url to archive a task
101
+ * @param {String} config.url.all - the url to get the status for all tasks for the current user
102
+ * @param {String} config.url.download - the url to download a file created by the task
103
+ * @param {Array} config.pollSingleIntervals - the array of poll intervals that will be used to regulate the polling speed for a simple task
104
+ * e.g. {iteration: 4, interval:1000} means that it will poll up to four times every 1000ms.
105
+ * @param {Array} config.pollAllIntervals - the array of poll intervals that will be used to regulate the main polling speed.
106
+ * e.g. {iteration: 10, interval:1000} means that it will poll up to 10 times every 5000ms.
107
+ * e.g. {iteration: 0, interval:10000} means that it will poll up to 10000ms indefinitely
108
+ *
109
+ * @return {taskQueueModel}
110
+ */
111
+
112
+
113
+ function taskQueueModel(config) {
114
+ var model;
11
115
  /**
12
- * This program is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU General Public License
14
- * as published by the Free Software Foundation; under version 2
15
- * of the License (non-upgradable).
16
- *
17
- * This program is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25
- *
26
- * Copyright (c) 2017 (original work) Open Assessment Technologies SA ;
116
+ * cached array of task data
117
+ * @type {Object}
27
118
  */
28
- var _defaults = {
29
- url: {
30
- get: '',
31
- archive: '',
32
- all: '',
33
- download: ''
34
- },
35
- pollSingleIntervals: [{
36
- iteration: 4,
37
- interval: 1000
38
- }],
39
- pollAllIntervals: [{
40
- iteration: 10,
41
- interval: 5000
42
- }, {
43
- iteration: 0,
44
- interval: 10000
45
- } //infinite
46
- ]
47
- };
119
+
120
+ var _cache;
48
121
  /**
49
- * Check if two tasks have equivalent task status
50
- * @param {Object} task1 - a task object to be compared
51
- * @param {Object} task2 - another task object to be compared
52
- * @returns {Boolean}
122
+ * store instance of single polling
123
+ * @type {Object}
53
124
  */
54
125
 
55
- function hasSameState(task1, task2) {
56
- if (task1.status === task2.status) {
57
- return true;
58
- } else if (task1.status === 'created' || task1.status === 'in_progress') {
59
- return task2.status === 'created' || task2.status === 'in_progress';
60
- }
61
126
 
62
- return false;
63
- }
127
+ var singlePollings = {};
64
128
 
65
- function translateReportMessages(taskData) {
66
- return taskData.map(item => {
67
- if (item.interpolationMessage) {
68
- item.message = __(item.interpolationMessage, ...item.interpolationData);
69
- }
129
+ var getPollSingleIntervals = function getPollSingleIntervals() {
130
+ if (config.pollSingleIntervals && _.isArray(config.pollSingleIntervals)) {
131
+ return _.cloneDeep(config.pollSingleIntervals);
132
+ }
133
+ };
70
134
 
71
- if (item.children.length > 0) {
72
- translateReportMessages(item.children);
73
- }
135
+ var getPollAllIntervals = function getPollAllIntervals() {
136
+ if (config.pollAllIntervals && _.isArray(config.pollAllIntervals)) {
137
+ return _.cloneDeep(config.pollAllIntervals);
138
+ }
139
+ };
74
140
 
75
- return item;
76
- });
77
- }
141
+ config = _.defaults(config || {}, _defaults);
78
142
  /**
79
- * Create a task queue model to communicates with the server REST API
80
- *
81
- * @param {Object} config
82
- * @param {Object} config.url - the list of server endpoints
83
- * @param {String} config.url.get - the url to get the status log for a single task
84
- * @param {String} config.url.archive - the url to archive a task
85
- * @param {String} config.url.all - the url to get the status for all tasks for the current user
86
- * @param {String} config.url.download - the url to download a file created by the task
87
- * @param {Array} config.pollSingleIntervals - the array of poll intervals that will be used to regulate the polling speed for a simple task
88
- * e.g. {iteration: 4, interval:1000} means that it will poll up to four times every 1000ms.
89
- * @param {Array} config.pollAllIntervals - the array of poll intervals that will be used to regulate the main polling speed.
90
- * e.g. {iteration: 10, interval:1000} means that it will poll up to 10 times every 5000ms.
91
- * e.g. {iteration: 0, interval:10000} means that it will poll up to 10000ms indefinitely
92
- *
93
- * @return {taskQueueModel}
143
+ * @typedef taskQueueModel - central model to query the backend's REST API for task queue
94
144
  */
95
145
 
96
-
97
- function taskQueueModel(config) {
98
- var model;
146
+ model = eventifier({
99
147
  /**
100
- * cached array of task data
101
- * @type {Object}
148
+ * Modify the task queue REST API endpoints
149
+ * @param urls - the new endpoints
150
+ * @returns {taskQueueModel}
102
151
  */
152
+ setEndpoints: function setEndpoints(urls) {
153
+ _.assign(config.url, urls || {});
154
+
155
+ return this;
156
+ },
103
157
 
104
- var _cache;
105
158
  /**
106
- * store instance of single polling
107
- * @type {Object}
159
+ * Get the status of a task identified by its unique task id
160
+ *
161
+ * @param {String} taskId - unique task identifier
162
+ * @returns {Promise}
108
163
  */
164
+ get: function get(taskId) {
165
+ var status;
109
166
 
167
+ if (!config.url || !config.url.get) {
168
+ throw new TypeError('config.url.get is not configured while get() is being called');
169
+ }
110
170
 
111
- var singlePollings = {};
171
+ status = request(config.url.get, {
172
+ taskId: taskId
173
+ }, 'GET', {}, true).then(function (taskData) {
174
+ // Workaround for translations
175
+ if (typeof taskData.report !== 'undefined' && typeof taskData.report.children !== 'undefined') {
176
+ taskData.report.children = translateReportMessages(taskData.report.children);
177
+ } //check taskData
178
+
179
+
180
+ if (taskData && taskData.status) {
181
+ if (_cache) {
182
+ //detect change
183
+ if (!_cache[taskData.id]) {
184
+ model.trigger('singletaskadded', taskData);
185
+ } else if (!hasSameState(_cache[taskData.id], taskData)) {
186
+ //check if the status has changed
187
+ model.trigger('singletaskstatuschange', taskData);
188
+ }
189
+ } else {
190
+ _cache = {};
191
+ }
112
192
 
113
- var getPollSingleIntervals = function getPollSingleIntervals() {
114
- if (config.pollSingleIntervals && _.isArray(config.pollSingleIntervals)) {
115
- return _.cloneDeep(config.pollSingleIntervals);
116
- }
117
- };
193
+ _cache[taskData.id] = taskData;
194
+ return taskData;
195
+ }
118
196
 
119
- var getPollAllIntervals = function getPollAllIntervals() {
120
- if (config.pollAllIntervals && _.isArray(config.pollAllIntervals)) {
121
- return _.cloneDeep(config.pollAllIntervals);
122
- }
123
- };
197
+ return Promise.reject(new Error('failed to get task data'));
198
+ });
199
+ status.catch(function (err) {
200
+ model.trigger('error', err);
201
+ });
202
+ return status;
203
+ },
124
204
 
125
- config = _.defaults(config || {}, _defaults);
126
205
  /**
127
- * @typedef taskQueueModel - central model to query the backend's REST API for task queue
206
+ * Get the task data, but try the cache first!
207
+ * @returns {Promise}
128
208
  */
209
+ getCached: function getCached(taskId) {
210
+ if (_cache && _cache[taskId]) {
211
+ return Promise.resolve(_cache[taskId]);
212
+ }
129
213
 
130
- model = eventifier({
131
- /**
132
- * Modify the task queue REST API endpoints
133
- * @param urls - the new endpoints
134
- * @returns {taskQueueModel}
135
- */
136
- setEndpoints: function setEndpoints(urls) {
137
- _.assign(config.url, urls || {});
214
+ return this.get(taskId);
215
+ },
138
216
 
139
- return this;
140
- },
217
+ /**
218
+ * Get the status of all task identified by their unique task id
219
+ *
220
+ * @returns {Promise} - resolved when the server response has been received
221
+ */
222
+ getAll: function getAll() {
223
+ var status;
141
224
 
142
- /**
143
- * Get the status of a task identified by its unique task id
144
- *
145
- * @param {String} taskId - unique task identifier
146
- * @returns {Promise}
147
- */
148
- get: function get(taskId) {
149
- var status;
225
+ if (!config.url || !config.url.all) {
226
+ throw new TypeError('config.url.all is not configured while getAll() is being called');
227
+ }
150
228
 
151
- if (!config.url || !config.url.get) {
152
- throw new TypeError('config.url.get is not configured while get() is being called');
153
- }
229
+ status = request(config.url.all, {
230
+ limit: 100
231
+ }, 'GET', {}, true).then(function (taskData) {
232
+ var newCache = {}; //check taskData
233
+
234
+ if (taskData) {
235
+ if (_cache) {
236
+ //detect change
237
+ _.forEach(taskData, function (task) {
238
+ var id = task.id;
154
239
 
155
- status = request(config.url.get, {
156
- taskId: taskId
157
- }, 'GET', {}, true).then(function (taskData) {
158
- // Workaround for translations
159
- if (typeof taskData.report !== 'undefined' && typeof taskData.report.children !== 'undefined') {
160
- taskData.report.children = translateReportMessages(taskData.report.children);
161
- } //check taskData
162
-
163
-
164
- if (taskData && taskData.status) {
165
- if (_cache) {
166
- //detect change
167
- if (!_cache[taskData.id]) {
168
- model.trigger('singletaskadded', taskData);
169
- } else if (!hasSameState(_cache[taskData.id], taskData)) {
240
+ if (!_cache[id]) {
241
+ model.trigger('multitaskadded', task);
242
+ } else if (!hasSameState(_cache[id], task)) {
170
243
  //check if the status has changed
171
- model.trigger('singletaskstatuschange', taskData);
244
+ model.trigger('multitaskstatuschange', task);
172
245
  }
173
- } else {
174
- _cache = {};
175
- }
176
246
 
177
- _cache[taskData.id] = taskData;
178
- return taskData;
179
- }
180
-
181
- return Promise.reject(new Error('failed to get task data'));
182
- });
183
- status.catch(function (err) {
184
- model.trigger('error', err);
185
- });
186
- return status;
187
- },
188
-
189
- /**
190
- * Get the task data, but try the cache first!
191
- * @returns {Promise}
192
- */
193
- getCached: function getCached(taskId) {
194
- if (_cache && _cache[taskId]) {
195
- return Promise.resolve(_cache[taskId]);
196
- }
247
+ newCache[id] = task;
248
+ });
197
249
 
198
- return this.get(taskId);
199
- },
250
+ _.forEach(_.difference(_.keys(_cache), _.keys(newCache)), function (id) {
251
+ model.trigger('taskremoved', _cache[id]);
252
+ });
253
+ } else {
254
+ _.forEach(taskData, function (task) {
255
+ newCache[task.id] = task;
256
+ });
257
+ } //update local cache
200
258
 
201
- /**
202
- * Get the status of all task identified by their unique task id
203
- *
204
- * @returns {Promise} - resolved when the server response has been received
205
- */
206
- getAll: function getAll() {
207
- var status;
208
259
 
209
- if (!config.url || !config.url.all) {
210
- throw new TypeError('config.url.all is not configured while getAll() is being called');
260
+ _cache = newCache;
261
+ return taskData;
211
262
  }
212
263
 
213
- status = request(config.url.all, {
214
- limit: 100
215
- }, 'GET', {}, true).then(function (taskData) {
216
- var newCache = {}; //check taskData
217
-
218
- if (taskData) {
219
- if (_cache) {
220
- //detect change
221
- _.forEach(taskData, function (task) {
222
- var id = task.id;
223
-
224
- if (!_cache[id]) {
225
- model.trigger('multitaskadded', task);
226
- } else if (!hasSameState(_cache[id], task)) {
227
- //check if the status has changed
228
- model.trigger('multitaskstatuschange', task);
229
- }
230
-
231
- newCache[id] = task;
232
- });
233
-
234
- _.forEach(_.difference(_.keys(_cache), _.keys(newCache)), function (id) {
235
- model.trigger('taskremoved', _cache[id]);
236
- });
237
- } else {
238
- _.forEach(taskData, function (task) {
239
- newCache[task.id] = task;
240
- });
241
- } //update local cache
264
+ return Promise.reject(new Error('failed to get all task data'));
265
+ });
266
+ status.catch(function (err) {
267
+ model.trigger('error', err);
268
+ });
269
+ return status;
270
+ },
242
271
 
272
+ /**
273
+ * Remove a task identified by its unique task id
274
+ *
275
+ * @param {String} taskId - the task id
276
+ * @returns {Promise} - resolved when achive action done
277
+ */
278
+ archive: function archive(taskId) {
279
+ var status;
243
280
 
244
- _cache = newCache;
245
- return taskData;
246
- }
281
+ if (!config.url || !config.url.archive) {
282
+ throw new TypeError('config.url.archive is not configured while archive() is being called');
283
+ }
247
284
 
248
- return Promise.reject(new Error('failed to get all task data'));
249
- });
250
- status.catch(function (err) {
251
- model.trigger('error', err);
252
- });
253
- return status;
254
- },
285
+ status = request(config.url.archive, {
286
+ taskId: taskId
287
+ }, 'GET', {}, true);
288
+ status.catch(function (res) {
289
+ model.trigger('error', res);
290
+ });
291
+ return status;
292
+ },
255
293
 
294
+ /**
295
+ * Poll status for all tasks
296
+ * @param {Boolean} [immediate] - tells if the polling should immediately start (otherwise, will wait until the next iteration)
297
+ * @returns {taskQueueModel}
298
+ */
299
+ pollAll: function pollAll(immediate) {
300
+ var self = this;
301
+ var loop = 0;
302
+ var pollingIntervals = getPollAllIntervals();
256
303
  /**
257
- * Remove a task identified by its unique task id
258
- *
259
- * @param {String} taskId - the task id
260
- * @returns {Promise} - resolved when achive action done
304
+ * gradually increase the polling interval to ease server load
305
+ * @private
306
+ * @param {Object} pollingInstance - a poll object
261
307
  */
262
- archive: function archive(taskId) {
263
- var status;
264
308
 
265
- if (!config.url || !config.url.archive) {
266
- throw new TypeError('config.url.archive is not configured while archive() is being called');
267
- }
309
+ var _updateInterval = function _updateInterval(pollingInstance) {
310
+ var pollingInterval;
268
311
 
269
- status = request(config.url.archive, {
270
- taskId: taskId
271
- }, 'GET', {}, true);
272
- status.catch(function (res) {
273
- model.trigger('error', res);
274
- });
275
- return status;
276
- },
277
-
278
- /**
279
- * Poll status for all tasks
280
- * @param {Boolean} [immediate] - tells if the polling should immediately start (otherwise, will wait until the next iteration)
281
- * @returns {taskQueueModel}
282
- */
283
- pollAll: function pollAll(immediate) {
284
- var self = this;
285
- var loop = 0;
286
- var pollingIntervals = getPollAllIntervals();
287
- /**
288
- * gradually increase the polling interval to ease server load
289
- * @private
290
- * @param {Object} pollingInstance - a poll object
291
- */
292
-
293
- var _updateInterval = function _updateInterval(pollingInstance) {
294
- var pollingInterval;
295
-
296
- if (loop) {
297
- loop--;
298
- } else {
299
- pollingInterval = pollingIntervals.shift();
312
+ if (loop) {
313
+ loop--;
314
+ } else {
315
+ pollingInterval = pollingIntervals.shift();
300
316
 
301
- if (pollingInterval && typeof pollingInterval.iteration !== 'undefined' && pollingInterval.interval) {
302
- loop = pollingInterval.iteration;
303
- pollingInstance.setInterval(pollingInterval.interval);
304
- }
317
+ if (pollingInterval && typeof pollingInterval.iteration !== 'undefined' && pollingInterval.interval) {
318
+ loop = pollingInterval.iteration;
319
+ pollingInstance.setInterval(pollingInterval.interval);
305
320
  }
306
- };
307
-
308
- if (!config.url || !config.url.all) {
309
- throw new TypeError('config.url.all is not configured while pollAll() is being called');
310
321
  }
322
+ };
311
323
 
312
- if (!this.globalPolling) {
313
- //no global polling yet, create one
314
- this.globalPolling = polling({
315
- action: function action() {
316
- // get into asynchronous mode
317
- var done = this.async();
318
- var statusArr;
319
- model.getAll().then(function (taskDataArray) {
320
- model.trigger('pollAll', taskDataArray); //smart polling: stop polling when there is no task in progress
324
+ if (!config.url || !config.url.all) {
325
+ throw new TypeError('config.url.all is not configured while pollAll() is being called');
326
+ }
321
327
 
322
- statusArr = _.map(taskDataArray, 'status');
328
+ if (!this.globalPolling) {
329
+ //no global polling yet, create one
330
+ this.globalPolling = polling({
331
+ action: function action() {
332
+ // get into asynchronous mode
333
+ var done = this.async();
334
+ var statusArr;
335
+ model.getAll().then(function (taskDataArray) {
336
+ model.trigger('pollAll', taskDataArray); //smart polling: stop polling when there is no task in progress
323
337
 
324
- if (statusArr.indexOf('in_progress') === -1 && statusArr.indexOf('created') === -1) {
325
- return done.reject();
326
- }
338
+ statusArr = _.map(taskDataArray, 'status');
327
339
 
328
- _updateInterval(self.globalPolling);
340
+ if (statusArr.indexOf('in_progress') === -1 && statusArr.indexOf('created') === -1) {
341
+ return done.reject();
342
+ }
329
343
 
330
- done.resolve();
331
- }).catch(function () {
332
- done.reject();
333
- });
334
- }
335
- });
344
+ _updateInterval(self.globalPolling);
336
345
 
337
- _updateInterval(this.globalPolling);
346
+ done.resolve();
347
+ }).catch(function () {
348
+ done.reject();
349
+ });
350
+ }
351
+ });
338
352
 
339
- this.globalPolling.start();
340
- this.trigger('pollAllStart');
341
- } else {
342
- this.globalPolling.start();
343
- this.trigger('pollAllStart');
344
- }
353
+ _updateInterval(this.globalPolling);
345
354
 
346
- if (immediate) {
347
- //if it is request to immediate start polling, start it now
348
- this.globalPolling.next();
349
- }
355
+ this.globalPolling.start();
356
+ this.trigger('pollAllStart');
357
+ } else {
358
+ this.globalPolling.start();
359
+ this.trigger('pollAllStart');
360
+ }
350
361
 
351
- return model;
352
- },
362
+ if (immediate) {
363
+ //if it is request to immediate start polling, start it now
364
+ this.globalPolling.next();
365
+ }
353
366
 
354
- /**
355
- * Stop the main polling action
356
- * @returns {taskQueueModel}
357
- */
358
- pollAllStop: function pollAllStop() {
359
- if (this.globalPolling) {
360
- this.globalPolling.stop();
361
- this.trigger('pollAllStop');
362
- }
367
+ return model;
368
+ },
363
369
 
364
- return this;
365
- },
370
+ /**
371
+ * Stop the main polling action
372
+ * @returns {taskQueueModel}
373
+ */
374
+ pollAllStop: function pollAllStop() {
375
+ if (this.globalPolling) {
376
+ this.globalPolling.stop();
377
+ this.trigger('pollAllStop');
378
+ }
366
379
 
380
+ return this;
381
+ },
382
+
383
+ /**
384
+ * Start a single fast polling for a single task id
385
+ * @param {String} taskId - the task id
386
+ * @returns {Promise} resolved when the single polling action finishes
387
+ */
388
+ pollSingle: function pollSingle(taskId) {
389
+ var self = this;
390
+ var loop = 0;
391
+ var pollingIntervals = getPollSingleIntervals();
367
392
  /**
368
- * Start a single fast polling for a single task id
369
- * @param {String} taskId - the task id
370
- * @returns {Promise} resolved when the single polling action finishes
393
+ * gradually increase the polling interval to ease server load
394
+ * @private
395
+ * @param {Object} pollingInstance - a poll object
371
396
  */
372
- pollSingle: function pollSingle(taskId) {
373
- var self = this;
374
- var loop = 0;
375
- var pollingIntervals = getPollSingleIntervals();
376
- /**
377
- * gradually increase the polling interval to ease server load
378
- * @private
379
- * @param {Object} pollingInstance - a poll object
380
- */
381
-
382
- var _updateInterval = function _updateInterval(pollingInstance) {
383
- var pollingInterval;
384
-
385
- if (loop) {
386
- loop--;
387
- return true; //continue polling
388
- } else {
389
- pollingInterval = pollingIntervals.shift();
390
397
 
391
- if (pollingInterval && pollingInterval.iteration && pollingInterval.interval) {
392
- loop = pollingInterval.iteration;
393
- pollingInstance.setInterval(pollingInterval.interval);
394
- return true; //continue polling
395
- } else {
396
- //stop polling
397
- return false;
398
- }
399
- }
400
- };
398
+ var _updateInterval = function _updateInterval(pollingInstance) {
399
+ var pollingInterval;
401
400
 
402
- if (!config.url || !config.url.get) {
403
- throw new TypeError('config.url.get is not configured while pollSingle() is being called');
404
- }
401
+ if (loop) {
402
+ loop--;
403
+ return true; //continue polling
404
+ } else {
405
+ pollingInterval = pollingIntervals.shift();
405
406
 
406
- if (singlePollings[taskId]) {
407
- singlePollings[taskId].stop();
407
+ if (pollingInterval && pollingInterval.iteration && pollingInterval.interval) {
408
+ loop = pollingInterval.iteration;
409
+ pollingInstance.setInterval(pollingInterval.interval);
410
+ return true; //continue polling
411
+ } else {
412
+ //stop polling
413
+ return false;
414
+ }
408
415
  }
416
+ };
409
417
 
410
- return new Promise(function (resolve) {
411
- var poll = polling({
412
- action: function action() {
413
- // get into asynchronous mode
414
- var done = this.async();
415
- self.get(taskId).then(function (taskData) {
416
- if (taskData.status === 'completed' || taskData.status === 'failed') {
417
- //the status status could be either "completed" or "failed"
418
- poll.stop();
419
- self.trigger('pollSingleFinished', taskId, taskData);
420
- resolve({
421
- finished: true,
422
- task: taskData
423
- });
424
- } else if (!_updateInterval(poll)) {
425
- //if we have reached the end of the total polling config
426
- self.trigger('pollSingleFinished', taskId, taskData);
427
- resolve({
428
- finished: false,
429
- task: taskData
430
- });
431
- } else {
432
- self.trigger('pollSingle', taskId, taskData);
433
- done.resolve(); //go to next poll iteration
434
- }
435
- }).catch(function () {
436
- done.reject();
437
- });
438
- }
439
- });
418
+ if (!config.url || !config.url.get) {
419
+ throw new TypeError('config.url.get is not configured while pollSingle() is being called');
420
+ }
440
421
 
441
- _updateInterval(poll);
422
+ if (singlePollings[taskId]) {
423
+ singlePollings[taskId].stop();
424
+ }
442
425
 
443
- singlePollings[taskId] = poll.start();
444
- self.trigger('pollSingleStart', taskId);
426
+ return new Promise(function (resolve) {
427
+ var poll = polling({
428
+ action: function action() {
429
+ // get into asynchronous mode
430
+ var done = this.async();
431
+ self.get(taskId).then(function (taskData) {
432
+ if (taskData.status === 'completed' || taskData.status === 'failed') {
433
+ //the status status could be either "completed" or "failed"
434
+ poll.stop();
435
+ self.trigger('pollSingleFinished', taskId, taskData);
436
+ resolve({
437
+ finished: true,
438
+ task: taskData
439
+ });
440
+ } else if (!_updateInterval(poll)) {
441
+ //if we have reached the end of the total polling config
442
+ self.trigger('pollSingleFinished', taskId, taskData);
443
+ resolve({
444
+ finished: false,
445
+ task: taskData
446
+ });
447
+ } else {
448
+ self.trigger('pollSingle', taskId, taskData);
449
+ done.resolve(); //go to next poll iteration
450
+ }
451
+ }).catch(function () {
452
+ done.reject();
453
+ });
454
+ }
445
455
  });
446
- },
447
456
 
448
- /**
449
- * Interrupt a single polling action
450
- * @param {String} taskId - the task id
451
- * @returns {model}
452
- */
453
- pollSingleStop: function pollSingleStop(taskId) {
454
- if (singlePollings && singlePollings[taskId]) {
455
- singlePollings[taskId].stop();
456
- this.trigger('pollSingleStop', taskId);
457
- }
457
+ _updateInterval(poll);
458
458
 
459
- return this;
460
- },
459
+ singlePollings[taskId] = poll.start();
460
+ self.trigger('pollSingleStart', taskId);
461
+ });
462
+ },
461
463
 
462
- /**
463
- * Call a task creation url
464
- * @param {String} url - the server side task queue creation service
465
- * @param {Object} [data] - request data
466
- * @returns {promise} - resolved when task creation response is sent back by the server
467
- */
468
- create: function create(url, data) {
469
- var taskCreate,
470
- self = this;
471
- taskCreate = request(url, data, 'POST', {}, true).then(function (creationResult) {
472
- //poll short result:
473
- if (creationResult && creationResult.task && creationResult.task.id) {
474
- self.trigger('created', creationResult);
475
- return self.pollSingle(creationResult.task.id).then(function (result) {
476
- if (creationResult.extra) {
477
- result.extra = creationResult.extra;
478
- }
464
+ /**
465
+ * Interrupt a single polling action
466
+ * @param {String} taskId - the task id
467
+ * @returns {model}
468
+ */
469
+ pollSingleStop: function pollSingleStop(taskId) {
470
+ if (singlePollings && singlePollings[taskId]) {
471
+ singlePollings[taskId].stop();
472
+ this.trigger('pollSingleStop', taskId);
473
+ }
479
474
 
480
- if (result.finished) {
481
- //send to queue
482
- self.trigger('fastFinished', result);
483
- } else {
484
- //send to queue
485
- self.trigger('enqueued', result);
486
- }
475
+ return this;
476
+ },
487
477
 
488
- return result;
489
- });
490
- }
478
+ /**
479
+ * Call a task creation url
480
+ * @param {String} url - the server side task queue creation service
481
+ * @param {Object} [data] - request data
482
+ * @returns {promise} - resolved when task creation response is sent back by the server
483
+ */
484
+ create: function create(url, data) {
485
+ var taskCreate,
486
+ self = this;
487
+ taskCreate = request(url, data, 'POST', {}, true).then(function (creationResult) {
488
+ //poll short result:
489
+ if (creationResult && creationResult.task && creationResult.task.id) {
490
+ self.trigger('created', creationResult);
491
+ return self.pollSingle(creationResult.task.id).then(function (result) {
492
+ if (creationResult.extra) {
493
+ result.extra = creationResult.extra;
494
+ }
491
495
 
492
- return Promise.reject(new Error('failed to get task data'));
493
- });
494
- taskCreate.catch(function (err) {
495
- model.trigger('error', err);
496
- });
497
- return taskCreate;
498
- },
496
+ if (result.finished) {
497
+ //send to queue
498
+ self.trigger('fastFinished', result);
499
+ } else {
500
+ //send to queue
501
+ self.trigger('enqueued', result);
502
+ }
499
503
 
500
- /**
501
- * Call the task result file download endpoint
502
- * @param {String} taskId - the task id
503
- * @returns {promise} - resolved when the download popup is shown
504
- */
505
- download: function download(taskId) {
506
- if (!config.url || !config.url.download) {
507
- throw new TypeError('config.url.download is not configured while download() is being called');
504
+ return result;
505
+ });
508
506
  }
509
507
 
510
- return new Promise(function (resolve, reject) {
511
- $.fileDownload(config.url.download, {
512
- httpMethod: 'POST',
513
- data: {
514
- taskId: taskId
515
- },
516
- successCallback: function (result) {
517
- resolve(result);
518
- },
519
- failCallback: function (err) {
520
- reject(err);
521
- }
522
- });
523
- });
524
- },
508
+ return Promise.reject(new Error('failed to get task data'));
509
+ });
510
+ taskCreate.catch(function (err) {
511
+ model.trigger('error', err);
512
+ });
513
+ return taskCreate;
514
+ },
525
515
 
526
- /**
527
- * Call the task result redirection endpoint
528
- * @param {String} taskId - the task id
529
- * @returns {Promise}
530
- */
531
- redirect: function redirect(taskId) {
532
- return this.getCached(taskId).then(function (taskData) {
533
- var redirectUrl = (taskData || {}).redirectUrl;
516
+ /**
517
+ * Call the task result file download endpoint
518
+ * @param {String} taskId - the task id
519
+ * @returns {promise} - resolved when the download popup is shown
520
+ */
521
+ download: function download(taskId) {
522
+ if (!config.url || !config.url.download) {
523
+ throw new TypeError('config.url.download is not configured while download() is being called');
524
+ }
534
525
 
535
- if (!redirectUrl) {
536
- throw new TypeError('config.redirectUrl is not configured while redirect() is being called');
526
+ return new Promise(function (resolve, reject) {
527
+ $.fileDownload(config.url.download, {
528
+ httpMethod: 'POST',
529
+ data: {
530
+ taskId: taskId
531
+ },
532
+ successCallback: function successCallback(result) {
533
+ resolve(result);
534
+ },
535
+ failCallback: function failCallback(err) {
536
+ reject(err);
537
537
  }
538
+ });
539
+ });
540
+ },
538
541
 
539
- if (redirectUrl.indexOf('http') !== 0) {
540
- throw new TypeError('redirectUrl does not look like a proper url: ' + redirectUrl);
541
- }
542
+ /**
543
+ * Call the task result redirection endpoint
544
+ * @param {String} taskId - the task id
545
+ * @returns {Promise}
546
+ */
547
+ redirect: function redirect(taskId) {
548
+ return this.getCached(taskId).then(function (taskData) {
549
+ var redirectUrl = (taskData || {}).redirectUrl;
542
550
 
543
- return request(taskData.redirectUrl);
544
- }).then(function (response) {
545
- if (!_.isEmpty(response)) {
546
- window.location.href = response;
547
- }
548
- }).catch(function (err) {
549
- //202 -> resource deleted, handle it has a user error
550
- if (err && err.code === 202 && err.response && err.response.errorMessage) {
551
- feedback().error(err.response.errorMessage);
552
- }
551
+ if (!redirectUrl) {
552
+ throw new TypeError('config.redirectUrl is not configured while redirect() is being called');
553
+ }
553
554
 
554
- throw err;
555
- });
556
- }
557
- });
558
- return model;
559
- }
555
+ if (redirectUrl.indexOf('http') !== 0) {
556
+ throw new TypeError('redirectUrl does not look like a proper url: ' + redirectUrl);
557
+ }
558
+
559
+ return request(taskData.redirectUrl);
560
+ }).then(function (response) {
561
+ if (!_.isEmpty(response)) {
562
+ window.location.href = response;
563
+ }
564
+ }).catch(function (err) {
565
+ //202 -> resource deleted, handle it has a user error
566
+ if (err && err.code === 202 && err.response && err.response.errorMessage) {
567
+ feedback().error(err.response.errorMessage);
568
+ }
569
+
570
+ throw err;
571
+ });
572
+ }
573
+ });
574
+ return model;
575
+ }
560
576
 
561
- return taskQueueModel;
577
+ return taskQueueModel;
562
578
 
563
579
  });