AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"tool_card_controller.min.js","sources":["../src/tool_card_controller.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Controls all of the behaviour and interaction with a tool type card. These are\n * listed on the LTI tool type management page.\n *\n * See template: mod_lti/tool_card\n *\n * @module mod_lti/tool_c
ard_controller\n * @copyright 2015 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.1\n */\n define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'core/modal',\n 'mod_lti/tool_type', 'mod_lti/events', 'mod_lti/keys',\n 'core/str'],\n function($, ajax, notification, templates, Modal, toolType, ltiEvents, KEYS, str) {\n\n var SELECTORS = {\n DELETE_BUTTON: '.delete',\n NAME_ELEMENT: '.name',\n DESCRIPTION_ELEMENT: '.description',\n CAPABILITIES_CONTAINER: '.capabilities-container',\n ACTIVATE_BUTTON: '.tool-card-footer a.activate',\n };\n\n // Timeout in seconds.\n var ANNOUNCEMENT_TIMEOUT = 2000;\n\n /**\n * Return the delete button element.\n *\n * @method getDeleteButton\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {JQuery} jQuery object\n */\n var getDeleteButton = fun
ction(element) {\n return element.find(SELECTORS.DELETE_BUTTON);\n };\n\n /**\n * Return the element representing the tool type name.\n *\n * @method getNameElement\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {JQuery} jQuery object\n */\n var getNameElement = function(element) {\n return element.find(SELECTORS.NAME_ELEMENT);\n };\n\n /**\n * Return the element representing the tool type description.\n *\n * @method getDescriptionElement\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {JQuery} jQuery object\n */\n var getDescriptionElement = function(element) {\n return element.find(SELECTORS.DESCRIPTION_ELEMENT);\n };\n\n /**\n * Return the activate button for the type.\n *\n * @method getActivateButton\n * @private\n * @param {Object} element jQuery object representing the tool card.\n *
@return {Object} jQuery object\n */\n var getActivateButton = function(element) {\n return element.find(SELECTORS.ACTIVATE_BUTTON);\n };\n\n /**\n * Checks if the type card has an activate button.\n *\n * @method hasActivateButton\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Boolean} true if has active buton\n */\n var hasActivateButton = function(element) {\n return getActivateButton(element).length ? true : false;\n };\n\n /**\n * Return the element that contains the capabilities approval for\n * the user.\n *\n * @method getCapabilitiesContainer\n * @private\n * @param {Object} element jQuery object representing the tool card.\n * @return {Object} The element\n */\n var getCapabilitiesContainer = function(element) {\n return element.find(SELECTORS.CAPABILITIES_CONTAINER);\n };\n\n /**\n * Checks if the tool type has capabilities that need ap
proval. If it\n * does then the container will be present.\n *\n * @method hasCapabilitiesContainer\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Boolean} true if has capbilities.\n */\n var hasCapabilitiesContainer = function(element) {\n return getCapabilitiesContainer(element).length ? true : false;\n };\n\n /**\n * Get the type id.\n *\n * @method getTypeId\n * @private\n * @param {Object} element jQuery object representing the tool card.\n * @return {String} Type ID\n */\n var getTypeId = function(element) {\n return element.attr('data-type-id');\n };\n\n /**\n * Stop any announcement currently visible on the card.\n *\n * @method clearAllAnnouncements\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var clearAllAnnouncements = function(element) {\n element.removeClass('announcement loading suc
cess fail capabilities');\n };\n\n /**\n * Show the loading announcement.\n *\n * @method startLoading\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var startLoading = function(element) {\n clearAllAnnouncements(element);\n element.addClass('announcement loading');\n };\n\n /**\n * Hide the loading announcement.\n *\n * @method stopLoading\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var stopLoading = function(element) {\n element.removeClass('announcement loading');\n };\n\n /**\n * Show the success announcement. The announcement is only\n * visible for 2 seconds.\n *\n * @method announceSuccess\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var announceSuccess = function(element) {\n var promise = $.
Deferred();\n\n clearAllAnnouncements(element);\n element.addClass('announcement success');\n setTimeout(function() {\n element.removeClass('announcement success');\n promise.resolve();\n }, ANNOUNCEMENT_TIMEOUT);\n\n return promise;\n };\n\n /**\n * Show the failure announcement. The announcement is only\n * visible for 2 seconds.\n *\n * @method announceFailure\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var announceFailure = function(element) {\n var promise = $.Deferred();\n\n clearAllAnnouncements(element);\n element.addClass('announcement fail');\n setTimeout(function() {\n element.removeClass('announcement fail');\n promise.resolve();\n }, ANNOUNCEMENT_TIMEOUT);\n\n return promise;\n };\n\n /**\n * Delete the tool type from the Moodle server.
Triggers a success\n * or failure announcement depending on the result.\n *\n * @method deleteType\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var deleteType = function(element) {\n var promise = $.Deferred();\n var typeId = getTypeId(element);\n startLoading(element);\n\n if (typeId === \"\") {\n return $.Deferred().resolve();\n }\n\n str.get_strings([\n {\n key: 'delete',\n component: 'mod_lti'\n },\n {\n key: 'delete_confirmation',\n component: 'mod_lti'\n },\n {\n key: 'delete',\n component: 'mod_lti'\n },\n {\n key: 'cancel',\n component: 'core'\n },\n ]
)\n .done(function(strs) {\n notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {\n toolType.delete(typeId)\n .done(function() {\n stopLoading(element);\n announceSuccess(element)\n .done(function() {\n element.remove();\n })\n .fail(notification.exception)\n .always(function() {\n // Always resolve because even if the announcement fails the type was deleted.\n promise.resolve();\n });\n })\n .f
ail(function(error) {\n announceFailure(element);\n promise.reject(error);\n });\n }, function() {\n stopLoading(element);\n promise.resolve();\n });\n })\n .fail(function(error) {\n stopLoading(element);\n notification.exception(error);\n promise.reject(error);\n });\n\n return promise;\n };\n\n /**\n * Save a given value in a data attribute on the element.\n *\n * @method setValueSnapshot\n * @private\n * @param {JQuery} element jQuery object representing the element.\n * @param {String} value to be saved.\n */\n var setValueSnapshot = function(element, value) {\n element.attr('data-val-snapshot', value);\n };\n\n /**\n * Return
the saved value from the element.\n *\n * @method getValueSnapshot\n * @private\n * @param {JQuery} element jQuery object representing the element.\n * @return {String} the saved value.\n */\n var getValueSnapshot = function(element) {\n return element.attr('data-val-snapshot');\n };\n\n /**\n * Save the current value of the tool description.\n *\n * @method snapshotDescription\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var snapshotDescription = function(element) {\n var descriptionElement = getDescriptionElement(element);\n\n if (descriptionElement.hasClass('loading')) {\n return;\n }\n\n var description = descriptionElement.text().trim();\n setValueSnapshot(descriptionElement, description);\n };\n\n /**\n * Send a request to update the description value for this tool\n * in the Moodle server.\n *\n * @method updateDescription\n
* @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var updateDescription = function(element) {\n var typeId = getTypeId(element);\n\n // Return early if we don't have an id because it's\n // required to save the changes.\n if (typeId === \"\") {\n return $.Deferred().resolve();\n }\n\n var descriptionElement = getDescriptionElement(element);\n\n // Return early if we're already saving a value.\n if (descriptionElement.hasClass('loading')) {\n return $.Deferred().resolve();\n }\n\n var description = descriptionElement.text().trim();\n var snapshotVal = getValueSnapshot(descriptionElement);\n\n // If the value hasn't change then don't bother sending the\n // update request.\n if (snapshotVal == description) {\n return $.Deferred().resolve();\n }\n\n descriptionElement
.addClass('loading');\n\n var promise = toolType.update({id: typeId, description: description});\n\n promise.done(function(type) {\n descriptionElement.removeClass('loading');\n // Make sure the text is updated with the description from the\n // server, just in case the update didn't work.\n descriptionElement.text(type.description);\n }).fail(notification.exception);\n\n // Probably need to handle failures better so that we can revert\n // the value in the input for the user.\n promise.fail(function() {\n descriptionElement.removeClass('loading');\n });\n\n return promise;\n };\n\n /**\n * Save the current value of the tool name.\n *\n * @method snapshotName\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var snapshotName = function(element) {\n var nameElement = getNameElement(element);\n\n if (nameElement.hasCl
ass('loading')) {\n return;\n }\n\n var name = nameElement.text().trim();\n setValueSnapshot(nameElement, name);\n };\n\n /**\n * Send a request to update the name value for this tool\n * in the Moodle server.\n *\n * @method updateName\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var updateName = function(element) {\n var typeId = getTypeId(element);\n\n // Return if we don't have an id.\n if (typeId === \"\") {\n return $.Deferred().resolve();\n }\n\n var nameElement = getNameElement(element);\n\n // Return if we're already saving.\n if (nameElement.hasClass('loading')) {\n return $.Deferred().resolve();\n }\n\n var name = nameElement.text().trim();\n var snapshotVal = getValueSnapshot(nameElement);\n\n // If the value hasn't change then don't bothe
r sending the\n // update request.\n if (snapshotVal == name) {\n return $.Deferred().resolve();\n }\n\n nameElement.addClass('loading');\n var promise = toolType.update({id: typeId, name: name});\n\n promise.done(function(type) {\n nameElement.removeClass('loading');\n // Make sure the text is updated with the name from the\n // server, just in case the update didn't work.\n nameElement.text(type.name);\n });\n\n // Probably need to handle failures better so that we can revert\n // the value in the input for the user.\n promise.fail(function() {\n nameElement.removeClass('loading');\n });\n\n return promise;\n };\n\n /**\n * Send a request to update the state for this tool to be configured (active)\n * in the Moodle server. A success or failure announcement is triggered depending\n * on the result.\n *\n * @method setStatusActive\n
* @private\n * @param {JQuery} element jQuery object representing the tool card.\n * @return {Promise} jQuery Deferred object\n */\n var setStatusActive = function(element) {\n var id = getTypeId(element);\n\n // Return if we don't have an id.\n if (id === \"\") {\n return $.Deferred().resolve();\n }\n\n startLoading(element);\n\n var promise = toolType.update({\n id: id,\n state: toolType.constants.state.configured\n });\n\n promise.then(function(toolTypeData) {\n stopLoading(element);\n announceSuccess(element);\n return toolTypeData;\n }).then(function(toolTypeData) {\n return templates.render('mod_lti/tool_card', toolTypeData);\n }).then(function(html, js) {\n templates.replaceNode(element, html, js);\n return;\n }).catch(function() {\n stopLoading(element);\n announceFailure(element);\n
});\n\n return promise;\n };\n\n /**\n * Show the capabilities approval screen to show which groups of data this\n * type requires access to in Moodle (if any).\n *\n * @method displayCapabilitiesApproval\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var displayCapabilitiesApproval = function(element) {\n element.addClass('announcement capabilities');\n };\n\n /**\n * Hide the capabilities approval screen.\n *\n * @method hideCapabilitiesApproval\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var hideCapabilitiesApproval = function(element) {\n element.removeClass('announcement capabilities');\n };\n\n /**\n * The user wishes to activate this tool so show them the capabilities that\n * they need to agree to or if there are none then set the tool type's state\n * to active.\n *\n * @method activateToolType\n
* @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var activateToolType = function(element) {\n if (hasCapabilitiesContainer(element)) {\n displayCapabilitiesApproval(element);\n } else {\n setStatusActive(element);\n }\n };\n\n /**\n * Sets up the listeners for user interaction on this tool type card.\n *\n * @method registerEventListeners\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n var registerEventListeners = function(element) {\n var deleteButton = getDeleteButton(element);\n deleteButton.click(function(e) {\n e.preventDefault();\n deleteType(element);\n });\n deleteButton.keypress(function(e) {\n if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {\n if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {\n e.preventDefault();\n
deleteButton.click();\n }\n }\n });\n\n var descriptionElement = getDescriptionElement(element);\n descriptionElement.focus(function(e) {\n e.preventDefault();\n // Save a copy of the current value for the description so that\n // we can check if the user has changed it before sending a request to\n // the server.\n snapshotDescription(element);\n });\n descriptionElement.blur(function(e) {\n e.preventDefault();\n updateDescription(element);\n });\n descriptionElement.keypress(function(e) {\n if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {\n if (e.keyCode == KEYS.ENTER) {\n e.preventDefault();\n descriptionElement.blur();\n }\n }\n });\n\n var nameElement = getNameElement(element);\n nameElement.focus(function(e) {\n
e.preventDefault();\n // Save a copy of the current value for the name so that\n // we can check if the user has changed it before sending a request to\n // the server.\n snapshotName(element);\n });\n nameElement.blur(function(e) {\n e.preventDefault();\n updateName(element);\n });\n nameElement.keypress(function(e) {\n if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {\n if (e.keyCode == KEYS.ENTER) {\n e.preventDefault();\n nameElement.blur();\n }\n }\n });\n\n // Only pending tool type cards have an activate button.\n if (hasActivateButton(element)) {\n var activateButton = getActivateButton(element);\n activateButton.click(function(e) {\n e.preventDefault();\n activateToolType(element);\n });\n activateButton.key
press(function(e) {\n if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {\n if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {\n e.preventDefault();\n activateButton.click();\n }\n }\n });\n }\n\n if (hasCapabilitiesContainer(element)) {\n var capabilitiesContainer = getCapabilitiesContainer(element);\n\n capabilitiesContainer.on(ltiEvents.CAPABILITIES_AGREE, function() {\n setStatusActive(element);\n });\n\n capabilitiesContainer.on(ltiEvents.CAPABILITIES_DECLINE, function() {\n hideCapabilitiesApproval(element);\n });\n }\n };\n\n /**\n * Sets up the templates for the tool configuration modal on this tool type card.\n *\n * @method registerModal\n * @private\n * @param {JQuery} element jQuery object representing the tool card.\n */\n
var registerModal = function(element) {\n const configurationLink = element.find('#' + element.data('uniqid') + '-' + element.data('deploymentid'));\n if (!configurationLink.length) {\n return;\n }\n const trigger = configurationLink.get(0);\n trigger.addEventListener('click', (e) => {\n e.preventDefault();\n var context = {\n 'uniqid': element.data('uniqid'),\n 'platformid': element.data('platformid'),\n 'clientid': element.data('clientid'),\n 'deploymentid': element.data('deploymentid'),\n 'urls': {\n 'publickeyset': element.data('publickeyseturl'),\n 'accesstoken': element.data('accesstokenurl'),\n 'authrequest': element.data('authrequesturl')\n }\n };\n var bodyPromise = templates.render('mod_lti/tool_config_modal_body', context);\n var mailTo = 'mailto:?subj
ect=' + encodeURIComponent(element.data('mailtosubject')) +\n '&body=' + encodeURIComponent(element.data('platformidstr')) + ':%20' +\n encodeURIComponent(element.data('platformid')) + '%0D%0A' +\n encodeURIComponent(element.data('clientidstr')) + ':%20' +\n encodeURIComponent(element.data('clientid')) + '%0D%0A' +\n encodeURIComponent(element.data('deploymentidstr')) + ':%20' +\n encodeURIComponent(element.data('deploymentid')) + '%0D%0A' +\n encodeURIComponent(element.data('publickeyseturlstr')) + ':%20' +\n encodeURIComponent(element.data('publickeyseturl')) + '%0D%0A' +\n encodeURIComponent(element.data('accesstokenurlstr')) + ':%20' +\n encodeURIComponent(element.data('accesstokenurl')) + '%0D%0A' +\n encodeURIComponent(element.data('authrequesturlstr')) + ':%20' +\n encodeURIComponent(element.data('authrequesturl')) + '%0D%0A
';\n context = {\n 'mailto': mailTo\n };\n var footerPromise = templates.render('mod_lti/tool_config_modal_footer', context);\n Modal.create({\n large: true,\n title: element.data('modaltitle'),\n body: bodyPromise,\n footer: footerPromise,\n show: true\n });\n });\n };\n\n return /** @alias module:mod_lti/tool_card_controller */ {\n\n /**\n * Initialise this module.\n *\n * @param {JQuery} element jQuery object representing the tool card.\n */\n init: function(element) {\n registerEventListeners(element);\n registerModal(element);\n }\n };\n});\n"],"names":["define","$","ajax","notification","templates","Modal","toolType","ltiEvents","KEYS","str","SELECTORS","getNameElement","element","find","getDescriptionElement","getActivateButton","getCapabilitiesContainer","hasCapabiliti
esContainer","length","getTypeId","attr","clearAllAnnouncements","removeClass","startLoading","addClass","stopLoading","announceSuccess","promise","Deferred","setTimeout","resolve","announceFailure","setValueSnapshot","value","getValueSnapshot","setStatusActive","id","update","state","constants","configured","then","toolTypeData","render","html","js","replaceNode","catch","registerEventListeners","deleteButton","getDeleteButton","click","e","preventDefault","typeId","get_strings","key","component","done","strs","confirm","delete","remove","fail","exception","always","error","reject","deleteType","keypress","metaKey","shiftKey","altKey","ctrlKey","keyCode","ENTER","SPACE","descriptionElement","focus","hasClass","description","text","trim","snapshotDescription","blur","type","updateDescription","nameElement","name","snapshotName","updateName","hasActivateButton","activateButton","displayCapabilitiesApproval","activateToolType","capabilitiesContainer","on","CAPABILITIES_AGREE","CAPABILITIES_DECLINE","hideCapabi
litiesApproval","init","configurationLink","data","get","addEventListener","context","bodyPromise","encodeURIComponent","footerPromise","create","large","title","body","footer","show","registerModal"],"mappings":"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"}