Skip to content

Commit

Permalink
MDL-71090 tool_dataprivacy: convert contact DPO to modal forms.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulholden committed Mar 23, 2021
1 parent c1db56b commit 2eee07d
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 72 deletions.
2 changes: 2 additions & 0 deletions admin/tool/dataprivacy/amd/build/contactdpo.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions admin/tool/dataprivacy/amd/build/contactdpo.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 67 additions & 0 deletions admin/tool/dataprivacy/amd/src/contactdpo.js
@@ -0,0 +1,67 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Javascript module for contacting the site DPO
*
* @module tool_dataprivacy/contactdpo
* @package tool_dataprivacy
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

import ModalForm from 'core_form/modalform';
import Notification from 'core/notification';
import {get_string as getString} from 'core/str';
import {add as addToast} from 'core/toast';

const SELECTORS = {
CONTACT_DPO: '[data-action="contactdpo"]',
};

/**
* Initialize module
*/
export const init = () => {
const triggerElement = document.querySelector(SELECTORS.CONTACT_DPO);

triggerElement.addEventListener('click', event => {
event.preventDefault();

const modalForm = new ModalForm({
modalConfig: {
title: getString('contactdataprotectionofficer', 'tool_dataprivacy'),
},
formClass: 'tool_dataprivacy\\form\\contactdpo',
saveButtonText: getString('send', 'tool_dataprivacy'),
returnFocus: triggerElement,
});

// Show a toast notification when the form is submitted.
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {
if (event.detail.result) {
getString('requestsubmitted', 'tool_dataprivacy').then(addToast).catch();
} else {
const warningMessages = event.detail.warnings.map(warning => warning.message);
Notification.addNotification({
type: 'error',
message: warningMessages.join('<br>')
});
}
});

modalForm.show();
});
};
3 changes: 2 additions & 1 deletion admin/tool/dataprivacy/classes/external.php
Expand Up @@ -212,7 +212,8 @@ public static function contact_dpo($message) {
$warnings[] = [
'item' => $dpo->id,
'warningcode' => 'errorsendingtodpo',
'message' => get_string('errorsendingmessagetodpo', 'tool_dataprivacy')
'message' => get_string('errorsendingmessagetodpo', 'tool_dataprivacy',
fullname($dpo))
];
}
}
Expand Down
100 changes: 100 additions & 0 deletions admin/tool/dataprivacy/classes/form/contactdpo.php
@@ -0,0 +1,100 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.


namespace tool_dataprivacy\form;

use context;
use context_user;
use moodle_exception;
use moodle_url;
use core_form\dynamic_form;
use tool_dataprivacy\api;
use tool_dataprivacy\external;

/**
* Contact DPO modal form
*
* @package tool_dataprivacy
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class contactdpo extends dynamic_form {

/**
* Form definition
*/
protected function definition() {
global $USER;

$mform = $this->_form;

$mform->addElement('static', 'replyto', get_string('replyto', 'tool_dataprivacy'), s($USER->email));

$mform->addElement('textarea', 'message', get_string('message', 'tool_dataprivacy'), 'cols="60" rows="8"');
$mform->setType('message', PARAM_TEXT);
$mform->addRule('message', get_string('required'), 'required', null, 'client');
}

/**
* Return form context
*
* @return context
*/
protected function get_context_for_dynamic_submission(): context {
global $USER;

return context_user::instance($USER->id);
}

/**
* Check if current user has access to this form, otherwise throw exception
*
* @throws moodle_exception
*/
protected function check_access_for_dynamic_submission(): void {
if (!api::can_contact_dpo()) {
throw new moodle_exception('errorcontactdpodisabled', 'tool_dataprivacy');
}
}

/**
* Process the form submission, used if form was submitted via AJAX
*
* @return array
*/
public function process_dynamic_submission() {
return external::contact_dpo($this->get_data()->message);
}

/**
* Load in existing data as form defaults (not applicable)
*/
public function set_data_for_dynamic_submission(): void {
return;
}

/**
* Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
*
* @return moodle_url
*/
protected function get_page_url_for_dynamic_submission(): moodle_url {
global $USER;

return new moodle_url('/user/profile.php', ['id' => $USER->id]);
}
}
5 changes: 1 addition & 4 deletions admin/tool/dataprivacy/classes/output/renderer.php
Expand Up @@ -55,14 +55,11 @@ public function render_my_data_requests_page(my_data_requests_page $page) {
/**
* Render the contact DPO link.
*
* @param string $replytoemail The Reply-to email address
* @return string The HTML for the link.
* @throws coding_exception
*/
public function render_contact_dpo_link($replytoemail) {
public function render_contact_dpo_link() {
$params = [
'data-action' => 'contactdpo',
'data-replytoemail' => $replytoemail,
];
return html_writer::link('#', get_string('contactdataprotectionofficer', 'tool_dataprivacy'), $params);
}
Expand Down
1 change: 1 addition & 0 deletions admin/tool/dataprivacy/lang/en/tool_dataprivacy.php
Expand Up @@ -135,6 +135,7 @@
$string['emailsalutation'] = 'Dear {$a},';
$string['errorcannotrequestdeleteforself'] = 'You don\'t have permission to create deletion request for yourself.';
$string['errorcannotrequestdeleteforother'] = 'You don\'t have permission to create deletion request for this user.';
$string['errorcontactdpodisabled'] = 'Contacting the privacy officer is disabled';
$string['errorinvalidrequestcomments'] = 'The comments field may contain plain text only.';
$string['errorinvalidrequestcreationmethod'] = 'Invalid request creation method!';
$string['errorinvalidrequeststatus'] = 'Invalid request status!';
Expand Down
6 changes: 4 additions & 2 deletions admin/tool/dataprivacy/lib.php
Expand Up @@ -54,10 +54,12 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser
// Contact data protection officer link.
if (\tool_dataprivacy\api::can_contact_dpo() && $iscurrentuser) {
$renderer = $PAGE->get_renderer('tool_dataprivacy');
$content = $renderer->render_contact_dpo_link($USER->email);
$content = $renderer->render_contact_dpo_link();
$node = new core_user\output\myprofile\node('privacyandpolicies', 'contactdpo', null, null, null, $content);
$category->add_node($node);
$PAGE->requires->js_call_amd('tool_dataprivacy/myrequestactions', 'init');

// Require our Javascript module to handle contact DPO interaction.
$PAGE->requires->js_call_amd('tool_dataprivacy/contactdpo', 'init');

$url = new moodle_url('/admin/tool/dataprivacy/mydatarequests.php');
$node = new core_user\output\myprofile\node('privacyandpolicies', 'datarequests',
Expand Down
58 changes: 0 additions & 58 deletions admin/tool/dataprivacy/templates/contact_dpo.mustache

This file was deleted.

Expand Up @@ -8,19 +8,21 @@ Feature: Contact the privacy officer
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | s1@example.com |
And I log in as "admin"
And I set the following administration settings values:
| contactdataprotectionofficer | 1 |
And I log out

@javascript
Scenario: Contacting the privacy officer
Given I log in as "student1"
Given the following config values are set as admin:
| contactdataprotectionofficer | 1 | tool_dataprivacy |
When I log in as "student1"
And I follow "Profile" in the user menu
And I should see "Contact the privacy officer"
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"
Then I should see "Your request has been submitted to the privacy officer"
And I click on "Data requests" "link"
And I should see "Hello DPO!" in the "General inquiry" "table_row"

Scenario: Contacting the privacy officer when not enabled
When I log in as "student1"
And I follow "Profile" in the user menu
Then "Contact the privacy officer" "link" should not exist

0 comments on commit 2eee07d

Please sign in to comment.