MDL-71610 theme_boost: add a edit mode switch

This commit is contained in:
Bas Brands
2021-09-29 09:25:36 +02:00
parent 214adb7984
commit 09f6ce9fed
12 changed files with 373 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
<?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/>.
/**
* Set Mode.
*
* @package core
* @copyright 2021 Andrew Lyons
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('config.php');
$setmode = optional_param('setmode', false, PARAM_BOOL);
$contextid = required_param('context', PARAM_INT);
$pageurl = required_param('pageurl', PARAM_LOCALURL);
require_sesskey();
require_login();
$context = \context_helper::instance_by_id($contextid);
$PAGE->set_context($context);
if ($context->id === \context_user::instance($USER->id)->id) {
$PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
}
if ($PAGE->user_allowed_editing()) {
$USER->editing = $setmode;
} else {
\core\notification::add(get_string('cannotswitcheditmodeon', 'error'), \core\notification::ERROR);
}
redirect($pageurl);
+1
View File
@@ -152,6 +152,7 @@ $string['cannotsetupblock'] = 'Blocks tables could NOT be set up successfully!';
$string['cannotsetupcapformod'] = 'Could not set up the capabilities for {$a}';
$string['cannotsetupcapforplugin'] = 'Could not set up the capabilities for {$a}';
$string['cannotshowhidecoursesincategory'] = 'Cannot show/hide the courses in category {$a}.';
$string['cannotswitcheditmodeon'] = 'Could not switch edit mode on';
$string['cannotsignup'] = 'You cannot create a new account because you are already logged in as {$a}.';
$string['cannotunassigncap'] = 'Could not unassign deprecated capability {$a->cap} from role {$a->role}';
$string['cannotunassignrolefrom'] = 'Cannot unassign this user from role id: {$a}';
+2
View File
@@ -579,6 +579,7 @@ $string['editfiles'] = 'Edit files';
$string['editgroupprofile'] = 'Edit group profile';
$string['editinga'] = 'Editing {$a}';
$string['editingteachershort'] = 'Editor';
$string['editmode'] = 'Edit mode';
$string['editlock'] = 'This value cannot be edited!';
$string['editmyprofile'] = 'Edit profile';
$string['editorbgcolor'] = 'Background-color';
@@ -1901,6 +1902,7 @@ $string['serverlocaltime'] = 'Server\'s local time';
$string['sessionforceclean'] = 'As a security precaution, user-generated scripts have been disabled within this session.';
$string['sessiontimeoutsoon'] = 'Your session is about to time out. Do you want to extend your current session?';
$string['setcategorytheme'] = 'Set category theme';
$string['setmode'] = 'Set mode';
$string['setpassword'] = 'Set password';
$string['setpasswordinstructions'] = 'Please enter your new password below, then save changes.';
$string['settings'] = 'Settings';
+2
View File
@@ -0,0 +1,2 @@
define ("core/edit_switch",["exports","core/ajax","core/event_dispatcher","core/notification"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=a.eventTypes=void 0;var e=function(a,c){return(0,b.call)([{methodname:"core_change_editmode",args:{context:a,setmode:c}}])[0]},f=function(a){if(a.checked){a.setAttribute("aria-checked",!0)}else{a.setAttribute("aria-checked",!1)}var b=h(a,a.checked);if(!b.defaultPrevented){window.location=a.dataset.pageurl}},g={editModeSet:"core/edit_switch/editModeSet"};a.eventTypes=g;var h=function(a,b){return(0,c.dispatchEvent)(g.editModeSet,{editMode:b},a,{cancelable:!0})};a.init=function init(a){var b=document.getElementById(a);b.addEventListener("change",function(){e(b.dataset.context,b.checked).then(function(a){if(a.success){f(b)}else{b.checked=!1}}).catch(d.exception)})}});
//# sourceMappingURL=edit_switch.min.js.map
File diff suppressed because one or more lines are too long
+121
View File
@@ -0,0 +1,121 @@
// 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/>.
/**
* Controls the edit switch.
*
* @module core/edit_switch
* @copyright 2021 Bas Brands <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {call as fetchMany} from 'core/ajax';
import {dispatchEvent} from 'core/event_dispatcher';
import {exception as displayException} from 'core/notification';
/**
* Change the Edit mode.
*
* @param {number} context The contextid that editing is being set for
* @param {bool} setmode Whether editing is set or not
* @return {Promise} Resolved with an array file the stored file url.
*/
const setEditMode = (context, setmode) => fetchMany([{
methodname: 'core_change_editmode',
args: {
context,
setmode,
},
}])[0];
/**
* Toggle the edit switch
*
* @method
* @protected
* @param {HTMLElement} editSwitch
*/
const toggleEditSwitch = editSwitch => {
if (editSwitch.checked) {
editSwitch.setAttribute('aria-checked', true);
} else {
editSwitch.setAttribute('aria-checked', false);
}
const event = notifyEditModeSet(editSwitch, editSwitch.checked);
if (!event.defaultPrevented) {
window.location = editSwitch.dataset.pageurl;
}
};
/**
* Names of events for core/edit_switch.
*
* @static
* @property {String} editModeSet See {@link event:core/edit_switch/editModeSet}
*/
export const eventTypes = {
/**
* An event triggered when the edit mode toggled.
*
* @event core/edit_switch/editModeSet
* @type {CustomEvent}
* @property {HTMLElement} target The switch used to toggle the edit mode
* @property {object} detail
* @property {bool} detail.editMode
*/
editModeSet: 'core/edit_switch/editModeSet',
};
/**
* Dispatch the editModeSet event after changing the edit mode.
*
* This event is cancelable.
*
* The default action is to reload the page after toggling the edit mode.
*
* @method
* @protected
* @param {HTMLElement} container
* @param {bool} editMode
* @returns {CustomEvent}
*/
const notifyEditModeSet = (container, editMode) => dispatchEvent(
eventTypes.editModeSet,
{editMode},
container,
{cancelable: true}
);
/**
* Add the eventlistener for the editswitch.
*
* @param {string} editingSwitchId The id of the editing switch to listen for
*/
export const init = editingSwitchId => {
const editSwitch = document.getElementById(editingSwitchId);
editSwitch.addEventListener('change', () => {
setEditMode(editSwitch.dataset.context, editSwitch.checked)
.then(result => {
if (result.success) {
toggleEditSwitch(editSwitch);
} else {
editSwitch.checked = false;
}
return;
})
.catch(displayException);
});
};
+103
View File
@@ -0,0 +1,103 @@
<?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/>.
/**
* A web service to load the mapping of moodle pix names to fontawesome icon names.
*
* @package core
* @category external
* @copyright 2021 Bas Brands <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\external;
use external_api;
use external_function_parameters;
use external_single_structure;
use external_value;
/**
* Web service to change the edit mode.
*
* @package core
* @copyright 2021 Bas Brands <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class editmode extends external_api {
/**
* Description of the parameters suitable for the `change_editmode` function.
*
* @return external_function_parameters
*/
public static function change_editmode_parameters(): external_function_parameters {
return new external_function_parameters(
[
'setmode' => new external_value(PARAM_BOOL, 'Set edit mode to'),
'context' => new external_value(PARAM_INT, 'Page context id')
]
);
}
/**
* Save the image and return any warnings and the new image url
*
* @param bool $setmode the current edit mode
* @param int $contextid the current page context id
* @return array the new edit mode.
*/
public static function change_editmode(bool $setmode, int $contextid): array {
global $USER, $PAGE;
$params = self::validate_parameters(
self::change_editmode_parameters(),
[
'setmode' => $setmode,
'context' => $contextid
]
);
$context = \context_helper::instance_by_id($params['context']);
self::validate_context($context);
$PAGE->set_context($context);
if ($context->id === \context_user::instance($USER->id)->id) {
$PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
}
$success = false;
if ($PAGE->user_allowed_editing()) {
$USER->editing = $setmode;
$success = true;
}
return ['success' => $success];
}
/**
* Description of the return value for the `change_editmode` function.
*
* @return external_single_structure
*/
public static function change_editmode_returns(): external_single_structure {
$keys = [
'success' => new external_value(PARAM_BOOL, 'The edit mode was changed', VALUE_REQUIRED),
];
return new external_single_structure($keys, 'editmode');
}
}
+7
View File
@@ -2779,6 +2779,13 @@ $functions = array(
'type' => 'write',
'ajax' => true,
],
'core_change_editmode' => [
'classname' => 'core\external\editmode',
'methodname' => 'change_editmode',
'description' => 'Change the editing mode',
'type' => 'write',
'ajax' => true,
],
);
$services = array(
+24
View File
@@ -2748,6 +2748,9 @@ EOD;
*/
public function edit_button(moodle_url $url) {
if ($this->page->theme->haseditswitch == true) {
return;
}
$url->param('sesskey', sesskey());
if ($this->page->user_is_editing()) {
$url->param('edit', 'off');
@@ -2760,6 +2763,27 @@ EOD;
return $this->single_button($url, $editstring);
}
/**
* Create a navbar switch for toggling editing mode.
*
* @return string Html containing the edit switch
*/
public function edit_switch() {
if ($this->page->user_allowed_editing()) {
$temp = (object) [
'legacyseturl' => (new moodle_url('/editmode.php'))->out(false),
'pagecontextid' => $this->page->context->id,
'pageurl' => $this->page->url,
'sesskey' => sesskey(),
];
if ($this->page->user_is_editing()) {
$temp->checked = true;
}
return $this->render_from_template('core/editswitch', $temp);
}
}
/**
* Returns HTML to display a simple button to close a window
*
+63
View File
@@ -0,0 +1,63 @@
{{!
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/>.
}}
{{!
@template theme_boost/editswitch
This template renders the top navbar.
Example context (json):
{
"url": "http://localhost/",
"sesskey": "sesskey",
"edit": 1,
"adminedit": true,
"checked": "",
"string": "Edit on"
}
}}
<form action="{{{legacyseturl}}}" method="post" class="d-flex align-items-center editmode-switch-form">
<div class="custom-control custom-control-right custom-switch text-nowrap">
<input type="checkbox"{{!
}} name="setmode"{{!
}}{{#checked}}{{!
}} aria-checked="true" checked{{!
}}{{/checked}}{{!
}}{{^checked}}{{!
}} aria-checked="false"{{!
}}{{/checked}}{{!
}} class="custom-control-input"{{!
}} id="{{uniqid}}-editingswitch"{{!
}} data-context="{{{pagecontextid}}}"{{!
}} data-pageurl="{{{pageurl}}}"{{!
}}>
<label class="custom-control-label" for="{{uniqid}}-editingswitch">
{{#str}} editmode {{/str}}
</label>
<input type="hidden" name="sesskey" value="{{{sesskey}}}">
<input type="hidden" name="pageurl" value="{{{pageurl}}}">
<input type="hidden" name="context" value="{{{pagecontextid}}}">
<noscript>
<input type="submit" value="{{#str}}setmode, core{{/str}}">
</noscript>
</div>
</form>
{{#js}}
require(['core/edit_switch'], function(editSwitch) {
editSwitch.init('{{uniqid}}-editingswitch');
});
{{/js}}
+1
View File
@@ -73,5 +73,6 @@
{{> core/user_menu }}
{{/usermenu}}
</div>
{{{ output.edit_switch }}}
</div>
</nav>
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2021092400.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2021092400.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0dev (Build: 20210924)'; // Human-friendly version name