From dc2721083c35d59eaabe9912d17b9b22611c8885 Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Thu, 5 Oct 2023 12:10:21 +0800 Subject: [PATCH] MDL-79584 core_payment: load strings in js and pass to template This template shouldn't really be using string helpers inside string helpers like it does, and this is unsupported in 4.3. This just moves the string resolution to js land and then passes that resolved string into the template instead. --- payment/amd/build/gateways_modal.min.js | 2 +- payment/amd/build/gateways_modal.min.js.map | 2 +- payment/amd/src/gateways_modal.js | 10 +++++++++- payment/templates/fee_breakdown.mustache | 22 +++++---------------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/payment/amd/build/gateways_modal.min.js b/payment/amd/build/gateways_modal.min.js index a4918d824c5..6864aef8ce2 100644 --- a/payment/amd/build/gateways_modal.min.js +++ b/payment/amd/build/gateways_modal.min.js @@ -1,3 +1,3 @@ -define("core_payment/gateways_modal",["exports","core/templates","core/str","./repository","./selectors","core/modal_events","core_payment/events","core/toast","core/notification","./modal_gateways"],(function(_exports,_templates,_str,_repository,_selectors,_modal_events,_events,_toast,_notification,_modal_gateways){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_selectors=_interopRequireDefault(_selectors),_modal_events=_interopRequireDefault(_modal_events),_events=_interopRequireDefault(_events),_notification=_interopRequireDefault(_notification),_modal_gateways=_interopRequireDefault(_modal_gateways);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const show=async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const body=await _templates.default.render("core_payment/gateways_modal",{}),modal=await _modal_gateways.default.create({title:(0,_str.getString)("selectpaymenttype","core_payment"),body:body,show:!0,removeOnClose:!0}),rootElement=modal.getRoot()[0];(0,_toast.addToastRegion)(rootElement),modal.getRoot().on(_modal_events.default.hidden,(()=>{null==focusOnClose||focusOnClose.focus()})),modal.getRoot().on(_events.default.proceed,(async e=>{e.preventDefault();const gateway=(rootElement.querySelector(_selectors.default.values.gateway)||{value:""}).value;if(gateway){const message=processPayment(gateway,rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid,rootNode.dataset.description);modal.hide(),_notification.default.addNotification({message:message,type:"success"}),location.href=rootNode.dataset.successurl}else(0,_toast.add)((0,_str.getString)("nogatewayselected","core_payment"),{type:"warning"})})),rootElement.addEventListener("change",(e=>{e.target.matches(_selectors.default.elements.gateways)&&updateCostRegion(rootElement,rootNode.dataset.cost)}));const gateways=await(0,_repository.getAvailableGateways)(rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid),context={gateways:gateways},{html:html,js:js}=await _templates.default.renderForPromise("core_payment/gateways",context);_templates.default.replaceNodeContents(rootElement.querySelector(_selectors.default.regions.gatewaysContainer),html,js),selectSingleGateway(rootElement),await updateCostRegion(rootElement,rootNode.dataset.cost)},selectSingleGateway=root=>{const gateways=root.querySelectorAll(_selectors.default.elements.gateways);1==gateways.length&&(gateways[0].checked=!0)},updateCostRegion=async function(root){let defaultCost=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const gatewayElement=root.querySelector(_selectors.default.values.gateway),surcharge=parseInt((gatewayElement||{dataset:{surcharge:0}}).dataset.surcharge),cost=(gatewayElement||{dataset:{cost:defaultCost}}).dataset.cost,{html:html,js:js}=await _templates.default.renderForPromise("core_payment/fee_breakdown",{fee:cost,surcharge:surcharge});_templates.default.replaceNodeContents(root.querySelector(_selectors.default.regions.costContainer),html,js)},processPayment=async(gateway,component,paymentArea,itemId,description)=>(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["paygw_".concat(gateway,"/gateways_modal")],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("paygw_".concat(gateway,"/gateways_modal"))):Promise.resolve(_systemImportTransformerGlobalIdentifier["paygw_".concat(gateway,"/gateways_modal")]))).process(component,paymentArea,itemId,description),init=()=>{init.initialised||(init.initialised=!0,document.addEventListener("click",(e=>{const gatewayTrigger=e.target.closest('[data-action="core_payment/triggerPayment"]');gatewayTrigger&&(e.preventDefault(),show(gatewayTrigger,{focusOnClose:e.target}))})))};_exports.init=init,init.initialised=!1})); +define("core_payment/gateways_modal",["exports","core/templates","core/str","./repository","./selectors","core/modal_events","core_payment/events","core/toast","core/notification","./modal_gateways"],(function(_exports,_templates,_str,_repository,_selectors,_modal_events,_events,_toast,_notification,_modal_gateways){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_selectors=_interopRequireDefault(_selectors),_modal_events=_interopRequireDefault(_modal_events),_events=_interopRequireDefault(_events),_notification=_interopRequireDefault(_notification),_modal_gateways=_interopRequireDefault(_modal_gateways);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const show=async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const body=await _templates.default.render("core_payment/gateways_modal",{}),modal=await _modal_gateways.default.create({title:(0,_str.getString)("selectpaymenttype","core_payment"),body:body,show:!0,removeOnClose:!0}),rootElement=modal.getRoot()[0];(0,_toast.addToastRegion)(rootElement),modal.getRoot().on(_modal_events.default.hidden,(()=>{null==focusOnClose||focusOnClose.focus()})),modal.getRoot().on(_events.default.proceed,(async e=>{e.preventDefault();const gateway=(rootElement.querySelector(_selectors.default.values.gateway)||{value:""}).value;if(gateway){const message=processPayment(gateway,rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid,rootNode.dataset.description);modal.hide(),_notification.default.addNotification({message:message,type:"success"}),location.href=rootNode.dataset.successurl}else(0,_toast.add)((0,_str.getString)("nogatewayselected","core_payment"),{type:"warning"})})),rootElement.addEventListener("change",(e=>{e.target.matches(_selectors.default.elements.gateways)&&updateCostRegion(rootElement,rootNode.dataset.cost)}));const gateways=await(0,_repository.getAvailableGateways)(rootNode.dataset.component,rootNode.dataset.paymentarea,rootNode.dataset.itemid),context={gateways:gateways},{html:html,js:js}=await _templates.default.renderForPromise("core_payment/gateways",context);_templates.default.replaceNodeContents(rootElement.querySelector(_selectors.default.regions.gatewaysContainer),html,js),selectSingleGateway(rootElement),await updateCostRegion(rootElement,rootNode.dataset.cost)},selectSingleGateway=root=>{const gateways=root.querySelectorAll(_selectors.default.elements.gateways);1==gateways.length&&(gateways[0].checked=!0)},updateCostRegion=async function(root){let defaultCost=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const gatewayElement=root.querySelector(_selectors.default.values.gateway),surcharge=parseInt((gatewayElement||{dataset:{surcharge:0}}).dataset.surcharge),cost=(gatewayElement||{dataset:{cost:defaultCost}}).dataset.cost,valueStr=surcharge?await(0,_str.getString)("feeincludesurcharge","core_payment",{fee:cost,surcharge:surcharge}):cost,surchargeStr=await(0,_str.getString)("labelvalue","core",{label:await(0,_str.getString)("cost","core"),value:valueStr}),{html:html,js:js}=await _templates.default.renderForPromise("core_payment/fee_breakdown",{surchargestr:surchargeStr});_templates.default.replaceNodeContents(root.querySelector(_selectors.default.regions.costContainer),html,js)},processPayment=async(gateway,component,paymentArea,itemId,description)=>(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["paygw_".concat(gateway,"/gateways_modal")],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("paygw_".concat(gateway,"/gateways_modal"))):Promise.resolve(_systemImportTransformerGlobalIdentifier["paygw_".concat(gateway,"/gateways_modal")]))).process(component,paymentArea,itemId,description),init=()=>{init.initialised||(init.initialised=!0,document.addEventListener("click",(e=>{const gatewayTrigger=e.target.closest('[data-action="core_payment/triggerPayment"]');gatewayTrigger&&(e.preventDefault(),show(gatewayTrigger,{focusOnClose:e.target}))})))};_exports.init=init,init.initialised=!1})); //# sourceMappingURL=gateways_modal.min.js.map \ No newline at end of file diff --git a/payment/amd/build/gateways_modal.min.js.map b/payment/amd/build/gateways_modal.min.js.map index 213c45d6638..320db15d55c 100644 --- a/payment/amd/build/gateways_modal.min.js.map +++ b/payment/amd/build/gateways_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"gateways_modal.min.js","sources":["../src/gateways_modal.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 .\n\n/**\n * Contain the logic for the gateways modal.\n *\n * @module core_payment/gateways_modal\n * @copyright 2019 Shamim Rezaie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport {getAvailableGateways} from './repository';\nimport Selectors from './selectors';\nimport ModalEvents from 'core/modal_events';\nimport PaymentEvents from 'core_payment/events';\nimport {add as addToast, addToastRegion} from 'core/toast';\nimport Notification from 'core/notification';\nimport ModalGateways from './modal_gateways';\n\n/**\n * Register event listeners for the module.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const gatewayTrigger = e.target.closest('[data-action=\"core_payment/triggerPayment\"]');\n if (gatewayTrigger) {\n e.preventDefault();\n\n show(gatewayTrigger, {focusOnClose: e.target});\n }\n });\n};\n\n/**\n * Shows the gateway selector modal.\n *\n * @param {HTMLElement} rootNode\n * @param {Object} options - Additional options\n * @param {HTMLElement} options.focusOnClose The element to focus on when the modal is closed.\n */\nconst show = async(rootNode, {\n focusOnClose = null,\n} = {}) => {\n\n // Load upfront, so we don't try to inject the internal content into a possibly-not-yet-resolved promise.\n const body = await Templates.render('core_payment/gateways_modal', {});\n\n const modal = await ModalGateways.create({\n title: getString('selectpaymenttype', 'core_payment'),\n body: body,\n show: true,\n removeOnClose: true,\n });\n\n const rootElement = modal.getRoot()[0];\n addToastRegion(rootElement);\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n focusOnClose?.focus();\n });\n\n modal.getRoot().on(PaymentEvents.proceed, async(e) => {\n e.preventDefault();\n const gateway = (rootElement.querySelector(Selectors.values.gateway) || {value: ''}).value;\n\n if (gateway) {\n const message = processPayment(\n gateway,\n rootNode.dataset.component,\n rootNode.dataset.paymentarea,\n rootNode.dataset.itemid,\n rootNode.dataset.description\n );\n\n modal.hide();\n Notification.addNotification({\n message,\n type: 'success',\n });\n location.href = rootNode.dataset.successurl;\n } else {\n // We cannot use await in the following line.\n // The reason is that we are preventing the default action of the save event being triggered,\n // therefore we cannot define the event handler function asynchronous.\n addToast(getString('nogatewayselected', 'core_payment'), {\n type: 'warning',\n });\n }\n });\n\n // Re-calculate the cost when gateway is changed.\n rootElement.addEventListener('change', e => {\n if (e.target.matches(Selectors.elements.gateways)) {\n updateCostRegion(rootElement, rootNode.dataset.cost);\n }\n });\n\n const gateways = await getAvailableGateways(rootNode.dataset.component, rootNode.dataset.paymentarea, rootNode.dataset.itemid);\n const context = {\n gateways\n };\n\n const {html, js} = await Templates.renderForPromise('core_payment/gateways', context);\n Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);\n selectSingleGateway(rootElement);\n await updateCostRegion(rootElement, rootNode.dataset.cost);\n};\n\n/**\n * Auto-select the gateway if there is only one gateway.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n */\nconst selectSingleGateway = root => {\n const gateways = root.querySelectorAll(Selectors.elements.gateways);\n\n if (gateways.length == 1) {\n gateways[0].checked = true;\n }\n};\n\n/**\n * Shows the cost of the item the user is purchasing in the cost region.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n * @param {string} defaultCost The default cost that is going to be displayed if no gateway is selected\n * @returns {Promise}\n */\nconst updateCostRegion = async(root, defaultCost = '') => {\n const gatewayElement = root.querySelector(Selectors.values.gateway);\n const surcharge = parseInt((gatewayElement || {dataset: {surcharge: 0}}).dataset.surcharge);\n const cost = (gatewayElement || {dataset: {cost: defaultCost}}).dataset.cost;\n\n const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: cost, surcharge});\n Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js);\n};\n\n/**\n * Process payment using the selected gateway.\n *\n * @param {string} gateway The gateway to be used for payment\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea Name of the area in the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} description Description of the payment\n * @returns {Promise}\n */\nconst processPayment = async(gateway, component, paymentArea, itemId, description) => {\n const paymentMethod = await import(`paygw_${gateway}/gateways_modal`);\n return paymentMethod.process(component, paymentArea, itemId, description);\n};\n\n/**\n * Set up the payment actions.\n */\nexport const init = () => {\n if (!init.initialised) {\n // Event listeners should only be registered once.\n init.initialised = true;\n registerEventListeners();\n }\n};\n\n/**\n * Whether the init function was called before.\n *\n * @static\n * @type {boolean}\n */\ninit.initialised = false;\n"],"names":["show","async","rootNode","focusOnClose","body","Templates","render","modal","ModalGateways","create","title","removeOnClose","rootElement","getRoot","on","ModalEvents","hidden","focus","PaymentEvents","proceed","e","preventDefault","gateway","querySelector","Selectors","values","value","message","processPayment","dataset","component","paymentarea","itemid","description","hide","addNotification","type","location","href","successurl","addEventListener","target","matches","elements","gateways","updateCostRegion","cost","context","html","js","renderForPromise","replaceNodeContents","regions","gatewaysContainer","selectSingleGateway","root","querySelectorAll","length","checked","defaultCost","gatewayElement","surcharge","parseInt","fee","costContainer","paymentArea","itemId","process","init","initialised","document","gatewayTrigger","closest"],"mappings":"y5BAsDMA,KAAOC,eAAMC,cAAUC,aACzBA,aAAe,6DACf,SAGMC,WAAaC,mBAAUC,OAAO,8BAA+B,IAE7DC,YAAcC,wBAAcC,OAAO,CACrCC,OAAO,kBAAU,oBAAqB,gBACtCN,KAAMA,KACNJ,MAAM,EACNW,eAAe,IAGbC,YAAcL,MAAMM,UAAU,6BACrBD,aAEfL,MAAMM,UAAUC,GAAGC,sBAAYC,QAAQ,KACnCb,MAAAA,cAAAA,aAAcc,WAGlBV,MAAMM,UAAUC,GAAGI,gBAAcC,SAASlB,MAAAA,IACtCmB,EAAEC,uBACIC,SAAWV,YAAYW,cAAcC,mBAAUC,OAAOH,UAAY,CAACI,MAAO,KAAKA,SAEjFJ,QAAS,OACHK,QAAUC,eACZN,QACApB,SAAS2B,QAAQC,UACjB5B,SAAS2B,QAAQE,YACjB7B,SAAS2B,QAAQG,OACjB9B,SAAS2B,QAAQI,aAGrB1B,MAAM2B,6BACOC,gBAAgB,CACzBR,QAAAA,QACAS,KAAM,YAEVC,SAASC,KAAOpC,SAAS2B,QAAQU,+BAKxB,kBAAU,oBAAqB,gBAAiB,CACrDH,KAAM,eAMlBxB,YAAY4B,iBAAiB,UAAUpB,IAC/BA,EAAEqB,OAAOC,QAAQlB,mBAAUmB,SAASC,WACpCC,iBAAiBjC,YAAaV,SAAS2B,QAAQiB,eAIjDF,eAAiB,oCAAqB1C,SAAS2B,QAAQC,UAAW5B,SAAS2B,QAAQE,YAAa7B,SAAS2B,QAAQG,QACjHe,QAAU,CACZH,SAAAA,WAGEI,KAACA,KAADC,GAAOA,UAAY5C,mBAAU6C,iBAAiB,wBAAyBH,4BACnEI,oBAAoBvC,YAAYW,cAAcC,mBAAU4B,QAAQC,mBAAoBL,KAAMC,IACpGK,oBAAoB1C,mBACdiC,iBAAiBjC,YAAaV,SAAS2B,QAAQiB,OAQnDQ,oBAAsBC,aAClBX,SAAWW,KAAKC,iBAAiBhC,mBAAUmB,SAASC,UAEnC,GAAnBA,SAASa,SACTb,SAAS,GAAGc,SAAU,IAWxBb,iBAAmB5C,eAAMsD,UAAMI,mEAAc,SACzCC,eAAiBL,KAAKhC,cAAcC,mBAAUC,OAAOH,SACrDuC,UAAYC,UAAUF,gBAAkB,CAAC/B,QAAS,CAACgC,UAAW,KAAKhC,QAAQgC,WAC3Ef,MAAQc,gBAAkB,CAAC/B,QAAS,CAACiB,KAAMa,eAAe9B,QAAQiB,MAElEE,KAACA,KAADC,GAAOA,UAAY5C,mBAAU6C,iBAAiB,6BAA8B,CAACa,IAAKjB,KAAMe,UAAAA,+BACpFV,oBAAoBI,KAAKhC,cAAcC,mBAAU4B,QAAQY,eAAgBhB,KAAMC,KAavFrB,eAAiB3B,MAAMqB,QAASQ,UAAWmC,YAAaC,OAAQjC,qPACtBX,sUAAAA,sGAAAA,+BACvB6C,QAAQrC,UAAWmC,YAAaC,OAAQjC,aAMpDmC,KAAO,KACXA,KAAKC,cAEND,KAAKC,aAAc,EAvIvBC,SAAS9B,iBAAiB,SAASpB,UACzBmD,eAAiBnD,EAAEqB,OAAO+B,QAAQ,+CACpCD,iBACAnD,EAAEC,iBAEFrB,KAAKuE,eAAgB,CAACpE,aAAciB,EAAEqB,kCA6IlD2B,KAAKC,aAAc"} \ No newline at end of file +{"version":3,"file":"gateways_modal.min.js","sources":["../src/gateways_modal.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 .\n\n/**\n * Contain the logic for the gateways modal.\n *\n * @module core_payment/gateways_modal\n * @copyright 2019 Shamim Rezaie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport {getAvailableGateways} from './repository';\nimport Selectors from './selectors';\nimport ModalEvents from 'core/modal_events';\nimport PaymentEvents from 'core_payment/events';\nimport {add as addToast, addToastRegion} from 'core/toast';\nimport Notification from 'core/notification';\nimport ModalGateways from './modal_gateways';\n\n/**\n * Register event listeners for the module.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const gatewayTrigger = e.target.closest('[data-action=\"core_payment/triggerPayment\"]');\n if (gatewayTrigger) {\n e.preventDefault();\n\n show(gatewayTrigger, {focusOnClose: e.target});\n }\n });\n};\n\n/**\n * Shows the gateway selector modal.\n *\n * @param {HTMLElement} rootNode\n * @param {Object} options - Additional options\n * @param {HTMLElement} options.focusOnClose The element to focus on when the modal is closed.\n */\nconst show = async(rootNode, {\n focusOnClose = null,\n} = {}) => {\n\n // Load upfront, so we don't try to inject the internal content into a possibly-not-yet-resolved promise.\n const body = await Templates.render('core_payment/gateways_modal', {});\n\n const modal = await ModalGateways.create({\n title: getString('selectpaymenttype', 'core_payment'),\n body: body,\n show: true,\n removeOnClose: true,\n });\n\n const rootElement = modal.getRoot()[0];\n addToastRegion(rootElement);\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n focusOnClose?.focus();\n });\n\n modal.getRoot().on(PaymentEvents.proceed, async(e) => {\n e.preventDefault();\n const gateway = (rootElement.querySelector(Selectors.values.gateway) || {value: ''}).value;\n\n if (gateway) {\n const message = processPayment(\n gateway,\n rootNode.dataset.component,\n rootNode.dataset.paymentarea,\n rootNode.dataset.itemid,\n rootNode.dataset.description\n );\n\n modal.hide();\n Notification.addNotification({\n message,\n type: 'success',\n });\n location.href = rootNode.dataset.successurl;\n } else {\n // We cannot use await in the following line.\n // The reason is that we are preventing the default action of the save event being triggered,\n // therefore we cannot define the event handler function asynchronous.\n addToast(getString('nogatewayselected', 'core_payment'), {\n type: 'warning',\n });\n }\n });\n\n // Re-calculate the cost when gateway is changed.\n rootElement.addEventListener('change', e => {\n if (e.target.matches(Selectors.elements.gateways)) {\n updateCostRegion(rootElement, rootNode.dataset.cost);\n }\n });\n\n const gateways = await getAvailableGateways(rootNode.dataset.component, rootNode.dataset.paymentarea, rootNode.dataset.itemid);\n const context = {\n gateways\n };\n\n const {html, js} = await Templates.renderForPromise('core_payment/gateways', context);\n Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);\n selectSingleGateway(rootElement);\n await updateCostRegion(rootElement, rootNode.dataset.cost);\n};\n\n/**\n * Auto-select the gateway if there is only one gateway.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n */\nconst selectSingleGateway = root => {\n const gateways = root.querySelectorAll(Selectors.elements.gateways);\n\n if (gateways.length == 1) {\n gateways[0].checked = true;\n }\n};\n\n/**\n * Shows the cost of the item the user is purchasing in the cost region.\n *\n * @param {HTMLElement} root An HTMLElement that contains the cost region\n * @param {string} defaultCost The default cost that is going to be displayed if no gateway is selected\n * @returns {Promise}\n */\nconst updateCostRegion = async(root, defaultCost = '') => {\n const gatewayElement = root.querySelector(Selectors.values.gateway);\n const surcharge = parseInt((gatewayElement || {dataset: {surcharge: 0}}).dataset.surcharge);\n const cost = (gatewayElement || {dataset: {cost: defaultCost}}).dataset.cost;\n const valueStr = surcharge ? await getString('feeincludesurcharge', 'core_payment', {fee: cost, surcharge: surcharge}) : cost;\n\n const surchargeStr = await getString('labelvalue', 'core',\n {\n label: await getString('cost', 'core'),\n value: valueStr\n }\n );\n\n const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {surchargestr: surchargeStr});\n Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js);\n};\n\n/**\n * Process payment using the selected gateway.\n *\n * @param {string} gateway The gateway to be used for payment\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea Name of the area in the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} description Description of the payment\n * @returns {Promise}\n */\nconst processPayment = async(gateway, component, paymentArea, itemId, description) => {\n const paymentMethod = await import(`paygw_${gateway}/gateways_modal`);\n return paymentMethod.process(component, paymentArea, itemId, description);\n};\n\n/**\n * Set up the payment actions.\n */\nexport const init = () => {\n if (!init.initialised) {\n // Event listeners should only be registered once.\n init.initialised = true;\n registerEventListeners();\n }\n};\n\n/**\n * Whether the init function was called before.\n *\n * @static\n * @type {boolean}\n */\ninit.initialised = false;\n"],"names":["show","async","rootNode","focusOnClose","body","Templates","render","modal","ModalGateways","create","title","removeOnClose","rootElement","getRoot","on","ModalEvents","hidden","focus","PaymentEvents","proceed","e","preventDefault","gateway","querySelector","Selectors","values","value","message","processPayment","dataset","component","paymentarea","itemid","description","hide","addNotification","type","location","href","successurl","addEventListener","target","matches","elements","gateways","updateCostRegion","cost","context","html","js","renderForPromise","replaceNodeContents","regions","gatewaysContainer","selectSingleGateway","root","querySelectorAll","length","checked","defaultCost","gatewayElement","surcharge","parseInt","valueStr","fee","surchargeStr","label","surchargestr","costContainer","paymentArea","itemId","process","init","initialised","document","gatewayTrigger","closest"],"mappings":"y5BAsDMA,KAAOC,eAAMC,cAAUC,aACzBA,aAAe,6DACf,SAGMC,WAAaC,mBAAUC,OAAO,8BAA+B,IAE7DC,YAAcC,wBAAcC,OAAO,CACrCC,OAAO,kBAAU,oBAAqB,gBACtCN,KAAMA,KACNJ,MAAM,EACNW,eAAe,IAGbC,YAAcL,MAAMM,UAAU,6BACrBD,aAEfL,MAAMM,UAAUC,GAAGC,sBAAYC,QAAQ,KACnCb,MAAAA,cAAAA,aAAcc,WAGlBV,MAAMM,UAAUC,GAAGI,gBAAcC,SAASlB,MAAAA,IACtCmB,EAAEC,uBACIC,SAAWV,YAAYW,cAAcC,mBAAUC,OAAOH,UAAY,CAACI,MAAO,KAAKA,SAEjFJ,QAAS,OACHK,QAAUC,eACZN,QACApB,SAAS2B,QAAQC,UACjB5B,SAAS2B,QAAQE,YACjB7B,SAAS2B,QAAQG,OACjB9B,SAAS2B,QAAQI,aAGrB1B,MAAM2B,6BACOC,gBAAgB,CACzBR,QAAAA,QACAS,KAAM,YAEVC,SAASC,KAAOpC,SAAS2B,QAAQU,+BAKxB,kBAAU,oBAAqB,gBAAiB,CACrDH,KAAM,eAMlBxB,YAAY4B,iBAAiB,UAAUpB,IAC/BA,EAAEqB,OAAOC,QAAQlB,mBAAUmB,SAASC,WACpCC,iBAAiBjC,YAAaV,SAAS2B,QAAQiB,eAIjDF,eAAiB,oCAAqB1C,SAAS2B,QAAQC,UAAW5B,SAAS2B,QAAQE,YAAa7B,SAAS2B,QAAQG,QACjHe,QAAU,CACZH,SAAAA,WAGEI,KAACA,KAADC,GAAOA,UAAY5C,mBAAU6C,iBAAiB,wBAAyBH,4BACnEI,oBAAoBvC,YAAYW,cAAcC,mBAAU4B,QAAQC,mBAAoBL,KAAMC,IACpGK,oBAAoB1C,mBACdiC,iBAAiBjC,YAAaV,SAAS2B,QAAQiB,OAQnDQ,oBAAsBC,aAClBX,SAAWW,KAAKC,iBAAiBhC,mBAAUmB,SAASC,UAEnC,GAAnBA,SAASa,SACTb,SAAS,GAAGc,SAAU,IAWxBb,iBAAmB5C,eAAMsD,UAAMI,mEAAc,SACzCC,eAAiBL,KAAKhC,cAAcC,mBAAUC,OAAOH,SACrDuC,UAAYC,UAAUF,gBAAkB,CAAC/B,QAAS,CAACgC,UAAW,KAAKhC,QAAQgC,WAC3Ef,MAAQc,gBAAkB,CAAC/B,QAAS,CAACiB,KAAMa,eAAe9B,QAAQiB,KAClEiB,SAAWF,gBAAkB,kBAAU,sBAAuB,eAAgB,CAACG,IAAKlB,KAAMe,UAAWA,YAAcf,KAEnHmB,mBAAqB,kBAAU,aAAc,OAC/C,CACIC,YAAa,kBAAU,OAAQ,QAC/BxC,MAAOqC,YAITf,KAACA,KAADC,GAAOA,UAAY5C,mBAAU6C,iBAAiB,6BAA8B,CAACiB,aAAcF,kCACvFd,oBAAoBI,KAAKhC,cAAcC,mBAAU4B,QAAQgB,eAAgBpB,KAAMC,KAavFrB,eAAiB3B,MAAMqB,QAASQ,UAAWuC,YAAaC,OAAQrC,qPACtBX,sUAAAA,sGAAAA,+BACvBiD,QAAQzC,UAAWuC,YAAaC,OAAQrC,aAMpDuC,KAAO,KACXA,KAAKC,cAEND,KAAKC,aAAc,EA/IvBC,SAASlC,iBAAiB,SAASpB,UACzBuD,eAAiBvD,EAAEqB,OAAOmC,QAAQ,+CACpCD,iBACAvD,EAAEC,iBAEFrB,KAAK2E,eAAgB,CAACxE,aAAciB,EAAEqB,kCAqJlD+B,KAAKC,aAAc"} \ No newline at end of file diff --git a/payment/amd/src/gateways_modal.js b/payment/amd/src/gateways_modal.js index ccbe3365369..3193c896570 100644 --- a/payment/amd/src/gateways_modal.js +++ b/payment/amd/src/gateways_modal.js @@ -144,8 +144,16 @@ const updateCostRegion = async(root, defaultCost = '') => { const gatewayElement = root.querySelector(Selectors.values.gateway); const surcharge = parseInt((gatewayElement || {dataset: {surcharge: 0}}).dataset.surcharge); const cost = (gatewayElement || {dataset: {cost: defaultCost}}).dataset.cost; + const valueStr = surcharge ? await getString('feeincludesurcharge', 'core_payment', {fee: cost, surcharge: surcharge}) : cost; - const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: cost, surcharge}); + const surchargeStr = await getString('labelvalue', 'core', + { + label: await getString('cost', 'core'), + value: valueStr + } + ); + + const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {surchargestr: surchargeStr}); Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js); }; diff --git a/payment/templates/fee_breakdown.mustache b/payment/templates/fee_breakdown.mustache index a9b5cf32ea7..319e4dcc4b6 100644 --- a/payment/templates/fee_breakdown.mustache +++ b/payment/templates/fee_breakdown.mustache @@ -24,26 +24,14 @@ * none Context variables required for this template: - * none + * surchargestr Example context (json): - {} + { + "surchargestr": "Cost: $10.00" + } }}
- {{#surcharge}} - {{# str }} labelvalue, core, { - "label": {{# quote }}{{# str }} cost {{/ str }}{{/ quote }}, - "value": {{# quote }}{{# str }} feeincludesurcharge, core_payment, { - "fee": "{{fee}}", - "surcharge": {{surcharge}} - } {{/ str }}{{/ quote }} - } {{/ str }} - {{/surcharge}} - {{^surcharge}} - {{# str }} labelvalue, core, { - "label": {{# quote }}{{# str }} cost {{/ str }}{{/ quote }}, - "value": "{{fee}}" - } {{/ str }} - {{/surcharge}} + {{surchargestr}}