MDL-64054 message: add all processors to message settings

Changed the settings page in the message drawer to display all message
notification processors (e.g. email, mobile, jabber) for the user to
configure based on which processors are enabled on the site.
This commit is contained in:
Ryan Wyllie 2018-11-19 14:30:23 +08:00
parent 01acb1ea90
commit 08ae9a7362
11 changed files with 418 additions and 140 deletions

View File

@ -1278,6 +1278,7 @@ $functions = array(
'type' => 'read',
'capabilities' => 'moodle/user:editownmessageprofile',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
'ajax' => true
),
'core_message_set_favourite_conversations' => array(
'classname' => 'core_message_external',

View File

@ -1 +1 @@
define(["jquery","core/notification","core/str","core/pubsub","core_message/message_repository","core/custom_interaction_events","core_message/message_drawer_events"],function(a,b,c,d,e,f,g){var h={SETTINGS:'[data-region="settings"]',PREFERENCE_CONTROL:'[data-region="preference-control"]',PRIVACY_PREFERENCE:'[data-preference="blocknoncontacts"] input[type="radio"]',EMAIL_ENABLED_PREFERENCE:'[data-preference="emailnotifications"] input[type="checkbox"]',ENTER_TO_SEND_PREFERENCE:'[data-preference="entertosend"] input[type="checkbox"]'},i={message_provider_moodle_instantmessage_loggedoff:{type:"emailnotifications",enabled:"email",disabled:"none"},message_provider_moodle_instantmessage_loggedin:{type:"emailnotifications",enabled:"email",disabled:"none"}},j=function(c,j){var k=c.find(h.SETTINGS);f.define(k,[f.events.activate]),k.on(f.events.activate,h.EMAIL_ENABLED_PREFERENCE,function(c){var f=a(c.target),k=f.closest(h.PREFERENCE_CONTROL),l=k.attr("data-preference"),m=f.prop("checked"),n=Object.keys(i).reduce(function(a,b){var c=i[b];return c.type===l&&a.push({type:b,value:m?c.enabled:c.disabled}),a},[]);e.savePreferences(j,n).then(function(){d.publish(g.PREFERENCES_UPDATED,n)})["catch"](b.exception)}),k.on(f.events.activate,h.PRIVACY_PREFERENCE,function(c){var f=a(c.target).val(),h=[{type:"message_blocknoncontacts",value:f}];e.savePreferences(j,h).then(function(){d.publish(g.PREFERENCES_UPDATED,h)})["catch"](b.exception)}),k.on(f.events.activate,h.ENTER_TO_SEND_PREFERENCE,function(c){var f=a(c.target).prop("checked"),h=[{type:"message_entertosend",value:f}];e.savePreferences(j,h).then(function(){d.publish(g.PREFERENCES_UPDATED,h)})["catch"](b.exception)})},k=function(b,c,d){return c.attr("data-init")||(j(c,d),c.attr("data-init",!0)),a.Deferred().resolve().promise()},l=function(){return c.get_string("messagedrawerviewsettings","core_message")};return{show:k,description:l}});
define(["jquery","core/notification","core/str","core/pubsub","core/templates","core_message/message_repository","core/custom_interaction_events","core_message/message_drawer_events"],function(a,b,c,d,e,f,g,h){var i={CHECKBOX:'input[type="checkbox"]',SETTINGS:'[data-region="settings"]',PRIVACY_PREFERENCE:'[data-preference="blocknoncontacts"] input[type="radio"]',NOTIFICATIONS_PREFERENCE:'[data-preference="notifications"] input[type="checkbox"]',ENTER_TO_SEND_PREFERENCE:'[data-preference="entertosend"] input[type="checkbox"]',NOTIFICATION_PREFERENCES_CONTAINER:'[data-region="notification-preference-container"]',CONTENT_CONTAINER:'[data-region="content-container"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]'},j={NOTIFICATION_PREFERENCES:"core_message/message_drawer_view_settings_body_content_notification_preferences"},k="message_provider_moodle_instantmessage",l=function(b,c){var d=b.find(i.PRIVACY_PREFERENCE);d.each(function(b,d){d=a(d),d.val()==c?d.prop("checked",!0):d.prop("checked",!1)})},m=function(a,b){var c=a.find(i.ENTER_TO_SEND_PREFERENCE);b?c.prop("checked",!0):c.prop("checked",!1)},n=function(a,c){return f.savePreferences(a,c).then(function(){d.publish(h.PREFERENCES_UPDATED,c)})["catch"](b.exception)},o=function(b,c){var d=b.find(i.SETTINGS);g.define(d,[g.events.activate]),d.on(g.events.activate,i.NOTIFICATIONS_PREFERENCE,function(b){var d=a(b.target).closest(i.NOTIFICATION_PREFERENCES_CONTAINER),e=d.find(i.CHECKBOX);if(e.length){var f=e.toArray().reduce(function(b,c){return c=a(c),c.prop("checked")&&b.push(c.attr("data-name")),b},[]),g=f.length?f.join(","):"none",h=[{type:"message_provider_moodle_instantmessage_loggedoff",value:g},{type:"message_provider_moodle_instantmessage_loggedin",value:g}];n(c,h)}}),d.on(g.events.activate,i.PRIVACY_PREFERENCE,function(b){var d=a(b.target).val(),e=[{type:"message_blocknoncontacts",value:d}];n(c,e)}),d.on(g.events.activate,i.ENTER_TO_SEND_PREFERENCE,function(b){var d=a(b.target).prop("checked"),e=[{type:"message_entertosend",value:d}];n(c,e)})},p=function(a,c){f.getUserMessagePreferences(c).then(function(b){l(a,b.blocknoncontacts),m(a,b.entertosend);var c=[];b.preferences.components.length&&b.preferences.components.forEach(function(a){if(a.notifications.length){var b=a.notifications.filter(function(a){return a.preferencekey==k});if(b.length){var d=a.notifications[0];c=d.processors.map(function(a){var b=a.loggedin.checked||a.loggedoff.checked;return{displayname:a.displayname,name:a.name,checked:b,locked:a.locked,lockedmessage:a.lockedmessage||null}})}}});var d=a.find(i.NOTIFICATION_PREFERENCES_CONTAINER);return!c.length||(d.removeClass("hidden"),e.render(j.NOTIFICATION_PREFERENCES,{processors:c}).then(function(a){return d.append(a),a}))}).then(function(){a.find(i.CONTENT_CONTAINER).removeClass("hidden"),a.find(i.PLACEHOLDER_CONTAINER).addClass("hidden"),o(a,c)})["catch"](b.exception)},q=function(b,c,d){return c.attr("data-init")||(p(c,d),c.attr("data-init",!0)),a.Deferred().resolve().promise()},r=function(){return c.get_string("messagedrawerviewsettings","core_message")};return{show:q,description:r}});

File diff suppressed because one or more lines are too long

View File

@ -26,6 +26,7 @@ define(
'core/notification',
'core/str',
'core/pubsub',
'core/templates',
'core_message/message_repository',
'core/custom_interaction_events',
'core_message/message_drawer_events'
@ -35,32 +36,81 @@ function(
Notification,
Str,
PubSub,
Templates,
Repository,
CustomEvents,
MessageDrawerEvents
) {
var SELECTORS = {
CHECKBOX: 'input[type="checkbox"]',
SETTINGS: '[data-region="settings"]',
PREFERENCE_CONTROL: '[data-region="preference-control"]',
PRIVACY_PREFERENCE: '[data-preference="blocknoncontacts"] input[type="radio"]',
EMAIL_ENABLED_PREFERENCE: '[data-preference="emailnotifications"] input[type="checkbox"]',
NOTIFICATIONS_PREFERENCE: '[data-preference="notifications"] input[type="checkbox"]',
ENTER_TO_SEND_PREFERENCE: '[data-preference="entertosend"] input[type="checkbox"]',
NOTIFICATION_PREFERENCES_CONTAINER: '[data-region="notification-preference-container"]',
CONTENT_CONTAINER: '[data-region="content-container"]',
PLACEHOLDER_CONTAINER: '[data-region="placeholder-container"]'
};
var PREFERENCES_EMAIL = {
'message_provider_moodle_instantmessage_loggedoff': {
type: 'emailnotifications',
enabled: 'email',
disabled: 'none'
},
'message_provider_moodle_instantmessage_loggedin': {
type: 'emailnotifications',
enabled: 'email',
disabled: 'none'
var TEMPLATES = {
NOTIFICATION_PREFERENCES: 'core_message/message_drawer_view_settings_body_content_notification_preferences'
};
var NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage';
/**
* Select the correct radio button in the DOM for the privacy preference.
*
* @param {Object} body The settings body element.
* @param {Number} value Which radio button should be set
*/
var setPrivacyPreference = function(body, value) {
var inputs = body.find(SELECTORS.PRIVACY_PREFERENCE);
inputs.each(function(index, input) {
input = $(input);
if (input.val() == value) {
input.prop('checked', true);
} else {
input.prop('checked', false);
}
});
};
/**
* Set the "enter to send" checkbox to the correct value in the DOM.
*
* @param {Object} body The settings body element.
* @param {Bool} value Whether enter to send is enabled or disabled.
*/
var setEnterToSend = function(body, value) {
var checkbox = body.find(SELECTORS.ENTER_TO_SEND_PREFERENCE);
if (value) {
checkbox.prop('checked', true);
} else {
checkbox.prop('checked', false);
}
};
/**
* Send a request to the server to save the given preferences. Also publish
* a preferences updated event for the rest of the message drawer to
* subscribe to.
*
* @param {Number} loggedInUserId The logged in user id.
* @param {Array} preferences The preferences to set.
* @return {Object} jQuery promise
*/
var savePreferences = function(loggedInUserId, preferences) {
return Repository.savePreferences(loggedInUserId, preferences)
.then(function() {
PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);
return;
})
.catch(Notification.exception);
};
/**
* Create all of the event listeners for the message preferences page.
*
@ -75,68 +125,139 @@ function(
CustomEvents.events.activate
]);
settingsContainer.on(CustomEvents.events.activate, SELECTORS.EMAIL_ENABLED_PREFERENCE, function(e) {
var checkbox = $(e.target);
var setting = checkbox.closest(SELECTORS.PREFERENCE_CONTROL);
var type = setting.attr('data-preference');
var isEnabled = checkbox.prop('checked');
var preferences = Object.keys(PREFERENCES_EMAIL).reduce(function(carry, preference) {
var config = PREFERENCES_EMAIL[preference];
if (config.type === type) {
carry.push({
type: preference,
value: isEnabled ? config.enabled : config.disabled
});
}
return carry;
}, []);
Repository.savePreferences(loggedInUserId, preferences)
.then(function() {
PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);
return;
})
.catch(Notification.exception);
settingsContainer.on(CustomEvents.events.activate, SELECTORS.NOTIFICATIONS_PREFERENCE, function(e) {
var container = $(e.target).closest(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);
var checkboxes = container.find(SELECTORS.CHECKBOX);
if (!checkboxes.length) {
return;
}
);
// The preference value is all of the enabled processors, comma separated, so let's
// see which ones are enabled.
var values = checkboxes.toArray().reduce(function(carry, checkbox) {
checkbox = $(checkbox);
if (checkbox.prop('checked')) {
carry.push(checkbox.attr('data-name'));
}
return carry;
}, []);
var newValue = values.length ? values.join(',') : 'none';
var preferences = [
{
type: 'message_provider_moodle_instantmessage_loggedoff',
value: newValue
},
{
type: 'message_provider_moodle_instantmessage_loggedin',
value: newValue
}
];
savePreferences(loggedInUserId, preferences);
});
settingsContainer.on(CustomEvents.events.activate, SELECTORS.PRIVACY_PREFERENCE, function(e) {
var newValue = $(e.target).val();
var preferences = [
{
type: 'message_blocknoncontacts',
value: newValue
}
];
var newValue = $(e.target).val();
var preferences = [
{
type: 'message_blocknoncontacts',
value: newValue
}
];
Repository.savePreferences(loggedInUserId, preferences)
.then(function() {
PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);
return;
})
.catch(Notification.exception);
}
);
savePreferences(loggedInUserId, preferences);
});
settingsContainer.on(CustomEvents.events.activate, SELECTORS.ENTER_TO_SEND_PREFERENCE, function(e) {
var newValue = $(e.target).prop('checked');
var preferences = [
{
type: 'message_entertosend',
value: newValue
}
];
var newValue = $(e.target).prop('checked');
var preferences = [
{
type: 'message_entertosend',
value: newValue
}
];
Repository.savePreferences(loggedInUserId, preferences)
.then(function() {
PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);
return;
})
.catch(Notification.exception);
}
);
savePreferences(loggedInUserId, preferences);
});
};
/**
* Initialise the module by loading the user's messaging preferences from the server and
* rendering them in the settings page.
*
* Moodle may have many (or no) message processors enabled to notify the user when they
* receive messages. We need to dynamically build the settings page based on which processors
* are configured for the user.
*
* @param {Object} body The settings body element.
* @param {Number} loggedInUserId The logged in user id.
*/
var init = function(body, loggedInUserId) {
// Load the message preferences from the server.
Repository.getUserMessagePreferences(loggedInUserId)
.then(function(response) {
// Set the values of the stright forward preferences.
setPrivacyPreference(body, response.blocknoncontacts);
setEnterToSend(body, response.entertosend);
// Parse the list of other preferences into a more usable format.
var notificationProcessors = [];
if (response.preferences.components.length) {
response.preferences.components.forEach(function(component) {
if (component.notifications.length) {
// Filter down to just the notification processors that work on instant
// messaging. We don't care about another other ones.
var notificationPreferences = component.notifications.filter(function(notification) {
return notification.preferencekey == NOTIFICATION_PREFERENCES_KEY;
});
if (notificationPreferences.length) {
// Messaging only has one config at the moment which is for notifications
// on personal messages.
var configuration = component.notifications[0];
notificationProcessors = configuration.processors.map(function(processor) {
// Consider the the processor enabled if either preference is set. This is
// for backwards compatibility. Going forward they will be treated as one
// setting.
var checked = processor.loggedin.checked || processor.loggedoff.checked;
return {
displayname: processor.displayname,
name: processor.name,
checked: checked,
// The admin can force processors to be enabled at a site level so
// we need to check if this processor has been locked by the admin.
locked: processor.locked,
lockedmessage: processor.lockedmessage || null,
};
});
}
}
});
}
var container = body.find(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);
if (notificationProcessors.length) {
// We have processors (i.e. email, mobile, jabber) to show.
container.removeClass('hidden');
// Render the processor options.
return Templates.render(TEMPLATES.NOTIFICATION_PREFERENCES, {processors: notificationProcessors})
.then(function(html) {
container.append(html);
return html;
});
} else {
return true;
}
})
.then(function() {
// We're done loading so hide the loading placeholder and show the settings.
body.find(SELECTORS.CONTENT_CONTAINER).removeClass('hidden');
body.find(SELECTORS.PLACEHOLDER_CONTAINER).addClass('hidden');
// Register the event listers for if the user wants to change the preferences.
registerEventListeners(body, loggedInUserId);
return;
})
.catch(Notification.exception);
};
/**
@ -150,7 +271,7 @@ function(
*/
var show = function(header, body, loggedInUserId) {
if (!body.attr('data-init')) {
registerEventListeners(body, loggedInUserId);
init(body, loggedInUserId);
body.attr('data-init', true);
}

View File

@ -954,6 +954,22 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat
return Ajax.call([request])[0];
};
/**
* Get the user's message preferences.
*
* @param {int} userId The user id to load preferences for
* @return {object} jQuery promise
*/
var getUserMessagePreferences = function(userId) {
var request = {
methodname: 'core_message_get_user_message_preferences',
args: {
userid: userId
}
};
return Ajax.call([request])[0];
};
return {
query: query,
countUnreadConversations: countUnreadConversations,
@ -985,6 +1001,7 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat
setFavouriteConversations: setFavouriteConversations,
unsetFavouriteConversations: unsetFavouriteConversations,
getMemberInfo: getMemberInfo,
markAllConversationMessagesAsRead: markAllConversationMessagesAsRead
markAllConversationMessagesAsRead: markAllConversationMessagesAsRead,
getUserMessagePreferences: getUserMessagePreferences
};
});

View File

@ -3917,6 +3917,8 @@ class core_message_external extends external_api {
'displayname' => new external_value(PARAM_TEXT, 'Display name'),
'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
'lockedmessage' => new external_value(PARAM_TEXT,
'Text to display if locked', VALUE_OPTIONAL),
'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
'loggedin' => new external_single_structure(
array(
@ -4066,6 +4068,7 @@ class core_message_external extends external_api {
'warnings' => array(),
'preferences' => $notificationlistoutput->export_for_template($renderer),
'blocknoncontacts' => \core_message\api::get_user_privacy_messaging_preference($user->id),
'entertosend' => get_user_preferences('message_entertosend', false, $user)
);
return $result;
}
@ -4081,6 +4084,7 @@ class core_message_external extends external_api {
array(
'preferences' => self::get_preferences_structure(),
'blocknoncontacts' => new external_value(PARAM_INT, 'Privacy messaging setting to define who can message you'),
'entertosend' => new external_value(PARAM_BOOL, 'User preference for using enter to send messages'),
'warnings' => new external_warnings(),
)
);

View File

@ -837,31 +837,22 @@ function core_message_standard_after_main_region_html() {
$requestcount = \core_message\api::count_received_contact_requests($USER);
$contactscount = \core_message\api::count_contacts($USER->id);
// Get the privacy settings options for being messaged.
$privacysetting = \core_message\api::get_user_privacy_messaging_preference($USER->id);
$choices = [];
$choices[] = [
'value' => \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
'text' => get_string('contactableprivacy_onlycontacts', 'message'),
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS)
'text' => get_string('contactableprivacy_onlycontacts', 'message')
];
$choices[] = [
'value' => \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
'text' => get_string('contactableprivacy_coursemember', 'message'),
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER)
'text' => get_string('contactableprivacy_coursemember', 'message')
];
if (!empty($CFG->messagingallusers)) {
// Add the MESSAGE_PRIVACY_SITE option when site-wide messaging between users is enabled.
$choices[] = [
'value' => \core_message\api::MESSAGE_PRIVACY_SITE,
'text' => get_string('contactableprivacy_site', 'message'),
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_SITE)
'text' => get_string('contactableprivacy_site', 'message')
];
}
// Email settings.
$emailloggedin = get_user_preferences('message_provider_moodle_instantmessage_loggedin', 'none', $USER);
$emailloggedoff = get_user_preferences('message_provider_moodle_instantmessage_loggedoff', 'none', $USER);
$emailenabled = $emailloggedin == 'email' || $emailloggedoff == 'email';
// Enter to send.
$entertosend = get_user_preferences('message_entertosend', false, $USER);
@ -908,7 +899,6 @@ function core_message_standard_after_main_region_html() {
],
'settings' => [
'privacy' => $choices,
'emailenabled' => $emailenabled,
'entertosend' => $entertosend
]
]);

View File

@ -35,61 +35,10 @@
}}
<div class="h-100 hidden bg-white" aria-hidden="true" data-region="view-settings">
{{#settings}}
<div data-region="settings" class="p-3">
<h3 class="h6 font-weight-bold">{{#str}}privacy, message{{/str}}</h3>
<p>{{#str}}privacy_desc, message{{/str}}</p>
<div
data-region="preference-control"
data-preference="blocknoncontacts"
class="mb-3"
>
{{#privacy}}
<div class="custom-control custom-radio mb-2">
<input
type="radio"
name="message_blocknoncontacts"
class="custom-control-input"
id="block-noncontacts-{{uniqid}}-{{value}}"
value="{{value}}"
{{#checked}}checked{{/checked}}
>
<label class="custom-control-label ml-2" for="block-noncontacts-{{uniqid}}-{{value}}">
{{text}}
</label>
</div>
{{/privacy}}
</div>
<h3 class="mb-2 mt-4 h6 font-weight-bold">{{#str}}categoryemail, admin{{/str}}</h3>
<div
data-region="preference-control"
data-preference="emailnotifications"
>
<span class="switch">
<input type="checkbox"
id="email-alerts-{{uniqid}}"
{{#emailenabled}}checked{{/emailenabled}}
>
<label for="email-alerts-{{uniqid}}">
{{#str}} emailalert, hub {{/str}}
</label>
</span>
</div>
<h3 class="mb-2 mt-4 h6 font-weight-bold">{{#str}} general, core {{/str}}</h3>
<div
data-region="preference-control"
data-preference="entertosend"
>
<span class="switch">
<input type="checkbox"
id="enter-to-send-{{uniqid}}"
{{#entertosend}}checked{{/entertosend}}
>
<label for="enter-to-send-{{uniqid}}">
{{#str}} useentertosend, core_message {{/str}}
</label>
</span>
</div>
<div class="hidden" data-region="content-container">
{{> core_message/message_drawer_view_settings_body_content }}
</div>
<div data-region="placeholder-container">
{{> core_message/message_drawer_view_settings_body_placeholder }}
</div>
{{/settings}}
</div>

View File

@ -0,0 +1,75 @@
{{!
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 core_message/message_drawer_view_settings_body_content
This template will render the content for the body of the settings page in the message drawer.
Classes required for JS:
* none
Data attributes required for JS:
* All data attributes are required
Context variables required for this template:
* userid The logged in user id
* urls The URLs for the popover
Example context (json):
{}
}}
{{#settings}}
<div data-region="settings" class="p-3">
<h3 class="h6 font-weight-bold">{{#str}} privacy, message {{/str}}</h3>
<p>{{#str}} privacy_desc, message {{/str}}</p>
<div data-preference="blocknoncontacts" class="mb-3">
{{#privacy}}
<div class="custom-control custom-radio mb-2">
<input
type="radio"
name="message_blocknoncontacts"
class="custom-control-input"
id="block-noncontacts-{{uniqid}}-{{value}}"
value="{{value}}"
>
<label class="custom-control-label ml-2" for="block-noncontacts-{{uniqid}}-{{value}}">
{{text}}
</label>
</div>
{{/privacy}}
</div>
<div class="hidden" data-region="notification-preference-container">
<h3 class="mb-2 mt-4 h6 font-weight-bold">{{#str}} notificationpreferences, core_message {{/str}}</h3>
</div>
<h3 class="mb-2 mt-4 h6 font-weight-bold">{{#str}} general, core {{/str}}</h3>
<div data-preference="entertosend">
<span class="switch">
<input type="checkbox"
id="enter-to-send-{{uniqid}}"
{{#entertosend}}checked{{/entertosend}}
>
<label for="enter-to-send-{{uniqid}}">
{{#str}} useentertosend, core_message {{/str}}
</label>
</span>
</div>
</div>
{{/settings}}

View File

@ -0,0 +1,49 @@
{{!
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 core_message/message_drawer_view_settings_body_content_notification_preferences
This template will render the notification perferences for the message settings..
Classes required for JS:
* none
Data attributes required for JS:
* All data attributes are required
Context variables required for this template:
* userid The logged in user id
* urls The URLs for the popover
Example context (json):
{}
}}
<div data-preference="notifications" class="d-flex flex-column">
{{#processors}}
<span class="switch">
<input type="checkbox"
id="{{name}}-{{uniqid}}"
data-name="{{name}}"
{{#checked}}checked{{/checked}}
{{#locked}}disabled{{/locked}}
>
<label for="{{name}}-{{uniqid}}">{{displayname}}{{#locked}} ({{lockedmessage}}){{/locked}}</label>
</span>
{{/processors}}
</div>

View File

@ -0,0 +1,72 @@
{{!
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 core_message/message_drawer_view_settings_body_placeholder
This template will render the body of the settings page in the message drawer.
Classes required for JS:
* none
Data attributes required for JS:
* All data attributes are required
Context variables required for this template:
* userid The logged in user id
* urls The URLs for the popover
Example context (json):
{}
}}
<div class="d-flex flex-column p-3">
<div class="w-25 bg-pulse-grey h6" style="height: 18px"></div>
<div class="w-75 bg-pulse-grey mb-4" style="height: 18px"></div>
<div class="mb-3">
<div class="w-100 d-flex mb-3">
<div class="bg-pulse-grey rounded-circle" style="width: 18px; height: 18px"></div>
<div class="bg-pulse-grey w-50 ml-2" style="height: 18px"></div>
</div>
<div class="w-100 d-flex mb-3">
<div class="bg-pulse-grey rounded-circle" style="width: 18px; height: 18px"></div>
<div class="bg-pulse-grey w-50 ml-2" style="height: 18px"></div>
</div>
<div class="w-100 d-flex mb-3">
<div class="bg-pulse-grey rounded-circle" style="width: 18px; height: 18px"></div>
<div class="bg-pulse-grey w-50 ml-2" style="height: 18px"></div>
</div>
</div>
<div class="w-50 bg-pulse-grey h6 mb-3 mt-2" style="height: 18px"></div>
<div class="mb-4">
<div class="w-100 d-flex mb-2 align-items-center">
<div class="bg-pulse-grey w-25" style="width: 18px; height: 27px"></div>
<div class="bg-pulse-grey w-25 ml-2" style="height: 18px"></div>
</div>
<div class="w-100 d-flex mb-2 align-items-center">
<div class="bg-pulse-grey w-25" style="width: 18px; height: 27px"></div>
<div class="bg-pulse-grey w-25 ml-2" style="height: 18px"></div>
</div>
</div>
<div class="w-25 bg-pulse-grey h6 mb-3 mt-2" style="height: 18px"></div>
<div class="mb-3">
<div class="w-100 d-flex mb-2 align-items-center">
<div class="bg-pulse-grey w-25" style="width: 18px; height: 27px"></div>
<div class="bg-pulse-grey w-50 ml-2" style="height: 18px"></div>
</div>
</div>
</div>