Merge branch 'MDL-63352-master' of git://github.com/peterRd/moodle
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/custom_interaction_events","block_timeline/view"],function(a,b,c){var d={TIMELINE_DAY_FILTER:'[data-region="day-filter"]',TIMELINE_DAY_FILTER_OPTION:"[data-from]",TIMELINE_VIEW_SELECTOR:'[data-region="view-selector"]',DATA_DAYS_OFFSET:"[data-days-offset]",DATA_DAYS_LIMIT:"[data-days-limit]"},e=function(e,f){var g=e.find(d.TIMELINE_DAY_FILTER);b.define(g,[b.events.activate]),g.on(b.events.activate,d.TIMELINE_DAY_FILTER_OPTION,function(b,g){var h=a(b.target).closest(d.TIMELINE_DAY_FILTER_OPTION);if(!h.hasClass("active")){var i=h.attr("data-from"),j=h.attr("data-to"),k=e.find(d.DATA_DAYS_OFFSET);k.attr("data-days-offset",i),void 0!=j?k.attr("data-days-limit",j):k.removeAttr("data-days-limit"),c.reset(f),g.originalEvent.preventDefault()}})},f=function(a,b){a.find(d.TIMELINE_VIEW_SELECTOR).on("shown shown.bs.tab",function(){c.shown(b)})},g=function(b,c){b=a(b),e(b,c),f(b,c)};return{init:g}});
|
||||
define(["jquery","core/custom_interaction_events","block_timeline/view","core/ajax","core/notification"],function(a,b,c,d,e){var f={TIMELINE_DAY_FILTER:'[data-region="day-filter"]',TIMELINE_DAY_FILTER_OPTION:"[data-from]",TIMELINE_VIEW_SELECTOR:'[data-region="view-selector"]',DATA_DAYS_OFFSET:"[data-days-offset]",DATA_DAYS_LIMIT:"[data-days-limit]"},g=function(a,b){var c={methodname:"core_user_update_user_preferences",args:{preferences:[{type:a,value:b}]}};d.call([c])[0].fail(e.exception)},h=function(d,e){var h=d.find(f.TIMELINE_DAY_FILTER);b.define(h,[b.events.activate]),h.on(b.events.activate,f.TIMELINE_DAY_FILTER_OPTION,function(b,h){var i=a(b.currentTarget).data("filtername"),j="block_timeline_user_filter_preference";g(j,i);var k=a(b.target).closest(f.TIMELINE_DAY_FILTER_OPTION);if(!k.hasClass("active")){var l=k.attr("data-from"),m=k.attr("data-to"),n=d.find(f.DATA_DAYS_OFFSET);n.attr("data-days-offset",l),void 0!=m?n.attr("data-days-limit",m):n.removeAttr("data-days-limit"),c.reset(e),h.originalEvent.preventDefault()}})},i=function(d,e){var h=d.find(f.TIMELINE_VIEW_SELECTOR);h.on("shown shown.bs.tab",function(){c.shown(e)}),b.define(h,[b.events.activate]),h.on(b.events.activate,"[data-toggle='tab']",function(b){var c=a(b.currentTarget).data("filtername"),d="block_timeline_user_sort_preference";g(d,c)})},j=function(b,c){b=a(b),h(b,c),i(b,c)};return{init:j}});
|
||||
@@ -25,12 +25,16 @@ define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events',
|
||||
'block_timeline/view'
|
||||
'block_timeline/view',
|
||||
'core/ajax',
|
||||
'core/notification'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents,
|
||||
View
|
||||
View,
|
||||
Ajax,
|
||||
Notification
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
@@ -41,6 +45,29 @@ function(
|
||||
DATA_DAYS_LIMIT: '[data-days-limit]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic handler to persist user preferences
|
||||
*
|
||||
* @param {string} type The name of the attribute you're updating
|
||||
* @param {string} value The value of the attribute you're updating
|
||||
*/
|
||||
var updateUserPreferences = function(type, value) {
|
||||
var request = {
|
||||
methodname: 'core_user_update_user_preferences',
|
||||
args: {
|
||||
preferences: [
|
||||
{
|
||||
type: type,
|
||||
value: value
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
Ajax.call([request])[0]
|
||||
.fail(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Event listener for the day selector ("Next 7 days", "Next 30 days", etc).
|
||||
*
|
||||
@@ -55,6 +82,11 @@ function(
|
||||
CustomEvents.events.activate,
|
||||
SELECTORS.TIMELINE_DAY_FILTER_OPTION,
|
||||
function(e, data) {
|
||||
// Update the user preference
|
||||
var filtername = $(e.currentTarget).data('filtername');
|
||||
var type = 'block_timeline_user_filter_preference';
|
||||
updateUserPreferences(type, filtername);
|
||||
|
||||
var option = $(e.target).closest(SELECTORS.TIMELINE_DAY_FILTER_OPTION);
|
||||
|
||||
if (option.hasClass('active')) {
|
||||
@@ -94,11 +126,21 @@ function(
|
||||
* @param {object} timelineViewRoot The root element for the timeline view
|
||||
*/
|
||||
var registerViewSelector = function(root, timelineViewRoot) {
|
||||
var viewSelector = root.find(SELECTORS.TIMELINE_VIEW_SELECTOR);
|
||||
|
||||
// Listen for when the user changes tab so that we can show the first set of courses
|
||||
// and load their events when they request the sort by courses view for the first time.
|
||||
root.find(SELECTORS.TIMELINE_VIEW_SELECTOR).on('shown shown.bs.tab', function() {
|
||||
viewSelector.on('shown shown.bs.tab', function() {
|
||||
View.shown(timelineViewRoot);
|
||||
});
|
||||
|
||||
// Event selector for user_sort
|
||||
CustomEvents.define(viewSelector, [CustomEvents.events.activate]);
|
||||
viewSelector.on(CustomEvents.events.activate, "[data-toggle='tab']", function(e) {
|
||||
var filtername = $(e.currentTarget).data('filtername');
|
||||
var type = 'block_timeline_user_sort_preference';
|
||||
updateUserPreferences(type, filtername);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,7 +50,10 @@ class block_timeline extends block_base {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
$renderable = new \block_timeline\output\main();
|
||||
$sort = get_user_preferences('block_timeline_user_sort_preference');
|
||||
$filter = get_user_preferences('block_timeline_user_filter_preference');
|
||||
|
||||
$renderable = new \block_timeline\output\main($sort, $filter);
|
||||
$renderer = $this->page->get_renderer('block_timeline');
|
||||
|
||||
$this->content = (object) [
|
||||
|
||||
@@ -30,6 +30,7 @@ use templatable;
|
||||
use core_course\external\course_summary_exporter;
|
||||
|
||||
require_once($CFG->dirroot . '/course/lib.php');
|
||||
require_once($CFG->dirroot . '/blocks/timeline/lib.php');
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,86 @@ class main implements renderable, templatable {
|
||||
/** Number of courses to load per page */
|
||||
const COURSES_PER_PAGE = 2;
|
||||
|
||||
/**
|
||||
* @var string The current filter preference
|
||||
*/
|
||||
public $filter;
|
||||
|
||||
/**
|
||||
* @var string The current sort/order preference
|
||||
*/
|
||||
public $order;
|
||||
|
||||
/**
|
||||
* main constructor.
|
||||
*
|
||||
* @param string $order Constant sort value from ../timeline/lib.php
|
||||
* @param string $filter Constant sort value from ../timeline/lib.php
|
||||
*/
|
||||
public function __construct($order, $filter) {
|
||||
$this->order = $order ? $order : BLOCK_TIMELINE_SORT_BY_DATES;
|
||||
$this->filter = $filter ? $filter : BLOCK_TIMELINE_FILTER_BY_7_DAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the available filters with the current user preference and return an array with
|
||||
* bool flags corresponding to which is active
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_filters_as_booleans() {
|
||||
$filters = [
|
||||
BLOCK_TIMELINE_FILTER_BY_NONE => false,
|
||||
BLOCK_TIMELINE_FILTER_BY_OVERDUE => false,
|
||||
BLOCK_TIMELINE_FILTER_BY_7_DAYS => false,
|
||||
BLOCK_TIMELINE_FILTER_BY_30_DAYS => false,
|
||||
BLOCK_TIMELINE_FILTER_BY_3_MONTHS => false,
|
||||
BLOCK_TIMELINE_FILTER_BY_6_MONTHS => false
|
||||
];
|
||||
|
||||
// Set the selected filter to true.
|
||||
$filters[$this->filter] = true;
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the offset/limit values corresponding to $this->filter
|
||||
* which are used to send through to the context as default values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_filter_offsets() {
|
||||
|
||||
$limit = false;
|
||||
if (in_array($this->filter, [BLOCK_TIMELINE_FILTER_BY_NONE, BLOCK_TIMELINE_FILTER_BY_OVERDUE])) {
|
||||
$offset = -14;
|
||||
if ($this->filter == BLOCK_TIMELINE_FILTER_BY_OVERDUE) {
|
||||
$limit = 0;
|
||||
}
|
||||
} else {
|
||||
$offset = 0;
|
||||
$limit = 7;
|
||||
|
||||
switch($this->filter) {
|
||||
case BLOCK_TIMELINE_FILTER_BY_30_DAYS:
|
||||
$limit = 30;
|
||||
break;
|
||||
case BLOCK_TIMELINE_FILTER_BY_3_MONTHS:
|
||||
$limit = 90;
|
||||
break;
|
||||
case BLOCK_TIMELINE_FILTER_BY_6_MONTHS:
|
||||
$limit = 180;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'daysoffset' => $offset,
|
||||
'dayslimit' => $limit
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
@@ -69,13 +150,22 @@ class main implements renderable, templatable {
|
||||
return $exporter->export($output);
|
||||
}, $inprogresscourses);
|
||||
|
||||
return [
|
||||
$filters = $this->get_filters_as_booleans();
|
||||
$offsets = $this->get_filter_offsets();
|
||||
$contextvariables = [
|
||||
'midnight' => usergetmidnight(time()),
|
||||
'coursepages' => [$formattedcourses],
|
||||
'urls' => [
|
||||
'nocourses' => $nocoursesurl,
|
||||
'noevents' => $noeventsurl
|
||||
]
|
||||
],
|
||||
'sorttimelinedates' => $this->order == BLOCK_TIMELINE_SORT_BY_DATES,
|
||||
'sorttimelinecourses' => $this->order == BLOCK_TIMELINE_SORT_BY_COURSES,
|
||||
'selectedfilter' => $this->filter,
|
||||
'hasdaysoffset' => true,
|
||||
'hasdayslimit' => $offsets['dayslimit'] !== false ,
|
||||
'nodayslimit' => $offsets['dayslimit'] === false ,
|
||||
];
|
||||
return array_merge($contextvariables, $filters, $offsets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
namespace block_timeline\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
use \core_privacy\local\metadata\collection;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for block_timeline.
|
||||
@@ -32,15 +33,40 @@ defined('MOODLE_INTERNAL') || die();
|
||||
* @copyright 2018 Ryan Wyllie <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\user_preference_provider {
|
||||
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
* Returns meta-data information about the myoverview block.
|
||||
*
|
||||
* @return string
|
||||
* @param \core_privacy\local\metadata\collection $collection A collection of meta-data.
|
||||
* @return \core_privacy\local\metadata\collection Return the collection of meta-data.
|
||||
*/
|
||||
public static function get_reason() : string {
|
||||
return 'privacy:metadata';
|
||||
public static function get_metadata(collection $collection) : collection {
|
||||
$collection->add_user_preference('block_timeline_user_sort_preference', 'privacy:metadata:timelinesortpreference');
|
||||
$collection->add_user_preference('block_timeline_user_filter_preference', 'privacy:metadata:timelinefilterpreference');
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user preferences for the myoverview block
|
||||
*
|
||||
* @param int $userid The userid of the user whose data is to be exported.
|
||||
*/
|
||||
public static function export_user_preferences(int $userid) {
|
||||
$preference = get_user_preferences('block_timeline_user_sort_preference', null, $userid);
|
||||
if (isset($preference)) {
|
||||
\core_privacy\local\request\writer::export_user_preference('block_timeline', 'block_timeline_user_sort_preference',
|
||||
get_string($preference, 'block_timeline'),
|
||||
get_string('privacy:metadata:timelinesortpreference', 'block_timeline')
|
||||
);
|
||||
}
|
||||
|
||||
$preference = get_user_preferences('block_timeline_user_filter_preference', null, $userid);
|
||||
if (isset($preference)) {
|
||||
\core_privacy\local\request\writer::export_user_preference('block_timeline', 'block_timeline_user_filter_preference',
|
||||
get_string($preference, 'block_timeline'),
|
||||
get_string('privacy:metadata:timelinefilterpreference', 'block_timeline')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,11 @@ $string['next7days'] = 'Next 7 days';
|
||||
$string['next3months'] = 'Next 3 months';
|
||||
$string['next6months'] = 'Next 6 months';
|
||||
$string['overdue'] = 'Overdue';
|
||||
$string['all'] = 'All';
|
||||
$string['pluginname'] = 'Timeline';
|
||||
$string['sortbycourses'] = 'Sort by courses';
|
||||
$string['sortbydates'] = 'Sort by dates';
|
||||
$string['timeline'] = 'Timeline';
|
||||
$string['viewcourse'] = 'View course';
|
||||
$string['privacy:metadata'] = 'The timeline block does not store any personal data.';
|
||||
$string['privacy:metadata:timelinesortpreference'] = 'The user sort preference for the timeline block.';
|
||||
$string['privacy:metadata:timelinefilterpreference'] = 'The user day filter preference for the timeline block.';
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Library functions for timeline
|
||||
*
|
||||
* @package block_timeline
|
||||
* @copyright 2018 Peter Dias
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Define constants to store the SORT user preference
|
||||
*/
|
||||
define('BLOCK_TIMELINE_SORT_BY_DATES', 'sortbydates');
|
||||
define('BLOCK_TIMELINE_SORT_BY_COURSES', 'sortbycourses');
|
||||
|
||||
/**
|
||||
* Define constants to store the FILTER user preference
|
||||
*/
|
||||
define('BLOCK_TIMELINE_FILTER_BY_NONE', 'all');
|
||||
define('BLOCK_TIMELINE_FILTER_BY_OVERDUE', 'overdue');
|
||||
define('BLOCK_TIMELINE_FILTER_BY_7_DAYS', 'next7days');
|
||||
define('BLOCK_TIMELINE_FILTER_BY_30_DAYS', 'next30days');
|
||||
define('BLOCK_TIMELINE_FILTER_BY_3_MONTHS', 'next3months');
|
||||
define('BLOCK_TIMELINE_FILTER_BY_6_MONTHS', 'next6months');
|
||||
|
||||
/**
|
||||
* Returns the name of the user preferences as well as the details this plugin uses.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function block_timeline_user_preferences() {
|
||||
$preferences['block_timeline_user_sort_preference'] = array(
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'default' => BLOCK_TIMELINE_SORT_BY_DATES,
|
||||
'type' => PARAM_ALPHA,
|
||||
'choices' => array(BLOCK_TIMELINE_SORT_BY_DATES, BLOCK_TIMELINE_SORT_BY_COURSES)
|
||||
);
|
||||
|
||||
$preferences['block_timeline_user_filter_preference'] = array(
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'default' => BLOCK_TIMELINE_FILTER_BY_30_DAYS,
|
||||
'type' => PARAM_ALPHANUM,
|
||||
'choices' => array(
|
||||
BLOCK_TIMELINE_FILTER_BY_NONE,
|
||||
BLOCK_TIMELINE_FILTER_BY_OVERDUE,
|
||||
BLOCK_TIMELINE_FILTER_BY_7_DAYS,
|
||||
BLOCK_TIMELINE_FILTER_BY_30_DAYS,
|
||||
BLOCK_TIMELINE_FILTER_BY_3_MONTHS,
|
||||
BLOCK_TIMELINE_FILTER_BY_6_MONTHS
|
||||
)
|
||||
);
|
||||
|
||||
return $preferences;
|
||||
}
|
||||
@@ -32,18 +32,20 @@
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu" data-show-active-item>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#all}} active {{/all}}"
|
||||
href="#"
|
||||
data-from="-14"
|
||||
data-filtername="all"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} all, core {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} all, core {{/str}}
|
||||
</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#overdue}} active {{/overdue}}"
|
||||
href="#"
|
||||
data-from="-14"
|
||||
data-to="0"
|
||||
data-filtername="overdue"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} overdue, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} overdue, block_timeline {{/str}}
|
||||
@@ -51,37 +53,41 @@
|
||||
<div class="dropdown-divider"></div>
|
||||
<h6 class="dropdown-header">{{#str}} duedate, block_timeline {{/str}}</h6>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#next7days}} active {{/next7days}}"
|
||||
href="#"
|
||||
data-from="0"
|
||||
data-to="7"
|
||||
data-filtername="next7days"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next7days, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} next7days, block_timeline {{/str}}
|
||||
</a>
|
||||
<a
|
||||
class="dropdown-item active"
|
||||
class="dropdown-item {{#next30days}} active {{/next30days}}"
|
||||
href="#"
|
||||
data-from="0"
|
||||
data-to="30"
|
||||
data-filtername="next30days"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next30days, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} next30days, block_timeline {{/str}}
|
||||
</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#next3months}} active {{/next3months}}"
|
||||
href="#"
|
||||
data-from="0"
|
||||
data-to="90"
|
||||
data-filtername="next3months"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next3months, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} next3months, block_timeline {{/str}}
|
||||
</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#next6months}} active {{/next6months}}"
|
||||
href="#"
|
||||
data-from="0"
|
||||
data-to="180"
|
||||
data-filtername="next6months"
|
||||
aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next6months, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} next6months, block_timeline {{/str}}
|
||||
|
||||
@@ -26,23 +26,25 @@
|
||||
<button type="button" class="btn btn-outline-secondary dropdown-toggle icon-no-margin" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{#pix}} i/filter {{/pix}}
|
||||
<span class="sr-only">
|
||||
{{#str}} ariaviewselector, block_timeline{{/str}}
|
||||
<span data-active-item-text>{{#str}} sortbydates, block_timeline {{/str}}</span>
|
||||
{{#sorttimelinecourses}}<span data-active-item-text>{{/sorttimelinecourses}}{{#str}} ariaviewselector, block_timeline{{/str}}{{#sorttimelinecourses}}</span>{{/sorttimelinecourses}}
|
||||
{{#sorttimelinedates}}<span data-active-item-text>{{/sorttimelinedates}}{{#str}} sortbydates, block_timeline {{/str}}{{#sorttimelinedates}}</span>{{/sorttimelinedates}}
|
||||
</span>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right list-group hidden" data-show-active-item data-skip-active-class="true">
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right list-group hidden" data-show-active-item data-skip-active-class="true" >
|
||||
<a
|
||||
class="dropdown-item active"
|
||||
class="dropdown-item {{#sorttimelinedates}}active{{/sorttimelinedates}}"
|
||||
href="#view_dates_{{uniqid}}"
|
||||
data-toggle="tab"
|
||||
data-filtername="sortbydates"
|
||||
aria-label="{{#str}} ariaviewselectoroption, block_timeline, {{#str}} sortbydates, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} sortbydates, block_timeline {{/str}}
|
||||
</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
class="dropdown-item {{#sorttimelinecourses}}active{{/sorttimelinecourses}}"
|
||||
href="#view_courses_{{uniqid}}"
|
||||
data-toggle="tab"
|
||||
data-filtername="sortbycourses"
|
||||
aria-label="{{#str}} ariaviewselectoroption, block_timeline, {{#str}} sortbycourses, block_timeline {{/str}}{{/str}}"
|
||||
>
|
||||
{{#str}} sortbycourses, block_timeline {{/str}}
|
||||
|
||||
@@ -20,15 +20,38 @@
|
||||
This template renders the timeline view for the timeline block.
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
{
|
||||
"midnight": 1538954668,
|
||||
"coursepages": [
|
||||
{}
|
||||
],
|
||||
"urls": {
|
||||
"nocourses": "#",
|
||||
"noevents": "#"
|
||||
},
|
||||
"sorttimelinedates": true,
|
||||
"sorttimelinecourses": false,
|
||||
"selectedfilter": "all",
|
||||
"hasdaysoffset": true,
|
||||
"hasdayslimit": false,
|
||||
"nodayslimit": true,
|
||||
"all": true,
|
||||
"overdue": false,
|
||||
"next7days": false,
|
||||
"next30days": false,
|
||||
"next3months": false,
|
||||
"next6months": false,
|
||||
"daysoffset": -14,
|
||||
"dayslimit": false
|
||||
}
|
||||
}}
|
||||
<div data-region="timeline-view">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active fade show" data-region="view-dates" id="view_dates_{{uniqid}}">
|
||||
<div class="tab-pane {{#sorttimelinedates}}active show{{/sorttimelinedates}} fade" data-region="view-dates" id="view_dates_{{uniqid}}">
|
||||
{{> block_timeline/view-dates }}
|
||||
</div>
|
||||
<div
|
||||
class="tab-pane fade"
|
||||
class="tab-pane {{#sorttimelinecourses}}active show{{/sorttimelinecourses}} fade"
|
||||
data-region="view-courses"
|
||||
data-midnight="{{midnight}}"
|
||||
data-limit="2"
|
||||
|
||||
@@ -70,3 +70,22 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
And I should not see "Course 4" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 4 closes" in the "Timeline" "block"
|
||||
|
||||
Scenario: Persistent sort filter
|
||||
Given I log in as "student1"
|
||||
And I click on "Sort" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by dates" "link" in the "Timeline" "block"
|
||||
And I click on "Sort" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by courses" "link" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
Then I should see "Course 1" in the "Timeline" "block"
|
||||
And I should see "Course 2" in the "Timeline" "block"
|
||||
And I should see "More courses" in the "Timeline" "block"
|
||||
And I should see "Test choice 1 closes" in the "Timeline" "block"
|
||||
And I should see "Test feedback 1 closes" in the "Timeline" "block"
|
||||
And I should not see "Course 3" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test assign 1 is due" in the "Timeline" "block"
|
||||
|
||||
@@ -86,3 +86,36 @@ Feature: The timeline block allows users to see upcoming activities
|
||||
And I should see "Test feedback 3 closes" in the "Timeline" "block"
|
||||
And I should see "Test feedback 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
|
||||
Scenario: Persistent All in date view
|
||||
Given I log in as "student1"
|
||||
And I click on "Next 30 days" "button" in the "Timeline" "block"
|
||||
When I click on "All" "link" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
Then I should see "Test assign 1 is due" in the "Timeline" "block"
|
||||
And I should see "Test feedback 1 closes" in the "Timeline" "block"
|
||||
And I should see "Test choice 1 closes" in the "Timeline" "block"
|
||||
And I should see "Test choice 3 closes" in the "Timeline" "block"
|
||||
And I should see "Test feedback 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 2 closes" in the "Timeline" "block"
|
||||
And I click on "[data-region='paging-bar'] [data-control='next']" "css_element" in the "Timeline" "block"
|
||||
And I should see "Test feedback 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test assign 1 is due" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 1 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 1 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
|
||||
Scenario: Persistent Overdue in date view
|
||||
Given I log in as "student1"
|
||||
And I click on "Next 30 days" "button" in the "Timeline" "block"
|
||||
When I click on "Overdue" "link" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
Then I should see "Test assign 1 is due" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 1 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 1 closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 3 closes" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 3 closes" in the "Timeline" "block"
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for the block_timeline implementation of the privacy API.
|
||||
*
|
||||
* @package block_timeline
|
||||
* @category test
|
||||
* @copyright 2018 Peter Dias <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use \core_privacy\local\request\writer;
|
||||
use \block_timeline\privacy\provider;
|
||||
|
||||
/**
|
||||
* Unit tests for the block_timeline implementation of the privacy API.
|
||||
*
|
||||
* @copyright 2018 Peter Dias <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class block_timeline_privacy_testcase extends \core_privacy\tests\provider_testcase {
|
||||
|
||||
/**
|
||||
* Ensure that export_user_preferences returns no data if the user has not visited the myoverview block.
|
||||
*/
|
||||
public function test_export_user_preferences_no_pref() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$this->assertFalse($writer->has_any_data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the preference courses is exported properly.
|
||||
*/
|
||||
public function test_export_user_preferences_date_sort_preference() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
set_user_preference('block_timeline_user_sort_preference', 'sortbydates', $user);
|
||||
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$blockpreferences = $writer->get_user_preferences('block_timeline');
|
||||
$this->assertEquals('Sort by dates', $blockpreferences->block_timeline_user_sort_preference->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the preference timeline is exported properly.
|
||||
*/
|
||||
public function test_export_user_preferences_course_sort_preference() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
set_user_preference('block_timeline_user_sort_preference', 'sortbycourses', $user);
|
||||
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$blockpreferences = $writer->get_user_preferences('block_timeline');
|
||||
$this->assertEquals('Sort by courses', $blockpreferences->block_timeline_user_sort_preference->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the preference timeline is exported properly.
|
||||
*/
|
||||
public function test_export_user_preferences_7day_filter_preference() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
set_user_preference('block_timeline_user_filter_preference', 'next7days', $user);
|
||||
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$blockpreferences = $writer->get_user_preferences('block_timeline');
|
||||
$this->assertEquals('Next 7 days', $blockpreferences->block_timeline_user_filter_preference->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the preference timeline is exported properly.
|
||||
*/
|
||||
public function test_export_user_preferences_all_filter_preference() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
set_user_preference('block_timeline_user_filter_preference', 'all', $user);
|
||||
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$blockpreferences = $writer->get_user_preferences('block_timeline');
|
||||
$this->assertEquals('All', $blockpreferences->block_timeline_user_filter_preference->value);
|
||||
}
|
||||
}
|
||||
@@ -32,33 +32,33 @@
|
||||
<span data-region="caret" class="caret"></span>
|
||||
</button>
|
||||
<ul role="menu" class="dropdown-menu" data-show-active-item>
|
||||
<li class="dropdown-item" data-from="-14">
|
||||
<li class="dropdown-item {{#all}} active {{/all}}" data-from="-14" data-filtername="all">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} all, core {{/str}}{{/str}}">
|
||||
{{#str}} all, core {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item" data-from="-14" data-to="0">
|
||||
<li class="dropdown-item {{#overdue}} active {{/overdue}}" data-from="-14" data-to="0" data-filtername="overdue">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} overdue, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} overdue, block_timeline {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-item" data-from="0" data-to="7">
|
||||
<li class="dropdown-item {{#next7days}} active {{/next7days}}" data-from="0" data-to="7" data-filtername="next7days">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next7days, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} next7days, block_timeline {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item active" data-from="0" data-to="30">
|
||||
<li class="dropdown-item {{#next30days}} active {{/next30days}}" data-from="0" data-to="30" data-filtername="next30days">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next30days, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} next30days, block_timeline {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item" data-from="0" data-to="90">
|
||||
<li class="dropdown-item {{#next3months}} active {{/next3months}}" data-from="0" data-to="90" data-filtername="next3months">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next3months, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} next3months, block_timeline {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item" data-from="0" data-to="180">
|
||||
<li class="dropdown-item {{#next6months}} active {{/next6months}}" data-from="0" data-to="180" data-filtername="next6months">
|
||||
<a href="#" aria-label="{{#str}} ariadayfilteroption, block_timeline, {{#str}} next6months, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} next6months, block_timeline {{/str}}
|
||||
</a>
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
<span data-region="caret" class="caret"></span>
|
||||
</button>
|
||||
<ul role="menu" class="dropdown-menu dropdown-menu-right" data-show-active-item>
|
||||
<li class="dropdown-item active" data-target="#view_dates_{{uniqid}}" data-toggle="tab">
|
||||
<li class="dropdown-item {{#sorttimelinedates}}active{{/sorttimelinedates}}" data-target="#view_dates_{{uniqid}}" data-toggle="tab" data-filtername="sortbydates">
|
||||
<a href="#" aria-label="{{#str}} ariaviewselectoroption, block_timeline, {{#str}} sortbydates, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} sortbydates, block_timeline {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item" data-target="#view_courses_{{uniqid}}" data-toggle="tab">
|
||||
<li class="dropdown-item {{#sorttimelinecourses}}active{{/sorttimelinecourses}}" data-target="#view_courses_{{uniqid}}" data-toggle="tab" data-filtername="sortbycourses">
|
||||
<a href="#" aria-label="{{#str}} ariaviewselectoroption, block_timeline, {{#str}} sortbycourses, block_timeline {{/str}}{{/str}}">
|
||||
{{#str}} sortbycourses, block_timeline {{/str}}
|
||||
</a>
|
||||
|
||||
@@ -20,15 +20,38 @@
|
||||
This template renders the timeline view for the timeline block.
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
{
|
||||
"midnight": 1538954668,
|
||||
"coursepages": [
|
||||
{}
|
||||
],
|
||||
"urls": {
|
||||
"nocourses": "#",
|
||||
"noevents": "#"
|
||||
},
|
||||
"sorttimelinedates": true,
|
||||
"sorttimelinecourses": false,
|
||||
"selectedfilter": "all",
|
||||
"hasdaysoffset": true,
|
||||
"hasdayslimit": false,
|
||||
"nodayslimit": true,
|
||||
"all": true,
|
||||
"overdue": false,
|
||||
"next7days": false,
|
||||
"next30days": false,
|
||||
"next3months": false,
|
||||
"next6months": false,
|
||||
"daysoffset": -14,
|
||||
"dayslimit": false
|
||||
}
|
||||
}}
|
||||
<div data-region="timeline-view">
|
||||
<div class="tab-content" style="overflow: visible">
|
||||
<div class="tab-pane active fade in" data-region="view-dates" id="view_dates_{{uniqid}}">
|
||||
<div class="tab-pane {{#sorttimelinedates}}active in{{/sorttimelinedates}} fade" data-region="view-dates" id="view_dates_{{uniqid}}">
|
||||
{{> block_timeline/view-dates }}
|
||||
</div>
|
||||
<div
|
||||
class="tab-pane fade"
|
||||
class="tab-pane {{#sorttimelinecourses}}active in{{/sorttimelinecourses}} fade"
|
||||
data-region="view-courses"
|
||||
data-midnight="{{midnight}}"
|
||||
data-limit="2"
|
||||
|
||||
Reference in New Issue
Block a user