@oat-sa/tao-core-ui 1.64.1 → 1.64.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +339 -339
- package/README.md +22 -22
- package/dist/actionbar.js +92 -92
- package/dist/adder.js +109 -109
- package/dist/animable/absorbable/absorbable.js +29 -29
- package/dist/animable/absorbable/css/absorb.css +7 -7
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/css/pulse.css +7 -7
- package/dist/animable/pulsable/css/pulse.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +23 -23
- package/dist/areaBroker.js +51 -51
- package/dist/autocomplete/css/autocomplete.css +7 -7
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +384 -384
- package/dist/autoscroll.js +22 -22
- package/dist/badge/badge.js +35 -35
- package/dist/badge/css/badge.css +7 -7
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +7 -7
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/breadcrumbs.js +57 -57
- package/dist/btngrouper.js +64 -64
- package/dist/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/dist/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/dist/bulkActionPopup.js +91 -91
- package/dist/button.js +89 -89
- package/dist/calculator/css/calculator.css +10 -10
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/calculator.js +51 -51
- package/dist/cascadingComboBox.js +34 -34
- package/dist/ckeditor/ckConfigurator.js +49 -49
- package/dist/ckeditor/dtdHandler.js +110 -110
- package/dist/class/css/selector.css +7 -7
- package/dist/class/css/selector.css.map +1 -1
- package/dist/class/selector.js +98 -98
- package/dist/component/alignable.js +81 -81
- package/dist/component/containable.js +37 -37
- package/dist/component/css/components.css +7 -7
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +7 -7
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +25 -25
- package/dist/component/placeable.js +70 -70
- package/dist/component/resizable.js +61 -61
- package/dist/component/stackable.js +20 -20
- package/dist/component/windowed.js +46 -46
- package/dist/component.js +140 -140
- package/dist/container.js +76 -76
- package/dist/contextualPopup/css/contextualPopup.css +7 -7
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/contextualPopup.js +100 -100
- package/dist/dashboard/css/dashboard.css +7 -7
- package/dist/dashboard/css/dashboard.css.map +1 -1
- package/dist/dashboard.js +62 -62
- package/dist/datalist/css/datalist.css +7 -7
- package/dist/datalist/css/datalist.css.map +1 -1
- package/dist/datalist.js +147 -147
- package/dist/datatable/css/datatable.css +7 -7
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable/filterStrategy/filterStrategy.js +27 -27
- package/dist/datatable/filterStrategy/multiple.js +25 -25
- package/dist/datatable/filterStrategy/single.js +25 -25
- package/dist/datatable.js +377 -377
- package/dist/dateRange/css/dateRange.css +7 -7
- package/dist/dateRange/css/dateRange.css.map +1 -1
- package/dist/dateRange/dateRange.js +97 -97
- package/dist/datetime/css/picker.css +7 -7
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/datetime/picker.js +161 -161
- package/dist/deleter.js +79 -79
- package/dist/destination/css/selector.css +7 -7
- package/dist/destination/css/selector.css.map +1 -1
- package/dist/destination/selector.js +52 -52
- package/dist/dialog/alert.js +26 -26
- package/dist/dialog/confirm.js +27 -27
- package/dist/dialog/confirmDelete.js +31 -31
- package/dist/dialog.js +141 -141
- package/dist/disabler.js +90 -90
- package/dist/documentViewer/css/documentViewer.css +7 -7
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +30 -30
- package/dist/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +25 -25
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +120 -120
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +89 -89
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +52 -52
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +112 -112
- package/dist/documentViewer/providers/pdfViewer/pdfjs/textManager.js +67 -67
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +81 -81
- package/dist/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +111 -111
- package/dist/documentViewer/providers/pdfViewer.js +29 -29
- package/dist/documentViewer/viewerFactory.js +71 -71
- package/dist/documentViewer.js +86 -86
- package/dist/dropdown/css/dropdown.css +7 -7
- package/dist/dropdown/css/dropdown.css.map +1 -1
- package/dist/dropdown.js +84 -84
- package/dist/durationer.js +58 -58
- package/dist/dynamicComponent/css/dynamicComponent.css +7 -7
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +103 -103
- package/dist/feedback.js +84 -84
- package/dist/figure/FigureStateActive.js +111 -111
- package/dist/filesender.js +26 -26
- package/dist/filter.js +34 -34
- package/dist/form/css/dropdownForm.css +7 -7
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/css/form.css +7 -7
- package/dist/form/css/form.css.map +1 -1
- package/dist/form/dropdownForm.js +99 -99
- package/dist/form/form.js +248 -248
- package/dist/form/simpleForm.js +71 -71
- package/dist/form/validator/css/validator.css +7 -7
- package/dist/form/validator/css/validator.css.map +1 -1
- package/dist/form/validator/renderer.js +52 -52
- package/dist/form/validator/validator.js +103 -103
- package/dist/form/widget/css/widget.css +7 -7
- package/dist/form/widget/css/widget.css.map +1 -1
- package/dist/form/widget/definitions.js +24 -24
- package/dist/form/widget/loader.js +16 -16
- package/dist/form/widget/providers/checkBox.js +62 -62
- package/dist/form/widget/providers/comboBox.js +46 -46
- package/dist/form/widget/providers/default.js +35 -35
- package/dist/form/widget/providers/hidden.js +37 -37
- package/dist/form/widget/providers/hiddenBox.js +58 -58
- package/dist/form/widget/providers/radioBox.js +57 -57
- package/dist/form/widget/providers/textArea.js +35 -35
- package/dist/form/widget/providers/textBox.js +34 -34
- package/dist/form/widget/widget.js +141 -141
- package/dist/form.js +10 -10
- package/dist/formValidator/formValidator.js +61 -61
- package/dist/formValidator/highlighters/highlighter.js +41 -41
- package/dist/formValidator/highlighters/message.js +29 -29
- package/dist/formValidator/highlighters/tooltip.js +32 -32
- package/dist/generis/form/css/form.css +7 -7
- package/dist/generis/form/css/form.css.map +1 -1
- package/dist/generis/form/form.js +73 -73
- package/dist/generis/validator/css/validator.css +7 -7
- package/dist/generis/validator/css/validator.css.map +1 -1
- package/dist/generis/validator/validator.js +38 -38
- package/dist/generis/widget/checkBox/checkBox.js +39 -39
- package/dist/generis/widget/comboBox/comboBox.js +32 -32
- package/dist/generis/widget/css/widget.css +7 -7
- package/dist/generis/widget/css/widget.css.map +1 -1
- package/dist/generis/widget/hiddenBox/hiddenBox.js +40 -40
- package/dist/generis/widget/loader.js +20 -20
- package/dist/generis/widget/textBox/textBox.js +27 -27
- package/dist/generis/widget/widget.js +47 -47
- package/dist/groupedComboBox.js +36 -36
- package/dist/groupvalidator.js +19 -19
- package/dist/hider.js +41 -41
- package/dist/highlighter.js +278 -278
- package/dist/image/ImgStateActive/extractLabel.js +20 -20
- package/dist/image/ImgStateActive/helper.js +16 -16
- package/dist/image/ImgStateActive/initHelper.js +85 -85
- package/dist/image/ImgStateActive/initMediaEditor.js +48 -48
- package/dist/image/ImgStateActive/mediaSizer.js +32 -32
- package/dist/image/ImgStateActive.js +104 -104
- package/dist/incrementer.js +58 -58
- package/dist/inplacer.js +87 -87
- package/dist/interactUtils.js +42 -42
- package/dist/itemButtonList/css/item-button-list.css +23 -23
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +102 -102
- package/dist/keyNavigation/navigableDomElement.js +76 -76
- package/dist/keyNavigation/navigator.js +158 -158
- package/dist/listbox/css/listbox.css +7 -7
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/listbox.js +84 -84
- package/dist/liststyler.js +57 -57
- package/dist/loadingButton/css/button.css +7 -7
- package/dist/loadingButton/css/button.css.map +1 -1
- package/dist/loadingButton/loadingButton.js +35 -35
- package/dist/lock.js +112 -112
- package/dist/login/login.js +87 -87
- package/dist/maths/calculator/basicCalculator.js +50 -50
- package/dist/maths/calculator/calculatorComponent.js +29 -29
- package/dist/maths/calculator/core/areaBroker.js +25 -25
- package/dist/maths/calculator/core/board.js +300 -300
- package/dist/maths/calculator/core/expression.js +98 -98
- package/dist/maths/calculator/core/labels.js +16 -16
- package/dist/maths/calculator/core/plugin.js +19 -19
- package/dist/maths/calculator/core/terms.js +26 -26
- package/dist/maths/calculator/core/tokenizer.js +98 -98
- package/dist/maths/calculator/core/tokens.js +75 -75
- package/dist/maths/calculator/css/calculator.css +7 -7
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/defaultCalculator.js +23 -23
- package/dist/maths/calculator/plugins/core/degrad.js +22 -22
- package/dist/maths/calculator/plugins/core/history.js +45 -45
- package/dist/maths/calculator/plugins/core/remind.js +22 -22
- package/dist/maths/calculator/plugins/core/stepNavigation.js +31 -31
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +48 -48
- package/dist/maths/calculator/plugins/modifiers/pow10.js +35 -35
- package/dist/maths/calculator/plugins/modifiers/sign.js +90 -90
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +47 -47
- package/dist/maths/calculator/pluginsLoader.js +21 -21
- package/dist/maths/calculator/scientificCalculator.js +78 -78
- package/dist/mediaEditor/mediaEditorComponent.js +51 -51
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +16 -16
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +47 -47
- package/dist/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/dist/mediaEditor/plugins/mediaDimension/helper.js +70 -70
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +140 -140
- package/dist/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +52 -52
- package/dist/mediaplayer/players/youtube.js +39 -39
- package/dist/mediaplayer/players.js +18 -18
- package/dist/mediaplayer/support.js +55 -55
- package/dist/mediaplayer/utils/reminder.js +100 -100
- package/dist/mediaplayer/utils/timeObserver.js +92 -92
- package/dist/mediaplayer/youtubeManager.js +51 -51
- package/dist/mediaplayer.js +447 -447
- package/dist/mediasizer.js +122 -122
- package/dist/modal.js +87 -87
- package/dist/movableComponent.js +35 -35
- package/dist/pageSizeSelector.js +31 -31
- package/dist/pageStatus.js +33 -33
- package/dist/pagination/css/pagination.css +7 -7
- package/dist/pagination/css/pagination.css.map +1 -1
- package/dist/pagination/paginationStrategy.js +23 -23
- package/dist/pagination/providers/pages.js +24 -24
- package/dist/pagination/providers/simple.js +22 -22
- package/dist/pagination.js +45 -45
- package/dist/previewer.js +67 -67
- package/dist/progressbar.js +58 -58
- package/dist/propertySelector/css/propertySelector.css +7 -7
- package/dist/propertySelector/css/propertySelector.css.map +1 -1
- package/dist/propertySelector/propertySelector.js +86 -86
- package/dist/report.js +73 -73
- package/dist/resource/css/selector.css +7 -7
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/filters.js +60 -60
- package/dist/resource/list.js +53 -53
- package/dist/resource/selectable.js +92 -92
- package/dist/resource/selector.js +182 -182
- package/dist/resource/tree.js +91 -91
- package/dist/resourcemgr/css/resourcemgr.css +7 -7
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +75 -75
- package/dist/resourcemgr/fileSelector.js +45 -45
- package/dist/resourcemgr/util/updatePermissions.js +4 -4
- package/dist/resourcemgr.js +49 -49
- package/dist/scroller.js +26 -26
- package/dist/searchModal/advancedSearch.js +155 -155
- package/dist/searchModal/css/advancedSearch.css +7 -7
- package/dist/searchModal/css/advancedSearch.css.map +1 -1
- package/dist/searchModal/css/searchModal.css +7 -7
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +134 -134
- package/dist/selecter.js +6 -6
- package/dist/stacker.js +43 -43
- package/dist/switch/css/switch.css +7 -7
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/switch/switch.js +62 -62
- package/dist/tableModel.js +33 -33
- package/dist/tabs/css/tabs.css +12 -12
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/tabs.js +220 -220
- package/dist/taskQueue/css/taskQueue.css +7 -7
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/status.js +59 -59
- package/dist/taskQueue/table.js +54 -54
- package/dist/taskQueue/taskQueue.js +18 -18
- package/dist/taskQueue/taskQueueModel.js +102 -102
- package/dist/taskQueue.js +47 -47
- package/dist/taskQueueButton/css/taskable.css +7 -7
- package/dist/taskQueueButton/css/taskable.css.map +1 -1
- package/dist/taskQueueButton/css/treeButton.css +7 -7
- package/dist/taskQueueButton/css/treeButton.css.map +1 -1
- package/dist/taskQueueButton/standardButton.js +39 -39
- package/dist/taskQueueButton/taskable.js +41 -41
- package/dist/taskQueueButton/treeButton.js +43 -43
- package/dist/themeLoader.js +75 -75
- package/dist/themes.js +84 -84
- package/dist/toggler.js +57 -57
- package/dist/tooltip.js +41 -41
- package/dist/tooltipster.js +17 -17
- package/dist/transformer.js +117 -117
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/dist/tristateCheckboxGroup.js +62 -62
- package/dist/uploader.js +145 -145
- package/dist/validator/validators.js +48 -48
- package/dist/validator.js +23 -23
- package/dist/waitForMedia.js +33 -33
- package/dist/waitingDialog/css/waitingDialog.css +7 -7
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/dist/waitingDialog/waitingDialog.js +54 -54
- package/package.json +110 -110
- package/scss/basic.scss +16 -16
- package/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +60 -60
- package/scss/ckeditor/skins/tao/scss/inc/_tao.scss +59 -59
- package/scss/font/tao/tao.svg +235 -235
- package/scss/inc/_base.scss +495 -495
- package/scss/inc/_bootstrap.scss +6 -6
- package/scss/inc/_buttons.scss +114 -114
- package/scss/inc/_colors.scss +93 -93
- package/scss/inc/_feedback.scss +154 -154
- package/scss/inc/_flex-grid.scss +15 -15
- package/scss/inc/_fonts.scss +4 -4
- package/scss/inc/_forms.scss +832 -832
- package/scss/inc/_functions.scss +283 -283
- package/scss/inc/_jquery.nouislider.scss +254 -254
- package/scss/inc/_normalize.scss +528 -528
- package/scss/inc/_report.scss +67 -67
- package/scss/inc/_secondary-properties.scss +89 -89
- package/scss/inc/_select2.scss +634 -634
- package/scss/inc/_toolbars.scss +155 -155
- package/scss/inc/_tooltip.scss +312 -312
- package/scss/inc/_variables.scss +21 -21
- package/scss/inc/base/_highlight.scss +5 -5
- package/scss/inc/base/_list-style.scss +58 -58
- package/scss/inc/base/_svg.scss +3 -3
- package/scss/inc/base/_table.scss +62 -62
- package/scss/inc/fonts/_source-sans-pro.scss +29 -29
- package/scss/inc/fonts/_tao-icon-classes.scss +227 -227
- package/scss/inc/fonts/_tao-icon-def.scss +12 -12
- package/scss/inc/fonts/_tao-icon-vars.scss +241 -241
- package/src/actionbar/tpl/main.tpl +8 -8
- package/src/actionbar.js +251 -251
- package/src/adder.js +250 -250
- package/src/animable/absorbable/absorbable.js +134 -134
- package/src/animable/absorbable/css/absorb.css +7 -7
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/animable/absorbable/scss/absorb.scss +37 -37
- package/src/animable/pulsable/css/pulse.css +7 -7
- package/src/animable/pulsable/css/pulse.css.map +1 -1
- package/src/animable/pulsable/pulsable.js +90 -90
- package/src/animable/pulsable/scss/pulse.scss +22 -22
- package/src/areaBroker.js +160 -160
- package/src/autocomplete/css/autocomplete.css +7 -7
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/autocomplete/scss/autocomplete.scss +37 -37
- package/src/autocomplete.js +1027 -1027
- package/src/autoscroll.js +57 -57
- package/src/badge/badge.js +119 -119
- package/src/badge/css/badge.css +7 -7
- package/src/badge/css/badge.css.map +1 -1
- package/src/badge/scss/badge.scss +92 -92
- package/src/badge/tpl/badge.tpl +4 -4
- package/src/breadcrumbs/css/breadcrumbs.css +7 -7
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/breadcrumbs/scss/breadcrumbs.scss +52 -52
- package/src/breadcrumbs/tpl/breadcrumbs.tpl +20 -20
- package/src/breadcrumbs.js +99 -99
- package/src/btngrouper.js +213 -213
- package/src/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/src/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/src/bulkActionPopup/scss/bulkActionPopup.scss +63 -63
- package/src/bulkActionPopup/tpl/layout.tpl +76 -76
- package/src/bulkActionPopup/tpl/select.tpl +8 -8
- package/src/bulkActionPopup.js +274 -274
- package/src/button/tpl/button.tpl +4 -4
- package/src/button.js +135 -135
- package/src/calculator/css/calculator.css +10 -10
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/calculator/scss/calculator.scss +139 -139
- package/src/calculator.js +188 -188
- package/src/cascadingComboBox.js +126 -126
- package/src/ckeditor/ckConfigurator.js +742 -742
- package/src/ckeditor/dtdHandler.js +1030 -1030
- package/src/class/css/selector.css +7 -7
- package/src/class/css/selector.css.map +1 -1
- package/src/class/scss/selector.scss +101 -101
- package/src/class/selector.js +329 -329
- package/src/class/tpl/listItem.tpl +9 -9
- package/src/class/tpl/selector.tpl +10 -10
- package/src/component/alignable.js +274 -274
- package/src/component/containable.js +122 -122
- package/src/component/css/components.css +7 -7
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +7 -7
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/component/draggable.js +104 -104
- package/src/component/placeable.js +233 -233
- package/src/component/resizable.js +195 -195
- package/src/component/scss/components.scss +507 -507
- package/src/component/scss/windowComponent.scss +62 -62
- package/src/component/stackable.js +67 -67
- package/src/component/tpl/window.tpl +7 -7
- package/src/component/windowed.js +206 -206
- package/src/component.js +401 -401
- package/src/container.js +200 -200
- package/src/contextualPopup/css/contextualPopup.css +7 -7
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/contextualPopup/scss/contextualPopup.scss +78 -78
- package/src/contextualPopup/tpl/popup.tpl +10 -10
- package/src/contextualPopup.js +294 -294
- package/src/css/basic.css +104 -104
- package/src/css/basic.css.map +1 -1
- package/src/dashboard/css/dashboard.css +7 -7
- package/src/dashboard/css/dashboard.css.map +1 -1
- package/src/dashboard/scss/dashboard.scss +93 -93
- package/src/dashboard/tpl/dashboard.tpl +16 -16
- package/src/dashboard/tpl/dashboardMetricsList.tpl +15 -15
- package/src/dashboard.js +179 -179
- package/src/datalist/css/datalist.css +7 -7
- package/src/datalist/css/datalist.css.map +1 -1
- package/src/datalist/scss/datalist.scss +116 -116
- package/src/datalist/tpl/list.tpl +24 -24
- package/src/datalist/tpl/main.tpl +44 -44
- package/src/datalist.js +500 -500
- package/src/datatable/css/datatable.css +7 -7
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datatable/filterStrategy/filterStrategy.js +70 -70
- package/src/datatable/filterStrategy/multiple.js +126 -126
- package/src/datatable/filterStrategy/single.js +108 -108
- package/src/datatable/scss/datatable.scss +149 -149
- package/src/datatable/tpl/button.tpl +6 -6
- package/src/datatable/tpl/layout.tpl +158 -158
- package/src/datatable.js +1056 -1056
- package/src/dateRange/css/dateRange.css +7 -7
- package/src/dateRange/css/dateRange.css.map +1 -1
- package/src/dateRange/dateRange.js +341 -341
- package/src/dateRange/scss/dateRange.scss +7 -7
- package/src/dateRange/tpl/select.tpl +18 -18
- package/src/datetime/css/picker.css +7 -7
- package/src/datetime/css/picker.css.map +1 -1
- package/src/datetime/picker.js +576 -576
- package/src/datetime/scss/picker.scss +192 -192
- package/src/datetime/tpl/picker.tpl +18 -18
- package/src/deleter/undo.tpl +6 -6
- package/src/deleter.js +296 -296
- package/src/destination/css/selector.css +7 -7
- package/src/destination/css/selector.css.map +1 -1
- package/src/destination/scss/selector.scss +36 -36
- package/src/destination/selector.js +195 -195
- package/src/destination/tpl/selector.tpl +13 -13
- package/src/dialog/alert.js +70 -70
- package/src/dialog/confirm.js +85 -85
- package/src/dialog/confirmDelete.js +95 -95
- package/src/dialog/tpl/body.tpl +24 -24
- package/src/dialog/tpl/buttons.tpl +6 -6
- package/src/dialog/tpl/checkbox.tpl +5 -5
- package/src/dialog.js +517 -517
- package/src/disabler.js +230 -230
- package/src/documentViewer/css/documentViewer.css +7 -7
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/documentViewer/providers/pdfViewer/fallback/viewer.js +69 -69
- package/src/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +41 -41
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.js +475 -475
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.tpl +20 -20
- package/src/documentViewer/providers/pdfViewer/pdfjs/match.tpl +1 -1
- package/src/documentViewer/providers/pdfViewer/pdfjs/page.tpl +4 -4
- package/src/documentViewer/providers/pdfViewer/pdfjs/pageView.js +318 -318
- package/src/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +167 -167
- package/src/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +451 -451
- package/src/documentViewer/providers/pdfViewer/pdfjs/textManager.js +252 -252
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.js +299 -299
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.tpl +16 -16
- package/src/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +351 -351
- package/src/documentViewer/providers/pdfViewer.js +93 -93
- package/src/documentViewer/scss/documentViewer.scss +184 -184
- package/src/documentViewer/viewerFactory.js +191 -191
- package/src/documentViewer.js +238 -238
- package/src/dropdown/css/dropdown.css +7 -7
- package/src/dropdown/css/dropdown.css.map +1 -1
- package/src/dropdown/scss/dropdown.scss +99 -99
- package/src/dropdown/tpl/dropdown.tpl +8 -8
- package/src/dropdown/tpl/list-item.tpl +4 -4
- package/src/dropdown.js +255 -255
- package/src/durationer.js +220 -220
- package/src/dynamicComponent/css/dynamicComponent.css +7 -7
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/dynamicComponent/scss/dynamicComponent.scss +98 -98
- package/src/dynamicComponent/tpl/layout.tpl +17 -17
- package/src/dynamicComponent.js +553 -553
- package/src/feedback/feedback.tpl +7 -7
- package/src/feedback.js +295 -295
- package/src/figure/FigureStateActive.js +184 -184
- package/src/filesender.js +112 -112
- package/src/filter/template.tpl +5 -5
- package/src/filter.js +129 -129
- package/src/form/css/dropdownForm.css +7 -7
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/form/css/form.css +7 -7
- package/src/form/css/form.css.map +1 -1
- package/src/form/dropdownForm.js +281 -281
- package/src/form/form.js +688 -688
- package/src/form/scss/dropdownForm.scss +60 -60
- package/src/form/scss/form.scss +25 -25
- package/src/form/simpleForm.js +125 -125
- package/src/form/tpl/dropdownForm.tpl +4 -4
- package/src/form/tpl/form.tpl +7 -7
- package/src/form/validator/css/validator.css +7 -7
- package/src/form/validator/css/validator.css.map +1 -1
- package/src/form/validator/renderer.js +118 -118
- package/src/form/validator/scss/validator.scss +14 -14
- package/src/form/validator/tpl/message.tpl +1 -1
- package/src/form/validator/tpl/validator.tpl +1 -1
- package/src/form/validator/validator.js +220 -220
- package/src/form/widget/css/widget.css +7 -7
- package/src/form/widget/css/widget.css.map +1 -1
- package/src/form/widget/definitions.js +51 -51
- package/src/form/widget/loader.js +40 -40
- package/src/form/widget/providers/checkBox.js +138 -138
- package/src/form/widget/providers/comboBox.js +63 -63
- package/src/form/widget/providers/default.js +90 -90
- package/src/form/widget/providers/hidden.js +62 -62
- package/src/form/widget/providers/hiddenBox.js +152 -152
- package/src/form/widget/providers/radioBox.js +99 -99
- package/src/form/widget/providers/textArea.js +52 -52
- package/src/form/widget/providers/textBox.js +48 -48
- package/src/form/widget/scss/widget.scss +55 -55
- package/src/form/widget/tpl/checkBox.tpl +25 -25
- package/src/form/widget/tpl/comboBox.tpl +13 -13
- package/src/form/widget/tpl/hidden.tpl +1 -1
- package/src/form/widget/tpl/hiddenBox.tpl +17 -17
- package/src/form/widget/tpl/label.tpl +6 -6
- package/src/form/widget/tpl/radioBox.tpl +25 -25
- package/src/form/widget/tpl/textArea.tpl +8 -8
- package/src/form/widget/tpl/widget.tpl +8 -8
- package/src/form/widget/widget.js +372 -372
- package/src/form.js +47 -47
- package/src/formValidator/formValidator.js +253 -253
- package/src/formValidator/highlighters/highlighter.js +103 -103
- package/src/formValidator/highlighters/message.js +68 -68
- package/src/formValidator/highlighters/tooltip.js +78 -78
- package/src/generis/form/css/form.css +7 -7
- package/src/generis/form/css/form.css.map +1 -1
- package/src/generis/form/form.js +239 -239
- package/src/generis/form/readme.md +70 -70
- package/src/generis/form/scss/form.scss +23 -23
- package/src/generis/form/tpl/form.tpl +16 -16
- package/src/generis/validator/css/validator.css +7 -7
- package/src/generis/validator/css/validator.css.map +1 -1
- package/src/generis/validator/readme.md +46 -46
- package/src/generis/validator/scss/validator.scss +13 -13
- package/src/generis/validator/validator.js +128 -128
- package/src/generis/widget/checkBox/checkBox.js +112 -112
- package/src/generis/widget/checkBox/checkBox.tpl +18 -18
- package/src/generis/widget/comboBox/comboBox.js +66 -66
- package/src/generis/widget/comboBox/comboBox.tpl +12 -12
- package/src/generis/widget/css/widget.css +7 -7
- package/src/generis/widget/css/widget.css.map +1 -1
- package/src/generis/widget/hiddenBox/hiddenBox.js +131 -131
- package/src/generis/widget/hiddenBox/hiddenBox.tpl +16 -16
- package/src/generis/widget/loader.js +49 -49
- package/src/generis/widget/readme.md +59 -59
- package/src/generis/widget/scss/widget.scss +61 -61
- package/src/generis/widget/textBox/textBox.js +64 -64
- package/src/generis/widget/textBox/textBox.tpl +7 -7
- package/src/generis/widget/widget.js +164 -164
- package/src/generis/widget/widget.tpl +5 -5
- package/src/groupedComboBox.js +99 -99
- package/src/groupvalidator.js +84 -84
- package/src/hider.js +88 -88
- package/src/highlighter.js +1192 -1192
- package/src/image/ImgStateActive/extractLabel.js +29 -29
- package/src/image/ImgStateActive/helper.js +36 -36
- package/src/image/ImgStateActive/initHelper.js +137 -137
- package/src/image/ImgStateActive/initMediaEditor.js +92 -92
- package/src/image/ImgStateActive/mediaSizer.js +63 -63
- package/src/image/ImgStateActive.js +115 -115
- package/src/incrementer.js +309 -309
- package/src/inplacer.js +315 -315
- package/src/interactUtils.js +140 -140
- package/src/itemButtonList/css/item-button-list.css +23 -23
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/itemButtonList/scss/item-button-list.scss +236 -236
- package/src/itemButtonList/tpl/itemButtonList.tpl +21 -21
- package/src/itemButtonList.js +274 -274
- package/src/keyNavigation/navigableDomElement.js +285 -285
- package/src/keyNavigation/navigator.js +535 -535
- package/src/listbox/css/listbox.css +7 -7
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/listbox/scss/listbox.scss +116 -116
- package/src/listbox/tpl/list.tpl +14 -14
- package/src/listbox/tpl/main.tpl +9 -9
- package/src/listbox.js +252 -252
- package/src/liststyler.js +155 -155
- package/src/loadingButton/css/button.css +7 -7
- package/src/loadingButton/css/button.css.map +1 -1
- package/src/loadingButton/loadingButton.js +110 -110
- package/src/loadingButton/scss/button.scss +41 -41
- package/src/loadingButton/tpl/button.tpl +5 -5
- package/src/lock/lock.tpl +16 -16
- package/src/lock.js +393 -393
- package/src/login/login.js +317 -317
- package/src/login/tpl/login.tpl +29 -29
- package/src/login/tpl/passwordReveal.tpl +7 -7
- package/src/maths/calculator/basicCalculator.js +55 -55
- package/src/maths/calculator/calculatorComponent.js +128 -128
- package/src/maths/calculator/core/areaBroker.js +38 -38
- package/src/maths/calculator/core/board.js +841 -841
- package/src/maths/calculator/core/expression.js +430 -430
- package/src/maths/calculator/core/labels.js +116 -116
- package/src/maths/calculator/core/plugin.js +40 -40
- package/src/maths/calculator/core/terms.js +459 -459
- package/src/maths/calculator/core/tokenizer.js +245 -245
- package/src/maths/calculator/core/tokens.js +178 -178
- package/src/maths/calculator/core/tpl/board.tpl +4 -4
- package/src/maths/calculator/css/calculator.css +7 -7
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/maths/calculator/defaultCalculator.js +66 -66
- package/src/maths/calculator/plugins/core/degrad.js +90 -90
- package/src/maths/calculator/plugins/core/history.js +166 -166
- package/src/maths/calculator/plugins/core/remind.js +96 -96
- package/src/maths/calculator/plugins/core/stepNavigation.js +175 -175
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/defaultTemplate.tpl +36 -36
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +91 -91
- package/src/maths/calculator/plugins/modifiers/pow10.js +143 -143
- package/src/maths/calculator/plugins/modifiers/sign.js +339 -339
- package/src/maths/calculator/plugins/screen/simpleScreen/defaultTemplate.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/history.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +190 -190
- package/src/maths/calculator/pluginsLoader.js +46 -46
- package/src/maths/calculator/scientificCalculator.js +74 -74
- package/src/maths/calculator/scss/calculator.scss +396 -396
- package/src/maths/calculator/tpl/basicKeyboard.tpl +37 -37
- package/src/maths/calculator/tpl/basicScreen.tpl +2 -2
- package/src/maths/calculator/tpl/scientificKeyboard.tpl +61 -61
- package/src/maths/calculator/tpl/scientificScreen.tpl +3 -3
- package/src/mediaEditor/mediaEditorComponent.js +141 -141
- package/src/mediaEditor/plugins/mediaAlignment/helper.js +110 -110
- package/src/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +99 -99
- package/src/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/src/mediaEditor/plugins/mediaAlignment/tpl/mediaAlignment.tpl +25 -25
- package/src/mediaEditor/plugins/mediaDimension/helper.js +190 -190
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +561 -561
- package/src/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/src/mediaEditor/plugins/mediaDimension/tpl/mediaDimension.tpl +55 -55
- package/src/mediaEditor/tpl/editor.tpl +4 -4
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -564
- package/src/mediaplayer/players/youtube.js +323 -323
- package/src/mediaplayer/players.js +29 -29
- package/src/mediaplayer/readme.md +305 -305
- package/src/mediaplayer/scss/player.scss +569 -569
- package/src/mediaplayer/support.js +126 -126
- package/src/mediaplayer/tpl/audio.tpl +6 -6
- package/src/mediaplayer/tpl/player.tpl +37 -37
- package/src/mediaplayer/tpl/source.tpl +1 -1
- package/src/mediaplayer/tpl/video.tpl +6 -6
- package/src/mediaplayer/tpl/youtube.tpl +1 -1
- package/src/mediaplayer/utils/reminder.js +184 -184
- package/src/mediaplayer/utils/timeObserver.js +143 -143
- package/src/mediaplayer/youtubeManager.js +161 -161
- package/src/mediaplayer.js +1606 -1606
- package/src/mediasizer/mediasizer.tpl +55 -55
- package/src/mediasizer.js +635 -635
- package/src/modal.js +365 -365
- package/src/movableComponent.js +78 -78
- package/src/pageSizeSelector/tpl/pageSizeSelector.tpl +9 -9
- package/src/pageSizeSelector.js +106 -106
- package/src/pageStatus.js +147 -147
- package/src/pagination/css/pagination.css +7 -7
- package/src/pagination/css/pagination.css.map +1 -1
- package/src/pagination/paginationStrategy.js +53 -53
- package/src/pagination/providers/pages.js +161 -161
- package/src/pagination/providers/simple.js +74 -74
- package/src/pagination/providers/tpl/pages/page.tpl +1 -1
- package/src/pagination/providers/tpl/pages.tpl +8 -8
- package/src/pagination/providers/tpl/simple.tpl +7 -7
- package/src/pagination/scss/pagination.scss +111 -111
- package/src/pagination.js +237 -237
- package/src/previewer.js +300 -300
- package/src/progressbar.js +165 -165
- package/src/propertySelector/css/propertySelector.css +7 -7
- package/src/propertySelector/css/propertySelector.css.map +1 -1
- package/src/propertySelector/propertySelector.js +286 -286
- package/src/propertySelector/scss/propertySelector.scss +66 -66
- package/src/propertySelector/tpl/property-description.tpl +12 -12
- package/src/propertySelector/tpl/property-selector.tpl +6 -6
- package/src/report/feedback.tpl +11 -11
- package/src/report/layout.tpl +10 -10
- package/src/report.js +184 -184
- package/src/resource/css/selector.css +7 -7
- package/src/resource/css/selector.css.map +1 -1
- package/src/resource/filters.js +208 -208
- package/src/resource/list.js +200 -200
- package/src/resource/scss/_filters.scss +26 -26
- package/src/resource/scss/_resource-list.scss +107 -107
- package/src/resource/scss/_resource-tree.scss +205 -205
- package/src/resource/scss/selector.scss +187 -187
- package/src/resource/selectable.js +322 -322
- package/src/resource/selector.js +871 -871
- package/src/resource/tpl/filters.tpl +2 -2
- package/src/resource/tpl/list.tpl +7 -7
- package/src/resource/tpl/listNode.tpl +4 -4
- package/src/resource/tpl/selector.tpl +46 -46
- package/src/resource/tpl/tree.tpl +4 -4
- package/src/resource/tpl/treeNode.tpl +30 -30
- package/src/resource/tree.js +398 -398
- package/src/resourcemgr/css/resourcemgr.css +7 -7
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +381 -381
- package/src/resourcemgr/filePreview.js +73 -73
- package/src/resourcemgr/fileSelector.js +322 -322
- package/src/resourcemgr/scss/resourcemgr.scss +254 -254
- package/src/resourcemgr/tpl/fileSelect.tpl +39 -39
- package/src/resourcemgr/tpl/folder.tpl +11 -11
- package/src/resourcemgr/tpl/layout.tpl +84 -84
- package/src/resourcemgr/tpl/rootFolder.tpl +13 -13
- package/src/resourcemgr/util/updatePermissions.js +53 -53
- package/src/resourcemgr.js +216 -216
- package/src/scroller.js +94 -94
- package/src/scss/basic.scss +16 -16
- package/src/searchModal/advancedSearch.js +638 -638
- package/src/searchModal/css/advancedSearch.css +7 -7
- package/src/searchModal/css/advancedSearch.css.map +1 -1
- package/src/searchModal/css/searchModal.css +7 -7
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/searchModal/scss/advancedSearch.scss +171 -171
- package/src/searchModal/scss/searchModal.scss +393 -393
- package/src/searchModal/tpl/advanced-search.tpl +9 -9
- package/src/searchModal/tpl/info-message.tpl +3 -3
- package/src/searchModal/tpl/invalid-criteria-warning.tpl +10 -10
- package/src/searchModal/tpl/layout.tpl +27 -27
- package/src/searchModal/tpl/list-checkbox-criterion.tpl +17 -17
- package/src/searchModal/tpl/list-select-criterion.tpl +12 -12
- package/src/searchModal/tpl/text-criterion.tpl +11 -11
- package/src/searchModal.js +760 -760
- package/src/selecter.js +43 -43
- package/src/stacker.js +133 -133
- package/src/switch/css/switch.css +7 -7
- package/src/switch/css/switch.css.map +1 -1
- package/src/switch/scss/switch.scss +83 -83
- package/src/switch/switch.js +195 -195
- package/src/switch/tpl/switch.tpl +7 -7
- package/src/tableModel.js +112 -112
- package/src/tabs/css/tabs.css +12 -12
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/tabs/scss/tabs.scss +50 -50
- package/src/tabs/tpl/panel.tpl +3 -3
- package/src/tabs/tpl/tabs.tpl +10 -10
- package/src/tabs.js +528 -528
- package/src/taskQueue/css/taskQueue.css +7 -7
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/taskQueue/scss/taskQueue.scss +47 -47
- package/src/taskQueue/status.js +228 -228
- package/src/taskQueue/table.js +350 -350
- package/src/taskQueue/taskQueue.js +33 -33
- package/src/taskQueue/taskQueueModel.js +548 -548
- package/src/taskQueue/tpl/statusMessage.tpl +7 -7
- package/src/taskQueue.js +216 -216
- package/src/taskQueueButton/css/taskable.css +7 -7
- package/src/taskQueueButton/css/taskable.css.map +1 -1
- package/src/taskQueueButton/css/treeButton.css +7 -7
- package/src/taskQueueButton/css/treeButton.css.map +1 -1
- package/src/taskQueueButton/scss/taskable.scss +4 -4
- package/src/taskQueueButton/scss/treeButton.scss +34 -34
- package/src/taskQueueButton/standardButton.js +108 -108
- package/src/taskQueueButton/taskable.js +202 -202
- package/src/taskQueueButton/tpl/report.tpl +5 -5
- package/src/taskQueueButton/tpl/treeButton.tpl +6 -6
- package/src/taskQueueButton/treeButton.js +108 -108
- package/src/themeLoader.js +252 -252
- package/src/themes.js +162 -162
- package/src/toggler.js +200 -200
- package/src/tooltip/default.tpl +3 -3
- package/src/tooltip.js +160 -160
- package/src/tooltipster.js +25 -25
- package/src/transformer.js +327 -327
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/src/tristateCheckboxGroup/scss/tristateCheckboxGroup.scss +15 -15
- package/src/tristateCheckboxGroup/tpl/li.tpl +6 -6
- package/src/tristateCheckboxGroup.js +207 -207
- package/src/uploader/fileEntry.tpl +6 -6
- package/src/uploader/uploader.tpl +32 -32
- package/src/uploader.js +594 -594
- package/src/validator/Report.js +10 -10
- package/src/validator/Validator.js +108 -108
- package/src/validator/validators.js +217 -217
- package/src/validator.js +262 -262
- package/src/waitForMedia.js +82 -82
- package/src/waitingDialog/css/waitingDialog.css +7 -7
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
- package/src/waitingDialog/scss/waitingDialog.scss +34 -34
- package/src/waitingDialog/waitingDialog.js +240 -240
|
@@ -1,548 +1,548 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This program is free software; you can redistribute it and/or
|
|
3
|
-
* modify it under the terms of the GNU General Public License
|
|
4
|
-
* as published by the Free Software Foundation; under version 2
|
|
5
|
-
* of the License (non-upgradable).
|
|
6
|
-
*
|
|
7
|
-
* This program is distributed in the hope that it will be useful,
|
|
8
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
-
* GNU General Public License for more details.
|
|
11
|
-
*
|
|
12
|
-
* You should have received a copy of the GNU General Public License
|
|
13
|
-
* along with this program; if not, write to the Free Software
|
|
14
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
-
*
|
|
16
|
-
* Copyright (c) 2017 (original work) Open Assessment Technologies SA ;
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @example
|
|
21
|
-
* taskQueueModelFactory({
|
|
22
|
-
* url : {
|
|
23
|
-
* get: urlHelper.route('get', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
24
|
-
* archive: urlHelper.route('archive', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
25
|
-
* all : urlHelper.route('getAll', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
26
|
-
* download : urlHelper.route('download', 'TaskQueueWebApi', 'taoTaskQueue')
|
|
27
|
-
* },
|
|
28
|
-
* pollSingleIntervals : [
|
|
29
|
-
* {iteration: 4, interval:1000},
|
|
30
|
-
* ],
|
|
31
|
-
* pollAllIntervals : [
|
|
32
|
-
* {iteration: 0, interval:5000},
|
|
33
|
-
* ]
|
|
34
|
-
* }).pollAll()
|
|
35
|
-
*/
|
|
36
|
-
import $ from 'jquery';
|
|
37
|
-
import _ from 'lodash';
|
|
38
|
-
import __ from 'i18n';
|
|
39
|
-
|
|
40
|
-
import eventifier from 'core/eventifier';
|
|
41
|
-
import polling from 'core/polling';
|
|
42
|
-
import request from 'core/dataProvider/request';
|
|
43
|
-
import feedback from 'ui/feedback';
|
|
44
|
-
import 'jquery.fileDownload';
|
|
45
|
-
|
|
46
|
-
var _defaults = {
|
|
47
|
-
url: {
|
|
48
|
-
get: '',
|
|
49
|
-
archive: '',
|
|
50
|
-
all: '',
|
|
51
|
-
download: ''
|
|
52
|
-
},
|
|
53
|
-
pollSingleIntervals: [{ iteration: 4, interval: 1000 }],
|
|
54
|
-
pollAllIntervals: [
|
|
55
|
-
{ iteration: 10, interval: 5000 },
|
|
56
|
-
{ iteration: 0, interval: 10000 } //infinite
|
|
57
|
-
]
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Check if two tasks have equivalent task status
|
|
62
|
-
* @param {Object} task1 - a task object to be compared
|
|
63
|
-
* @param {Object} task2 - another task object to be compared
|
|
64
|
-
* @returns {Boolean}
|
|
65
|
-
*/
|
|
66
|
-
function hasSameState(task1, task2) {
|
|
67
|
-
if (task1.status === task2.status) {
|
|
68
|
-
return true;
|
|
69
|
-
} else if (task1.status === 'created' || task1.status === 'in_progress') {
|
|
70
|
-
return task2.status === 'created' || task2.status === 'in_progress';
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function translateReportMessages(taskData) {
|
|
76
|
-
return taskData.map(item => {
|
|
77
|
-
if (item.interpolationMessage) {
|
|
78
|
-
item.message = __(item.interpolationMessage, ...item.interpolationData);
|
|
79
|
-
}
|
|
80
|
-
if (item.children.length > 0) {
|
|
81
|
-
translateReportMessages(item.children);
|
|
82
|
-
}
|
|
83
|
-
return item;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Create a task queue model to communicates with the server REST API
|
|
89
|
-
*
|
|
90
|
-
* @param {Object} config
|
|
91
|
-
* @param {Object} config.url - the list of server endpoints
|
|
92
|
-
* @param {String} config.url.get - the url to get the status log for a single task
|
|
93
|
-
* @param {String} config.url.archive - the url to archive a task
|
|
94
|
-
* @param {String} config.url.all - the url to get the status for all tasks for the current user
|
|
95
|
-
* @param {String} config.url.download - the url to download a file created by the task
|
|
96
|
-
* @param {Array} config.pollSingleIntervals - the array of poll intervals that will be used to regulate the polling speed for a simple task
|
|
97
|
-
* e.g. {iteration: 4, interval:1000} means that it will poll up to four times every 1000ms.
|
|
98
|
-
* @param {Array} config.pollAllIntervals - the array of poll intervals that will be used to regulate the main polling speed.
|
|
99
|
-
* e.g. {iteration: 10, interval:1000} means that it will poll up to 10 times every 5000ms.
|
|
100
|
-
* e.g. {iteration: 0, interval:10000} means that it will poll up to 10000ms indefinitely
|
|
101
|
-
*
|
|
102
|
-
* @return {taskQueueModel}
|
|
103
|
-
*/
|
|
104
|
-
export default function taskQueueModel(config) {
|
|
105
|
-
var model;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* cached array of task data
|
|
109
|
-
* @type {Object}
|
|
110
|
-
*/
|
|
111
|
-
var _cache;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* store instance of single polling
|
|
115
|
-
* @type {Object}
|
|
116
|
-
*/
|
|
117
|
-
var singlePollings = {};
|
|
118
|
-
|
|
119
|
-
var getPollSingleIntervals = function getPollSingleIntervals() {
|
|
120
|
-
if (config.pollSingleIntervals && _.isArray(config.pollSingleIntervals)) {
|
|
121
|
-
return _.cloneDeep(config.pollSingleIntervals);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
var getPollAllIntervals = function getPollAllIntervals() {
|
|
126
|
-
if (config.pollAllIntervals && _.isArray(config.pollAllIntervals)) {
|
|
127
|
-
return _.cloneDeep(config.pollAllIntervals);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
config = _.defaults(config || {}, _defaults);
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @typedef taskQueueModel - central model to query the backend's REST API for task queue
|
|
135
|
-
*/
|
|
136
|
-
model = eventifier({
|
|
137
|
-
/**
|
|
138
|
-
* Modify the task queue REST API endpoints
|
|
139
|
-
* @param urls - the new endpoints
|
|
140
|
-
* @returns {taskQueueModel}
|
|
141
|
-
*/
|
|
142
|
-
setEndpoints: function setEndpoints(urls) {
|
|
143
|
-
_.assign(config.url, urls || {});
|
|
144
|
-
return this;
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Get the status of a task identified by its unique task id
|
|
149
|
-
*
|
|
150
|
-
* @param {String} taskId - unique task identifier
|
|
151
|
-
* @returns {Promise}
|
|
152
|
-
*/
|
|
153
|
-
get: function get(taskId) {
|
|
154
|
-
var status;
|
|
155
|
-
|
|
156
|
-
if (!config.url || !config.url.get) {
|
|
157
|
-
throw new TypeError('config.url.get is not configured while get() is being called');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
status = request(config.url.get, { taskId: taskId }, 'GET', {}, true).then(function(taskData) {
|
|
161
|
-
// Workaround for translations
|
|
162
|
-
if (typeof taskData.report !== 'undefined' && typeof taskData.report.children !== 'undefined') {
|
|
163
|
-
taskData.report.children = translateReportMessages(taskData.report.children);
|
|
164
|
-
}
|
|
165
|
-
//check taskData
|
|
166
|
-
if (taskData && taskData.status) {
|
|
167
|
-
if (_cache) {
|
|
168
|
-
//detect change
|
|
169
|
-
if (!_cache[taskData.id]) {
|
|
170
|
-
model.trigger('singletaskadded', taskData);
|
|
171
|
-
} else if (!hasSameState(_cache[taskData.id], taskData)) {
|
|
172
|
-
//check if the status has changed
|
|
173
|
-
model.trigger('singletaskstatuschange', taskData);
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
_cache = {};
|
|
177
|
-
}
|
|
178
|
-
_cache[taskData.id] = taskData;
|
|
179
|
-
return taskData;
|
|
180
|
-
}
|
|
181
|
-
return Promise.reject(new Error('failed to get task data'));
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
status.catch(function(err) {
|
|
185
|
-
model.trigger('error', err);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
return status;
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Get the task data, but try the cache first!
|
|
193
|
-
* @returns {Promise}
|
|
194
|
-
*/
|
|
195
|
-
getCached: function getCached(taskId) {
|
|
196
|
-
if (_cache && _cache[taskId]) {
|
|
197
|
-
return Promise.resolve(_cache[taskId]);
|
|
198
|
-
}
|
|
199
|
-
return this.get(taskId);
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Get the status of all task identified by their unique task id
|
|
204
|
-
*
|
|
205
|
-
* @returns {Promise} - resolved when the server response has been received
|
|
206
|
-
*/
|
|
207
|
-
getAll: function getAll() {
|
|
208
|
-
var status;
|
|
209
|
-
|
|
210
|
-
if (!config.url || !config.url.all) {
|
|
211
|
-
throw new TypeError('config.url.all is not configured while getAll() is being called');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
status = request(config.url.all, { limit: 100 }, 'GET', {}, true).then(function(taskData) {
|
|
215
|
-
var newCache = {};
|
|
216
|
-
//check taskData
|
|
217
|
-
if (taskData) {
|
|
218
|
-
if (_cache) {
|
|
219
|
-
//detect change
|
|
220
|
-
_.forEach(taskData, function(task) {
|
|
221
|
-
var id = task.id;
|
|
222
|
-
if (!_cache[id]) {
|
|
223
|
-
model.trigger('multitaskadded', task);
|
|
224
|
-
} else if (!hasSameState(_cache[id], task)) {
|
|
225
|
-
//check if the status has changed
|
|
226
|
-
model.trigger('multitaskstatuschange', task);
|
|
227
|
-
}
|
|
228
|
-
newCache[id] = task;
|
|
229
|
-
});
|
|
230
|
-
_.forEach(_.difference(_.keys(_cache), _.keys(newCache)), function(id) {
|
|
231
|
-
model.trigger('taskremoved', _cache[id]);
|
|
232
|
-
});
|
|
233
|
-
} else {
|
|
234
|
-
_.forEach(taskData, function(task) {
|
|
235
|
-
newCache[task.id] = task;
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
//update local cache
|
|
239
|
-
_cache = newCache;
|
|
240
|
-
|
|
241
|
-
return taskData;
|
|
242
|
-
}
|
|
243
|
-
return Promise.reject(new Error('failed to get all task data'));
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
status.catch(function(err) {
|
|
247
|
-
model.trigger('error', err);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
return status;
|
|
251
|
-
},
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Remove a task identified by its unique task id
|
|
255
|
-
*
|
|
256
|
-
* @param {String} taskId - the task id
|
|
257
|
-
* @returns {Promise} - resolved when achive action done
|
|
258
|
-
*/
|
|
259
|
-
archive: function archive(taskId) {
|
|
260
|
-
var status;
|
|
261
|
-
|
|
262
|
-
if (!config.url || !config.url.archive) {
|
|
263
|
-
throw new TypeError('config.url.archive is not configured while archive() is being called');
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
status = request(config.url.archive, { taskId: taskId }, 'GET', {}, true);
|
|
267
|
-
|
|
268
|
-
status.catch(function(res) {
|
|
269
|
-
model.trigger('error', res);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
return status;
|
|
273
|
-
},
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Poll status for all tasks
|
|
277
|
-
* @param {Boolean} [immediate] - tells if the polling should immediately start (otherwise, will wait until the next iteration)
|
|
278
|
-
* @returns {taskQueueModel}
|
|
279
|
-
*/
|
|
280
|
-
pollAll: function pollAll(immediate) {
|
|
281
|
-
var self = this;
|
|
282
|
-
var loop = 0;
|
|
283
|
-
var pollingIntervals = getPollAllIntervals();
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* gradually increase the polling interval to ease server load
|
|
287
|
-
* @private
|
|
288
|
-
* @param {Object} pollingInstance - a poll object
|
|
289
|
-
*/
|
|
290
|
-
var _updateInterval = function _updateInterval(pollingInstance) {
|
|
291
|
-
var pollingInterval;
|
|
292
|
-
if (loop) {
|
|
293
|
-
loop--;
|
|
294
|
-
} else {
|
|
295
|
-
pollingInterval = pollingIntervals.shift();
|
|
296
|
-
if (
|
|
297
|
-
pollingInterval &&
|
|
298
|
-
typeof pollingInterval.iteration !== 'undefined' &&
|
|
299
|
-
pollingInterval.interval
|
|
300
|
-
) {
|
|
301
|
-
loop = pollingInterval.iteration;
|
|
302
|
-
pollingInstance.setInterval(pollingInterval.interval);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
if (!config.url || !config.url.all) {
|
|
308
|
-
throw new TypeError('config.url.all is not configured while pollAll() is being called');
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (!this.globalPolling) {
|
|
312
|
-
//no global polling yet, create one
|
|
313
|
-
this.globalPolling = polling({
|
|
314
|
-
action: function action() {
|
|
315
|
-
// get into asynchronous mode
|
|
316
|
-
var done = this.async();
|
|
317
|
-
var statusArr;
|
|
318
|
-
model
|
|
319
|
-
.getAll()
|
|
320
|
-
.then(function(taskDataArray) {
|
|
321
|
-
model.trigger('pollAll', taskDataArray);
|
|
322
|
-
|
|
323
|
-
//smart polling: stop polling when there is no task in progress
|
|
324
|
-
statusArr = _.map(taskDataArray, 'status');
|
|
325
|
-
if (statusArr.indexOf('in_progress') === -1 && statusArr.indexOf('created') === -1) {
|
|
326
|
-
return done.reject();
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
_updateInterval(self.globalPolling);
|
|
330
|
-
done.resolve();
|
|
331
|
-
})
|
|
332
|
-
.catch(function() {
|
|
333
|
-
done.reject();
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
_updateInterval(this.globalPolling);
|
|
338
|
-
this.globalPolling.start();
|
|
339
|
-
this.trigger('pollAllStart');
|
|
340
|
-
} else {
|
|
341
|
-
this.globalPolling.start();
|
|
342
|
-
this.trigger('pollAllStart');
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
if (immediate) {
|
|
346
|
-
//if it is request to immediate start polling, start it now
|
|
347
|
-
this.globalPolling.next();
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
return model;
|
|
351
|
-
},
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Stop the main polling action
|
|
355
|
-
* @returns {taskQueueModel}
|
|
356
|
-
*/
|
|
357
|
-
pollAllStop: function pollAllStop() {
|
|
358
|
-
if (this.globalPolling) {
|
|
359
|
-
this.globalPolling.stop();
|
|
360
|
-
this.trigger('pollAllStop');
|
|
361
|
-
}
|
|
362
|
-
return this;
|
|
363
|
-
},
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Start a single fast polling for a single task id
|
|
367
|
-
* @param {String} taskId - the task id
|
|
368
|
-
* @returns {Promise} resolved when the single polling action finishes
|
|
369
|
-
*/
|
|
370
|
-
pollSingle: function pollSingle(taskId) {
|
|
371
|
-
var self = this;
|
|
372
|
-
var loop = 0;
|
|
373
|
-
|
|
374
|
-
var pollingIntervals = getPollSingleIntervals();
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* gradually increase the polling interval to ease server load
|
|
378
|
-
* @private
|
|
379
|
-
* @param {Object} pollingInstance - a poll object
|
|
380
|
-
*/
|
|
381
|
-
var _updateInterval = function _updateInterval(pollingInstance) {
|
|
382
|
-
var pollingInterval;
|
|
383
|
-
if (loop) {
|
|
384
|
-
loop--;
|
|
385
|
-
return true; //continue polling
|
|
386
|
-
} else {
|
|
387
|
-
pollingInterval = pollingIntervals.shift();
|
|
388
|
-
if (pollingInterval && pollingInterval.iteration && pollingInterval.interval) {
|
|
389
|
-
loop = pollingInterval.iteration;
|
|
390
|
-
pollingInstance.setInterval(pollingInterval.interval);
|
|
391
|
-
return true; //continue polling
|
|
392
|
-
} else {
|
|
393
|
-
//stop polling
|
|
394
|
-
return false;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
if (!config.url || !config.url.get) {
|
|
400
|
-
throw new TypeError('config.url.get is not configured while pollSingle() is being called');
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (singlePollings[taskId]) {
|
|
404
|
-
singlePollings[taskId].stop();
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return new Promise(function(resolve) {
|
|
408
|
-
var poll = polling({
|
|
409
|
-
action: function action() {
|
|
410
|
-
// get into asynchronous mode
|
|
411
|
-
var done = this.async();
|
|
412
|
-
self.get(taskId)
|
|
413
|
-
.then(function(taskData) {
|
|
414
|
-
if (taskData.status === 'completed' || taskData.status === 'failed') {
|
|
415
|
-
//the status status could be either "completed" or "failed"
|
|
416
|
-
poll.stop();
|
|
417
|
-
self.trigger('pollSingleFinished', taskId, taskData);
|
|
418
|
-
resolve({ finished: true, task: taskData });
|
|
419
|
-
} else if (!_updateInterval(poll)) {
|
|
420
|
-
//if we have reached the end of the total polling config
|
|
421
|
-
self.trigger('pollSingleFinished', taskId, taskData);
|
|
422
|
-
resolve({ finished: false, task: taskData });
|
|
423
|
-
} else {
|
|
424
|
-
self.trigger('pollSingle', taskId, taskData);
|
|
425
|
-
done.resolve(); //go to next poll iteration
|
|
426
|
-
}
|
|
427
|
-
})
|
|
428
|
-
.catch(function() {
|
|
429
|
-
done.reject();
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
_updateInterval(poll);
|
|
434
|
-
singlePollings[taskId] = poll.start();
|
|
435
|
-
self.trigger('pollSingleStart', taskId);
|
|
436
|
-
});
|
|
437
|
-
},
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Interrupt a single polling action
|
|
441
|
-
* @param {String} taskId - the task id
|
|
442
|
-
* @returns {model}
|
|
443
|
-
*/
|
|
444
|
-
pollSingleStop: function pollSingleStop(taskId) {
|
|
445
|
-
if (singlePollings && singlePollings[taskId]) {
|
|
446
|
-
singlePollings[taskId].stop();
|
|
447
|
-
this.trigger('pollSingleStop', taskId);
|
|
448
|
-
}
|
|
449
|
-
return this;
|
|
450
|
-
},
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Call a task creation url
|
|
454
|
-
* @param {String} url - the server side task queue creation service
|
|
455
|
-
* @param {Object} [data] - request data
|
|
456
|
-
* @returns {promise} - resolved when task creation response is sent back by the server
|
|
457
|
-
*/
|
|
458
|
-
create: function create(url, data) {
|
|
459
|
-
var taskCreate,
|
|
460
|
-
self = this;
|
|
461
|
-
taskCreate = request(url, data, 'POST', {}, true).then(function(creationResult) {
|
|
462
|
-
//poll short result:
|
|
463
|
-
if (creationResult && creationResult.task && creationResult.task.id) {
|
|
464
|
-
self.trigger('created', creationResult);
|
|
465
|
-
return self.pollSingle(creationResult.task.id).then(function(result) {
|
|
466
|
-
if (creationResult.extra) {
|
|
467
|
-
result.extra = creationResult.extra;
|
|
468
|
-
}
|
|
469
|
-
if (result.finished) {
|
|
470
|
-
//send to queue
|
|
471
|
-
self.trigger('fastFinished', result);
|
|
472
|
-
} else {
|
|
473
|
-
//send to queue
|
|
474
|
-
self.trigger('enqueued', result);
|
|
475
|
-
}
|
|
476
|
-
return result;
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
return Promise.reject(new Error('failed to get task data'));
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
taskCreate.catch(function(err) {
|
|
483
|
-
model.trigger('error', err);
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
return taskCreate;
|
|
487
|
-
},
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Call the task result file download endpoint
|
|
491
|
-
* @param {String} taskId - the task id
|
|
492
|
-
* @returns {promise} - resolved when the download popup is shown
|
|
493
|
-
*/
|
|
494
|
-
download: function download(taskId) {
|
|
495
|
-
if (!config.url || !config.url.download) {
|
|
496
|
-
throw new TypeError('config.url.download is not configured while download() is being called');
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
return new Promise(function(resolve, reject) {
|
|
500
|
-
$.fileDownload(config.url.download, {
|
|
501
|
-
httpMethod: 'POST',
|
|
502
|
-
data: { taskId: taskId },
|
|
503
|
-
successCallback: function(result) {
|
|
504
|
-
resolve(result);
|
|
505
|
-
},
|
|
506
|
-
failCallback: function(err) {
|
|
507
|
-
reject(err);
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
},
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Call the task result redirection endpoint
|
|
515
|
-
* @param {String} taskId - the task id
|
|
516
|
-
* @returns {Promise}
|
|
517
|
-
*/
|
|
518
|
-
redirect: function redirect(taskId) {
|
|
519
|
-
return this.getCached(taskId)
|
|
520
|
-
.then(function(taskData) {
|
|
521
|
-
var redirectUrl = (taskData || {}).redirectUrl;
|
|
522
|
-
if (!redirectUrl) {
|
|
523
|
-
throw new TypeError('config.redirectUrl is not configured while redirect() is being called');
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if (redirectUrl.indexOf('http') !== 0) {
|
|
527
|
-
throw new TypeError('redirectUrl does not look like a proper url: ' + redirectUrl);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
return request(taskData.redirectUrl);
|
|
531
|
-
})
|
|
532
|
-
.then(function(response) {
|
|
533
|
-
if (!_.isEmpty(response)) {
|
|
534
|
-
window.location.href = response;
|
|
535
|
-
}
|
|
536
|
-
})
|
|
537
|
-
.catch(function(err) {
|
|
538
|
-
//202 -> resource deleted, handle it has a user error
|
|
539
|
-
if (err && err.code === 202 && err.response && err.response.errorMessage) {
|
|
540
|
-
feedback().error(err.response.errorMessage);
|
|
541
|
-
}
|
|
542
|
-
throw err;
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
return model;
|
|
548
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* This program is free software; you can redistribute it and/or
|
|
3
|
+
* modify it under the terms of the GNU General Public License
|
|
4
|
+
* as published by the Free Software Foundation; under version 2
|
|
5
|
+
* of the License (non-upgradable).
|
|
6
|
+
*
|
|
7
|
+
* This program is distributed in the hope that it will be useful,
|
|
8
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
* GNU General Public License for more details.
|
|
11
|
+
*
|
|
12
|
+
* You should have received a copy of the GNU General Public License
|
|
13
|
+
* along with this program; if not, write to the Free Software
|
|
14
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2017 (original work) Open Assessment Technologies SA ;
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @example
|
|
21
|
+
* taskQueueModelFactory({
|
|
22
|
+
* url : {
|
|
23
|
+
* get: urlHelper.route('get', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
24
|
+
* archive: urlHelper.route('archive', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
25
|
+
* all : urlHelper.route('getAll', 'TaskQueueWebApi', 'taoTaskQueue'),
|
|
26
|
+
* download : urlHelper.route('download', 'TaskQueueWebApi', 'taoTaskQueue')
|
|
27
|
+
* },
|
|
28
|
+
* pollSingleIntervals : [
|
|
29
|
+
* {iteration: 4, interval:1000},
|
|
30
|
+
* ],
|
|
31
|
+
* pollAllIntervals : [
|
|
32
|
+
* {iteration: 0, interval:5000},
|
|
33
|
+
* ]
|
|
34
|
+
* }).pollAll()
|
|
35
|
+
*/
|
|
36
|
+
import $ from 'jquery';
|
|
37
|
+
import _ from 'lodash';
|
|
38
|
+
import __ from 'i18n';
|
|
39
|
+
|
|
40
|
+
import eventifier from 'core/eventifier';
|
|
41
|
+
import polling from 'core/polling';
|
|
42
|
+
import request from 'core/dataProvider/request';
|
|
43
|
+
import feedback from 'ui/feedback';
|
|
44
|
+
import 'jquery.fileDownload';
|
|
45
|
+
|
|
46
|
+
var _defaults = {
|
|
47
|
+
url: {
|
|
48
|
+
get: '',
|
|
49
|
+
archive: '',
|
|
50
|
+
all: '',
|
|
51
|
+
download: ''
|
|
52
|
+
},
|
|
53
|
+
pollSingleIntervals: [{ iteration: 4, interval: 1000 }],
|
|
54
|
+
pollAllIntervals: [
|
|
55
|
+
{ iteration: 10, interval: 5000 },
|
|
56
|
+
{ iteration: 0, interval: 10000 } //infinite
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check if two tasks have equivalent task status
|
|
62
|
+
* @param {Object} task1 - a task object to be compared
|
|
63
|
+
* @param {Object} task2 - another task object to be compared
|
|
64
|
+
* @returns {Boolean}
|
|
65
|
+
*/
|
|
66
|
+
function hasSameState(task1, task2) {
|
|
67
|
+
if (task1.status === task2.status) {
|
|
68
|
+
return true;
|
|
69
|
+
} else if (task1.status === 'created' || task1.status === 'in_progress') {
|
|
70
|
+
return task2.status === 'created' || task2.status === 'in_progress';
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function translateReportMessages(taskData) {
|
|
76
|
+
return taskData.map(item => {
|
|
77
|
+
if (item.interpolationMessage) {
|
|
78
|
+
item.message = __(item.interpolationMessage, ...item.interpolationData);
|
|
79
|
+
}
|
|
80
|
+
if (item.children.length > 0) {
|
|
81
|
+
translateReportMessages(item.children);
|
|
82
|
+
}
|
|
83
|
+
return item;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a task queue model to communicates with the server REST API
|
|
89
|
+
*
|
|
90
|
+
* @param {Object} config
|
|
91
|
+
* @param {Object} config.url - the list of server endpoints
|
|
92
|
+
* @param {String} config.url.get - the url to get the status log for a single task
|
|
93
|
+
* @param {String} config.url.archive - the url to archive a task
|
|
94
|
+
* @param {String} config.url.all - the url to get the status for all tasks for the current user
|
|
95
|
+
* @param {String} config.url.download - the url to download a file created by the task
|
|
96
|
+
* @param {Array} config.pollSingleIntervals - the array of poll intervals that will be used to regulate the polling speed for a simple task
|
|
97
|
+
* e.g. {iteration: 4, interval:1000} means that it will poll up to four times every 1000ms.
|
|
98
|
+
* @param {Array} config.pollAllIntervals - the array of poll intervals that will be used to regulate the main polling speed.
|
|
99
|
+
* e.g. {iteration: 10, interval:1000} means that it will poll up to 10 times every 5000ms.
|
|
100
|
+
* e.g. {iteration: 0, interval:10000} means that it will poll up to 10000ms indefinitely
|
|
101
|
+
*
|
|
102
|
+
* @return {taskQueueModel}
|
|
103
|
+
*/
|
|
104
|
+
export default function taskQueueModel(config) {
|
|
105
|
+
var model;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* cached array of task data
|
|
109
|
+
* @type {Object}
|
|
110
|
+
*/
|
|
111
|
+
var _cache;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* store instance of single polling
|
|
115
|
+
* @type {Object}
|
|
116
|
+
*/
|
|
117
|
+
var singlePollings = {};
|
|
118
|
+
|
|
119
|
+
var getPollSingleIntervals = function getPollSingleIntervals() {
|
|
120
|
+
if (config.pollSingleIntervals && _.isArray(config.pollSingleIntervals)) {
|
|
121
|
+
return _.cloneDeep(config.pollSingleIntervals);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
var getPollAllIntervals = function getPollAllIntervals() {
|
|
126
|
+
if (config.pollAllIntervals && _.isArray(config.pollAllIntervals)) {
|
|
127
|
+
return _.cloneDeep(config.pollAllIntervals);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
config = _.defaults(config || {}, _defaults);
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @typedef taskQueueModel - central model to query the backend's REST API for task queue
|
|
135
|
+
*/
|
|
136
|
+
model = eventifier({
|
|
137
|
+
/**
|
|
138
|
+
* Modify the task queue REST API endpoints
|
|
139
|
+
* @param urls - the new endpoints
|
|
140
|
+
* @returns {taskQueueModel}
|
|
141
|
+
*/
|
|
142
|
+
setEndpoints: function setEndpoints(urls) {
|
|
143
|
+
_.assign(config.url, urls || {});
|
|
144
|
+
return this;
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get the status of a task identified by its unique task id
|
|
149
|
+
*
|
|
150
|
+
* @param {String} taskId - unique task identifier
|
|
151
|
+
* @returns {Promise}
|
|
152
|
+
*/
|
|
153
|
+
get: function get(taskId) {
|
|
154
|
+
var status;
|
|
155
|
+
|
|
156
|
+
if (!config.url || !config.url.get) {
|
|
157
|
+
throw new TypeError('config.url.get is not configured while get() is being called');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
status = request(config.url.get, { taskId: taskId }, 'GET', {}, true).then(function(taskData) {
|
|
161
|
+
// Workaround for translations
|
|
162
|
+
if (typeof taskData.report !== 'undefined' && typeof taskData.report.children !== 'undefined') {
|
|
163
|
+
taskData.report.children = translateReportMessages(taskData.report.children);
|
|
164
|
+
}
|
|
165
|
+
//check taskData
|
|
166
|
+
if (taskData && taskData.status) {
|
|
167
|
+
if (_cache) {
|
|
168
|
+
//detect change
|
|
169
|
+
if (!_cache[taskData.id]) {
|
|
170
|
+
model.trigger('singletaskadded', taskData);
|
|
171
|
+
} else if (!hasSameState(_cache[taskData.id], taskData)) {
|
|
172
|
+
//check if the status has changed
|
|
173
|
+
model.trigger('singletaskstatuschange', taskData);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
_cache = {};
|
|
177
|
+
}
|
|
178
|
+
_cache[taskData.id] = taskData;
|
|
179
|
+
return taskData;
|
|
180
|
+
}
|
|
181
|
+
return Promise.reject(new Error('failed to get task data'));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
status.catch(function(err) {
|
|
185
|
+
model.trigger('error', err);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
return status;
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get the task data, but try the cache first!
|
|
193
|
+
* @returns {Promise}
|
|
194
|
+
*/
|
|
195
|
+
getCached: function getCached(taskId) {
|
|
196
|
+
if (_cache && _cache[taskId]) {
|
|
197
|
+
return Promise.resolve(_cache[taskId]);
|
|
198
|
+
}
|
|
199
|
+
return this.get(taskId);
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Get the status of all task identified by their unique task id
|
|
204
|
+
*
|
|
205
|
+
* @returns {Promise} - resolved when the server response has been received
|
|
206
|
+
*/
|
|
207
|
+
getAll: function getAll() {
|
|
208
|
+
var status;
|
|
209
|
+
|
|
210
|
+
if (!config.url || !config.url.all) {
|
|
211
|
+
throw new TypeError('config.url.all is not configured while getAll() is being called');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
status = request(config.url.all, { limit: 100 }, 'GET', {}, true).then(function(taskData) {
|
|
215
|
+
var newCache = {};
|
|
216
|
+
//check taskData
|
|
217
|
+
if (taskData) {
|
|
218
|
+
if (_cache) {
|
|
219
|
+
//detect change
|
|
220
|
+
_.forEach(taskData, function(task) {
|
|
221
|
+
var id = task.id;
|
|
222
|
+
if (!_cache[id]) {
|
|
223
|
+
model.trigger('multitaskadded', task);
|
|
224
|
+
} else if (!hasSameState(_cache[id], task)) {
|
|
225
|
+
//check if the status has changed
|
|
226
|
+
model.trigger('multitaskstatuschange', task);
|
|
227
|
+
}
|
|
228
|
+
newCache[id] = task;
|
|
229
|
+
});
|
|
230
|
+
_.forEach(_.difference(_.keys(_cache), _.keys(newCache)), function(id) {
|
|
231
|
+
model.trigger('taskremoved', _cache[id]);
|
|
232
|
+
});
|
|
233
|
+
} else {
|
|
234
|
+
_.forEach(taskData, function(task) {
|
|
235
|
+
newCache[task.id] = task;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
//update local cache
|
|
239
|
+
_cache = newCache;
|
|
240
|
+
|
|
241
|
+
return taskData;
|
|
242
|
+
}
|
|
243
|
+
return Promise.reject(new Error('failed to get all task data'));
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
status.catch(function(err) {
|
|
247
|
+
model.trigger('error', err);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return status;
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Remove a task identified by its unique task id
|
|
255
|
+
*
|
|
256
|
+
* @param {String} taskId - the task id
|
|
257
|
+
* @returns {Promise} - resolved when achive action done
|
|
258
|
+
*/
|
|
259
|
+
archive: function archive(taskId) {
|
|
260
|
+
var status;
|
|
261
|
+
|
|
262
|
+
if (!config.url || !config.url.archive) {
|
|
263
|
+
throw new TypeError('config.url.archive is not configured while archive() is being called');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
status = request(config.url.archive, { taskId: taskId }, 'GET', {}, true);
|
|
267
|
+
|
|
268
|
+
status.catch(function(res) {
|
|
269
|
+
model.trigger('error', res);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return status;
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Poll status for all tasks
|
|
277
|
+
* @param {Boolean} [immediate] - tells if the polling should immediately start (otherwise, will wait until the next iteration)
|
|
278
|
+
* @returns {taskQueueModel}
|
|
279
|
+
*/
|
|
280
|
+
pollAll: function pollAll(immediate) {
|
|
281
|
+
var self = this;
|
|
282
|
+
var loop = 0;
|
|
283
|
+
var pollingIntervals = getPollAllIntervals();
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* gradually increase the polling interval to ease server load
|
|
287
|
+
* @private
|
|
288
|
+
* @param {Object} pollingInstance - a poll object
|
|
289
|
+
*/
|
|
290
|
+
var _updateInterval = function _updateInterval(pollingInstance) {
|
|
291
|
+
var pollingInterval;
|
|
292
|
+
if (loop) {
|
|
293
|
+
loop--;
|
|
294
|
+
} else {
|
|
295
|
+
pollingInterval = pollingIntervals.shift();
|
|
296
|
+
if (
|
|
297
|
+
pollingInterval &&
|
|
298
|
+
typeof pollingInterval.iteration !== 'undefined' &&
|
|
299
|
+
pollingInterval.interval
|
|
300
|
+
) {
|
|
301
|
+
loop = pollingInterval.iteration;
|
|
302
|
+
pollingInstance.setInterval(pollingInterval.interval);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
if (!config.url || !config.url.all) {
|
|
308
|
+
throw new TypeError('config.url.all is not configured while pollAll() is being called');
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!this.globalPolling) {
|
|
312
|
+
//no global polling yet, create one
|
|
313
|
+
this.globalPolling = polling({
|
|
314
|
+
action: function action() {
|
|
315
|
+
// get into asynchronous mode
|
|
316
|
+
var done = this.async();
|
|
317
|
+
var statusArr;
|
|
318
|
+
model
|
|
319
|
+
.getAll()
|
|
320
|
+
.then(function(taskDataArray) {
|
|
321
|
+
model.trigger('pollAll', taskDataArray);
|
|
322
|
+
|
|
323
|
+
//smart polling: stop polling when there is no task in progress
|
|
324
|
+
statusArr = _.map(taskDataArray, 'status');
|
|
325
|
+
if (statusArr.indexOf('in_progress') === -1 && statusArr.indexOf('created') === -1) {
|
|
326
|
+
return done.reject();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
_updateInterval(self.globalPolling);
|
|
330
|
+
done.resolve();
|
|
331
|
+
})
|
|
332
|
+
.catch(function() {
|
|
333
|
+
done.reject();
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
_updateInterval(this.globalPolling);
|
|
338
|
+
this.globalPolling.start();
|
|
339
|
+
this.trigger('pollAllStart');
|
|
340
|
+
} else {
|
|
341
|
+
this.globalPolling.start();
|
|
342
|
+
this.trigger('pollAllStart');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (immediate) {
|
|
346
|
+
//if it is request to immediate start polling, start it now
|
|
347
|
+
this.globalPolling.next();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return model;
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Stop the main polling action
|
|
355
|
+
* @returns {taskQueueModel}
|
|
356
|
+
*/
|
|
357
|
+
pollAllStop: function pollAllStop() {
|
|
358
|
+
if (this.globalPolling) {
|
|
359
|
+
this.globalPolling.stop();
|
|
360
|
+
this.trigger('pollAllStop');
|
|
361
|
+
}
|
|
362
|
+
return this;
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Start a single fast polling for a single task id
|
|
367
|
+
* @param {String} taskId - the task id
|
|
368
|
+
* @returns {Promise} resolved when the single polling action finishes
|
|
369
|
+
*/
|
|
370
|
+
pollSingle: function pollSingle(taskId) {
|
|
371
|
+
var self = this;
|
|
372
|
+
var loop = 0;
|
|
373
|
+
|
|
374
|
+
var pollingIntervals = getPollSingleIntervals();
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* gradually increase the polling interval to ease server load
|
|
378
|
+
* @private
|
|
379
|
+
* @param {Object} pollingInstance - a poll object
|
|
380
|
+
*/
|
|
381
|
+
var _updateInterval = function _updateInterval(pollingInstance) {
|
|
382
|
+
var pollingInterval;
|
|
383
|
+
if (loop) {
|
|
384
|
+
loop--;
|
|
385
|
+
return true; //continue polling
|
|
386
|
+
} else {
|
|
387
|
+
pollingInterval = pollingIntervals.shift();
|
|
388
|
+
if (pollingInterval && pollingInterval.iteration && pollingInterval.interval) {
|
|
389
|
+
loop = pollingInterval.iteration;
|
|
390
|
+
pollingInstance.setInterval(pollingInterval.interval);
|
|
391
|
+
return true; //continue polling
|
|
392
|
+
} else {
|
|
393
|
+
//stop polling
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
if (!config.url || !config.url.get) {
|
|
400
|
+
throw new TypeError('config.url.get is not configured while pollSingle() is being called');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (singlePollings[taskId]) {
|
|
404
|
+
singlePollings[taskId].stop();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
return new Promise(function(resolve) {
|
|
408
|
+
var poll = polling({
|
|
409
|
+
action: function action() {
|
|
410
|
+
// get into asynchronous mode
|
|
411
|
+
var done = this.async();
|
|
412
|
+
self.get(taskId)
|
|
413
|
+
.then(function(taskData) {
|
|
414
|
+
if (taskData.status === 'completed' || taskData.status === 'failed') {
|
|
415
|
+
//the status status could be either "completed" or "failed"
|
|
416
|
+
poll.stop();
|
|
417
|
+
self.trigger('pollSingleFinished', taskId, taskData);
|
|
418
|
+
resolve({ finished: true, task: taskData });
|
|
419
|
+
} else if (!_updateInterval(poll)) {
|
|
420
|
+
//if we have reached the end of the total polling config
|
|
421
|
+
self.trigger('pollSingleFinished', taskId, taskData);
|
|
422
|
+
resolve({ finished: false, task: taskData });
|
|
423
|
+
} else {
|
|
424
|
+
self.trigger('pollSingle', taskId, taskData);
|
|
425
|
+
done.resolve(); //go to next poll iteration
|
|
426
|
+
}
|
|
427
|
+
})
|
|
428
|
+
.catch(function() {
|
|
429
|
+
done.reject();
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
_updateInterval(poll);
|
|
434
|
+
singlePollings[taskId] = poll.start();
|
|
435
|
+
self.trigger('pollSingleStart', taskId);
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Interrupt a single polling action
|
|
441
|
+
* @param {String} taskId - the task id
|
|
442
|
+
* @returns {model}
|
|
443
|
+
*/
|
|
444
|
+
pollSingleStop: function pollSingleStop(taskId) {
|
|
445
|
+
if (singlePollings && singlePollings[taskId]) {
|
|
446
|
+
singlePollings[taskId].stop();
|
|
447
|
+
this.trigger('pollSingleStop', taskId);
|
|
448
|
+
}
|
|
449
|
+
return this;
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Call a task creation url
|
|
454
|
+
* @param {String} url - the server side task queue creation service
|
|
455
|
+
* @param {Object} [data] - request data
|
|
456
|
+
* @returns {promise} - resolved when task creation response is sent back by the server
|
|
457
|
+
*/
|
|
458
|
+
create: function create(url, data) {
|
|
459
|
+
var taskCreate,
|
|
460
|
+
self = this;
|
|
461
|
+
taskCreate = request(url, data, 'POST', {}, true).then(function(creationResult) {
|
|
462
|
+
//poll short result:
|
|
463
|
+
if (creationResult && creationResult.task && creationResult.task.id) {
|
|
464
|
+
self.trigger('created', creationResult);
|
|
465
|
+
return self.pollSingle(creationResult.task.id).then(function(result) {
|
|
466
|
+
if (creationResult.extra) {
|
|
467
|
+
result.extra = creationResult.extra;
|
|
468
|
+
}
|
|
469
|
+
if (result.finished) {
|
|
470
|
+
//send to queue
|
|
471
|
+
self.trigger('fastFinished', result);
|
|
472
|
+
} else {
|
|
473
|
+
//send to queue
|
|
474
|
+
self.trigger('enqueued', result);
|
|
475
|
+
}
|
|
476
|
+
return result;
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
return Promise.reject(new Error('failed to get task data'));
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
taskCreate.catch(function(err) {
|
|
483
|
+
model.trigger('error', err);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
return taskCreate;
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Call the task result file download endpoint
|
|
491
|
+
* @param {String} taskId - the task id
|
|
492
|
+
* @returns {promise} - resolved when the download popup is shown
|
|
493
|
+
*/
|
|
494
|
+
download: function download(taskId) {
|
|
495
|
+
if (!config.url || !config.url.download) {
|
|
496
|
+
throw new TypeError('config.url.download is not configured while download() is being called');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return new Promise(function(resolve, reject) {
|
|
500
|
+
$.fileDownload(config.url.download, {
|
|
501
|
+
httpMethod: 'POST',
|
|
502
|
+
data: { taskId: taskId },
|
|
503
|
+
successCallback: function(result) {
|
|
504
|
+
resolve(result);
|
|
505
|
+
},
|
|
506
|
+
failCallback: function(err) {
|
|
507
|
+
reject(err);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
},
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Call the task result redirection endpoint
|
|
515
|
+
* @param {String} taskId - the task id
|
|
516
|
+
* @returns {Promise}
|
|
517
|
+
*/
|
|
518
|
+
redirect: function redirect(taskId) {
|
|
519
|
+
return this.getCached(taskId)
|
|
520
|
+
.then(function(taskData) {
|
|
521
|
+
var redirectUrl = (taskData || {}).redirectUrl;
|
|
522
|
+
if (!redirectUrl) {
|
|
523
|
+
throw new TypeError('config.redirectUrl is not configured while redirect() is being called');
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (redirectUrl.indexOf('http') !== 0) {
|
|
527
|
+
throw new TypeError('redirectUrl does not look like a proper url: ' + redirectUrl);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return request(taskData.redirectUrl);
|
|
531
|
+
})
|
|
532
|
+
.then(function(response) {
|
|
533
|
+
if (!_.isEmpty(response)) {
|
|
534
|
+
window.location.href = response;
|
|
535
|
+
}
|
|
536
|
+
})
|
|
537
|
+
.catch(function(err) {
|
|
538
|
+
//202 -> resource deleted, handle it has a user error
|
|
539
|
+
if (err && err.code === 202 && err.response && err.response.errorMessage) {
|
|
540
|
+
feedback().error(err.response.errorMessage);
|
|
541
|
+
}
|
|
542
|
+
throw err;
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
return model;
|
|
548
|
+
}
|