UNPKG

@oat-sa/tao-test-runner-qti

Version:
185 lines (171 loc) 8.51 kB
define(['i18n', 'taoQtiTest/runner/helpers/stats', 'handlebars', 'lib/handlebars/helpers'], function (__, statsHelper, Handlebars, Helpers0) { 'use strict'; __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __; statsHelper = statsHelper && Object.prototype.hasOwnProperty.call(statsHelper, 'default') ? statsHelper['default'] : statsHelper; Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars; Helpers0 = Helpers0 && Object.prototype.hasOwnProperty.call(Helpers0, 'default') ? Helpers0['default'] : Helpers0; if (!Helpers0.__initialized) { Helpers0(Handlebars); Helpers0.__initialized = true; } var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { this.compilerInfo = [4,'>= 1.0.0']; helpers = this.merge(helpers, Handlebars.helpers); data = data || {}; var stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; function program1(depth0,data) { var buffer = "", stack1, helper; buffer += "<b>"; if (helper = helpers.header) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.header); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } buffer += escapeExpression(stack1) + "</b><br><br>"; return buffer; } stack1 = helpers['if'].call(depth0, (depth0 && depth0.header), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); if(stack1 || stack1 === 0) { return stack1; } else { return ''; } }); function messageHeaderTpl(data, options, asString) { var html = Template(data, options); return (asString || true) ? html : $(html); } /** * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * 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) 2016-2021 (original work) Open Assessment Technologies SA ; */ /** * Completes an exit message * @param {String} scope - scope to consider for calculating the stats * @param {Object} runner - testRunner instance * @param {String} message - custom message that will be appended to the unanswered stats count * @param {Boolean} sync - flag for sync the unanswered stats in exit message and the unanswered stats in the toolbox * @param {String|undefined} submitButtonLabel - point the user to the submit button * @returns {String} Returns the message text */ function getExitMessage(scope, runner) { let message = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; let sync = arguments.length > 3 ? arguments[3] : undefined; let submitButtonLabel = arguments.length > 4 ? arguments[4] : undefined; let itemsCountMessage = ''; const testRunnerOptions = runner.getOptions(); const messageEnabled = testRunnerOptions.enableUnansweredItemsWarning; if (messageEnabled) { itemsCountMessage = getUnansweredItemsWarning(scope, runner, sync).trim(); if (itemsCountMessage) { itemsCountMessage += '.'; } } return `${getHeader(scope)}${itemsCountMessage} ${getActionMessage(scope, submitButtonLabel)}${message}`.trim(); } /** * Build message if not all items have answers * @param {String} scope - scope to consider for calculating the stats * @returns {String} Returns the message text */ function getHeader(scope) { let header = ''; if (scope === 'section' || scope === 'testSection') { header = __('You are about to leave this section.'); } else if (scope === 'test' || scope === 'testWithoutInaccessibleItems') { header = __('You are about to submit the test.'); } else if (scope === 'part') { header = __('You are about to submit this test part.'); } return messageHeaderTpl({ header: header.trim() }); } /** * Generates the message to help users perform the action * @param {String} scope - scope to consider for calculating the stats * @param {String} [submitButtonLabel] - Pointed user perform click on given button * @returns {String} Returns the message text */ function getActionMessage(scope) { let submitButtonLabel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : __('OK'); var msg; switch (scope) { case 'section': case 'testSection': case 'part': return __('Click "%s" to continue.', submitButtonLabel).trim(); case 'test': case 'testWithoutInaccessibleItems': msg = __('You will not be able to access this test once submitted. Click "%s" to continue and submit the test.', submitButtonLabel); return `${msg}`; } return ''; } /** * Build message for the flagged items if any. * @param {Object} stats - The stats for the current context * @param {String} [message] - The existing message to complete * @returns {string|*} */ function getFlaggedItemsWarning(stats) { let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; const flaggedCount = stats && stats.flagged; if (!flaggedCount) { return message; } if (message) { return `${message} ${__('and you flagged %s item(s) that you can review now', flaggedCount.toString())}`; } return __('You flagged %s item(s) that you can review now', flaggedCount.toString()); } /** * Build message if not all items have answers * @param {String} scope - scope to consider for calculating the stats * @param {Object} runner - testRunner instance * @param {Boolean} sync - flag for sync the unanswered stats in exit message and the unanswered stats in the toolbox. Default false * @returns {String} Returns the message text */ function getUnansweredItemsWarning(scope, runner, sync) { const stats = statsHelper.getInstantStats(scope, runner, sync); const unansweredCount = stats && stats.questions - stats.answered; const flaggedCount = stats && stats.flagged; let itemsCountMessage = ''; if (scope === 'section' || scope === 'testSection') { itemsCountMessage = __('You answered %s of %s question(s) for this section of the test', stats.answered.toString(), stats.questions.toString()); if (flaggedCount) { itemsCountMessage += `, ${__('and flagged %s of them', flaggedCount.toString())}`; } } else if (scope === 'test' || scope === 'testWithoutInaccessibleItems') { if (unansweredCount > 1) { itemsCountMessage = __('There are %s unanswered questions', unansweredCount.toString()); } else if (unansweredCount === 1) { itemsCountMessage = __('There is %s unanswered question', unansweredCount.toString()); } if (flaggedCount) { itemsCountMessage = getFlaggedItemsWarning(stats, itemsCountMessage); } } else if (scope === 'part') { if (unansweredCount > 1) { itemsCountMessage = __('There are %s unanswered questions in this part of the test', unansweredCount.toString()); } else if (unansweredCount === 1) { itemsCountMessage = __('There is %s unanswered question in this part of the test', unansweredCount.toString()); } if (flaggedCount) { itemsCountMessage = getFlaggedItemsWarning(stats, itemsCountMessage); } } itemsCountMessage = itemsCountMessage.trim(); return itemsCountMessage; } var messages = { getExitMessage: getExitMessage }; return messages; });