MDL-68076 core: display call to feedback on user dashboard

This commit is contained in:
Shamim Rezaie 2020-04-30 15:36:31 +10:00
parent 6872c96569
commit d74a826829
5 changed files with 198 additions and 0 deletions

2
lib/amd/build/userfeedback.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
define ("core/userfeedback",["exports","core/ajax","core/notification"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerEventListeners=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}var f={regions:{root:"[data-region=\"core/userfeedback\"]"},actions:{}};f.actions.give="".concat(f.regions.root," [data-action=\"give\"]");f.actions.remind="".concat(f.regions.root," [data-action=\"remind\"]");a.registerEventListeners=function registerEventListeners(){document.addEventListener("click",function(a){var b=a.target.closest(f.actions.give);if(b){a.preventDefault();g().then(function(){return h("give")}).then(function(){var a=b.closest(f.regions.root);a.remove()}).catch(c.default.exception)}var d=a.target.closest(f.actions.remind);if(d){a.preventDefault();h("remind").then(function(){var a=d.closest(f.regions.root);a.remove()}).catch(c.default.exception)}})};var g=function(){return b.default.call([{methodname:"core_get_userfeedback_url",args:{contextid:M.cfg.contextid}}])[0].then(function(a){if(!window.open(a)){throw new Error("Unable to open popup")}})},h=function(a){return b.default.call([{methodname:"core_create_userfeedback_action_record",args:{action:a}}])[0]}});
//# sourceMappingURL=userfeedback.min.js.map

File diff suppressed because one or more lines are too long

103
lib/amd/src/userfeedback.js Normal file
View File

@ -0,0 +1,103 @@
// 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/>.
/**
* Handle clicking on action links of the feedback alert.
*
* @module core/cta_feedback
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
import Notification from 'core/notification';
const Selectors = {
regions: {
root: '[data-region="core/userfeedback"]',
},
actions: {},
};
Selectors.actions.give = `${Selectors.regions.root} [data-action="give"]`;
Selectors.actions.remind = `${Selectors.regions.root} [data-action="remind"]`;
/**
* Attach the necessary event handlers to the action links
*/
export const registerEventListeners = () => {
document.addEventListener('click', e => {
const giveAction = e.target.closest(Selectors.actions.give);
if (giveAction) {
e.preventDefault();
giveFeedback()
.then(() => {
return recordAction('give');
})
.then(() => {
const root = giveAction.closest(Selectors.regions.root);
root.remove();
return;
})
.catch(Notification.exception);
}
const remindAction = e.target.closest(Selectors.actions.remind);
if (remindAction) {
e.preventDefault();
recordAction('remind')
.then(() => {
const root = remindAction.closest(Selectors.regions.root);
root.remove();
return;
})
.catch(Notification.exception);
}
});
};
/**
* The action function that is called when users choose to give feedback.
*
* @returns {Promise<void>}
*/
const giveFeedback = () => {
return Ajax.call([{
methodname: 'core_get_userfeedback_url',
args: {
contextid: M.cfg.contextid,
}
}])[0]
.then(url => {
if (!window.open(url)) {
throw new Error('Unable to open popup');
}
return;
});
};
/**
* Record the action that the user took.
*
* @param {string} action The action that the user took. Either give or remind.
* @returns {Promise<null>}
*/
const recordAction = action => {
return Ajax.call([{
methodname: 'core_create_userfeedback_action_record',
args: {
action,
}
}])[0];
};

View File

@ -45,4 +45,92 @@ class core_userfeedback {
* @var int Do not ask user to give feedback.
*/
public const REMIND_NEVER = 3;
/**
* Displays the feedback reminder block.
*/
public static function print_reminder_block(): void {
global $PAGE;
static $jscalled = false;
$actions = [
[
'title' => get_string('calltofeedback_give'),
'url' => '#',
'data' => [
'action' => 'give',
],
],
[
'title' => get_string('calltofeedback_remind'),
'url' => '#',
'data' => [
'action' => 'remind',
],
],
];
$icon = [
'pix' => 'i/bullhorn',
'component' => 'core'
];
\core\notification::add_call_to_action($icon, get_string('calltofeedback'), $actions, 'core/userfeedback');
if (!$jscalled) {
$jscalled = true;
// Calling the following more than once will register event listeners twice.
$PAGE->requires->js_call_amd('core/userfeedback', 'registerEventListeners');
}
}
/**
* Indicates whether the feedback reminder block should be shown or not.
*
* @return bool
*/
public static function should_display_reminder(): bool {
global $CFG;
if ($CFG->enableuserfeedback && isloggedin() && !isguestuser()) {
$give = get_user_preferences('core_userfeedback_give');
$remind = get_user_preferences('core_userfeedback_remind');
$lastactiontime = max($give ?: 0, $remind ?: 0);
switch ($CFG->userfeedback_nextreminder) {
case self::REMIND_AFTER_UPGRADE:
$lastupgrade = self::last_major_upgrade_time();
if ($lastupgrade >= $lastactiontime) {
return $lastupgrade + ($CFG->userfeedback_remindafter * DAYSECS) < time();
}
break;
case self::REMIND_PERIODICALLY:
return $lastactiontime + ($CFG->userfeedback_remindafter * DAYSECS) < time();
break;
}
}
return false;
}
/**
* Returns the last major upgrade time
*
* @return int
*/
private static function last_major_upgrade_time(): int {
global $DB;
$targetversioncast = $DB->sql_cast_char2real('targetversion');
$versioncast = $DB->sql_cast_char2real('version');
// A time difference more than 3 months has to be a core upgrade.
$time = $DB->get_field_sql("SELECT timemodified
FROM {upgrade_log}
WHERE plugin = 'core' AND $targetversioncast - $versioncast > 30000
ORDER BY timemodified DESC
LIMIT 1");
return (int)$time;
}
}

View File

@ -163,6 +163,10 @@ if (empty($CFG->forcedefaultmymoodle) && $PAGE->user_allowed_editing()) {
echo $OUTPUT->header();
if (core_userfeedback::should_display_reminder()) {
core_userfeedback::print_reminder_block();
}
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();