diff --git a/admin/tool/dataprivacy/amd/build/myrequestactions.min.js b/admin/tool/dataprivacy/amd/build/myrequestactions.min.js
index a6ba75991d1..b1b7317c48a 100644
--- a/admin/tool/dataprivacy/amd/build/myrequestactions.min.js
+++ b/admin/tool/dataprivacy/amd/build/myrequestactions.min.js
@@ -1,2 +1,2 @@
-define ("tool_dataprivacy/myrequestactions",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events","core/templates","core/pending"],function(a,b,c,d,e,f,g,h){var j={CANCEL_REQUEST:"[data-action=\"cancel\"]",CONTACT_DPO:"[data-action=\"contactdpo\"]"},k=function(){this.registerEvents()};k.prototype.registerEvents=function(){a(j.CANCEL_REQUEST).click(function(g){g.preventDefault();var h=a(this).data("requestid");d.get_strings([{key:"cancelrequest",component:"tool_dataprivacy"},{key:"cancelrequestconfirmation",component:"tool_dataprivacy"}]).then(function(a){var d=a[0],g=a[1];return e.create({title:d,body:g,type:e.types.SAVE_CANCEL}).then(function(a){a.setSaveButtonText(d);a.getRoot().on(f.save,function(){b.call([{methodname:"tool_dataprivacy_cancel_data_request",args:{requestid:h}}])[0].done(function(a){if(a.result){window.location.reload()}else{c.addNotification({message:a.warnings[0].message,type:"error"})}}).fail(c.exception)});a.getRoot().on(f.hidden,function(){a.destroy()});return a})}).done(function(a){a.show()}).fail(c.exception)});a(j.CONTACT_DPO).click(function(b){var j=new h("dataprivacy/crud:initModal:contactdpo");b.preventDefault();var k=a(this).data("replytoemail"),l="";d.get_strings([{key:"contactdataprotectionofficer",component:"tool_dataprivacy"},{key:"send",component:"tool_dataprivacy"}]).then(function(a){var b=a[0];l=a[1];return e.create({title:b,body:g.render("tool_dataprivacy/contact_dpo",{replytoemail:k}),type:e.types.SAVE_CANCEL,large:!0})}).then(function(b){b.setSaveButtonText(l);b.show();b.getRoot().on(f.save,function(b){var c=a("#message").val().trim();if(0===c.length){b.preventDefault();a("[data-region=\"messageinput\"]").addClass("has-danger notifyproblem");a("#id_error_message").removeAttr("hidden")}else{i(c)}});b.getRoot().on(f.hidden,function(){b.destroy()})}).then(j.resolve).catch(c.exception)})};function i(a){var e="success";b.call([{methodname:"tool_dataprivacy_contact_dpo",args:{message:a}}])[0].then(function(a){if(a.result){return d.get_string("requestsubmitted","tool_dataprivacy")}e="error";return a.warnings.join("
")}).done(function(a){c.addNotification({message:a,type:e})}).fail(c.exception)}return{init:function init(){return new k}}});
+define ("tool_dataprivacy/myrequestactions",["exports","core/ajax","core/notification","core/pending","core/str"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=f(b);c=f(c);d=f(d);function f(a){return a&&a.__esModule?a:{default:a}}function g(a,b){return m(a)||l(a,b)||j(a,b)||h()}function h(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function j(a,b){if(!a)return;if("string"==typeof a)return k(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return k(a,b)}function k(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c.\n\n/**\n * AMD module to enable users to manage their own data requests.\n *\n * @module tool_dataprivacy/myrequestactions\n * @package tool_dataprivacy\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/templates',\n 'core/pending'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, Pending) {\n\n /**\n * List of action selectors.\n *\n * @type {{CANCEL_REQUEST: string}}\n * @type {{CONTACT_DPO: string}}\n */\n var ACTIONS = {\n CANCEL_REQUEST: '[data-action=\"cancel\"]',\n CONTACT_DPO: '[data-action=\"contactdpo\"]',\n };\n\n /**\n * MyRequestActions class.\n */\n var MyRequestActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n MyRequestActions.prototype.registerEvents = function() {\n $(ACTIONS.CANCEL_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n var stringkeys = [\n {\n key: 'cancelrequest',\n component: 'tool_dataprivacy'\n },\n {\n key: 'cancelrequestconfirmation',\n component: 'tool_dataprivacy'\n }\n ];\n\n Str.get_strings(stringkeys).then(function(langStrings) {\n var title = langStrings[0];\n var confirmMessage = langStrings[1];\n return ModalFactory.create({\n title: title,\n body: confirmMessage,\n type: ModalFactory.types.SAVE_CANCEL\n }).then(function(modal) {\n modal.setSaveButtonText(title);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n // Cancel the request.\n var params = {\n 'requestid': requestId\n };\n\n var request = {\n methodname: 'tool_dataprivacy_cancel_data_request',\n args: params\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n });\n }).done(function(modal) {\n // Show the modal!\n modal.show();\n\n }).fail(Notification.exception);\n });\n\n $(ACTIONS.CONTACT_DPO).click(function(e) {\n var pendingPromise = new Pending('dataprivacy/crud:initModal:contactdpo');\n e.preventDefault();\n\n var replyToEmail = $(this).data('replytoemail');\n\n var keys = [\n {\n key: 'contactdataprotectionofficer',\n component: 'tool_dataprivacy'\n },\n {\n key: 'send',\n component: 'tool_dataprivacy'\n },\n ];\n\n var sendButtonText = '';\n Str.get_strings(keys).then(function(langStrings) {\n var modalTitle = langStrings[0];\n sendButtonText = langStrings[1];\n var context = {\n 'replytoemail': replyToEmail\n };\n return ModalFactory.create({\n title: modalTitle,\n body: Templates.render('tool_dataprivacy/contact_dpo', context),\n type: ModalFactory.types.SAVE_CANCEL,\n large: true\n });\n }).then(function(modal) {\n modal.setSaveButtonText(sendButtonText);\n\n // Show the modal!\n modal.show();\n\n // Handle send event.\n modal.getRoot().on(ModalEvents.save, function(e) {\n var message = $('#message').val().trim();\n if (message.length === 0) {\n e.preventDefault();\n // Show validation error when the message is empty.\n $('[data-region=\"messageinput\"]').addClass('has-danger notifyproblem');\n $('#id_error_message').removeAttr('hidden');\n } else {\n // Send the message.\n sendMessageToDPO(message);\n }\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return;\n }).then(pendingPromise.resolve)\n .catch(Notification.exception);\n });\n };\n\n /**\n * Send message to the Data Protection Officer.\n *\n * @param {String} message The message to send.\n */\n function sendMessageToDPO(message) {\n var request = {\n methodname: 'tool_dataprivacy_contact_dpo',\n args: {\n message: message\n }\n };\n\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return Str.get_string('requestsubmitted', 'tool_dataprivacy');\n }\n requestType = 'error';\n return data.warnings.join('
');\n\n }).done(function(message) {\n Notification.addNotification({\n message: message,\n type: requestType\n });\n\n }).fail(Notification.exception);\n }\n\n return /** @alias module:tool_dataprivacy/myrequestactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the unified user filter.\n *\n * @method init\n * @return {MyRequestActions}\n */\n 'init': function() {\n return new MyRequestActions();\n }\n };\n});\n"],"file":"myrequestactions.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/myrequestactions.js"],"names":["SELECTORS","CANCEL_REQUEST","init","document","addEventListener","event","triggerElement","target","closest","preventDefault","key","component","then","cancelRequest","cancelConfirm","Notification","confirm","pendingPromise","Pending","request","methodname","args","requestid","dataset","Ajax","call","response","result","window","location","reload","addNotification","type","message","warnings","resolve","catch","exception"],"mappings":"kNAwBA,OACA,OACA,O,khCAGMA,CAAAA,CAAS,CAAG,CACdC,cAAc,CAAE,0CADF,C,QAOE,QAAPC,CAAAA,IAAO,EAAM,CACtBC,QAAQ,CAACC,gBAAT,CAA0B,OAA1B,CAAmC,SAAAC,CAAK,CAAI,CACxC,GAAMC,CAAAA,CAAc,CAAGD,CAAK,CAACE,MAAN,CAAaC,OAAb,CAAqBR,CAAS,CAACC,cAA/B,CAAvB,CACA,GAAuB,IAAnB,GAAAK,CAAJ,CAA6B,CACzB,MACH,CAEDD,CAAK,CAACI,cAAN,GAOA,kBALwB,CACpB,CAACC,GAAG,CAAE,eAAN,CAAuBC,SAAS,CAAE,kBAAlC,CADoB,CAEpB,CAACD,GAAG,CAAE,2BAAN,CAAmCC,SAAS,CAAE,kBAA9C,CAFoB,CAKxB,EAA4BC,IAA5B,CAAiC,WAAoC,cAAlCC,CAAkC,MAAnBC,CAAmB,MACjE,MAAOC,WAAaC,OAAb,CAAqBH,CAArB,CAAoCC,CAApC,CAAmDD,CAAnD,CAAkE,IAAlE,CAAwE,UAAM,IAC3EI,CAAAA,CAAc,CAAG,GAAIC,UAAJ,CAAY,gCAAZ,CAD0D,CAE3EC,CAAO,CAAG,CACZC,UAAU,CAAE,sCADA,CAEZC,IAAI,CAAE,CAACC,SAAS,CAAEhB,CAAc,CAACiB,OAAf,CAAuBD,SAAnC,CAFM,CAFiE,CAOjFE,UAAKC,IAAL,CAAU,CAACN,CAAD,CAAV,EAAqB,CAArB,EAAwBP,IAAxB,CAA6B,SAAAc,CAAQ,CAAI,CACrC,GAAIA,CAAQ,CAACC,MAAb,CAAqB,CACjBC,MAAM,CAACC,QAAP,CAAgBC,MAAhB,EACH,CAFD,IAEO,CACHf,UAAagB,eAAb,CAA6B,CACzBC,IAAI,CAAE,OADmB,CAEzBC,OAAO,CAAEP,CAAQ,CAACQ,QAAT,CAAkB,CAAlB,EAAqBD,OAFL,CAA7B,CAIH,CACD,MAAOhB,CAAAA,CAAc,CAACkB,OAAf,EACV,CAVD,EAUGC,KAVH,CAUSrB,UAAasB,SAVtB,CAWH,CAlBM,CAmBV,CApBD,EAoBGD,KApBH,EAqBH,CAlCD,CAmCH,C","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 * AMD module to enable users to manage their own data requests.\n *\n * @module tool_dataprivacy/myrequestactions\n * @package tool_dataprivacy\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport {get_strings as getStrings} from 'core/str';\n\nconst SELECTORS = {\n CANCEL_REQUEST: '[data-action=\"cancel\"][data-requestid]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n const triggerElement = event.target.closest(SELECTORS.CANCEL_REQUEST);\n if (triggerElement === null) {\n return;\n }\n\n event.preventDefault();\n\n const requiredStrings = [\n {key: 'cancelrequest', component: 'tool_dataprivacy'},\n {key: 'cancelrequestconfirmation', component: 'tool_dataprivacy'},\n ];\n\n getStrings(requiredStrings).then(([cancelRequest, cancelConfirm]) => {\n return Notification.confirm(cancelRequest, cancelConfirm, cancelRequest, null, () => {\n const pendingPromise = new Pending('tool/dataprivacy:cancelRequest');\n const request = {\n methodname: 'tool_dataprivacy_cancel_data_request',\n args: {requestid: triggerElement.dataset.requestid}\n };\n\n Ajax.call([request])[0].then(response => {\n if (response.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n type: 'error',\n message: response.warnings[0].message\n });\n }\n return pendingPromise.resolve();\n }).catch(Notification.exception);\n });\n }).catch();\n });\n};\n"],"file":"myrequestactions.min.js"}
\ No newline at end of file
diff --git a/admin/tool/dataprivacy/amd/src/myrequestactions.js b/admin/tool/dataprivacy/amd/src/myrequestactions.js
index 54f94fb3e01..b75b3869697 100644
--- a/admin/tool/dataprivacy/amd/src/myrequestactions.js
+++ b/admin/tool/dataprivacy/amd/src/myrequestactions.js
@@ -21,206 +21,53 @@
* @copyright 2018 Jun Pataleta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-define([
- 'jquery',
- 'core/ajax',
- 'core/notification',
- 'core/str',
- 'core/modal_factory',
- 'core/modal_events',
- 'core/templates',
- 'core/pending'],
-function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, Pending) {
- /**
- * List of action selectors.
- *
- * @type {{CANCEL_REQUEST: string}}
- * @type {{CONTACT_DPO: string}}
- */
- var ACTIONS = {
- CANCEL_REQUEST: '[data-action="cancel"]',
- CONTACT_DPO: '[data-action="contactdpo"]',
- };
+import Ajax from 'core/ajax';
+import Notification from 'core/notification';
+import Pending from 'core/pending';
+import {get_strings as getStrings} from 'core/str';
- /**
- * MyRequestActions class.
- */
- var MyRequestActions = function() {
- this.registerEvents();
- };
+const SELECTORS = {
+ CANCEL_REQUEST: '[data-action="cancel"][data-requestid]',
+};
- /**
- * Register event listeners.
- */
- MyRequestActions.prototype.registerEvents = function() {
- $(ACTIONS.CANCEL_REQUEST).click(function(e) {
- e.preventDefault();
-
- var requestId = $(this).data('requestid');
- var stringkeys = [
- {
- key: 'cancelrequest',
- component: 'tool_dataprivacy'
- },
- {
- key: 'cancelrequestconfirmation',
- component: 'tool_dataprivacy'
- }
- ];
-
- Str.get_strings(stringkeys).then(function(langStrings) {
- var title = langStrings[0];
- var confirmMessage = langStrings[1];
- return ModalFactory.create({
- title: title,
- body: confirmMessage,
- type: ModalFactory.types.SAVE_CANCEL
- }).then(function(modal) {
- modal.setSaveButtonText(title);
-
- // Handle save event.
- modal.getRoot().on(ModalEvents.save, function() {
- // Cancel the request.
- var params = {
- 'requestid': requestId
- };
-
- var request = {
- methodname: 'tool_dataprivacy_cancel_data_request',
- args: params
- };
-
- Ajax.call([request])[0].done(function(data) {
- if (data.result) {
- window.location.reload();
- } else {
- Notification.addNotification({
- message: data.warnings[0].message,
- type: 'error'
- });
- }
- }).fail(Notification.exception);
- });
-
- // Handle hidden event.
- modal.getRoot().on(ModalEvents.hidden, function() {
- // Destroy when hidden.
- modal.destroy();
- });
-
- return modal;
- });
- }).done(function(modal) {
- // Show the modal!
- modal.show();
-
- }).fail(Notification.exception);
- });
-
- $(ACTIONS.CONTACT_DPO).click(function(e) {
- var pendingPromise = new Pending('dataprivacy/crud:initModal:contactdpo');
- e.preventDefault();
-
- var replyToEmail = $(this).data('replytoemail');
-
- var keys = [
- {
- key: 'contactdataprotectionofficer',
- component: 'tool_dataprivacy'
- },
- {
- key: 'send',
- component: 'tool_dataprivacy'
- },
- ];
-
- var sendButtonText = '';
- Str.get_strings(keys).then(function(langStrings) {
- var modalTitle = langStrings[0];
- sendButtonText = langStrings[1];
- var context = {
- 'replytoemail': replyToEmail
- };
- return ModalFactory.create({
- title: modalTitle,
- body: Templates.render('tool_dataprivacy/contact_dpo', context),
- type: ModalFactory.types.SAVE_CANCEL,
- large: true
- });
- }).then(function(modal) {
- modal.setSaveButtonText(sendButtonText);
-
- // Show the modal!
- modal.show();
-
- // Handle send event.
- modal.getRoot().on(ModalEvents.save, function(e) {
- var message = $('#message').val().trim();
- if (message.length === 0) {
- e.preventDefault();
- // Show validation error when the message is empty.
- $('[data-region="messageinput"]').addClass('has-danger notifyproblem');
- $('#id_error_message').removeAttr('hidden');
- } else {
- // Send the message.
- sendMessageToDPO(message);
- }
- });
-
- // Handle hidden event.
- modal.getRoot().on(ModalEvents.hidden, function() {
- // Destroy when hidden.
- modal.destroy();
- });
-
- return;
- }).then(pendingPromise.resolve)
- .catch(Notification.exception);
- });
- };
-
- /**
- * Send message to the Data Protection Officer.
- *
- * @param {String} message The message to send.
- */
- function sendMessageToDPO(message) {
- var request = {
- methodname: 'tool_dataprivacy_contact_dpo',
- args: {
- message: message
- }
- };
-
- var requestType = 'success';
- Ajax.call([request])[0].then(function(data) {
- if (data.result) {
- return Str.get_string('requestsubmitted', 'tool_dataprivacy');
- }
- requestType = 'error';
- return data.warnings.join('
');
-
- }).done(function(message) {
- Notification.addNotification({
- message: message,
- type: requestType
- });
-
- }).fail(Notification.exception);
- }
-
- return /** @alias module:tool_dataprivacy/myrequestactions */ {
- // Public variables and functions.
-
- /**
- * Initialise the unified user filter.
- *
- * @method init
- * @return {MyRequestActions}
- */
- 'init': function() {
- return new MyRequestActions();
+/**
+ * Initialize module
+ */
+export const init = () => {
+ document.addEventListener('click', event => {
+ const triggerElement = event.target.closest(SELECTORS.CANCEL_REQUEST);
+ if (triggerElement === null) {
+ return;
}
- };
-});
+
+ event.preventDefault();
+
+ const requiredStrings = [
+ {key: 'cancelrequest', component: 'tool_dataprivacy'},
+ {key: 'cancelrequestconfirmation', component: 'tool_dataprivacy'},
+ ];
+
+ getStrings(requiredStrings).then(([cancelRequest, cancelConfirm]) => {
+ return Notification.confirm(cancelRequest, cancelConfirm, cancelRequest, null, () => {
+ const pendingPromise = new Pending('tool/dataprivacy:cancelRequest');
+ const request = {
+ methodname: 'tool_dataprivacy_cancel_data_request',
+ args: {requestid: triggerElement.dataset.requestid}
+ };
+
+ Ajax.call([request])[0].then(response => {
+ if (response.result) {
+ window.location.reload();
+ } else {
+ Notification.addNotification({
+ type: 'error',
+ message: response.warnings[0].message
+ });
+ }
+ return pendingPromise.resolve();
+ }).catch(Notification.exception);
+ });
+ }).catch();
+ });
+};
diff --git a/admin/tool/dataprivacy/tests/behat/my_data_requests.feature b/admin/tool/dataprivacy/tests/behat/my_data_requests.feature
new file mode 100644
index 00000000000..15de9cd732e
--- /dev/null
+++ b/admin/tool/dataprivacy/tests/behat/my_data_requests.feature
@@ -0,0 +1,26 @@
+@tool @tool_dataprivacy
+Feature: Manage my own data requests
+ In order to manage my own data requests
+ As a user
+ I need to be able to view and cancel all my data requests
+
+ Background:
+ Given the following "users" exist:
+ | username | firstname | lastname | email |
+ | student1 | Student | 1 | s1@example.com |
+ And the following config values are set as admin:
+ | contactdataprotectionofficer | 1 | tool_dataprivacy |
+
+ @javascript
+ Scenario: Cancel my own data request
+ Given I log in as "student1"
+ And I follow "Profile" in the user menu
+ And I click on "Contact the privacy officer" "link"
+ And I set the field "Message" to "Hello DPO!"
+ And I click on "Send" "button" in the "Contact the privacy officer" "dialogue"
+ And I should see "Your request has been submitted to the privacy officer"
+ When I click on "Data requests" "link"
+ And I open the action menu in "Hello DPO!" "table_row"
+ And I choose "Cancel" in the open action menu
+ And I click on "Cancel request" "button" in the "Cancel request" "dialogue"
+ Then I should see "Cancelled" in the "Hello DPO!" "table_row"