Merge branch 'MDL-63337-master' of git://github.com/bmbrands/moodle
authorJun Pataleta <jun@moodle.com>
Mon, 15 Oct 2018 13:03:16 +0000 (21:03 +0800)
committerJun Pataleta <jun@moodle.com>
Mon, 15 Oct 2018 13:03:16 +0000 (21:03 +0800)
56 files changed:
blocks/myoverview/amd/build/main.min.js [new file with mode: 0644]
blocks/myoverview/amd/build/paging_bar.min.js [deleted file]
blocks/myoverview/amd/build/paging_content.min.js [deleted file]
blocks/myoverview/amd/build/repository.min.js [new file with mode: 0644]
blocks/myoverview/amd/build/view.min.js [new file with mode: 0644]
blocks/myoverview/amd/build/view_nav.min.js [new file with mode: 0644]
blocks/myoverview/amd/src/main.js [new file with mode: 0644]
blocks/myoverview/amd/src/paging_bar.js [deleted file]
blocks/myoverview/amd/src/paging_content.js [deleted file]
blocks/myoverview/amd/src/repository.js [new file with mode: 0644]
blocks/myoverview/amd/src/view.js [new file with mode: 0644]
blocks/myoverview/amd/src/view_nav.js [new file with mode: 0644]
blocks/myoverview/classes/output/courses_view.php [deleted file]
blocks/myoverview/classes/output/main.php
blocks/myoverview/db/upgrade.php [deleted file]
blocks/myoverview/lang/en/block_myoverview.php
blocks/myoverview/templates/course-paging-content-item.mustache [deleted file]
blocks/myoverview/templates/course-paging-content.mustache [deleted file]
blocks/myoverview/templates/courses-view-by-status.mustache [deleted file]
blocks/myoverview/templates/courses-view-course-item.mustache [deleted file]
blocks/myoverview/templates/courses-view-nav-grouping-display-filter.mustache [deleted file]
blocks/myoverview/templates/courses-view.mustache
blocks/myoverview/templates/main.mustache
blocks/myoverview/templates/nav-display-selector.mustache [new file with mode: 0644]
blocks/myoverview/templates/nav-grouping-selector.mustache [new file with mode: 0644]
blocks/myoverview/templates/nav-sort-selector.mustache [new file with mode: 0644]
blocks/myoverview/templates/no-courses.mustache [moved from blocks/myoverview/templates/paging-bar-item.mustache with 57% similarity]
blocks/myoverview/templates/paging-bar.mustache [deleted file]
blocks/myoverview/templates/paging-content.mustache [deleted file]
blocks/myoverview/templates/placeholder-course.mustache [moved from theme/bootstrapbase/templates/block_myoverview/paging-content-item.mustache with 59% similarity]
blocks/myoverview/templates/progress-bar.mustache [moved from blocks/myoverview/templates/paging-content-item.mustache with 60% similarity]
blocks/myoverview/templates/progress-chart.mustache [deleted file]
blocks/myoverview/templates/view-cards.mustache [new file with mode: 0644]
blocks/myoverview/templates/view-list.mustache [new file with mode: 0644]
blocks/myoverview/templates/view-summary.mustache [new file with mode: 0644]
blocks/myoverview/tests/behat/block_myoverview_dashboard.feature
blocks/myoverview/tests/behat/block_myoverview_progress.feature
blocks/myoverview/version.php
course/classes/external/course_summary_exporter.php
course/externallib.php
course/lib.php
course/tests/externallib_test.php
enrol/tests/enrollib_test.php
lib/enrollib.php
theme/boost/scss/moodle/blocks.scss
theme/boost/scss/preset/default.scss
theme/boost/style/moodle.css
theme/bootstrapbase/less/moodle/blocks.less
theme/bootstrapbase/less/moodle/bs4-compat.less
theme/bootstrapbase/style/moodle.css
theme/bootstrapbase/templates/block_myoverview/course-paging-content-item.mustache [deleted file]
theme/bootstrapbase/templates/block_myoverview/courses-view-course-item.mustache [deleted file]
theme/bootstrapbase/templates/block_myoverview/courses-view-nav-grouping-display-filter.mustache [deleted file]
theme/bootstrapbase/templates/block_myoverview/courses-view.mustache [deleted file]
theme/bootstrapbase/templates/block_myoverview/main.mustache [deleted file]
theme/bootstrapbase/templates/block_myoverview/paging-bar.mustache [deleted file]

diff --git a/blocks/myoverview/amd/build/main.min.js b/blocks/myoverview/amd/build/main.min.js
new file mode 100644 (file)
index 0000000..ce2592d
Binary files /dev/null and b/blocks/myoverview/amd/build/main.min.js differ
diff --git a/blocks/myoverview/amd/build/paging_bar.min.js b/blocks/myoverview/amd/build/paging_bar.min.js
deleted file mode 100644 (file)
index 40e8b6d..0000000
Binary files a/blocks/myoverview/amd/build/paging_bar.min.js and /dev/null differ
diff --git a/blocks/myoverview/amd/build/paging_content.min.js b/blocks/myoverview/amd/build/paging_content.min.js
deleted file mode 100644 (file)
index 97da2ca..0000000
Binary files a/blocks/myoverview/amd/build/paging_content.min.js and /dev/null differ
diff --git a/blocks/myoverview/amd/build/repository.min.js b/blocks/myoverview/amd/build/repository.min.js
new file mode 100644 (file)
index 0000000..ab27262
Binary files /dev/null and b/blocks/myoverview/amd/build/repository.min.js differ
diff --git a/blocks/myoverview/amd/build/view.min.js b/blocks/myoverview/amd/build/view.min.js
new file mode 100644 (file)
index 0000000..1d9b214
Binary files /dev/null and b/blocks/myoverview/amd/build/view.min.js differ
diff --git a/blocks/myoverview/amd/build/view_nav.min.js b/blocks/myoverview/amd/build/view_nav.min.js
new file mode 100644 (file)
index 0000000..978c770
Binary files /dev/null and b/blocks/myoverview/amd/build/view_nav.min.js differ
diff --git a/blocks/myoverview/amd/src/main.js b/blocks/myoverview/amd/src/main.js
new file mode 100644 (file)
index 0000000..22dfdcf
--- /dev/null
@@ -0,0 +1,58 @@
+// 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/>.
+
+/**
+ * Javascript to initialise the myoverview block.
+ *
+ * @package    block_myoverview
+ * @copyright  2018 Bas Brands <bas@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(
+[
+    'jquery',
+    'block_myoverview/view',
+    'block_myoverview/view_nav'
+],
+function(
+    $,
+    View,
+    ViewNav
+) {
+
+    var SELECTORS = {
+        COURSES_VIEW: '[data-region="courses-view"]',
+        COURSES_VIEW_CONTENT: '[data-region="course-view-content"]'
+    };
+    /**
+     * Initialise all of the modules for the overview block.
+     * 
+     * @param {object} root The root element for the overview block.
+     */
+    var init = function(root) {
+        root = $(root);
+        var coursesViewRoot = root.find(SELECTORS.COURSES_VIEW);
+        var coursesViewContent = root.find(SELECTORS.COURSES_VIEW_CONTENT);
+        // Initialise the course navigation elements.
+        ViewNav.init(root, coursesViewRoot, coursesViewContent);
+        // Initialise the courses view modules.
+        View.init(coursesViewRoot, coursesViewContent);
+    };
+
+    return {
+        init: init
+    };
+});
diff --git a/blocks/myoverview/amd/src/paging_bar.js b/blocks/myoverview/amd/src/paging_bar.js
deleted file mode 100644 (file)
index e153e2d..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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/>.
-
-/**
- * Javascript to load and render the paging bar.
- *
- * @module     block_myoverview/paging_bar
- * @package    block_myoverview
- * @copyright  2016 Ryan Wyllie <ryan@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-define(['jquery', 'core/custom_interaction_events'],
-        function($, CustomEvents) {
-
-    var SELECTORS = {
-        ROOT: '[data-region="paging-bar"]',
-        PAGE_ITEM: '[data-region="page-item"]',
-        ACTIVE_PAGE_ITEM: '[data-region="page-item"].active'
-    };
-
-    var EVENTS = {
-        PAGE_SELECTED: 'block_myoverview-paging-bar-page-selected',
-    };
-
-    /**
-     * Get the page element by number.
-     *
-     * @param {object} root The root element.
-     * @param {Number} pageNumber The page number.
-     * @returns {*}
-     */
-    var getPageByNumber = function(root, pageNumber) {
-        return root.find(SELECTORS.PAGE_ITEM + '[data-page-number="' + pageNumber + '"]');
-    };
-
-    /**
-     * Get the page number.
-     *
-     * @param {object} root The root element.
-     * @param {object} page The page.
-     * @returns {*} the page number
-     */
-    var getPageNumber = function(root, page) {
-        var pageNumber = page.attr('data-page-number');
-
-        if (pageNumber == 'first') {
-            pageNumber = 1;
-        } else if (pageNumber == 'last') {
-            pageNumber = root.attr('data-page-count');
-        }
-
-        return pageNumber;
-    };
-
-    /**
-     * Register event listeners for the module.
-     * @param {object} root The root element.
-     */
-    var registerEventListeners = function(root) {
-        root = $(root);
-        CustomEvents.define(root, [
-            CustomEvents.events.activate
-        ]);
-
-        root.on(CustomEvents.events.activate, SELECTORS.PAGE_ITEM, function(e, data) {
-            var page = $(e.target).closest(SELECTORS.PAGE_ITEM);
-            var activePage = root.find(SELECTORS.ACTIVE_PAGE_ITEM);
-            var pageNumber = getPageNumber(root, page);
-            var isSamePage = pageNumber == getPageNumber(root, activePage);
-
-            if (!isSamePage) {
-                root.find(SELECTORS.PAGE_ITEM).removeClass('active');
-                getPageByNumber(root, pageNumber).addClass('active');
-            }
-
-            root.trigger(EVENTS.PAGE_SELECTED, [{
-                pageNumber: pageNumber,
-                isSamePage: isSamePage,
-            }]);
-
-            data.originalEvent.preventDefault();
-        });
-    };
-
-    return {
-        registerEventListeners: registerEventListeners,
-        events: EVENTS,
-        rootSelector: SELECTORS.ROOT,
-    };
-});
diff --git a/blocks/myoverview/amd/src/paging_content.js b/blocks/myoverview/amd/src/paging_content.js
deleted file mode 100644 (file)
index 1e33dae..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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/>.
-
-/**
- * Paging content module.
- *
- * @module     block_myoverview/paging_content
- * @package    block_myoverview
- * @copyright  2016 Ryan Wyllie <ryan@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-define(['jquery', 'core/templates', 'block_myoverview/paging_bar'],
-        function($, Templates, PagingBar) {
-
-    var SELECTORS = {
-        ROOT: '[data-region="paging-content"]',
-        PAGE_REGION: '[data-region="paging-content-item"]'
-    };
-
-    /**
-     * Constructor of the paging content module.
-     *
-     * @param {object} root
-     * @param {object} pagingBarElement
-     * @constructor
-     */
-    var PagingContent = function(root, pagingBarElement) {
-        this.root = $(root);
-        this.pagingBar = $(pagingBarElement);
-
-    };
-
-    PagingContent.rootSelector = SELECTORS.ROOT;
-
-    /**
-     * Load content and create page.
-     *
-     * @param {Number} pageNumber
-     * @returns {*|Promise}
-     */
-    PagingContent.prototype.createPage = function(pageNumber) {
-
-        return this.loadContent(pageNumber).then(function(html, js) {
-            Templates.appendNodeContents(this.root, html, js);
-        }.bind(this)).then(function() {
-                return this.findPage(pageNumber);
-            }.bind(this)
-        );
-    };
-
-    /**
-     * Find a page by the number.
-     *
-     * @param {Number} pageNumber The number of the page to be found.
-     * @returns {*} Page root
-     */
-    PagingContent.prototype.findPage = function(pageNumber) {
-        return this.root.find('[data-page="' + pageNumber + '"]');
-    };
-
-    /**
-     * Make a page visible.
-     *
-     * @param {Number} pageNumber The number of the page to be visible.
-     */
-    PagingContent.prototype.showPage = function(pageNumber) {
-
-        var existingPage = this.findPage(pageNumber);
-        this.root.find(SELECTORS.PAGE_REGION).addClass('hidden');
-
-        if (existingPage.length) {
-            existingPage.removeClass('hidden');
-        } else {
-            this.createPage(pageNumber).done(function(newPage) {
-                newPage.removeClass('hidden');
-            });
-        }
-    };
-
-    /**
-     * Event listeners.
-     */
-    PagingContent.prototype.registerEventListeners = function() {
-
-        this.pagingBar.on(PagingBar.events.PAGE_SELECTED, function(e, data) {
-            if (!data.isSamePage) {
-                this.showPage(data.pageNumber);
-            }
-        }.bind(this));
-    };
-
-    return PagingContent;
-});
diff --git a/blocks/myoverview/amd/src/repository.js b/blocks/myoverview/amd/src/repository.js
new file mode 100644 (file)
index 0000000..b4f7b5d
--- /dev/null
@@ -0,0 +1,53 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * A javascript module to retrieve enrolled coruses from the server.
+ *
+ * @package    block_myoverview
+ * @copyright  2018 Bas Brands <base@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['core/ajax'], function(Ajax) {
+
+    /**
+     * Retrieve a list of enrolled courses.
+     *
+     * Valid args are:
+     * string classification    future, inprogress, past
+     * int limit                number of records to retreive
+     * int Offset               offset for pagination
+     * int sort                 sort by lastaccess or name
+     *
+     * @method getEnrolledCoursesByTimeline
+     * @param {object} args The request arguments
+     * @return {promise} Resolved with an array of courses
+     */
+    var getEnrolledCoursesByTimeline = function(args) {
+
+        var request = {
+            methodname: 'core_course_get_enrolled_courses_by_timeline_classification',
+            args: args
+        };
+
+        var promise = Ajax.call([request])[0];
+
+        return promise;
+    };
+
+    return {
+        getEnrolledCoursesByTimeline: getEnrolledCoursesByTimeline
+    };
+});
diff --git a/blocks/myoverview/amd/src/view.js b/blocks/myoverview/amd/src/view.js
new file mode 100644 (file)
index 0000000..b6b6c62
--- /dev/null
@@ -0,0 +1,188 @@
+// 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/>.
+
+/**
+ * Manage the courses view for the overview block.
+ *
+ * @package    block_myoverview
+ * @copyright  2018 Bas Brands <bas@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(
+[
+    'jquery',
+    'core/notification',
+    'block_myoverview/repository',
+    'core/paged_content_factory',
+    'core/templates',
+],
+function(
+    $,
+    Notification,
+    Repository,
+    PagedContentFactory,
+    Templates
+) {
+
+    var TEMPLATES = {
+        COURSES_CARDS: 'block_myoverview/view-cards',
+        COURSES_LIST: 'block_myoverview/view-list',
+        COURSES_SUMMARY: 'block_myoverview/view-summary',
+        NOCOURSES: 'block_myoverview/no-courses'
+    };
+
+    var NUMCOURSES_PERPAGE = [12, 24];
+
+    var currentCourseList = [];
+
+    /**
+     * Get filter values from DOM.
+     *
+     * @param {object} root The root element for the courses view.
+     * @return {filters} Set filters.
+     */
+    var getFilterValues = function(root) {
+        var filters = {};
+        filters.display = root.attr('data-display');
+        filters.grouping = root.attr('data-grouping');
+        filters.sort = root.attr('data-sort');
+        return filters;
+    };
+
+    // We want the paged content controls below the paged content area
+    // and the controls should be ignored while data is loading.
+    var DEFAULT_PAGED_CONTENT_CONFIG = {
+        ignoreControlWhileLoading: true,
+        controlPlacementBottom: true,
+    };
+
+    /**
+     * Get enrolled courses from backend.
+     *
+     * @param {object} filters The filters for this view.
+     * @param {int} limit The number of courses to show.
+     * @param {int} pageNumber The pagenumber to view.
+     * @return {promise} Resolved with an array of courses.
+     */
+    var getMyCourses = function(filters, limit, pageNumber) {
+        return Repository.getEnrolledCoursesByTimeline({
+            offset:  pageNumber * limit,
+            limit: limit,
+            classification: filters.grouping,
+            sort: filters.sort
+        });
+    };
+
+    /**
+     * Render the dashboard courses.
+     *
+     * @param {object} root The root element for the courses view.
+     * @param {array} coursesData containing array of returned courses.
+     * @param {object} filters The filters for this view.
+     * @return {promise} jQuery promise resolved after rendering is complete.
+     */
+    var renderCourses = function(root, coursesData, filters) {
+
+        var currentTemplate = '';
+        if (filters.display == 'cards') {
+            currentTemplate = TEMPLATES.COURSES_CARDS;
+        } else if (filters.display == 'list') {
+            currentTemplate = TEMPLATES.COURSES_LIST;
+        } else {
+            currentTemplate = TEMPLATES.COURSES_SUMMARY;
+        }
+
+        if (coursesData.courses.length) {
+            return Templates.render(currentTemplate, {
+                courses: coursesData.courses
+            });
+        } else {
+            var nocoursesimg = root.attr('data-nocoursesimg');
+            return Templates.render(TEMPLATES.NOCOURSES, {
+                nocoursesimg: nocoursesimg
+            });
+        }
+    };
+
+    /**
+     * Intialise the courses list and cards views on page load.
+     * 
+     * @param {object} root The root element for the courses view.
+     * @param {object} content The content element for the courses view.
+     */
+    var init = function(root, content) {
+
+        root = $(root);
+
+        var filters = getFilterValues(root);
+
+        var pagedContentPromise = PagedContentFactory.createWithLimit(
+            NUMCOURSES_PERPAGE,
+            function(pagesData, actions) {
+                var promises = [];
+
+                pagesData.forEach(function(pageData) {
+                    var pageNumber = pageData.pageNumber - 1;
+
+                    var pagePromise = getMyCourses(
+                        filters,
+                        pageData.limit,
+                        pageNumber
+                    ).then(function(coursesData) {
+                        if (coursesData.courses.length < pageData.limit) {
+                            actions.allItemsLoaded(pageData.pageNumber);
+                        }
+                        currentCourseList = coursesData;
+                        return renderCourses(root, coursesData, filters);
+                    })
+                    .catch(Notification.exception);
+
+                    promises.push(pagePromise);
+                });
+
+                return promises;
+            },
+            DEFAULT_PAGED_CONTENT_CONFIG
+        );
+
+        pagedContentPromise.then(function(html, js) {
+            return Templates.replaceNodeContents(content, html, js);
+        }).catch(Notification.exception);
+    };
+
+    /**
+     * Reset the courses views to their original
+     * state on first page load.
+     * 
+     * This is called when configuration has changed for the event lists
+     * to cause them to reload their data.
+     * 
+     * @param {object} root The root element for the timeline view.
+     * @param {object} content The content element for the timeline view.
+     */
+    var reset = function(root, content) {
+        var filters = getFilterValues(root);
+        renderCourses(root, currentCourseList, filters)
+            .then(function(html, js) {
+                return Templates.replaceNodeContents(content, html, js);
+            }).catch(Notification.exception);
+    };
+
+    return {
+        init: init,
+        reset: reset
+    };
+});
diff --git a/blocks/myoverview/amd/src/view_nav.js b/blocks/myoverview/amd/src/view_nav.js
new file mode 100644 (file)
index 0000000..131c386
--- /dev/null
@@ -0,0 +1,109 @@
+// 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/>.
+
+/**
+ * Manage the timeline view navigation for the overview block.
+ *
+ * @package    block_myoverview
+ * @copyright  2018 Bas Brands <bas@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(
+[
+    'jquery',
+    'core/custom_interaction_events',
+    'block_myoverview/view'
+],
+function(
+    $,
+    CustomEvents,
+    View
+) {
+
+    var SELECTORS = {
+        FILTERS: '[data-region="filter"]',
+        FILTER_OPTION: '[data-filter]',
+        DISPLAY_OPTION: '[data-display-option]'
+    };
+
+    /**
+     * Event listener for the Display filter (cards, list).
+     * 
+     * @param {object} root The root element for the overview block
+     * @param {object} viewRoot The root element for displaying courses.
+     * @param {object} viewContent content The content element for the courses view.
+     */
+    var registerSelector = function(root, viewRoot, viewContent) {
+
+        var Selector = root.find(SELECTORS.FILTERS);
+
+        CustomEvents.define(Selector, [CustomEvents.events.activate]);
+        Selector.on(
+            CustomEvents.events.activate,
+            SELECTORS.FILTER_OPTION,
+            function(e, data) {
+                var option = $(e.target);
+
+                if (option.hasClass('active')) {
+                    // If it's already active then we don't need to do anything.
+                    return;
+                }
+
+                var attributename = 'data-' + option.attr('data-filter');
+                viewRoot.attr(attributename, option.attr('data-value'));
+
+                // Reset the views.
+                View.init(viewRoot, viewContent);
+
+                data.originalEvent.preventDefault();
+            }
+        );
+
+        CustomEvents.define(Selector, [CustomEvents.events.activate]);
+        Selector.on(
+            CustomEvents.events.activate,
+            SELECTORS.DISPLAY_OPTION,
+            function(e, data) {
+                var option = $(e.target);
+
+                if (option.hasClass('active')) {
+                    return;
+                }
+
+                viewRoot.attr('data-display', option.attr('data-value'));
+                View.reset(viewRoot, viewContent);
+                data.originalEvent.preventDefault();
+            }
+        );
+    };
+
+    /**
+     * Initialise the timeline view navigation by adding event listeners to
+     * the navigation elements.
+     * 
+     * @param {object} root The root element for the myoverview block
+     * @param {object} viewRoot The root element for the myoverview block
+     * @param {object} viewContent The content element for the myoverview block
+     */
+    var init = function(root, viewRoot, viewContent) {
+        root = $(root);
+        registerSelector(root, viewRoot, viewContent);
+    };
+
+    return {
+        init: init
+    };
+});
diff --git a/blocks/myoverview/classes/output/courses_view.php b/blocks/myoverview/classes/output/courses_view.php
deleted file mode 100644 (file)
index 2c6027e..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-<?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/>.
-
-/**
- * Class containing data for courses view in the myoverview block.
- *
- * @package    block_myoverview
- * @copyright  2017 Ryan Wyllie <ryan@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-namespace block_myoverview\output;
-defined('MOODLE_INTERNAL') || die();
-
-use renderable;
-use renderer_base;
-use templatable;
-use core_course\external\course_summary_exporter;
-
-/**
- * Class containing data for courses view in the myoverview block.
- *
- * @copyright  2017 Simey Lameze <simey@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class courses_view implements renderable, templatable {
-    /** Quantity of courses per page. */
-    const COURSES_PER_PAGE = 6;
-
-    /** @var array $courses List of courses the user is enrolled in. */
-    protected $courses = [];
-
-    /** @var array $coursesprogress List of progress percentage for each course. */
-    protected $coursesprogress = [];
-
-    /**
-     * The courses_view constructor.
-     *
-     * @param array $courses list of courses.
-     * @param array $coursesprogress list of courses progress.
-     */
-    public function __construct($courses, $coursesprogress) {
-        $this->courses = $courses;
-        $this->coursesprogress = $coursesprogress;
-    }
-
-    /**
-     * Export this data so it can be used as the context for a mustache template.
-     *
-     * @param \renderer_base $output
-     * @return array
-     */
-    public function export_for_template(renderer_base $output) {
-        global $CFG;
-        require_once($CFG->dirroot.'/course/lib.php');
-
-        // Build courses view data structure.
-        $coursesview = [
-            'hascourses' => !empty($this->courses)
-        ];
-
-        // How many courses we have per status?
-        $coursesbystatus = ['past' => 0, 'inprogress' => 0, 'future' => 0];
-        foreach ($this->courses as $course) {
-            $courseid = $course->id;
-            $context = \context_course::instance($courseid);
-            $exporter = new course_summary_exporter($course, [
-                'context' => $context
-            ]);
-            $exportedcourse = $exporter->export($output);
-            // Convert summary to plain text.
-            $exportedcourse->summary = content_to_text($exportedcourse->summary, $exportedcourse->summaryformat);
-
-            $course = new \core_course_list_element($course);
-            foreach ($course->get_course_overviewfiles() as $file) {
-                $isimage = $file->is_valid_image();
-                if ($isimage) {
-                    $url = file_encode_url("$CFG->wwwroot/pluginfile.php",
-                        '/'. $file->get_contextid(). '/'. $file->get_component(). '/'.
-                        $file->get_filearea(). $file->get_filepath(). $file->get_filename(), !$isimage);
-                    $exportedcourse->courseimage = $url;
-                    $exportedcourse->classes = 'courseimage';
-                    break;
-                }
-            }
-
-            $exportedcourse->color = $this->coursecolor($course->id);
-
-            if (!isset($exportedcourse->courseimage)) {
-                $pattern = new \core_geopattern();
-                $pattern->setColor($exportedcourse->color);
-                $pattern->patternbyid($courseid);
-                $exportedcourse->classes = 'coursepattern';
-                $exportedcourse->courseimage = $pattern->datauri();
-            }
-
-            // Include course visibility.
-            $exportedcourse->visible = (bool)$course->visible;
-
-            $courseprogress = null;
-
-            $classified = course_classify_for_timeline($course);
-
-            if (isset($this->coursesprogress[$courseid])) {
-                $courseprogress = $this->coursesprogress[$courseid]['progress'];
-                $exportedcourse->hasprogress = !is_null($courseprogress);
-                $exportedcourse->progress = $courseprogress;
-            }
-
-            if ($classified == COURSE_TIMELINE_PAST) {
-                // Courses that have already ended.
-                $pastpages = floor($coursesbystatus['past'] / $this::COURSES_PER_PAGE);
-
-                $coursesview['past']['pages'][$pastpages]['courses'][] = $exportedcourse;
-                $coursesview['past']['pages'][$pastpages]['active'] = ($pastpages == 0 ? true : false);
-                $coursesview['past']['pages'][$pastpages]['page'] = $pastpages + 1;
-                $coursesview['past']['haspages'] = true;
-                $coursesbystatus['past']++;
-            } else if ($classified == COURSE_TIMELINE_FUTURE) {
-                // Courses that have not started yet.
-                $futurepages = floor($coursesbystatus['future'] / $this::COURSES_PER_PAGE);
-
-                $coursesview['future']['pages'][$futurepages]['courses'][] = $exportedcourse;
-                $coursesview['future']['pages'][$futurepages]['active'] = ($futurepages == 0 ? true : false);
-                $coursesview['future']['pages'][$futurepages]['page'] = $futurepages + 1;
-                $coursesview['future']['haspages'] = true;
-                $coursesbystatus['future']++;
-            } else {
-                // Courses still in progress. Either their end date is not set, or the end date is not yet past the current date.
-                $inprogresspages = floor($coursesbystatus['inprogress'] / $this::COURSES_PER_PAGE);
-
-                $coursesview['inprogress']['pages'][$inprogresspages]['courses'][] = $exportedcourse;
-                $coursesview['inprogress']['pages'][$inprogresspages]['active'] = ($inprogresspages == 0 ? true : false);
-                $coursesview['inprogress']['pages'][$inprogresspages]['page'] = $inprogresspages + 1;
-                $coursesview['inprogress']['haspages'] = true;
-                $coursesbystatus['inprogress']++;
-            }
-        }
-
-        // Build courses view paging bar structure.
-        foreach ($coursesbystatus as $status => $total) {
-            $quantpages = ceil($total / $this::COURSES_PER_PAGE);
-
-            if ($quantpages) {
-                $coursesview[$status]['pagingbar']['disabled'] = ($quantpages <= 1);
-                $coursesview[$status]['pagingbar']['pagecount'] = $quantpages;
-                $coursesview[$status]['pagingbar']['first'] = ['page' => '&laquo;', 'url' => '#'];
-                $coursesview[$status]['pagingbar']['last'] = ['page' => '&raquo;', 'url' => '#'];
-                for ($page = 0; $page < $quantpages; $page++) {
-                    $coursesview[$status]['pagingbar']['pages'][$page] = [
-                        'number' => $page + 1,
-                        'page' => $page + 1,
-                        'url' => '#',
-                        'active' => ($page == 0 ? true : false)
-                    ];
-                }
-            }
-        }
-
-        return $coursesview;
-    }
-
-    /**
-     * Generate a semi-random color based on the courseid number (so it will always return
-     * the same color for a course)
-     *
-     * @param int $courseid
-     * @return string $color, hexvalue color code.
-     */
-    protected function coursecolor($courseid) {
-        // The colour palette is hardcoded for now. It would make sense to combine it with theme settings.
-        $basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894', '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
-
-        $color = $basecolors[$courseid % 10];
-        return $color;
-    }
-}
index 46834f3..c734468 100644 (file)
@@ -27,14 +27,13 @@ defined('MOODLE_INTERNAL') || die();
 use renderable;
 use renderer_base;
 use templatable;
-use core_completion\progress;
 
 require_once($CFG->libdir . '/completionlib.php');
 
 /**
  * Class containing data for my overview block.
  *
- * @copyright  2017 Simey Lameze <simey@moodle.com>
+ * @copyright  2018 Bas Brands <bas@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class main implements renderable, templatable {
@@ -45,38 +44,11 @@ class main implements renderable, templatable {
      * @return stdClass
      */
     public function export_for_template(renderer_base $output) {
-        global $USER;
 
-        $courses = enrol_get_my_courses('*');
-        $coursesprogress = [];
-
-        foreach ($courses as $course) {
-
-            $completion = new \completion_info($course);
-
-            // First, let's make sure completion is enabled.
-            if (!$completion->is_enabled()) {
-                continue;
-            }
-
-            $percentage = progress::get_course_progress_percentage($course);
-            if (!is_null($percentage)) {
-                $percentage = floor($percentage);
-            }
-
-            $coursesprogress[$course->id]['completed'] = $completion->is_course_complete($USER->id);
-            $coursesprogress[$course->id]['progress'] = $percentage;
-        }
-
-        $coursesview = new courses_view($courses, $coursesprogress);
         $nocoursesurl = $output->image_url('courses', 'block_myoverview')->out();
 
-        return [
-            'midnight' => usergetmidnight(time()),
-            'coursesview' => $coursesview->export_for_template($output),
-            'urls' => [
-                'nocourses' => $nocoursesurl,
-            ],
+        return (object) [
+            'nocoursesimg' => $nocoursesurl
         ];
     }
 }
diff --git a/blocks/myoverview/db/upgrade.php b/blocks/myoverview/db/upgrade.php
deleted file mode 100644 (file)
index b91cb96..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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/>.
-
-/**
- * This file keeps track of upgrades to the myoverview block
- *
- * @package block_myoverview
- * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Upgrade code for the myoverview block.
- *
- * @param int $oldversion
- */
-function xmldb_block_myoverview_upgrade($oldversion) {
-    global $DB;
-
-    if ($oldversion < 2018092700) {
-        $DB->delete_records('user_preferences', ['name' => 'block_myoverview_last_tab']);
-        upgrade_block_savepoint(true, 2018092700, 'myoverview');
-    }
-
-    return true;
-}
index df3ae66..49fe21c 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['all'] = 'All';
+$string['aria:allcourses'] = 'All courses';
+$string['aria:card'] = 'Switch to card view';
+$string['aria:controls'] = 'Course overview controls';
+$string['aria:courseimage'] = 'Course image:';
+$string['aria:coursename'] = 'Course name:';
+$string['aria:coursesummary'] = 'Course summary text:';
+$string['aria:courseprogress'] = 'Course progress:';
+$string['aria:displaydropdown'] = 'Display dropdown';
+$string['aria:future'] = 'Show future courses';
+$string['aria:groupingdropdown'] = 'Grouping dropdown';
+$string['aria:inprogress'] = 'Show in courses in progress';
+$string['aria:lastaccessed'] = 'Sort courses by last accessed date';
+$string['aria:list'] = 'Switch to list view';
+$string['aria:title'] = 'Sort courses by title';
+$string['aria:past'] = 'Show past courses';
+$string['aria:summary'] = 'Switch to summary view';
+$string['aria:sortingdropdown'] = 'Sorting dropdown';
+$string['card'] = 'Card';
+$string['courseprogress'] = 'Course progress:';
+$string['complete'] = 'Complete';
+$string['favorite'] = 'Favorite';
 $string['future'] = 'Future';
+$string['future:aria'] = 'View future courses';
+$string['hidden'] = 'Hidden';
 $string['inprogress'] = 'In progress';
+$string['inprogress:aria'] = 'View in progress courses';
+$string['lastaccessed'] = 'Last accessed';
+$string['lastaccessed:aria'] = 'Sort course by lastaccessed';
+$string['list'] = 'List';
 $string['morecourses'] = 'More courses';
 $string['myoverview:addinstance'] = 'Add a new course overview block';
 $string['myoverview:myaddinstance'] = 'Add a new course overview block to Dashboard';
-$string['nocourses'] = 'No courses';
-$string['nocoursesinprogress'] = 'No in progress courses';
 $string['nocoursesfuture'] = 'No future courses';
+$string['nocoursesinprogress'] = 'No in progress courses';
+$string['nocourses'] = 'No courses';
 $string['nocoursespast'] = 'No past courses';
 $string['past'] = 'Past';
 $string['pluginname'] = 'Course overview';
-$string['viewcourse'] = 'View course';
-$string['viewcoursename'] = 'View course {$a}';
 $string['privacy:metadata'] = 'The myoverview block does not store any personal data.';
+$string['summary'] = 'Summary';
+$string['title'] = 'Title';
+$string['viewcoursename'] = 'View course {$a}';
+$string['viewcourse'] = 'View course';
+
diff --git a/blocks/myoverview/templates/course-paging-content-item.mustache b/blocks/myoverview/templates/course-paging-content-item.mustache
deleted file mode 100644 (file)
index bbaa637..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{{!
-    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 block_myoverview/course-paging-content-item
-
-    This template renders each course block.
-
-    Example context (json):
-    {
-        "page": 1,
-        "active": true,
-        "courses": [
-            {
-                "fullnamedisplay": "course 1",
-                "viewurl": "https://www.google.com",
-                "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-            },
-            {
-                "fullnamedisplay": "course 2",
-                "viewurl": "https://www.google.com",
-                "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-            }
-        ]
-    }
-}}
-{{< block_myoverview/paging-content-item }}
-    {{$classes}}row card-deck{{/classes}}
-    {{$content}}
-        {{#courses}}
-            {{> block_myoverview/courses-view-course-item }}
-        {{/courses}}
-    {{/content}}
-{{/ block_myoverview/paging-content-item }}
diff --git a/blocks/myoverview/templates/course-paging-content.mustache b/blocks/myoverview/templates/course-paging-content.mustache
deleted file mode 100644 (file)
index 85ee437..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-{{!
-    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 block_myoverview/course-paging-content
-
-    This template renders the each course block containing a summary and calendar events.
-
-    Example context (json):
-    {
-        "pages": [
-            {
-                "page": 1,
-                "active": true,
-                "courses": [
-                    {
-                        "fullnamedisplay": "course 1",
-                        "viewurl": "https://www.google.com",
-                        "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-                    },
-                    {
-                        "fullnamedisplay": "course 2",
-                        "viewurl": "https://www.google.com",
-                        "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-                    }
-                ]
-            }
-        ]
-    }
-}}
-{{< block_myoverview/paging-content }}
-    {{$paging-content-item}}
-        {{> block_myoverview/course-paging-content-item }}
-    {{/paging-content-item}}
-{{/ block_myoverview/paging-content }}
diff --git a/blocks/myoverview/templates/courses-view-by-status.mustache b/blocks/myoverview/templates/courses-view-by-status.mustache
deleted file mode 100644 (file)
index 3360d55..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-{{!
-    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 block_myoverview/courses-view-by-status
-
-    This template renders the courses view for the myoverview block.
-
-    Example context (json):
-    {}
-}}
-<div id="{{$id}}courses-view-status-{{uniqid}}{{/id}}"
-     data-status="{{$status}}{{/status}}">
-
-    {{> block_myoverview/course-paging-content }}
-
-    <div class="text-xs-center text-center">
-        {{> block_myoverview/paging-bar }}
-    </div>
-</div>
-{{#js}}
-require(['jquery', 'block_myoverview/paging_bar', 'block_myoverview/paging_content'],
-    function($, PagingBar, PagingContent) {
-
-    var root = $('#{{$id}}courses-view-status-{{uniqid}}{{/id}}');
-    var pagingBarElement = root.find(PagingBar.rootSelector);
-    var pagingContentElement = root.find(PagingContent.rootSelector);
-
-    var content = new PagingContent(pagingContentElement, pagingBarElement);
-    content.registerEventListeners();
-});
-{{/js}}
diff --git a/blocks/myoverview/templates/courses-view-course-item.mustache b/blocks/myoverview/templates/courses-view-course-item.mustache
deleted file mode 100644 (file)
index db2034d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-{{!
-    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 block_myoverview/courses-view-course-item
-
-    This template renders the course summary (view by courses) for the myoverview block.
-
-    Example context (json):
-    {
-        "fullnamedisplay": "course 3",
-        "viewurl": "https://www.google.com",
-        "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-    }
-}}
-<div class="card mb-3 courses-view-course-item">
-    <a href="{{viewurl}}">
-        <div class="card-img-top myoverviewimg {{classes}}" style='background-image: url("{{{courseimage}}}");'>
-        </div>
-    </a>
-    <div class="card-body course-info-container" id="course-info-container-{{id}}">
-
-        <div class="media">
-            <div class="mr-2">
-                {{> block_myoverview/progress-chart}}
-            </div>
-            <div class="media-body">
-                <h4 class="h5"><a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a></h4>
-            </div>
-        </div>
-
-        <p class="text-muted">
-            {{#shortentext}} 140, {{summary}}{{/shortentext}}
-        </p>
-    </div>
-</div>
\ No newline at end of file
diff --git a/blocks/myoverview/templates/courses-view-nav-grouping-display-filter.mustache b/blocks/myoverview/templates/courses-view-nav-grouping-display-filter.mustache
deleted file mode 100644 (file)
index f7aa275..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-{{!
-    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 block_myoverview/courses-view-nav-grouping-display-filter
-
-    This template renders the main content area for the myoverview block.
-
-    Example context (json):
-    {}
-}}
-<div data-region="courses-grouping-display-filter" class="btn-group">
-    <button type="button" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-        {{#str}} inprogress, block_myoverview {{/str}}
-    </button>
-    <div class="dropdown-menu list-group hidden" data-show-active-item data-skip-active-class="true">
-        <a class="dropdown-item active" href="#myoverview_courses_view_in_progress" data-toggle="tab">
-            {{#str}} inprogress, block_myoverview {{/str}}
-        </a>
-        <a class="dropdown-item" href="#myoverview_courses_view_future" data-toggle="tab">
-            {{#str}} future, block_myoverview {{/str}}
-        </a>
-        <a class="dropdown-item" href="#myoverview_courses_view_past" data-toggle="tab">
-            {{#str}} past, block_myoverview {{/str}}
-        </a>
-    </div>
-</div>
index cb5b926..ab97aa4 100644 (file)
     This template renders the courses view for the myoverview block.
 
     Example context (json):
-    {}
+    {
+        "nocoursesimg": "https://moodlesite/theme/image.php/boost/block_myoverview/1535727318/courses"
+    }
 }}
-<div id="courses-view-{{uniqid}}" data-region="courses-view">
-    {{#hascourses}}
-    <div class="tab-content">
-        <div class="tab-pane active fade show" id="myoverview_courses_view_in_progress">
-            {{#inprogress}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-in-progress{{/id}}
-                    {{$status}}1{{/status}}
-                    {{$pagingbarid}}pb-for-in-progress{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/inprogress}}
-            {{^inprogress}}
-                <div class="justify-content-center text-center mt-5">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursesinprogress, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted mt-3">{{#str}} nocoursesinprogress, block_myoverview {{/str}}</p>
-                </div>
-            {{/inprogress}}
+<div id="courses-view-{{uniqid}}"
+    data-region="courses-view"
+    data-display="cards"
+    data-grouping="all"
+    data-sort="fullname"
+    data-nocoursesimg="{{nocoursesimg}}">
+    <div data-region="course-view-content">
+        <div data-region="courses-loading-placeholder">
+            <div class="row card-deck">
+                {{> block_myoverview/placeholder-course }}
+                {{> block_myoverview/placeholder-course }}
+                {{> block_myoverview/placeholder-course }}
+                {{> block_myoverview/placeholder-course }}
+            </div>
         </div>
-        <div class="tab-pane fade" id="myoverview_courses_view_future">
-            {{#future}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-future{{/id}}
-                    {{$status}}2{{/status}}
-                    {{$pagingbarid}}pb-for-future{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/future}}
-            {{^future}}
-                <div class="justify-content-center text-center mt-5">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursesfuture, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted mt-3">{{#str}} nocoursesfuture, block_myoverview {{/str}}</p>
-                </div>
-            {{/future}}
-        </div>
-        <div class="tab-pane fade" id="myoverview_courses_view_past">
-            {{#past}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-past{{/id}}
-                    {{$status}}0{{/status}}
-                    {{$pagingbarid}}pb-for-past{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/past}}
-            {{^past}}
-                <div class="justify-content-center text-center mt-5">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursespast, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted mt-3">{{#str}} nocoursespast, block_myoverview {{/str}}</p>
-                </div>
-            {{/past}}
-        </div>
-    </div>
-    {{/hascourses}}
-    {{^hascourses}}
-    <div class="justify-content-center text-center mt-5">
-        <img class="empty-placeholder-image-lg"
-             src="{{urls.nocourses}}"
-             alt="{{#str}} nocourses, block_myoverview {{/str}}"
-             role="presentation">
-        <p class="text-muted mt-3">{{#str}} nocourses, block_myoverview {{/str}}</p>
     </div>
-    {{/hascourses}}
-</div>
\ No newline at end of file
+</div>
index fef8e9f..1d593e8 100644 (file)
     {}
 }}
 
-<div id="block-myoverview-{{uniqid}}" class="block-myoverview" data-region="myoverview">
-    <div class="container p-0 m-b-1">
-        <div class="row no-gutters">
-            {{#coursesview}}
-                {{#hascourses}}
-                    <div class="{{#viewingtimeline}}d-none{{/viewingtimeline}}" data-tab-content="courses">
-                        {{> block_myoverview/courses-view-nav-grouping-display-filter }}
-                    </div>
-                {{/hascourses}}
-            {{/coursesview}}
-        </div>
-    </div>
-    <div class="container p-0">
-        {{#coursesview}}
+<div id="block-myoverview-{{uniqid}}" class="block-myoverview" data-region="myoverview" role="navigation">
+
+            <div data-region="filter" class="d-flex m-b-1" aria-label="{{#str}} aria:controls, block_myoverview {{/str}}">
+                {{> block_myoverview/nav-grouping-selector }}
+
+                {{> block_myoverview/nav-sort-selector }}
+
+                {{> block_myoverview/nav-display-selector }}
+            </div>
+
+    <div class="container-fluid p-0">
         {{> block_myoverview/courses-view }}
-        {{/coursesview}}
     </div>
 </div>
+{{#js}}
+require(
+[
+    'jquery',
+    'block_myoverview/main',
+],
+function(
+    $,
+    Main
+) {
+    var root = $('#block-myoverview-{{uniqid}}');
+    Main.init(root);
+});
+{{/js}}
diff --git a/blocks/myoverview/templates/nav-display-selector.mustache b/blocks/myoverview/templates/nav-display-selector.mustache
new file mode 100644 (file)
index 0000000..e5661dc
--- /dev/null
@@ -0,0 +1,47 @@
+{{!
+    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 block_myoverview/nav-display-selector
+
+    This template renders display dropdown.
+
+    Example context (json):
+    {}
+}}
+<div class="dropdown">
+    <button id="displaydropdown" type="button" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
+    aria-label="{{#str}} aria:displaydropdown, block_myoverview {{/str}}">
+        <span class="d-sm-inline-block">{{#pix}} a/view_icon_active {{/pix}}</span>
+    </button>
+    <ul class="dropdown-menu" data-show-active-item aria-labelledby="displaydropdown">
+        <li>
+            <a class="dropdown-item active" href="#" data-display-option="display" data-value="cards" aria-label="{{#str}} aria:card, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+            {{#str}} card, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-display-option="display" data-value="list" aria-label="{{#str}} aria:list, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+            {{#str}} list, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-display-option="display" data-value="summary" aria-label="{{#str}} aria:summary, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+            {{#str}} summary, block_myoverview {{/str}}
+            </a>
+        </li>
+    </ul>
+</div>
\ No newline at end of file
diff --git a/blocks/myoverview/templates/nav-grouping-selector.mustache b/blocks/myoverview/templates/nav-grouping-selector.mustache
new file mode 100644 (file)
index 0000000..ac57aa7
--- /dev/null
@@ -0,0 +1,51 @@
+{{!
+    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 block_myoverview/nav-grouping-selector
+
+    This template renders grouping dropdown.
+
+    Example context (json):
+    {}
+}}
+<div class="dropdown">
+    <button id="groupingdropdown" type="button" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{{#str}} aria:groupingdropdown, block_myoverview {{/str}}">
+        <span class="d-sm-inline-block">{{#str}} all, block_myoverview {{/str}}</span>
+    </button>
+    <ul class="dropdown-menu" data-show-active-item aria-labelledby="groupingdropdown">
+        <li>
+            <a class="dropdown-item active" href="#" data-filter="grouping" data-value="all" aria-label="{{#str}} aria:allcourses, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} all, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-filter="grouping" data-value="inprogress" aria-label="{{#str}} aria:inprogress, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} inprogress, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-filter="grouping" data-value="future" aria-label="{{#str}} aria:future, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} future, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-filter="grouping" data-value="past" aria-label="{{#str}} aria:past, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} past, block_myoverview {{/str}}
+            </a>
+        </li>
+    </ul>
+</div>
diff --git a/blocks/myoverview/templates/nav-sort-selector.mustache b/blocks/myoverview/templates/nav-sort-selector.mustache
new file mode 100644 (file)
index 0000000..e647be9
--- /dev/null
@@ -0,0 +1,43 @@
+{{!
+    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 block_myoverview/nav-sort-selector
+
+    This template renders sorting dropdown.
+
+    Example context (json):
+    {}
+}}
+
+<div class="dropdown mr-1 ml-auto">
+    {{#str}} sortby, core {{/str}}
+    <button id="sortingdropdown" type="button" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown"  aria-haspopup="true" aria-expanded="false" aria-label="{{#str}} aria:sortingdropdown, block_myoverview {{/str}}">
+        <span class="d-sm-inline-block">{{#str}} title, block_myoverview {{/str}}</span>
+    </button>
+    <ul class="dropdown-menu" data-show-active-item aria-labelledby="sortingdropdown">
+        <li>
+            <a class="dropdown-item active" href="#" data-filter="sort" data-value="fullname" aria-label="{{#str}} aria:title, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} title, block_myoverview {{/str}}
+            </a>
+        </li>
+        <li>
+            <a class="dropdown-item" href="#" data-filter="sort" data-value="ul.timeaccess desc" aria-label="{{#str}} aria:lastaccessed, block_myoverview {{/str}}" aria-controls="courses-view-{{uniqid}}">
+                {{#str}} lastaccessed, block_myoverview {{/str}}
+            </a>
+        </li>
+    </ul>
+</div>
\ No newline at end of file
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
-    @template block_myoverview/paging-bar-item
+    @template block_myoverview/no-courses
 
-    This template renders a single item in the paging bar.
+    This template renders the no courses message.
 
     Example context (json):
     {
-        "url": "#",
-        "number": 1,
-        "page": "1",
-        "active": true
+        "nocoursesimg": "https://moodlesite/theme/image.php/boost/block_myoverview/1535727318/courses"
     }
 }}
-<li class="page-item {{#active}}active{{/active}} {{#disabled}}disabled{{/disabled}}"
-    data-region="page-item"
-    data-page-number="{{$pagenumber}}{{number}}{{/pagenumber}}">
-
-    <a href="{{url}}"
-       class="page-link"
-       data-region="page-link">
-        {{$item-content}}
-            {{{page}}}
-        {{/item-content}}
-    </a>
-</li>
+<div class="text-xs-center text-center m-t-3" data-region="empty-message">
+    <img class="empty-placeholder-image-lg"
+         src="{{nocoursesimg}}"
+         alt="{{#str}} nocourses, block_myoverview {{/str}}"
+         role="presentation">
+    <p class="text-muted mt-3">{{#str}} nocourses, block_myoverview {{/str}}</p>
+</div> 
\ No newline at end of file
diff --git a/blocks/myoverview/templates/paging-bar.mustache b/blocks/myoverview/templates/paging-bar.mustache
deleted file mode 100644 (file)
index 71ffecf..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-{{!
-    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 block_myoverview/paging-bar
-
-    This template renders the bootstrap style paging bar.
-
-    Example context (json):
-    {
-        "pagingbar": {
-            "pagecount": 2,
-            "previous": {},
-            "next": {},
-            "first": {
-                "url": "#",
-                "page": "first"
-            },
-            "last": {
-                "url": "#",
-                "page": "last"
-            },
-            "pages": [
-                {
-                    "url": "#",
-                    "number": 1,
-                    "page": "1",
-                    "active": true
-                },
-                {
-                    "url": "#",
-                    "number": 2,
-                    "page": "2"
-                }
-            ]
-        }
-    }
-}}
-{{#pagingbar}}
-<nav aria-label="{{label}}"
-     id="{{$pagingbarid}}paging-bar-{{uniqid}}{{/pagingbarid}}"
-     data-region="paging-bar"
-     data-page-count="{{pagecount}}">
-
-    <ul class="pagination">
-        {{#previous}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$item-content}}
-                    <span aria-hidden="true">&laquo;</span>
-                    <span class="sr-only">{{#str}}previous{{/str}}</span>
-                {{/item-content}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/previous}}
-        {{#first}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$pagenumber}}first{{/pagenumber}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/first}}
-        {{#pages}}
-            {{> block_myoverview/paging-bar-item }}
-        {{/pages}}
-        {{#last}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$pagenumber}}last{{/pagenumber}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/last}}
-        {{#next}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$item-content}}
-                    <span aria-hidden="true">&raquo;</span>
-                    <span class="sr-only">{{#str}}next{{/str}}</span>
-                {{/item-content}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/next}}
-    </ul>
-</nav>
-{{#js}}
-require(['jquery', 'block_myoverview/paging_bar'], function($, PagingBar) {
-    var root = $('#{{$pagingbarid}}paging-bar-{{uniqid}}{{/pagingbarid}}');
-    PagingBar.registerEventListeners(root);
-});
-{{/js}}
-{{/pagingbar}}
diff --git a/blocks/myoverview/templates/paging-content.mustache b/blocks/myoverview/templates/paging-content.mustache
deleted file mode 100644 (file)
index 83a9cdd..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-{{!
-    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 block_myoverview/paging-content
-
-    This template renders each of the content regions for a paginated
-    content section.
-
-    Example context (json):
-    {
-        "pages": [
-            {
-                "active": true,
-                "page": 1,
-                "content": "<p>Some page content</p>"
-            },
-            {
-                "page": 2,
-                "content": "<p>Some page content</p>"
-            }
-        ]
-    }
-}}
-<div id="{{$pagingcontentid}}paging-content-{{uniqid}}{{/pagingcontentid}}" data-region="paging-content">
-    {{#pages}}
-        {{$paging-content-item}}
-            {{> block_myoverview/paging-content-item }}
-        {{/paging-content-item}}
-    {{/pages}}
-</div>
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
-    @template block_myoverview/paging-content-item
+    @template block_myoverview/placeholder-course
 
-    This template renders the content of a page. It is to be used with
-    the paging bar to toggle visibility of the content items.
+    This template renders an course card item loading placeholder for the myoverview block.
 
     Example context (json):
-    {
-        "active": true,
-        "page": 1,
-        "content": "<p>Some page content</p>"
-    }
+    {}
 }}
-<div data-region="paging-content-item"
-     data-page="{{page}}"
-     class="row-fluid {{^active}}hidden{{/active}} {{$classes}}{{/classes}}">
-    {{$content}}
-        {{{content}}}
-    {{/content}}
-</div>
+<div class="card course-card border-0">
+    <div class="card-img-top bg-pulse-grey w-100" style="height: 7rem">
+    </div>
+    <div class="card-body course-info-container">
+        <div class="bg-pulse-grey w-100 m-b-3" style="height: 1rem"></div>
+    </div>
+    <div class="bg-pulse-grey w-100" style="height: 3rem">
+    </div>
+</div> 
\ No newline at end of file
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
-    @template block_myoverview/paging-content-item
+    @template block_myoverview/progress-bar
 
-    This template renders the content of a page. It is to be used with
-    the paging bar to toggle visibility of the content items.
+    This template renders a simple progress bar.
 
     Example context (json):
     {
-        "active": true,
-        "page": 1,
-        "content": "<p>Some page content</p>"
+        "progress": 50
     }
 }}
-<div data-region="paging-content-item"
-     data-page="{{page}}"
-     class="{{^active}}hidden{{/active}} {{$classes}}{{/classes}}">
-    {{$content}}
-        {{{content}}}
-    {{/content}}
+
+<div class="progress">
+       <div class="progress-bar bar" role="progressbar" aria-valuenow="{{progress}}" style="width: {{progress}}%" aria-valuemin="0" aria-valuemax="100"></div>
 </div>
+<div class="small">
+    <span class="sr-only">{{#str}}aria:courseprogress, block_myoverview{{/str}}</span>
+       <strong>{{progress}}%</strong> {{#str}}complete, block_myoverview{{/str}}
+</div>
\ No newline at end of file
diff --git a/blocks/myoverview/templates/progress-chart.mustache b/blocks/myoverview/templates/progress-chart.mustache
deleted file mode 100644 (file)
index 18ff2a4..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-{{!
-    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 block_myoverview/progress-chart
-
-    This template renders a doughnut chart to show course progress.
-
-    Example context (json):
-    {
-        "hasprogress": true,
-        "progress": "60"
-    }
-}}
-<div class="progress-chart-container m-b-1">
-    {{#hasprogress}}
-    <div class="progress-doughnut">
-        <div class="progress-text {{#progress}}has-percent{{/progress}}">{{progress}}&#37;</div>
-        <div class="progress-indicator">
-            <svg xmlns="http://www.w3.org/2000/svg">
-                <g>
-                    <title aria-hidden="true">{{progress}}&#37;</title>
-                    <circle class="circle percent-{{progress}}"
-                            r="27.5"
-                            cx="35"
-                            cy="35"/>
-                </g>
-            </svg>
-        </div>
-    </div>
-    {{/hasprogress}}
-    {{^hasprogress}}
-    <div class="no-progress">
-        {{#pix}} i/course {{/pix}}
-    </div>
-    {{/hasprogress}}
-</div>
diff --git a/blocks/myoverview/templates/view-cards.mustache b/blocks/myoverview/templates/view-cards.mustache
new file mode 100644 (file)
index 0000000..8b0eaa3
--- /dev/null
@@ -0,0 +1,62 @@
+{{!
+    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 block_myoverview/view-cards
+
+    This template renders the cards view for the myoverview block.
+
+    Example context (json):
+    {
+        "courses": [
+            {
+                "name": "Assignment due 1",
+                "viewurl": "https://moodlesite/course/view.php?id=2",
+                "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg",
+                "fullname": "course 3",
+                "hasprogress": true,
+                "progress": 10
+            }
+        ]
+    }
+}}
+
+<div class="row card-deck" role="list">
+{{#courses}}
+    <div class="card course-card" role="listitem">
+        <a href="{{viewurl}}" tabindex="-1" role="presentation">
+            <div class="card-img-top myoverviewimg" style='background-image: url("{{{courseimage}}}");'>
+                <span class="sr-only">{{#str}}aria:courseimage, block_myoverview{{/str}}</span>
+            </div>
+        </a>
+        <div class="card-body course-info-container" id="course-info-container-{{id}}">
+            <div class="d-flex">
+                <div class="card-title">
+                    <a href="{{viewurl}}">
+                        <span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
+                        {{#shortentext}}140, {{{fullname}}} {{/shortentext}}
+                    </a>
+                </div>
+            </div>
+        </div>
+        {{#hasprogress}}
+        <div class="card-footer course-card-footer">
+            {{> block_myoverview/progress-bar}}
+        </div>
+        {{/hasprogress}}
+    </div>
+{{/courses}}
+</div>
\ No newline at end of file
diff --git a/blocks/myoverview/templates/view-list.mustache b/blocks/myoverview/templates/view-list.mustache
new file mode 100644 (file)
index 0000000..799c524
--- /dev/null
@@ -0,0 +1,55 @@
+{{!
+    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 block_myoverview/view-list
+
+    This template renders the list view for the myoverview block.
+
+    Example context (json):
+    {
+        "courses": [
+            {
+                "name": "Assignment due 1",
+                "viewurl": "https://moodlesite/course/view.php?id=2",
+                "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg",
+                "fullname": "course 3",
+                "hasprogress": true,
+                "progress": 10
+            }
+        ]
+    }
+}}  
+
+<ul class="list-group" role="list">
+{{#courses}}
+    <li class="list-group-item course-listitem" role="listitem">
+        <div class="row-fluid">
+            <div class="{{#hasprogress}}col-6 span6{{/hasprogress}}{{^hasprogress}}col-12 span12{{/hasprogress}}">
+                <a href="{{viewurl}}">
+                    <span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
+                    {{{fullname}}}
+                </a>
+            </div>
+            {{#hasprogress}}
+            <div class="col-6 span6">
+                {{> block_myoverview/progress-bar}}
+            </div>
+            {{/hasprogress}}
+        </div>
+    </li>
+{{/courses}}
+</ul>
\ No newline at end of file
diff --git a/blocks/myoverview/templates/view-summary.mustache b/blocks/myoverview/templates/view-summary.mustache
new file mode 100644 (file)
index 0000000..8f9531c
--- /dev/null
@@ -0,0 +1,62 @@
+{{!
+    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 block_myoverview/view-summary
+
+    This template renders the list view for the myoverview block.
+
+    Example context (json):
+    {
+        "courses": [
+            {
+                "name": "Assignment due 1",
+                "viewurl": "https://moodlesite/course/view.php?id=2",
+                "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg",
+                "fullname": "course 3",
+                "summary": "This course is about assignments",
+                "hasprogress": true,
+                "progress": 10
+            }
+        ]
+    }
+}}
+<div role="list">
+{{#courses}}
+    <div class="course-summaryitem m-b-1 p-2" role="listitem">
+        <div class="row-fluid d-flex">
+            <a href="{{viewurl}}" class="col-sm-4 col-xl-3 span4" tabindex="-1" role="presentation">
+                <img src="{{{courseimage}}}" class="summaryimage img-fluid" alt="{{#str}}aria:courseimage, block_myoverview{{/str}}">
+            </a>
+            <div class="col-sm-8 col-xl-9 span8 align-self-stretch d-flex flex-column">
+                <a href="{{viewurl}}">
+                    <span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
+                    <h4>{{{fullname}}}</h4>
+                </a>
+                <div class="summary">
+                    <span class="sr-only">{{#str}}aria:coursesummary, block_myoverview{{/str}}</span>
+                    {{{summary}}}
+                </div>
+                <div class="ml-auto mt-auto w-50 p-t-1">
+                    {{#hasprogress}}
+                        {{> block_myoverview/progress-bar}}
+                    {{/hasprogress}}
+                </div>
+            </div>
+        </div>
+    </div>
+{{/courses}}
+</div>
\ No newline at end of file
index de37359..7607052 100644 (file)
@@ -7,30 +7,62 @@ Feature: The my overview block allows users to easily access their courses
   Background:
     Given the following "users" exist:
       | username | firstname | lastname | email                | idnumber |
-      | student1 | Student   | 1        | student1@example.com | S1       |
-      | student2 | Student   | 2        | student2@example.com | S2       |
+      | student1 | Student   | X        | student1@example.com | S1       |
     And the following "courses" exist:
       | fullname | shortname | category | startdate                   | enddate         |
       | Course 1 | C1        | 0        | ##1 month ago##             | ##15 days ago## |
       | Course 2 | C2        | 0        | ##yesterday##               | ##tomorrow## |
-      | Course 3 | C3        | 0        | ##first day of next month## | ##last day of next month## |
+      | Course 3 | C3        | 0        | ##yesterday##               | ##tomorrow## |
+      | Course 4 | C4        | 0        | ##yesterday##               | ##tomorrow## |
+      | Course 5 | C5        | 0        | ##first day of next month## | ##last day of next month## |
     And the following "course enrolments" exist:
       | user | course | role |
       | student1 | C1 | student |
       | student1 | C2 | student |
       | student1 | C3 | student |
+      | student1 | C4 | student |
+      | student1 | C5 | student |
 
-  Scenario: See the courses I am enrolled by their status on courses view
+  Scenario: View past courses
     Given I log in as "student1"
-    And I should see "Course 2" in the "Course overview" "block"
-    And I should not see "Course 1" in the "Course overview" "block"
-    And I click on "In progress" "button" in the "Course overview" "block"
-    And I click on "Future" "link" in the "Course overview" "block"
-    And I should see "Course 3" in the "Course overview" "block"
-    And I should not see "Course 1" in the "Course overview" "block"
-    And I click on "Future" "button" in the "Course overview" "block"
+    And I click on "All" "button" in the "Course overview" "block"
     When I click on "Past" "link" in the "Course overview" "block"
     Then I should see "Course 1" in the "Course overview" "block"
     And I should not see "Course 2" in the "Course overview" "block"
     And I should not see "Course 3" in the "Course overview" "block"
+    And I should not see "Course 4" in the "Course overview" "block"
+    And I should not see "Course 5" in the "Course overview" "block"
+    And I log out
+
+  Scenario: View future courses
+    Given I log in as "student1"
+    And I click on "All" "button" in the "Course overview" "block"
+    When I click on "Future" "link" in the "Course overview" "block"
+    Then I should see "Course 5" in the "Course overview" "block"
+    And I should not see "Course 1" in the "Course overview" "block"
+    And I should not see "Course 2" in the "Course overview" "block"
+    And I should not see "Course 3" in the "Course overview" "block"
+    And I should not see "Course 4" in the "Course overview" "block"
     And I log out
+
+  Scenario: View inprogress courses
+    Given I log in as "student1"
+    And I click on "All" "button" in the "Course overview" "block"
+    When I click on "In progress" "link" in the "Course overview" "block"
+    Then I should see "Course 2" in the "Course overview" "block"
+    Then I should see "Course 3" in the "Course overview" "block"
+    Then I should see "Course 4" in the "Course overview" "block"
+    And I should not see "Course 1" in the "Course overview" "block"
+    And I should not see "Course 5" in the "Course overview" "block"
+    And I log out
+
+  Scenario: View all courses
+    Given I log in as "student1"
+    And I click on "All" "button" in the "Course overview" "block"
+    When I click on "All" "link" in the "Course overview" "block"
+    Then I should see "Course 1" in the "Course overview" "block"
+    Then I should see "Course 2" in the "Course overview" "block"
+    Then I should see "Course 3" in the "Course overview" "block"
+    Then I should see "Course 4" in the "Course overview" "block"
+    Then I should see "Course 5" in the "Course overview" "block"
+    And I log out
\ No newline at end of file
index 5ed5656..06813f5 100644 (file)
@@ -20,6 +20,13 @@ Feature: Course overview block show users their progress on courses
       | teacher1 | C1 | editingteacher  |
       | student1 | C1 | student         |
 
+  Scenario: Course progress percentage should not be displayed if completion is not enabled
+    Given I log in as "student1"
+    And I click on "All" "button" in the "Course overview" "block"
+    When I click on "All" "link" in the "Course overview" "block"
+    Then I should not see "0%" in the "Course overview" "block"
+    And I log out
+
   Scenario: User complete activity and verify his progress
     Given I log in as "teacher1"
     And I am on "Course 1" course homepage with editing mode on
@@ -30,12 +37,13 @@ Feature: Course overview block show users their progress on courses
       | id_completionview   | 1                                                 |
     And I press "Save and return to course"
     And I log out
-    And I log in as "student1"
+    When I log in as "student1"
+    And I click on "All" "button" in the "Course overview" "block"
     Then I should see "Course 1" in the "Course overview" "block"
     And I should see "0%" in the "Course overview" "block"
     And I am on "Course 1" course homepage
     And I follow "Test choice 1"
     And I follow "Dashboard" in the user menu
-    And I should see "Course 1" in the "Course overview" "block"
+    And I click on "All" "button" in the "Course overview" "block"
     And I should see "100%" in the "Course overview" "block"
     And I log out
index 6b8960c..14b42c4 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2018092700;         // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version   = 2018100100;         // The current plugin version (Date: YYYYMMDDXX).
 $plugin->requires  = 2018050800;         // Requires this Moodle version.
 $plugin->component = 'block_myoverview'; // Full name of the plugin (used for diagnostics).
index 342296e..032c018 100644 (file)
@@ -41,9 +41,22 @@ class course_summary_exporter extends \core\external\exporter {
     }
 
     protected function get_other_values(renderer_base $output) {
+        $courseimage = self::get_course_image($this->data);
+        if (!$courseimage) {
+            $courseimage = self::get_course_pattern($this->data);
+        }
+        $progress = self::get_course_progress($this->data);
+        $hasprogress = false;
+        if ($progress === 0 || $progress > 0) {
+            $hasprogress = true;
+        }
+        $progress = floor($progress);
         return array(
             'fullnamedisplay' => get_course_display_name_for_list($this->data),
-            'viewurl' => (new moodle_url('/course/view.php', array('id' => $this->data->id)))->out(false)
+            'viewurl' => (new moodle_url('/course/view.php', array('id' => $this->data->id)))->out(false),
+            'courseimage' => $courseimage,
+            'progress' => $progress,
+            'hasprogress' => $hasprogress
         );
     }
 
@@ -96,7 +109,81 @@ class course_summary_exporter extends \core\external\exporter {
             ),
             'viewurl' => array(
                 'type' => PARAM_URL,
+            ),
+            'courseimage' => array(
+                'type' => PARAM_RAW,
+            ),
+            'progress' => array(
+                'type' => PARAM_INT,
+                'optional' => true
+            ),
+            'hasprogress' => array(
+                'type' => PARAM_BOOL
             )
         );
     }
+
+    /**
+     * Get the course image if added to course.
+     *
+     * @param object $course
+     * @return string url of course image
+     */
+    public static function get_course_image($course) {
+        global $CFG;
+        $courseinlist = new \core_course_list_element($course);
+        foreach ($courseinlist->get_course_overviewfiles() as $file) {
+            if ($file->is_valid_image()) {
+                $pathcomponents = [
+                    '/pluginfile.php',
+                    $file->get_contextid(),
+                    $file->get_component(),
+                    $file->get_filearea() . $file->get_filepath() . $file->get_filename()
+                ];
+                $path = implode('/', $pathcomponents);
+                return (new moodle_url($path))->out();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the course pattern datauri.
+     *
+     * The datauri is an encoded svg that can be passed as a url.
+     * @param object $course
+     * @return string datauri
+     */
+    public static function get_course_pattern($course) {
+        $color = self::coursecolor($course->id);
+        $pattern = new \core_geopattern();
+        $pattern->setColor($color);
+        $pattern->patternbyid($course->id);
+        return $pattern->datauri();
+    }
+
+    /**
+     * Get the course progress percentage.
+     *
+     * @param object $course
+     * @return int progress
+     */
+    public static function get_course_progress($course) {
+        return \core_completion\progress::get_course_progress_percentage($course);
+    }
+
+    /**
+     * Get the course color.
+     *
+     * @param int $courseid
+     * @return string hex color code.
+     */
+    public static function coursecolor($courseid) {
+        // The colour palette is hardcoded for now. It would make sense to combine it with theme settings.
+        $basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894',
+            '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
+
+        $color = $basecolors[$courseid % 10];
+        return $color;
+    }
 }
index 0aadfae..08c35bf 100644 (file)
@@ -3654,6 +3654,8 @@ class core_course_external extends external_api {
         $sort = $params['sort'];
 
         switch($classification) {
+            case COURSE_TIMELINE_ALL:
+                break;
             case COURSE_TIMELINE_PAST:
                 break;
             case COURSE_TIMELINE_INPROGRESS:
index c255e55..a1d9680 100644 (file)
@@ -55,6 +55,7 @@ define('FIRSTUSEDEXCELROW', 3);
 define('MOD_CLASS_ACTIVITY', 0);
 define('MOD_CLASS_RESOURCE', 1);
 
+define('COURSE_TIMELINE_ALL', 'all');
 define('COURSE_TIMELINE_PAST', 'past');
 define('COURSE_TIMELINE_INPROGRESS', 'inprogress');
 define('COURSE_TIMELINE_FUTURE', 'future');
@@ -4204,8 +4205,9 @@ function course_filter_courses_by_timeline_classification(
     int $limit = 0
 ) : array {
 
-    if (!in_array($classification, [COURSE_TIMELINE_PAST, COURSE_TIMELINE_INPROGRESS, COURSE_TIMELINE_FUTURE])) {
-        $message = 'Classification must be one of COURSE_TIMELINE_PAST, '
+    if (!in_array($classification,
+            [COURSE_TIMELINE_ALL, COURSE_TIMELINE_PAST, COURSE_TIMELINE_INPROGRESS, COURSE_TIMELINE_FUTURE])) {
+        $message = 'Classification must be one of COURSE_TIMELINE_ALL, COURSE_TIMELINE_PAST, '
             . 'COURSE_TIMELINE_INPROGRESS or COURSE_TIMELINE_FUTURE';
         throw new moodle_exception($message);
     }
@@ -4217,7 +4219,7 @@ function course_filter_courses_by_timeline_classification(
     foreach ($courses as $course) {
         $numberofcoursesprocessed++;
 
-        if ($classification == course_classify_for_timeline($course)) {
+        if ($classification == COURSE_TIMELINE_ALL || $classification == course_classify_for_timeline($course)) {
             $filteredcourses[] = $course;
             $filtermatches++;
         }
index abde22d..e7759b0 100644 (file)
@@ -2556,6 +2556,66 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
                 'expectedcourses' => ['cfuture', 'dfuture', 'efuture'],
                 'expectednextoffset' => 15
             ],
+            'all no limit or offset' => [
+                'coursedata' => $coursedata,
+                'classification' => 'all',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => [
+                    'afuture',
+                    'ainprogress',
+                    'apast',
+                    'bfuture',
+                    'binprogress',
+                    'bpast',
+                    'cfuture',
+                    'cinprogress',
+                    'cpast',
+                    'dfuture',
+                    'dinprogress',
+                    'dpast',
+                    'efuture',
+                    'einprogress',
+                    'epast'
+                ],
+                'expectednextoffset' => 15
+            ],
+            'all limit no offset' => [
+                'coursedata' => $coursedata,
+                'classification' => 'all',
+                'limit' => 5,
+                'offset' => 0,
+                'expectedcourses' => [
+                    'afuture',
+                    'ainprogress',
+                    'apast',
+                    'bfuture',
+                    'binprogress'
+                ],
+                'expectednextoffset' => 5
+            ],
+            'all limit and offset' => [
+                'coursedata' => $coursedata,
+                'classification' => 'all',
+                'limit' => 5,
+                'offset' => 5,
+                'expectedcourses' => [
+                    'bpast',
+                    'cfuture',
+                    'cinprogress',
+                    'cpast',
+                    'dfuture'
+                ],
+                'expectednextoffset' => 10
+            ],
+            'all offset past result set' => [
+                'coursedata' => $coursedata,
+                'classification' => 'all',
+                'limit' => 5,
+                'offset' => 50,
+                'expectedcourses' => [],
+                'expectednextoffset' => 50
+            ],
         ];
     }
 
index 0cabb96..34b5b48 100644 (file)
@@ -792,4 +792,186 @@ class core_enrollib_testcase extends advanced_testcase {
         // There are still only two distinct users.
         $this->assertEquals(2, count_enrolled_users($context));
     }
+
+    /**
+     * Test cases for the test_enrol_get_my_courses_sort_by_last_access test.
+     */
+    public function get_enrol_get_my_courses_sort_by_last_access_test_cases() {
+        $now = time();
+
+        $enrolledcoursesdata = [
+            ['shortname' => 'a', 'lastaccess' => $now - 2],
+            ['shortname' => 'b', 'lastaccess' => $now - 1],
+            ['shortname' => 'c', 'lastaccess' => $now],
+            ['shortname' => 'd', 'lastaccess' => $now - 1],
+            ['shortname' => 'e']
+        ];
+        $unenrolledcoursesdata = [
+            ['shortname' => 'x', 'lastaccess' => $now - 2],
+            ['shortname' => 'y', 'lastaccess' => $now - 1],
+            ['shortname' => 'z', 'lastaccess' => $now]
+        ];
+
+        return [
+            'empty set' => [
+                'enrolledcoursesdata' => [],
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => []
+            ],
+            'ul.timeaccess asc, shortname asc no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc, shortname asc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['e', 'a', 'b', 'd', 'c']
+            ],
+            'ul.timeaccess asc, shortname asc with limit no offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc, shortname asc',
+                'limit' => 2,
+                'offset' => 0,
+                'expectedcourses' => ['e', 'a']
+            ],
+            'ul.timeaccess asc, shortname asc with limit and offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc, shortname asc',
+                'limit' => 2,
+                'offset' => 2,
+                'expectedcourses' => ['b', 'd']
+            ],
+            'ul.timeaccess asc, shortname asc with limit and offset beyond end of data set' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc, shortname asc',
+                'limit' => 2,
+                'offset' => 4,
+                'expectedcourses' => ['c']
+            ],
+            'ul.timeaccess desc, shortname asc no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess desc, shortname asc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['c', 'b', 'd', 'a', 'e']
+            ],
+            'ul.timeaccess desc, shortname desc, no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess desc, shortname desc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['c', 'd', 'b', 'a', 'e']
+            ],
+            'ul.timeaccess asc, shortname desc, no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'ul.timeaccess asc, shortname desc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['e', 'a', 'd', 'b', 'c']
+            ],
+            'shortname asc, no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'shortname asc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['a', 'b', 'c', 'd', 'e']
+            ],
+            'shortname desc, no limit or offset' => [
+                'enrolledcoursesdata' => $enrolledcoursesdata,
+                'unenrolledcoursesdata' => $unenrolledcoursesdata,
+                'sort' => 'shortname desc',
+                'limit' => 0,
+                'offset' => 0,
+                'expectedcourses' => ['e', 'd', 'c', 'b', 'a']
+            ],
+        ];
+    }
+
+    /**
+     * Test the get_enrolled_courses_by_timeline_classification function.
+     *
+     * @dataProvider get_enrol_get_my_courses_sort_by_last_access_test_cases()
+     * @param array $enrolledcoursesdata Courses to create and enrol the user in
+     * @param array $unenrolledcoursesdata Courses to create nut not enrol the user in
+     * @param string $sort Sort string for the enrol function
+     * @param int $limit Maximum number of results
+     * @param int $offset Offset the courses result set by this amount
+     * @param array $expectedcourses Expected courses in result
+     */
+    public function test_enrol_get_my_courses_sort_by_last_access(
+        $enrolledcoursesdata,
+        $unenrolledcoursesdata,
+        $sort,
+        $limit,
+        $offset,
+        $expectedcourses
+    ) {
+        global $DB, $CFG;
+
+        $this->resetAfterTest();
+        $generator = $this->getDataGenerator();
+        $student = $generator->create_user();
+        $lastaccessrecords = [];
+
+        foreach ($enrolledcoursesdata as $coursedata) {
+            $lastaccess = null;
+
+            if (isset($coursedata['lastaccess'])) {
+                $lastaccess = $coursedata['lastaccess'];
+                unset($coursedata['lastaccess']);
+            }
+
+            $course = $generator->create_course($coursedata);
+            $generator->enrol_user($student->id, $course->id, 'student');
+
+            if (!is_null($lastaccess)) {
+                $lastaccessrecords[] = [
+                    'userid' => $student->id,
+                    'courseid' => $course->id,
+                    'timeaccess' => $lastaccess
+                ];
+            }
+        }
+
+        foreach ($unenrolledcoursesdata as $coursedata) {
+            $lastaccess = null;
+
+            if (isset($coursedata['lastaccess'])) {
+                $lastaccess = $coursedata['lastaccess'];
+                unset($coursedata['lastaccess']);
+            }
+
+            $course = $generator->create_course($coursedata);
+
+            if (!is_null($lastaccess)) {
+                $lastaccessrecords[] = [
+                    'userid' => $student->id,
+                    'courseid' => $course->id,
+                    'timeaccess' => $lastaccess
+                ];
+            }
+        }
+
+        if (!empty($lastaccessrecords)) {
+            $DB->insert_records('user_lastaccess', $lastaccessrecords);
+        }
+
+        $this->setUser($student);
+
+        $result = enrol_get_my_courses('shortname', $sort, $limit, [], false, $offset);
+        $actual = array_map(function($course) {
+            return $course->shortname;
+        }, array_values($result));
+
+        $this->assertEquals($expectedcourses, $actual);
+    }
 }
index fa20f65..5ddf497 100644 (file)
@@ -554,6 +554,8 @@ function enrol_add_course_navigation(navigation_node $coursenode, $course) {
  *
  * @param string|array $fields Extra fields to be returned (array or comma-separated list).
  * @param string|null $sort Comma separated list of fields to sort by, defaults to respecting navsortmycoursessort.
+ * Allowed prefixes for sort fields are: "ul" for the user_lastaccess table, "c" for the courses table,
+ * "ue" for the user_enrolments table.
  * @param int $limit max number of courses
  * @param array $courseids the list of course ids to filter by
  * @param bool $allaccessible Include courses user is not enrolled in, but can access
@@ -599,17 +601,32 @@ function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $coursei
 
     $orderby = "";
     $sort    = trim($sort);
+    $sorttimeaccess = false;
+    $allowedsortprefixes = array('c', 'ul', 'ue');
     if (!empty($sort)) {
         $rawsorts = explode(',', $sort);
         $sorts = array();
         foreach ($rawsorts as $rawsort) {
             $rawsort = trim($rawsort);
-            if (strpos($rawsort, 'c.') === 0) {
-                $rawsort = substr($rawsort, 2);
+            if (preg_match('/^ul\.(\S*)\s(asc|desc)/i', $rawsort, $matches)) {
+                if (strcasecmp($matches[2], 'asc') == 0) {
+                    $sorts[] = 'COALESCE(ul.' . $matches[1] . ', 0) ASC';
+                } else {
+                    $sorts[] = 'COALESCE(ul.' . $matches[1] . ', 0) DESC';
+                }
+                $sorttimeaccess = true;
+            } else if (strpos($rawsort, '.') !== false) {
+                $prefix = explode('.', $rawsort);
+                if (in_array($prefix[0], $allowedsortprefixes)) {
+                    $sorts[] = trim($rawsort);
+                } else {
+                    throw new coding_exception('Invalid $sort parameter in enrol_get_my_courses()');
+                }
+            } else {
+                $sorts[] = 'c.'.trim($rawsort);
             }
-            $sorts[] = trim($rawsort);
         }
-        $sort = 'c.'.implode(',c.', $sorts);
+        $sort = implode(',', $sorts);
         $orderby = "ORDER BY $sort";
     }
 
@@ -628,6 +645,9 @@ function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $coursei
     $params['contextlevel'] = CONTEXT_COURSE;
     $wheres = implode(" AND ", $wheres);
 
+    $timeaccessselect = "";
+    $timeaccessjoin = "";
+
     if (!empty($courseids)) {
         list($courseidssql, $courseidsparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
         $wheres = sprintf("%s AND c.id %s", $wheres, $courseidssql);
@@ -640,14 +660,20 @@ function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $coursei
         $courseidsql .= "
                 SELECT DISTINCT e.courseid
                   FROM {enrol} e
-                  JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)
+                  JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid1)
                  WHERE ue.status = :active AND e.status = :enabled AND ue.timestart < :now1
                        AND (ue.timeend = 0 OR ue.timeend > :now2)";
-        $params['userid'] = $USER->id;
+        $params['userid1'] = $USER->id;
         $params['active'] = ENROL_USER_ACTIVE;
         $params['enabled'] = ENROL_INSTANCE_ENABLED;
         $params['now1'] = round(time(), -2); // Improves db caching.
         $params['now2'] = $params['now1'];
+
+        if ($sorttimeaccess) {
+            $params['userid2'] = $USER->id;
+            $timeaccessselect = ', ul.timeaccess as lastaccessed';
+            $timeaccessjoin = "LEFT JOIN {user_lastaccess} ul ON (ul.courseid = c.id AND ul.userid = :userid2)";
+        }
     }
 
     // When including non-enrolled but accessible courses...
@@ -708,9 +734,10 @@ function enrol_get_my_courses($fields = null, $sort = null, $limit = 0, $coursei
 
     // Note: we can not use DISTINCT + text fields due to Oracle and MS limitations, that is why
     // we have the subselect there.
-    $sql = "SELECT $coursefields $ccselect
+    $sql = "SELECT $coursefields $ccselect $timeaccessselect
               FROM {course} c
               JOIN ($courseidsql) en ON (en.courseid = c.id)
+           $timeaccessjoin
            $ccjoin
              WHERE $wheres
           $orderby";
index 4ab424a..980888c 100644 (file)
@@ -72,113 +72,94 @@ $blocks-plus-gutter: $blocks-column-width + ( $grid-gutter-width / 2 );
     }
 }
 
-$chart-size: 70px;
-$doughnut-border-size: 15px;
-$doughnut-dasharray: 173;
-$doughnut-empty-colour: $gray-lighter;
-$doughnut-fill-colour: $brand-warning;
-
-.progress-chart-container {
-    height: $chart-size;
-    width: $chart-size;
-
-    .progress-doughnut {
-        position: relative;
-        height: $chart-size;
-        width: $chart-size;
-        background-clip: padding-box;
-        border: $doughnut-border-size solid $doughnut-empty-colour;
-        border-radius: 50%;
-        box-sizing: border-box;
-
-        .progress-text {
-            position: absolute;
-            top: 50%;
-            /*rtl:ignore*/
-            left: 50%;
-            transform: translate(-50%, -50%);
-            color: $doughnut-empty-colour;
-
-            &.has-percent {
-                color: $doughnut-fill-colour;
-            }
-        }
+$card-gutter : $card-deck-margin * 2;
 
-        .progress-indicator {
-            position: absolute;
-            top: ($doughnut-border-size * -1);
-            left: ($doughnut-border-size * -1);
-            height: $chart-size;
-            width: $chart-size;
-
-            svg {
-                position: relative;
-                height: 100%;
-                width: 100%;
-
-                .circle {
-                    stroke-width: $doughnut-border-size;
-                    stroke: $doughnut-fill-colour;
-                    fill: none;
-                    stroke-dasharray: $doughnut-dasharray;
-                    stroke-dashoffset: $doughnut-dasharray;
-                    transform: rotate(-90deg);
-                    transform-origin: center center;
-
-                    @for $i from 1 through 100 {
-                        &.percent-#{$i} {
-                            stroke-dashoffset: $doughnut-dasharray - ($i / 100 * $doughnut-dasharray);
-                        }
-                    }
-                }
-            }
+.block_myoverview {
+    .empty-placeholder-image-lg {
+        height: 125px;
+    }
+    .course-card {
+        margin-bottom: $card-gutter;
+        flex-basis: 100%;
+    }
+    .course-info-container {
+        padding: 0.8rem;
+    }
+    .course-card-footer {
+        padding: 0.8rem;
+    }
+    .progress {
+        height: 0.5rem;
+    }
+    .myoverviewimg {
+        height: 7rem;
+        background-position: center;
+        background-size: cover;
+    }
+    .course-summaryitem {
+        border: $border-width solid $border-color;
+        background-color: $body-bg;
+    }
+    .summary img {
+        max-width: 100%;
+    }
+    @include media-breakpoint-down(sm) {
+        .summaryimage {
+            max-height: 7rem;
         }
     }
+}
 
-    .no-progress {
-        height: $chart-size;
-        width: $chart-size;
-        background-color: $doughnut-empty-colour;
-        border-radius: 50%;
-        position: relative;
-
-        .icon {
-            position: absolute;
-            top: 50%;
-            /*rtl:ignore*/
-            left: 50%;
-            margin: 0;
-            transform: translate(-63%, -50%);
-            color: #fff;
-            height: ($chart-size / 2) + 10px;
-            width: ($chart-size / 2) + 10px;
-            font-size: ($chart-size / 2) + 10px;
+#region-main {
+    .block_myoverview {
+        .course-card {
+            flex-grow: 0;
+            flex-shrink: 0;
+            flex-basis: calc(50% - #{$card-gutter});
+        }
+        @include media-breakpoint-up(sm) {
+            .course-card {
+                flex-basis: calc(50% - #{$card-gutter});
+            }
+        }
+        @include media-breakpoint-up(md) {
+            .course-card {
+                flex-basis: calc(33.33% - #{$card-gutter});
+            }
+        }
+        @include media-breakpoint-up(lg) {
+            .course-card {
+                flex-basis: calc(25% - #{$card-gutter});
+            }
+        }
+        @include media-breakpoint-up(xl) {
+            .course-card {
+                flex-basis: calc(20% - #{$card-gutter});
+            }
         }
     }
 }
 
-.block_myoverview {
-    .empty-placeholder-image-sm {
-        height: 50px;
+#region-main.has-blocks .block_myoverview {
+    @include media-breakpoint-up(lg) {
+        .course-card {
+            flex-basis: calc(33.33% - #{$card-gutter});
+        }
     }
-
-    .empty-placeholder-image-lg {
-        height: 125px;
+    @include media-breakpoint-up(xl) {
+        .course-card {
+            flex-basis: calc(25% - #{$card-gutter});
+        }
     }
 }
 
-.card-deck {
-    .card {
-        $card-gutter : $card-deck-margin * 2;
-        flex-grow: 0;
-        flex-shrink: 0;
+body.drawer-open-left #region-main.has-blocks .block_myoverview {
+    .course-card {
         flex-basis: calc(50% - #{$card-gutter});
     }
-    .myoverviewimg {
-        height: 150px;
-        &.courseimage {
-            background-position: center;
-            background-size: cover;
+    @include media-breakpoint-up(lg) {
+        .course-card {
+            flex-basis: calc(33.33% - #{$card-gutter});
         }
     }
 }
index cd04cd5..d11f963 100644 (file)
@@ -58,6 +58,8 @@ $breadcrumb-divider-rtl: "/" !default;
 // Alerts
 $alert-border-width:                0 !default;
 
+$card-group-margin: .25rem;
+
 $theme-colors: (
     primary: $primary,
     secondary: $gray-200,
index a9b1453..6e3e54f 100644 (file)
@@ -5576,25 +5576,25 @@ tbody.collapse.show {
   display: flex;
   flex-direction: column; }
   .card-deck .card, .card-deck #page-enrol-users #filterform, #page-enrol-users .card-deck #filterform, .card-deck .que .history, .que .card-deck .history, .card-deck .userprofile .profile_tree section, .userprofile .profile_tree .card-deck section, .card-deck .groupinfobox, .card-deck .well {
-    margin-bottom: 15px; }
+    margin-bottom: 0.25rem; }
   @media (min-width: 576px) {
     .card-deck {
       flex-flow: row wrap;
-      margin-right: -15px;
-      margin-left: -15px; }
+      margin-right: -0.25rem;
+      margin-left: -0.25rem; }
       .card-deck .card, .card-deck #page-enrol-users #filterform, #page-enrol-users .card-deck #filterform, .card-deck .que .history, .que .card-deck .history, .card-deck .userprofile .profile_tree section, .userprofile .profile_tree .card-deck section, .card-deck .groupinfobox, .card-deck .well {
         display: flex;
         flex: 1 0 0%;
         flex-direction: column;
-        margin-right: 15px;
+        margin-right: 0.25rem;
         margin-bottom: 0;
-        margin-left: 15px; } }
+        margin-left: 0.25rem; } }
 
 .card-group {
   display: flex;
   flex-direction: column; }
   .card-group > .card, #page-enrol-users .card-group > #filterform, .que .card-group > .history, .userprofile .profile_tree .card-group > section, .card-group > .groupinfobox, .card-group > .well {
-    margin-bottom: 15px; }
+    margin-bottom: 0.25rem; }
   @media (min-width: 576px) {
     .card-group {
       flex-flow: row wrap; }
@@ -11131,278 +11131,73 @@ div.editor_atto_toolbar button .icon {
   [data-region="blocks-column"] {
     width: 100%; } }
 
-.progress-chart-container {
-  height: 70px;
-  width: 70px; }
-  .progress-chart-container .progress-doughnut {
-    position: relative;
-    height: 70px;
-    width: 70px;
-    background-clip: padding-box;
-    border: 15px solid #dee2e6;
-    border-radius: 50%;
-    box-sizing: border-box; }
-    .progress-chart-container .progress-doughnut .progress-text {
-      position: absolute;
-      top: 50%;
-      /*rtl:ignore*/
-      left: 50%;
-      transform: translate(-50%, -50%);
-      color: #dee2e6; }
-      .progress-chart-container .progress-doughnut .progress-text.has-percent {
-        color: #ff7518; }
-    .progress-chart-container .progress-doughnut .progress-indicator {
-      position: absolute;
-      top: -15px;
-      left: -15px;
-      height: 70px;
-      width: 70px; }
-      .progress-chart-container .progress-doughnut .progress-indicator svg {
-        position: relative;
-        height: 100%;
-        width: 100%; }
-        .progress-chart-container .progress-doughnut .progress-indicator svg .circle {
-          stroke-width: 15px;
-          stroke: #ff7518;
-          fill: none;
-          stroke-dasharray: 173;
-          stroke-dashoffset: 173;
-          transform: rotate(-90deg);
-          transform-origin: center center; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-1 {
-            stroke-dashoffset: 171.27; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-2 {
-            stroke-dashoffset: 169.54; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-3 {
-            stroke-dashoffset: 167.81; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-4 {
-            stroke-dashoffset: 166.08; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-5 {
-            stroke-dashoffset: 164.35; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-6 {
-            stroke-dashoffset: 162.62; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-7 {
-            stroke-dashoffset: 160.89; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-8 {
-            stroke-dashoffset: 159.16; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-9 {
-            stroke-dashoffset: 157.43; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-10 {
-            stroke-dashoffset: 155.7; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-11 {
-            stroke-dashoffset: 153.97; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-12 {
-            stroke-dashoffset: 152.24; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-13 {
-            stroke-dashoffset: 150.51; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-14 {
-            stroke-dashoffset: 148.78; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-15 {
-            stroke-dashoffset: 147.05; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-16 {
-            stroke-dashoffset: 145.32; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-17 {
-            stroke-dashoffset: 143.59; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-18 {
-            stroke-dashoffset: 141.86; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-19 {
-            stroke-dashoffset: 140.13; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-20 {
-            stroke-dashoffset: 138.4; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-21 {
-            stroke-dashoffset: 136.67; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-22 {
-            stroke-dashoffset: 134.94; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-23 {
-            stroke-dashoffset: 133.21; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-24 {
-            stroke-dashoffset: 131.48; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-25 {
-            stroke-dashoffset: 129.75; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-26 {
-            stroke-dashoffset: 128.02; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-27 {
-            stroke-dashoffset: 126.29; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-28 {
-            stroke-dashoffset: 124.56; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-29 {
-            stroke-dashoffset: 122.83; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-30 {
-            stroke-dashoffset: 121.1; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-31 {
-            stroke-dashoffset: 119.37; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-32 {
-            stroke-dashoffset: 117.64; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-33 {
-            stroke-dashoffset: 115.91; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-34 {
-            stroke-dashoffset: 114.18; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-35 {
-            stroke-dashoffset: 112.45; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-36 {
-            stroke-dashoffset: 110.72; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-37 {
-            stroke-dashoffset: 108.99; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-38 {
-            stroke-dashoffset: 107.26; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-39 {
-            stroke-dashoffset: 105.53; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-40 {
-            stroke-dashoffset: 103.8; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-41 {
-            stroke-dashoffset: 102.07; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-42 {
-            stroke-dashoffset: 100.34; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-43 {
-            stroke-dashoffset: 98.61; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-44 {
-            stroke-dashoffset: 96.88; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-45 {
-            stroke-dashoffset: 95.15; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-46 {
-            stroke-dashoffset: 93.42; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-47 {
-            stroke-dashoffset: 91.69; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-48 {
-            stroke-dashoffset: 89.96; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-49 {
-            stroke-dashoffset: 88.23; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-50 {
-            stroke-dashoffset: 86.5; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-51 {
-            stroke-dashoffset: 84.77; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-52 {
-            stroke-dashoffset: 83.04; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-53 {
-            stroke-dashoffset: 81.31; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-54 {
-            stroke-dashoffset: 79.58; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-55 {
-            stroke-dashoffset: 77.85; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-56 {
-            stroke-dashoffset: 76.12; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-57 {
-            stroke-dashoffset: 74.39; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-58 {
-            stroke-dashoffset: 72.66; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-59 {
-            stroke-dashoffset: 70.93; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-60 {
-            stroke-dashoffset: 69.2; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-61 {
-            stroke-dashoffset: 67.47; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-62 {
-            stroke-dashoffset: 65.74; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-63 {
-            stroke-dashoffset: 64.01; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-64 {
-            stroke-dashoffset: 62.28; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-65 {
-            stroke-dashoffset: 60.55; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-66 {
-            stroke-dashoffset: 58.82; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-67 {
-            stroke-dashoffset: 57.09; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-68 {
-            stroke-dashoffset: 55.36; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-69 {
-            stroke-dashoffset: 53.63; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-70 {
-            stroke-dashoffset: 51.9; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-71 {
-            stroke-dashoffset: 50.17; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-72 {
-            stroke-dashoffset: 48.44; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-73 {
-            stroke-dashoffset: 46.71; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-74 {
-            stroke-dashoffset: 44.98; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-75 {
-            stroke-dashoffset: 43.25; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-76 {
-            stroke-dashoffset: 41.52; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-77 {
-            stroke-dashoffset: 39.79; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-78 {
-            stroke-dashoffset: 38.06; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-79 {
-            stroke-dashoffset: 36.33; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-80 {
-            stroke-dashoffset: 34.6; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-81 {
-            stroke-dashoffset: 32.87; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-82 {
-            stroke-dashoffset: 31.14; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-83 {
-            stroke-dashoffset: 29.41; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-84 {
-            stroke-dashoffset: 27.68; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-85 {
-            stroke-dashoffset: 25.95; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-86 {
-            stroke-dashoffset: 24.22; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-87 {
-            stroke-dashoffset: 22.49; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-88 {
-            stroke-dashoffset: 20.76; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-89 {
-            stroke-dashoffset: 19.03; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-90 {
-            stroke-dashoffset: 17.3; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-91 {
-            stroke-dashoffset: 15.57; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-92 {
-            stroke-dashoffset: 13.84; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-93 {
-            stroke-dashoffset: 12.11; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-94 {
-            stroke-dashoffset: 10.38; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-95 {
-            stroke-dashoffset: 8.65; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-96 {
-            stroke-dashoffset: 6.92; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-97 {
-            stroke-dashoffset: 5.19; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-98 {
-            stroke-dashoffset: 3.46; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-99 {
-            stroke-dashoffset: 1.73; }
-          .progress-chart-container .progress-doughnut .progress-indicator svg .circle.percent-100 {
-            stroke-dashoffset: 0; }
-  .progress-chart-container .no-progress {
-    height: 70px;
-    width: 70px;
-    background-color: #dee2e6;
-    border-radius: 50%;
-    position: relative; }
-    .progress-chart-container .no-progress .icon {
-      position: absolute;
-      top: 50%;
-      /*rtl:ignore*/
-      left: 50%;
-      margin: 0;
-      transform: translate(-63%, -50%);
-      color: #fff;
-      height: 45px;
-      width: 45px;
-      font-size: 45px; }
-
-.block_myoverview .empty-placeholder-image-sm {
-  height: 50px; }
-
 .block_myoverview .empty-placeholder-image-lg {
   height: 125px; }
 
-.card-deck .card, .card-deck #page-enrol-users #filterform, #page-enrol-users .card-deck #filterform, .card-deck .que .history, .que .card-deck .history, .card-deck .userprofile .profile_tree section, .userprofile .profile_tree .card-deck section, .card-deck .groupinfobox, .card-deck .well {
+.block_myoverview .course-card {
+  margin-bottom: 0.5rem;
+  flex-basis: 100%; }
+
+.block_myoverview .course-info-container {
+  padding: 0.8rem; }
+
+.block_myoverview .course-card-footer {
+  padding: 0.8rem; }
+
+.block_myoverview .progress {
+  height: 0.5rem; }
+
+.block_myoverview .myoverviewimg {
+  height: 7rem;
+  background-position: center;
+  background-size: cover; }
+
+.block_myoverview .course-summaryitem {
+  border: 1px solid #dee2e6;
+  background-color: #fff; }
+
+.block_myoverview .summary img {
+  max-width: 100%; }
+
+@media (max-width: 767.98px) {
+  .block_myoverview .summaryimage {
+    max-height: 7rem; } }
+
+#region-main .block_myoverview .course-card {
   flex-grow: 0;
   flex-shrink: 0;
-  flex-basis: calc(50% - 30px); }
+  flex-basis: calc(50% - 0.5rem); }
+
+@media (min-width: 576px) {
+  #region-main .block_myoverview .course-card {
+    flex-basis: calc(50% - 0.5rem); } }
+
+@media (min-width: 768px) {
+  #region-main .block_myoverview .course-card {
+    flex-basis: calc(33.33% - 0.5rem); } }
 
-.card-deck .myoverviewimg {
-  height: 150px; }
-  .card-deck .myoverviewimg.courseimage {
-    background-position: center;
-    background-size: cover; }
+@media (min-width: 992px) {
+  #region-main .block_myoverview .course-card {
+    flex-basis: calc(25% - 0.5rem); } }
+
+@media (min-width: 1200px) {
+  #region-main .block_myoverview .course-card {
+    flex-basis: calc(20% - 0.5rem); } }
+
+@media (min-width: 992px) {
+  #region-main.has-blocks .block_myoverview .course-card {
+    flex-basis: calc(33.33% - 0.5rem); } }
+
+@media (min-width: 1200px) {
+  #region-main.has-blocks .block_myoverview .course-card {
+    flex-basis: calc(25% - 0.5rem); } }
+
+body.drawer-open-left #region-main.has-blocks .block_myoverview .course-card {
+  flex-basis: calc(50% - 0.5rem); }
+
+@media (min-width: 992px) {
+  body.drawer-open-left #region-main.has-blocks .block_myoverview .course-card {
+    flex-basis: calc(33.33% - 0.5rem); } }
 
 .block_settings .block_tree [aria-expanded="true"],
 .block_settings .block_tree [aria-expanded="true"].emptybranch,
index 79229ac..936abbc 100644 (file)
 }
 
 .block_myoverview {
-    background-color: transparent;
-
-    .row-fluid [class*="span"] {
-        margin-left: 0;
-    }
-
-    .empty-placeholder-image-sm {
-        height: 50px;
+    *,
+    *::before,
+    *::after {
+        box-sizing: border-box;
     }
-
     .empty-placeholder-image-lg {
         height: 125px;
     }
-
-    .courses-view-course-item {
-        height: 220px;
-        overflow-y: hidden;
+    .course-card {
+        .border-radius(@baseBorderRadius);
+        margin-bottom: 0.5rem;
+        flex-grow: 0;
+        flex-shrink: 0;
+        flex-basis: ~"calc(50% - 0.6rem)";
+    }
+    .course-info-container {
+        flex: 1 1 auto;
+        padding: 0.8rem;
+    }
+    .course-card-footer {
+        padding: 0.8rem;
+        background-color: @wellBackground;
+        border-top: 1px solid darken(@wellBackground, 7%);
+        .border-bottom-radius(@baseBorderRadius);
+    }
+    .progress {
+        height: 0.5rem;
+        margin-bottom: 0;
+    }
+    .myoverviewimg {
+        height: 7rem;
+        background-position: center;
+        background-size: cover;
+        .border-top-radius(@baseBorderRadius);
+    }
+    .list-group {
+        margin: 0;
+    }
+    .course-listitem {
+        display: block;
+        padding: 0.75rem 1.25rem;
+        margin-bottom: 0.5rem;
+        background-color: @white;
+        border: 1px solid @tableBorder;
+        .border-radius(@baseBorderRadius);
+    }
+    .course-summaryitem {
+        padding: 0.5rem;
+        background-color: @white;
+        border: 1px solid @tableBorder;
+        .border-radius(@baseBorderRadius);
+    }
+    .summary img {
+        max-width: 100%;
     }
 
-    h4 {
-        font-weight: normal;
+    @media (max-width: 576px) {
+        .summaryimage {
+            max-height: 7rem;
+        }
     }
 
-    .well {
-        background-color: @white;
-        box-shadow: none;
-        margin: 0 5px 10px;
+    @media (min-width: 576px) {
+        .card-deck {
+            display: flex;
+            flex-flow: row wrap;
+            margin-right: -.25rem;
+            margin-left: -.25rem;
+        }
+        .course-card {
+            display: flex;
+            flex-direction: column;
+            margin-right: 0.25rem;
+            margin-left: 0.25rem;
+        }
     }
-    .myoverviewimg {
-        height: 150px;
-        &.courseimage {
-            background-position: center;
-            background-size: cover;
+
+    @media (min-width: 1200px) {
+        .course-card {
+            flex-basis: ~"calc(33% - 0.5rem)";
         }
     }
-}
+}
\ No newline at end of file
index 3fd60ca..a2a2334 100644 (file)
 .w-25 {
     width: 25%;
 }
+
+.d-flex {
+    display: flex !important;
+}
+
+.flex-column {
+    flex-direction: column !important;
+}
+
+.align-self-stretch {
+    align-self: stretch;
+}
+
+.ml-auto {
+    margin-left: auto;
+}
+
+.mt-auto {
+    margin-top: auto;
+}
index 79dd22b..25b62ed 100644 (file)
@@ -16536,36 +16536,100 @@ body {
   height: 35px;
   width: 35px;
 }
-.block_myoverview {
-  background-color: transparent;
-}
-.block_myoverview .row-fluid [class*="span"] {
-  margin-left: 0;
-}
-.block_myoverview .empty-placeholder-image-sm {
-  height: 50px;
+.block_myoverview *,
+.block_myoverview *::before,
+.block_myoverview *::after {
+  box-sizing: border-box;
 }
 .block_myoverview .empty-placeholder-image-lg {
   height: 125px;
 }
-.block_myoverview .courses-view-course-item {
-  height: 220px;
-  overflow-y: hidden;
+.block_myoverview .course-card {
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+  margin-bottom: 0.5rem;
+  flex-grow: 0;
+  flex-shrink: 0;
+  flex-basis: calc(50% - 0.6rem);
 }
-.block_myoverview h4 {
-  font-weight: normal;
+.block_myoverview .course-info-container {
+  flex: 1 1 auto;
+  padding: 0.8rem;
 }
-.block_myoverview .well {
-  background-color: #fff;
-  box-shadow: none;
-  margin: 0 5px 10px;
+.block_myoverview .course-card-footer {
+  padding: 0.8rem;
+  background-color: #f5f5f5;
+  border-top: 1px solid #e3e3e3;
+  -webkit-border-bottom-right-radius: 4px;
+  -moz-border-radius-bottomright: 4px;
+  border-bottom-right-radius: 4px;
+  -webkit-border-bottom-left-radius: 4px;
+  -moz-border-radius-bottomleft: 4px;
+  border-bottom-left-radius: 4px;
 }
-.block_myoverview .myoverviewimg {
-  height: 150px;
+.block_myoverview .progress {
+  height: 0.5rem;
+  margin-bottom: 0;
 }
-.block_myoverview .myoverviewimg.courseimage {
+.block_myoverview .myoverviewimg {
+  height: 7rem;
   background-position: center;
   background-size: cover;
+  -webkit-border-top-right-radius: 4px;
+  -moz-border-radius-topright: 4px;
+  border-top-right-radius: 4px;
+  -webkit-border-top-left-radius: 4px;
+  -moz-border-radius-topleft: 4px;
+  border-top-left-radius: 4px;
+}
+.block_myoverview .list-group {
+  margin: 0;
+}
+.block_myoverview .course-listitem {
+  display: block;
+  padding: 0.75rem 1.25rem;
+  margin-bottom: 0.5rem;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.block_myoverview .course-summaryitem {
+  padding: 0.5rem;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.block_myoverview .summary img {
+  max-width: 100%;
+}
+@media (max-width: 576px) {
+  .block_myoverview .summaryimage {
+    max-height: 7rem;
+  }
+}
+@media (min-width: 576px) {
+  .block_myoverview .card-deck {
+    display: flex;
+    flex-flow: row wrap;
+    margin-right: -0.25rem;
+    margin-left: -0.25rem;
+  }
+  .block_myoverview .course-card {
+    display: flex;
+    flex-direction: column;
+    margin-right: 0.25rem;
+    margin-left: 0.25rem;
+  }
+}
+@media (min-width: 1200px) {
+  .block_myoverview .course-card {
+    flex-basis: calc(33% - 0.5rem);
+  }
 }
 /**
  * Moodle forms HTML isn't changeable via renderers (yet?) so this
@@ -22107,3 +22171,18 @@ ul.indented-list {
 .w-25 {
   width: 25%;
 }
+.d-flex {
+  display: flex !important;
+}
+.flex-column {
+  flex-direction: column !important;
+}
+.align-self-stretch {
+  align-self: stretch;
+}
+.ml-auto {
+  margin-left: auto;
+}
+.mt-auto {
+  margin-top: auto;
+}
diff --git a/theme/bootstrapbase/templates/block_myoverview/course-paging-content-item.mustache b/theme/bootstrapbase/templates/block_myoverview/course-paging-content-item.mustache
deleted file mode 100644 (file)
index 75fe6c8..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{{!
-    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 block_myoverview/course-paging-content-item
-
-    This template renders each course block.
-
-    Example context (json):
-    {
-        "page": 1,
-        "active": true,
-        "courses": [
-            {
-                "fullnamedisplay": "course 1",
-                "viewurl": "https://www.google.com",
-                "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-            },
-            {
-                "fullnamedisplay": "course 2",
-                "viewurl": "https://www.google.com",
-                "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-            }
-        ]
-    }
-}}
-{{< block_myoverview/paging-content-item }}
-    {{$content}}
-        {{#courses}}
-            {{> block_myoverview/courses-view-course-item }}
-        {{/courses}}
-        <div class="clearfix"></div>
-    {{/content}}
-{{/ block_myoverview/paging-content-item }}
diff --git a/theme/bootstrapbase/templates/block_myoverview/courses-view-course-item.mustache b/theme/bootstrapbase/templates/block_myoverview/courses-view-course-item.mustache
deleted file mode 100644 (file)
index d9fd70e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-{{!
-    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 block_myoverview/course-view-course-item
-
-    This template renders the course summary (view by courses) for the myoverview block.
-
-    Example context (json):
-    {
-        "shortname": "course 3",
-        "viewurl": "https://www.google.com",
-        "summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
-    }
-}}
-<div class="span6">
-    <div class="well well-small">
-        <a href="{{viewurl}}">
-            <div class="myoverviewimg m-b-1 {{classes}}" style='background-image: url("{{{courseimage}}}");'>
-            </div>
-        </a>
-        <div class="course-info-container" id="course-info-container-{{id}}">
-            <div class="media">
-                <div class="pull-left">
-                    <div class="media-object">
-                        {{> block_myoverview/progress-chart}}
-                    </div>
-                </div>
-                <div class="media-body">
-                    <h4 class="media-heading">
-                        <a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a>
-                    </h4>
-                </div>
-            </div>
-            <p class="text-muted">
-                {{#shortentext}} 140, {{{summary}}}{{/shortentext}}
-            </p>
-        </div>
-    </div>
-</div>
diff --git a/theme/bootstrapbase/templates/block_myoverview/courses-view-nav-grouping-display-filter.mustache b/theme/bootstrapbase/templates/block_myoverview/courses-view-nav-grouping-display-filter.mustache
deleted file mode 100644 (file)
index 0cd929c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-{{!
-    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 block_myoverview/courses-view-nav-grouping-display-filter
-
-    This template renders the main content area for the myoverview block.
-
-    Example context (json):
-    {}
-}}
-<div data-region="courses-grouping-display-filter" class="btn-group">
-    <button type="button" class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-        <span data-active-item-text>{{#str}} inprogress, block_myoverview {{/str}}</span>
-        <span data-region="caret" class="caret"></span>
-    </button>
-    <ul class="dropdown-menu" data-show-active-item>
-        <li class="dropdown-item active" data-target="#myoverview_courses_view_in_progress" data-toggle="tab">
-            <a tabindex="-1" href="#">{{#str}} inprogress, block_myoverview {{/str}}</a>
-        </li>
-        <li class="dropdown-item" data-target="#myoverview_courses_view_future" data-toggle="tab">
-            <a tabindex="-1" href="#">{{#str}} future, block_myoverview {{/str}}</a>
-        </li>
-        <li class="dropdown-item" data-target="#myoverview_courses_view_past" data-toggle="tab">
-            <a tabindex="-1" href="#">{{#str}} past, block_myoverview {{/str}}</a>
-        </li>
-    </ul>
-</div>
diff --git a/theme/bootstrapbase/templates/block_myoverview/courses-view.mustache b/theme/bootstrapbase/templates/block_myoverview/courses-view.mustache
deleted file mode 100644 (file)
index 5bfc78d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-{{!
-    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 block_myoverview/courses-view
-
-    This template renders the courses view for the myoverview block.
-
-    Example context (json):
-    {}
-}}
-<div id="courses-view-{{uniqid}}" data-region="courses-view">
-    {{#hascourses}}
-    <div class="tab-content">
-        <div class="tab-pane active fade in" id="myoverview_courses_view_in_progress">
-            {{#inprogress}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-in-progress{{/id}}
-                    {{$status}}1{{/status}}
-                    {{$pagingbarid}}pb-for-in-progress{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/inprogress}}
-            {{^inprogress}}
-                <div class="text-xs-center text-center m-t-3">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursesinprogress, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted m-t-1">{{#str}} nocoursesinprogress, block_myoverview {{/str}}</p>
-                </div>
-            {{/inprogress}}
-        </div>
-        <div class="tab-pane fade" id="myoverview_courses_view_future">
-            {{#future}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-future{{/id}}
-                    {{$status}}2{{/status}}
-                    {{$pagingbarid}}pb-for-future{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/future}}
-            {{^future}}
-                <div class="text-xs-center text-center m-t-3">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursesfuture, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted m-t-1">{{#str}} nocoursesfuture, block_myoverview {{/str}}</p>
-                </div>
-            {{/future}}
-        </div>
-        <div class="tab-pane fade" id="myoverview_courses_view_past">
-            {{#past}}
-                {{< block_myoverview/courses-view-by-status }}
-                    {{$id}}courses-view-past{{/id}}
-                    {{$status}}0{{/status}}
-                    {{$pagingbarid}}pb-for-past{{/pagingbarid}}
-                    {{$pagingcontentid}}pc-for-in-progress{{/pagingcontentid}}
-                {{/ block_myoverview/courses-view-by-status }}
-            {{/past}}
-            {{^past}}
-                <div class="text-xs-center text-center m-t-3">
-                    <img class="empty-placeholder-image-lg"
-                         src="{{urls.nocourses}}"
-                         alt="{{#str}} nocoursespast, block_myoverview {{/str}}"
-                         role="presentation">
-                    <p class="text-muted m-t-1">{{#str}} nocoursespast, block_myoverview {{/str}}</p>
-                </div>
-            {{/past}}
-        </div>
-    </div>
-    {{/hascourses}}
-    {{^hascourses}}
-    <div class="text-xs-center text-center m-t-3">
-        <img class="empty-placeholder-image-lg"
-             src="{{urls.nocourses}}"
-             alt="{{#str}} nocourses, block_myoverview {{/str}}">
-        <p class="text-muted m-t-1">{{#str}} nocourses, block_myoverview {{/str}}</p>
-    </div>
-    {{/hascourses}}
-</div>
-{{#js}}
-require(['jquery', 'core/custom_interaction_events'], function($, customEvents) {
-    var root = $('#courses-view-{{uniqid}}');
-    customEvents.define(root, [customEvents.events.activate]);
-    root.on(customEvents.events.activate, '[data-toggle="btns"] > .btn', function(e) {
-        root.find('.btn.active').removeClass('active');
-        $(e.target).closest('.btn').addClass('active');
-    });
-});
-{{/js}}
diff --git a/theme/bootstrapbase/templates/block_myoverview/main.mustache b/theme/bootstrapbase/templates/block_myoverview/main.mustache
deleted file mode 100644 (file)
index 3a8a005..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-{{!
-    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 block_myoverview/main
-
-    This template renders the main content area for the myoverview block.
-
-    Example context (json):
-    {}
-}}
-
-<div id="block-myoverview-{{uniqid}}" class="block-myoverview" data-region="myoverview">
-    <div class="container-fluid p-0 m-b-1">
-        <div class="row-fluid no-gutters">
-            {{#coursesview}}
-                {{#hascourses}}
-                    <div class="{{#viewingtimeline}}d-none{{/viewingtimeline}}" data-tab-content="courses">
-                        {{> block_myoverview/courses-view-nav-grouping-display-filter }}
-                    </div>
-                {{/hascourses}}
-            {{/coursesview}}
-        </div>
-    </div>
-    <div class="container-fluid p-0">
-        {{#coursesview}}
-        {{> block_myoverview/courses-view }}
-        {{/coursesview}}
-    </div>
-</div>
diff --git a/theme/bootstrapbase/templates/block_myoverview/paging-bar.mustache b/theme/bootstrapbase/templates/block_myoverview/paging-bar.mustache
deleted file mode 100644 (file)
index 96d44d1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-{{!
-    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 block_myoverview/paging-bar
-
-    This template renders the bootstrap style paging bar.
-
-    Example context (json):
-    {
-        "pagingbar": {
-            "pagecount": 2,
-            "previous": {},
-            "next": {},
-            "first": {
-                "url": "#",
-                "page": "first"
-            },
-            "last": {
-                "url": "#",
-                "page": "last"
-            },
-            "pages": [
-                {
-                    "url": "#",
-                    "number": 1,
-                    "page": "1",
-                    "active": true
-                },
-                {
-                    "url": "#",
-                    "number": 2,
-                    "page": "2"
-                }
-            ]
-        }
-    }
-}}
-{{#pagingbar}}
-<div aria-label="{{label}}"
-     id="{{$pagingbarid}}paging-bar-{{uniqid}}{{/pagingbarid}}"
-     class="pagination"
-     data-region="paging-bar"
-     data-page-count="{{pagecount}}">
-
-    <ul>
-        {{#previous}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$item-content}}
-                    <span aria-hidden="true">&laquo;</span>
-                    <span class="sr-only">{{#str}}previous{{/str}}</span>
-                {{/item-content}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/previous}}
-        {{#first}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$pagenumber}}first{{/pagenumber}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/first}}
-        {{#pages}}
-            {{> block_myoverview/paging-bar-item }}
-        {{/pages}}
-        {{#last}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$pagenumber}}last{{/pagenumber}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/last}}
-        {{#next}}
-            {{< block_myoverview/paging-bar-item }}
-                {{$item-content}}
-                    <span aria-hidden="true">&raquo;</span>
-                    <span class="sr-only">{{#str}}next{{/str}}</span>
-                {{/item-content}}
-            {{/ block_myoverview/paging-bar-item }}
-        {{/next}}
-    </ul>
-</div>
-{{#js}}
-require(['jquery', 'block_myoverview/paging_bar'], function($, PagingBar) {
-    var root = $('#{{$pagingbarid}}paging-bar-{{uniqid}}{{/pagingbarid}}');
-    PagingBar.registerEventListeners(root);
-});
-{{/js}}
-{{/pagingbar}}