diff --git a/views/js/controller/creator/creator.js b/views/js/controller/creator/creator.js index 11dc778bf5..e04c1ccf13 100644 --- a/views/js/controller/creator/creator.js +++ b/views/js/controller/creator/creator.js @@ -13,7 +13,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Copyright (c) 2014-2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); + * Copyright (c) 2014-2024 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); */ /** * @author Bertrand Chevrier @@ -74,6 +74,23 @@ define([ ('use strict'); const logger = loggerFactory('taoQtiTest/controller/creator'); + /** + * We assume the ClientLibConfigRegistry is filled up with something like this: + * 'taoQtiTest/controller/creator/creator' => [ + * 'provider' => 'qtiTest', + * ], + * + * Or, with something like this for allowing multiple buttons in case of several providers are available: + * 'taoQtiTest/controller/creator/creator' => [ + * 'provider' => 'qtiTest', + * 'providers' => [ + * ['id' => 'qtiTest', 'label' => 'Preview'], + * ['id' => 'xxxx', 'label' => 'xxxx'], + * ... + * ], + * ], + */ + /** * The test creator controller is the main entry point * and orchestrates data retrieval and view/components loading. @@ -94,7 +111,7 @@ define([ start(options) { const $container = $('#test-creator'); const $saver = $('#saver'); - const $previewer = $('#previewer'); + const $menu = $('ul.test-editor-menu'); const $back = $('#authoringBack'); let creatorContext; @@ -119,21 +136,42 @@ define([ }); //preview button - if (!Object.keys(options.labels).length) { - $previewer.attr('disabled', true).addClass('disabled'); - } - $previewer.on('click', e => { - e.preventDefault(); - if (!$previewer.hasClass('disabled')) { - creatorContext.trigger('preview'); + let previewId = 0; + const createPreviewButton = ({ id, label } = {}) => { + // configured labels will need to to be registered elsewhere for the translations + const translate = text => text && __(text); + + const btnIdx = previewId ? `-${previewId}` : ''; + const $button = $( + templates.menuButton({ + id: `previewer${btnIdx}`, + testId: `preview-test${btnIdx}`, + icon: 'preview', + label: translate(label) || __('Preview') + }) + ).on('click', e => { + e.preventDefault(); + if (!$(e.currentTarget).hasClass('disabled')) { + creatorContext.trigger('preview', id, previewId); + } + }); + if (!Object.keys(options.labels).length) { + $button.attr('disabled', true).addClass('disabled'); } - }); + $menu.append($button); + previewId++; + return $button; + }; + const previewButtons = options.providers + ? options.providers.map(createPreviewButton) + : [createPreviewButton()]; + const isTestContainsItems = () => { if ($container.find('.test-content').find('.itemref').length) { - $previewer.attr('disabled', false).removeClass('disabled'); + previewButtons.forEach($previewer => $previewer.attr('disabled', false).removeClass('disabled')); return true; } else { - $previewer.attr('disabled', true).addClass('disabled'); + previewButtons.forEach($previewer => $previewer.attr('disabled', true).addClass('disabled')); return false; } }; @@ -222,12 +260,13 @@ define([ } }); - creatorContext.on('preview', function () { + creatorContext.on('preview', provider => { if (isTestContainsItems() && !creatorContext.isTestHasErrors()) { const saveUrl = options.routes.save; const testUri = saveUrl.slice(saveUrl.indexOf('uri=') + 4); const config = module.config(); - return previewerFactory(config.provider, decodeURIComponent(testUri), { + const type = provider || config.provider || 'qtiTest'; + return previewerFactory(type, decodeURIComponent(testUri), { readOnly: false, fullPage: true, pluginsOptions: config.pluginsOptions @@ -251,7 +290,9 @@ define([ if (creatorContext.isTestHasErrors()) { event.preventDefault(); feedback().warning( - __('The test cannot be saved because it currently contains invalid settings.\nPlease fix the invalid settings and try again.') + __( + 'The test cannot be saved because it currently contains invalid settings.\nPlease fix the invalid settings and try again.' + ) ); } else { creatorContext.trigger('save'); diff --git a/views/js/controller/creator/templates/index.js b/views/js/controller/creator/templates/index.js index dabb6d4289..c5821e7ac2 100644 --- a/views/js/controller/creator/templates/index.js +++ b/views/js/controller/creator/templates/index.js @@ -33,7 +33,8 @@ define([ 'tpl!taoQtiTest/controller/creator/templates/itemref-props-weight', 'tpl!taoQtiTest/controller/creator/templates/rubricblock-props', 'tpl!taoQtiTest/controller/creator/templates/category-presets', - 'tpl!taoQtiTest/controller/creator/templates/subsection' + 'tpl!taoQtiTest/controller/creator/templates/subsection', + 'tpl!taoQtiTest/controller/creator/templates/menu-button' ], function( defaults, @@ -49,7 +50,8 @@ function( itemRefPropsWeight, rubricBlockProps, categoryPresets, - subsection + subsection, + menuButton ){ 'use strict'; @@ -66,6 +68,7 @@ function( rubricblock : applyTemplateConfiguration(rubricBlock), outcomes : applyTemplateConfiguration(outcomes), subsection : applyTemplateConfiguration(subsection), + menuButton : applyTemplateConfiguration(menuButton), properties : { test : applyTemplateConfiguration(testProps), testpart : applyTemplateConfiguration(testPartProps), diff --git a/views/js/controller/creator/templates/menu-button.tpl b/views/js/controller/creator/templates/menu-button.tpl new file mode 100644 index 0000000000..db3cd48653 --- /dev/null +++ b/views/js/controller/creator/templates/menu-button.tpl @@ -0,0 +1,6 @@ +
  • + + + {{label}} + +
  • diff --git a/views/templates/creator.tpl b/views/templates/creator.tpl index 77ff818d51..acd9f2f62f 100755 --- a/views/templates/creator.tpl +++ b/views/templates/creator.tpl @@ -19,19 +19,13 @@
    -
      +
      • -
      • - - - - -