Merge branch 'MDL-64054-master' of git://github.com/ryanwyllie/moodle

This commit is contained in:
Damyon Wiese 2018-11-21 10:07:42 +08:00
commit 730284fc16
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

@ -3918,6 +3918,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(
@ -4067,6 +4069,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;
}
@ -4082,6 +4085,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

@ -851,31 +851,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);
@ -941,7 +932,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>