MDL-63062 block_recentlyaccessedcourses: add block and styles
authorVíctor Déniz Falcón <victor@moodle.com>
Mon, 5 Nov 2018 21:50:40 +0000 (21:50 +0000)
committerVíctor Déniz Falcón <victor@moodle.com>
Mon, 5 Nov 2018 23:46:57 +0000 (23:46 +0000)
25 files changed:
blocks/recentlyaccessedcourses/amd/build/main.min.js [new file with mode: 0644]
blocks/recentlyaccessedcourses/amd/src/main.js [new file with mode: 0644]
blocks/recentlyaccessedcourses/block_recentlyaccessedcourses.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/classes/output/main.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/classes/output/renderer.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/classes/privacy/provider.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/db/access.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/db/install.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/lang/en/block_recentlyaccessedcourses.php [new file with mode: 0644]
blocks/recentlyaccessedcourses/pix/courses.svg [new file with mode: 0644]
blocks/recentlyaccessedcourses/templates/main.mustache [new file with mode: 0644]
blocks/recentlyaccessedcourses/templates/no-courses.mustache [new file with mode: 0644]
blocks/recentlyaccessedcourses/templates/placeholder-course.mustache [new file with mode: 0644]
blocks/recentlyaccessedcourses/templates/recentlyaccessedcourses-view.mustache [new file with mode: 0644]
blocks/recentlyaccessedcourses/templates/view-cards.mustache [new file with mode: 0644]
blocks/recentlyaccessedcourses/tests/behat/block_recentlyaccessedcourses_dashboard.feature [new file with mode: 0644]
blocks/recentlyaccessedcourses/version.php [new file with mode: 0644]
blocks/recentlyaccesseditems/templates/placeholder-item.mustache
blocks/recentlyaccesseditems/templates/view-cards.mustache
lib/blocklib.php
lib/classes/plugin_manager.php
theme/boost/scss/moodle/blocks.scss
theme/boost/style/moodle.css
theme/bootstrapbase/less/moodle/blocks.less
theme/bootstrapbase/style/moodle.css

diff --git a/blocks/recentlyaccessedcourses/amd/build/main.min.js b/blocks/recentlyaccessedcourses/amd/build/main.min.js
new file mode 100644 (file)
index 0000000..e6d471c
Binary files /dev/null and b/blocks/recentlyaccessedcourses/amd/build/main.min.js differ
diff --git a/blocks/recentlyaccessedcourses/amd/src/main.js b/blocks/recentlyaccessedcourses/amd/src/main.js
new file mode 100644 (file)
index 0000000..8c84aa8
--- /dev/null
@@ -0,0 +1,105 @@
+// 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 Recently accessed courses block.
+ *
+ * @module     block_recentlyaccessedcourses/main.js
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(
+    [
+        'jquery',
+        'core_course/repository',
+        'core/templates',
+        'core/notification'
+    ],
+    function(
+        $,
+        CoursesRepository,
+        Templates,
+        Notification
+    ) {
+
+        var SELECTORS = {
+            COURSES_VIEW: '[data-region="recentlyaccessedcourses-view"]',
+            COURSES_VIEW_CONTENT: '[data-region="recentlyaccessedcourses-view-content"]'
+        };
+
+        var NUM_COURSES_TOTAL = 10;
+
+        /**
+         * Get enrolled courses from backend.
+         *
+         * @method getRecentCourses
+         * @param {int} userid User from which the courses will be obtained
+         * @param {int} limit Only return this many results
+         * @return {array} Courses user has accessed
+         */
+        var getRecentCourses = function(userid, limit) {
+            return CoursesRepository.getLastAccessedCourses(userid, limit);
+        };
+
+        /**
+         * Render the dashboard courses.
+         *
+         * @method renderCourses
+         * @param {object} root The root element for the courses view.
+         * @param {array} courses containing array of returned courses.
+         * @return {promise} Resolved with HTML and JS strings
+         */
+        var renderCourses = function(root, courses) {
+            if (courses.length > 0) {
+                return Templates.render('block_recentlyaccessedcourses/view-cards', {
+                    courses: courses
+                });
+            } else {
+                var nocoursesimgurl = root.attr('data-nocoursesimgurl');
+                return Templates.render('block_recentlyaccessedcourses/no-courses', {
+                    nocoursesimgurl: nocoursesimgurl
+                });
+            }
+        };
+
+        /**
+         * Get and show the recent courses into the block.
+         *
+         * @param {int} userid User from which the courses will be obtained
+         * @param {object} root The root element for the recentlyaccessedcourses block.
+         */
+        var init = function(userid, root) {
+            root = $(root);
+            var recentcoursesViewRoot = root.find(SELECTORS.COURSES_VIEW);
+            var recentcoursesViewContent = root.find(SELECTORS.COURSES_VIEW_CONTENT);
+
+            var coursesPromise = getRecentCourses(userid, NUM_COURSES_TOTAL);
+
+            coursesPromise.then(function(courses) {
+                var pagedContentPromise = renderCourses(recentcoursesViewRoot, courses);
+
+                pagedContentPromise.then(function(html, js) {
+                    return Templates.replaceNodeContents(recentcoursesViewContent, html, js);
+                }).catch(Notification.exception);
+                return coursesPromise;
+            }).catch(Notification.exception);
+        };
+
+        return {
+            init: init
+        };
+    });
diff --git a/blocks/recentlyaccessedcourses/block_recentlyaccessedcourses.php b/blocks/recentlyaccessedcourses/block_recentlyaccessedcourses.php
new file mode 100644 (file)
index 0000000..9f1127b
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Class definition for the Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Recently accessed courses block class.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_recentlyaccessedcourses extends block_base {
+    /**
+     * Initialize class member variables
+     */
+    public function init() {
+        $this->title = get_string('pluginname', 'block_recentlyaccessedcourses');
+    }
+
+    /**
+     * Returns the contents.
+     *
+     * @return stdClass contents of block
+     */
+    public function get_content() {
+        if (isset($this->content)) {
+            return $this->content;
+        }
+
+        $renderable = new block_recentlyaccessedcourses\output\main();
+        $renderer = $this->page->get_renderer('block_recentlyaccessedcourses');
+
+        $this->content = new stdClass();
+        $this->content->text = $renderer->render($renderable);
+        $this->content->footer = '';
+
+        return $this->content;
+    }
+
+    /**
+     * Locations where block can be displayed.
+     *
+     * @return array
+     */
+    public function applicable_formats() {
+        return array('my' => true);
+    }
+}
diff --git a/blocks/recentlyaccessedcourses/classes/output/main.php b/blocks/recentlyaccessedcourses/classes/output/main.php
new file mode 100644 (file)
index 0000000..09bbe03
--- /dev/null
@@ -0,0 +1,55 @@
+<?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 the Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace block_recentlyaccessedcourses\output;
+defined('MOODLE_INTERNAL') || die();
+
+use renderable;
+use renderer_base;
+use templatable;
+
+/**
+ * Class containing data for Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class main implements renderable, templatable {
+    /**
+     * Export this data so it can be used as the context for a mustache template.
+     *
+     * @param renderer_base $output
+     * @return \stdClass|array
+     */
+    public function export_for_template(renderer_base $output) {
+        global $USER;
+
+        $nocoursesurl = $output->image_url('courses', 'block_recentlyaccessedcourses')->out();
+
+        return [
+            'userid' => $USER->id,
+            'nocoursesimgurl' => $nocoursesurl
+        ];
+    }
+}
diff --git a/blocks/recentlyaccessedcourses/classes/output/renderer.php b/blocks/recentlyaccessedcourses/classes/output/renderer.php
new file mode 100644 (file)
index 0000000..efebe9f
--- /dev/null
@@ -0,0 +1,47 @@
+<?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/>.
+
+/**
+ * Recently accessed courses block renderer
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace block_recentlyaccessedcourses\output;
+defined('MOODLE_INTERNAL') || die;
+
+use plugin_renderer_base;
+
+/**
+ * Recently accessed courses block renderer
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class renderer extends plugin_renderer_base {
+
+    /**
+     * Return the main content for the Recently accessed courses block.
+     *
+     * @param main $main The main renderable
+     * @return string HTML string
+     */
+    public function render_recentcourses(main $main) {
+        return $this->render_from_template('block_recentlyaccessedcourses/main', $main->export_for_template($this));
+    }
+}
diff --git a/blocks/recentlyaccessedcourses/classes/privacy/provider.php b/blocks/recentlyaccessedcourses/classes/privacy/provider.php
new file mode 100644 (file)
index 0000000..2cd3c29
--- /dev/null
@@ -0,0 +1,46 @@
+<?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/>.
+
+/**
+ * Privacy Subsystem implementation for Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_recentlyaccessedcourses\privacy;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Privacy Subsystem for Recently accessed courses block.
+ *
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class provider implements \core_privacy\local\metadata\null_provider {
+
+    /**
+     * Get the language string identifier with the component's language
+     * file to explain why this plugin stores no data.
+     *
+     * @return  string
+     */
+    public static function get_reason() : string {
+        return 'privacy:metadata';
+    }
+}
diff --git a/blocks/recentlyaccessedcourses/db/access.php b/blocks/recentlyaccessedcourses/db/access.php
new file mode 100644 (file)
index 0000000..a06c1b9
--- /dev/null
@@ -0,0 +1,48 @@
+<?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/>.
+
+/**
+ * Capabilities for the Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$capabilities = array(
+
+    'block/recentlyaccessedcourses:myaddinstance' => array(
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'archetypes' => array(
+            'user' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/my:manageblocks'
+    ),
+
+    'block/recentlyaccessedcourses:addinstance' => array(
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_BLOCK,
+        'archetypes' => array(
+            'manager' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:manageblocks'
+    )
+);
diff --git a/blocks/recentlyaccessedcourses/db/install.php b/blocks/recentlyaccessedcourses/db/install.php
new file mode 100644 (file)
index 0000000..bd88cc7
--- /dev/null
@@ -0,0 +1,106 @@
+<?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/>.
+
+/**
+ * Recently accessed courses block installation.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com> based on code from 2018 Ryan Wyllie <ryan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+ /**
+  * Add the Recently accessed courses block to the dashboard for all users by default
+  * when it is installed.
+  */
+function xmldb_block_recentlyaccessedcourses_install() {
+    global $DB;
+
+    if ($DB->count_records('block_instances') < 1) {
+        // Only add the recentlyaccessedcourses block if it's being installed on an existing site.
+        // For new sites it will be added by blocks_add_default_system_blocks().
+        return;
+    }
+
+    if ($defaultmypage = $DB->get_record('my_pages', array('userid' => null, 'name' => '__default', 'private' => 1))) {
+        $subpagepattern = $defaultmypage->id;
+    } else {
+        $subpagepattern = null;
+    }
+
+    $page = new moodle_page();
+    $systemcontext = context_system::instance();
+    $page->set_context($systemcontext);
+    // Add the block to the default /my.
+    $page->blocks->add_region('content');
+    $page->blocks->add_block('recentlyaccessedcourses', 'content', 0, false, 'my-index', $subpagepattern);
+
+    // Now we need to find all users that have viewed their dashboard because it'll have
+    // made duplicates of the default block_instances for them so they won't see the new
+    // recentlyaccessedcourses block without the admin resetting all of the dashboards.
+    //
+    // Instead we'll just add the recentlyaccessedcourses block to their dashboards here.
+    $sql = "SELECT parentcontextid, subpagepattern
+              FROM {block_instances}
+             WHERE pagetypepattern = 'my-index'
+                   AND parentcontextid != ?";
+    $params = [$systemcontext->id];
+    $existingrecords = $DB->get_recordset_sql($sql, $params);
+    $blockinstances = [];
+    $seencontexts = [];
+    $now = time();
+
+    foreach ($existingrecords as $existingrecord) {
+        $parentcontextid = $existingrecord->parentcontextid;
+        if (isset($seencontexts[$parentcontextid])) {
+            // If we've seen this context already then skip it because we don't want
+            // to add duplicate recentlyaccessedcourses blocks to the same context. This happens
+            // if something funny is going on with the subpagepattern.
+            continue;
+        } else {
+            $seencontexts[$parentcontextid] = true;
+        }
+
+        $blockinstances[] = [
+            'blockname' => 'recentlyaccessedcourses',
+            'parentcontextid' => $parentcontextid,
+            'showinsubcontexts' => false,
+            'pagetypepattern' => 'my-index',
+            'subpagepattern' => $existingrecord->subpagepattern,
+            'defaultregion' => 'content',
+            'defaultweight' => 0,
+            'configdata' => '',
+            'timecreated' => $now,
+            'timemodified' => $now,
+        ];
+
+        if (count($blockinstances) >= 1000) {
+            // Insert after every 1000 records so that the memory usage doesn't
+            // get out of control.
+            $DB->insert_records('block_instances', $blockinstances);
+            $blockinstances = [];
+        }
+    }
+
+    $existingrecords->close();
+
+    if (!empty($blockinstances)) {
+        // Insert what ever is left over.
+        $DB->insert_records('block_instances', $blockinstances);
+    }
+}
diff --git a/blocks/recentlyaccessedcourses/lang/en/block_recentlyaccessedcourses.php b/blocks/recentlyaccessedcourses/lang/en/block_recentlyaccessedcourses.php
new file mode 100644 (file)
index 0000000..dd0f6c9
--- /dev/null
@@ -0,0 +1,27 @@
+<?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/>.
+/**
+ * Strings for the Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+$string['nocourses'] = 'No recent courses';
+$string['pluginname'] = 'Recently accessed courses';
+$string['privacy:metadata'] = 'The timeline block does not store any personal data.';
+$string['recentlyaccessedcourses:addinstance'] = 'Add a new Recently accessed courses block';
+$string['recentlyaccessedcourses:myaddinstance'] = 'Add a new Recently accessed courses block to Dashboard';
diff --git a/blocks/recentlyaccessedcourses/pix/courses.svg b/blocks/recentlyaccessedcourses/pix/courses.svg
new file mode 100644 (file)
index 0000000..75e59fc
--- /dev/null
@@ -0,0 +1,52 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="157 -1305 148 125" preserveAspectRatio="xMinYMid meet">
+  <defs>
+    <style>
+      .cls-1 {
+        clip-path: url(#clip-Courses);
+      }
+
+      .cls-2 {
+        fill: #eee;
+      }
+
+      .cls-3 {
+        fill: #c4c8cc;
+      }
+
+      .cls-4 {
+        fill: #fff;
+      }
+    </style>
+    <clipPath id="clip-Courses">
+      <rect x="157" y="-1305" width="148" height="125"/>
+    </clipPath>
+  </defs>
+  <g id="Courses" class="cls-1">
+    <g id="Group_44" data-name="Group 44" transform="translate(-268 -1781)">
+      <ellipse id="Ellipse_41" data-name="Ellipse 41" class="cls-2" cx="74" cy="14.785" rx="74" ry="14.785" transform="translate(425 571.43)"/>
+      <rect id="Rectangle_87" data-name="Rectangle 87" class="cls-3" width="95.097" height="110.215" transform="translate(451.909 476)"/>
+      <g id="Group_43" data-name="Group 43" transform="translate(464.04 494)">
+        <rect id="Rectangle_88" data-name="Rectangle 88" class="cls-4" width="31.043" height="34" transform="translate(0)"/>
+        <rect id="Rectangle_89" data-name="Rectangle 89" class="cls-4" width="31.043" height="34" transform="translate(0 42)"/>
+        <rect id="Rectangle_90" data-name="Rectangle 90" class="cls-4" width="31.067" height="34" transform="translate(39.005)"/>
+        <rect id="Rectangle_91" data-name="Rectangle 91" class="cls-4" width="31.067" height="34" transform="translate(39.005 42)"/>
+        <rect id="Rectangle_92" data-name="Rectangle 92" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 16.549)"/>
+        <rect id="Rectangle_93" data-name="Rectangle 93" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 58.549)"/>
+        <rect id="Rectangle_94" data-name="Rectangle 94" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 16.549)"/>
+        <rect id="Rectangle_95" data-name="Rectangle 95" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 58.549)"/>
+        <rect id="Rectangle_96" data-name="Rectangle 96" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 21.825)"/>
+        <rect id="Rectangle_97" data-name="Rectangle 97" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 26.825)"/>
+        <rect id="Rectangle_98" data-name="Rectangle 98" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 63.825)"/>
+        <rect id="Rectangle_99" data-name="Rectangle 99" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 68.825)"/>
+        <rect id="Rectangle_100" data-name="Rectangle 100" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 21.825)"/>
+        <rect id="Rectangle_101" data-name="Rectangle 101" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 26.825)"/>
+        <rect id="Rectangle_102" data-name="Rectangle 102" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 63.825)"/>
+        <rect id="Rectangle_103" data-name="Rectangle 103" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 68.825)"/>
+        <ellipse id="Ellipse_42" data-name="Ellipse 42" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 3.55)"/>
+        <ellipse id="Ellipse_43" data-name="Ellipse 43" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 45.55)"/>
+        <ellipse id="Ellipse_44" data-name="Ellipse 44" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 3.55)"/>
+        <ellipse id="Ellipse_45" data-name="Ellipse 45" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 45.55)"/>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/blocks/recentlyaccessedcourses/templates/main.mustache b/blocks/recentlyaccessedcourses/templates/main.mustache
new file mode 100644 (file)
index 0000000..514fedb
--- /dev/null
@@ -0,0 +1,50 @@
+{{!
+    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_recentlyaccessedcourses/main
+
+    This template renders the main content area for the Recently accessed courses block.
+
+    Example context (json):
+    {
+        "userid": 2,
+        "nocoursesimgurl": "https://moodlesite/theme/image.php/boost/block_recentlyaccessedcourses/1535727318/courses"
+    }
+}}
+
+<div id="block-recentlyaccessedcourses-{{uniqid}}" class="block-recentlyaccessedcourses" data-region="recentlyaccessedcourses"
+     data-userid="{{userid}}">
+    <div class="container-fluid p-0">
+        {{> block_recentlyaccessedcourses/recentlyaccessedcourses-view }}
+    </div>
+</div>
+{{#js}}
+require(
+[
+    'jquery',
+    'block_recentlyaccessedcourses/main'
+],
+function(
+    $,
+    Main
+) {
+    var root = $('#block-recentlyaccessedcourses-{{uniqid}}');
+    var userid = root.attr('data-userid');
+
+    Main.init(userid, root);
+});
+{{/js}}
\ No newline at end of file
diff --git a/blocks/recentlyaccessedcourses/templates/no-courses.mustache b/blocks/recentlyaccessedcourses/templates/no-courses.mustache
new file mode 100644 (file)
index 0000000..0cb3109
--- /dev/null
@@ -0,0 +1,33 @@
+{{!
+    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_recentlyaccessedcourses/no-courses
+
+    This template renders the no courses message.
+
+    Example context (json):
+    {
+        "nocoursesimgurl": "https://moodlesite/theme/image.php/boost/block_recentlyaccessedcourses/1535727318/courses"
+    }
+}}
+<div class="text-xs-center text-center m-t-3" data-region="empty-message">
+    <img class="empty-placeholder-image-lg"
+         src="{{nocoursesimgurl}}"
+         alt="{{#str}} nocourses, block_recentlyaccessedcourses {{/str}}"
+         role="presentation">
+    <p class="text-muted mt-3">{{#str}} nocourses, block_recentlyaccessedcourses {{/str}}</p>
+</div>
\ No newline at end of file
diff --git a/blocks/recentlyaccessedcourses/templates/placeholder-course.mustache b/blocks/recentlyaccessedcourses/templates/placeholder-course.mustache
new file mode 100644 (file)
index 0000000..da6b325
--- /dev/null
@@ -0,0 +1,31 @@
+{{!
+    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_recentlyaccessedcourses/placeholder-course
+
+    This template renders an course card item loading placeholder for the recentlyaccessedcourses block.
+
+    Example context (json):
+    {}
+}}
+<div class="card dashboard-card border-0">
+    <div class="card-img-top bg-pulse-grey w-100" style="height: 7rem">
+    </div>
+    <div class="card-body recent-course-info-container">
+        <div class="bg-pulse-grey w-100 m-b-3" style="height: 1rem"></div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/blocks/recentlyaccessedcourses/templates/recentlyaccessedcourses-view.mustache b/blocks/recentlyaccessedcourses/templates/recentlyaccessedcourses-view.mustache
new file mode 100644 (file)
index 0000000..7c220ee
--- /dev/null
@@ -0,0 +1,45 @@
+{{!
+    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_recentlyaccessedcourses/recentlyaccessedcourses-view
+
+    This template renders the courses view for the recentlyaccessedcourses block.
+
+    Example context (json):
+    {
+        "nocoursesimgurl": "https://moodlesite/theme/image.php/boost/block_recentlyaccessedcourses/1535727318/courses"
+    }
+}}
+<div id="recentlyaccessedcourses-view-{{uniqid}}"
+     data-region="recentlyaccessedcourses-view"
+     data-nocoursesimgurl="{{nocoursesimgurl}}">
+    <div data-region="recentlyaccessedcourses-view-content">
+        <div data-region="recentlyaccessedcourses-loading-placeholder">
+            <div class="card-deck dashboard-card-deck">
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+                {{> block_recentlyaccessedcourses/placeholder-course }}
+            </div>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/blocks/recentlyaccessedcourses/templates/view-cards.mustache b/blocks/recentlyaccessedcourses/templates/view-cards.mustache
new file mode 100644 (file)
index 0000000..b54c6c7
--- /dev/null
@@ -0,0 +1,49 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public Licensebllsdsadfasfd
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template block_recentlyaccessedcourses/view-cards
+
+    This template renders the carousel for the recentlyaccessedcourses block.
+
+    Example context (json):
+    {
+        "courses": [
+            {
+                "name": "Assignment due 1",
+                "viewurl": "https://moodlesite/course/view.php?id=2",
+                "courseimageurl": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg",
+                "fullname": "course 3"
+            }
+        ]
+    }
+}}
+
+<div class="card-deck dashboard-card-deck" role="list">
+    {{#courses}}
+        <a href="{{viewurl}}" title="{{fullname}}" class="card dashboard-card" role="list-item">
+            <div class="card-img-top dashboard-card-img" style='background-image: url("{{{courseimage}}}");'>
+            </div>
+            <div class="card-body pr-1 course-info-container">
+                <div class="d-flex">
+                    <div class="card-title d-inline-block text-truncate">
+                        {{{fullname}}}
+                    </div>
+                </div>
+            </div>
+        </a>
+    {{/courses}}
+</div>
\ No newline at end of file
diff --git a/blocks/recentlyaccessedcourses/tests/behat/block_recentlyaccessedcourses_dashboard.feature b/blocks/recentlyaccessedcourses/tests/behat/block_recentlyaccessedcourses_dashboard.feature
new file mode 100644 (file)
index 0000000..2a32157
--- /dev/null
@@ -0,0 +1,41 @@
+@block @block_recentlyaccessedcourses @javascript
+Feature: The recently accessed courses block allows users to easily access their most recently accessed courses
+  In order to access the most recently accessed courses
+  As a user
+  I can use the Recently accessed courses block in my dashboard
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | student1 | Student   | 1        | student1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+      | Course 2 | C2        |
+      | Course 3 | C3        |
+      | Course 4 | C4        |
+      | Course 5 | C5        |
+    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: User has not accessed any course
+    Given I log in as "student1"
+    Then I should see "No recent courses" in the "Recently accessed courses" "block"
+
+  Scenario: User has accessed two courses
+    Given I log in as "student1"
+    And I should not see "Course 1" in the "Recently accessed courses" "block"
+    And I should not see "Course 2" in the "Recently accessed courses" "block"
+    When I am on "Course 1" course homepage
+    And I am on "Course 2" course homepage
+    And I follow "Dashboard" in the user menu
+    Then I should see "Course 1" in the "Recently accessed courses" "block"
+    And I should see "Course 2" in the "Recently accessed courses" "block"
+    And I should not see "Course 3" in the "Recently accessed courses" "block"
+    And I should not see "Course 4" in the "Recently accessed courses" "block"
+    And I should not see "Course 5" in the "Recently accessed courses" "block"
diff --git a/blocks/recentlyaccessedcourses/version.php b/blocks/recentlyaccessedcourses/version.php
new file mode 100644 (file)
index 0000000..d73c64a
--- /dev/null
@@ -0,0 +1,27 @@
+<?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/>.
+/**
+ * Version details for the Recently accessed courses block.
+ *
+ * @package    block_recentlyaccessedcourses
+ * @copyright  2018 Victor Deniz <victor@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version   = 2018102300;            // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2018102300;            // Requires this Moodle version.
+$plugin->component = 'block_recentlyaccessedcourses'; // Full name of the plugin (used for diagnostics).
index e1bf633..91155c9 100644 (file)
     Example context (json):
     {}
 }}
-<div class="card-body course-info-container">
-    <div class="d-flex flex-row align-items-center" style="height: 32px">
-        <div class="bg-pulse-grey rounded-circle" style="height: 32px; width: 32px;"></div>
-        <div class="w-100 line-height-3 ml-1">
+<div class="card dashboard-card border-0">
+    <div class="card-body course-info-container">
+        <div class="d-flex flex-row align-items-center" style="height: 32px">
+            <div class="bg-pulse-grey rounded-circle" style="height: 32px; width: 32px;"></div>
+            <div class="w-100 line-height-3 ml-1">
                 <div class="bg-pulse-grey w-100" style="height: 15px;"></div>
                 <div class="bg-pulse-grey w-75 mt-1" style="height: 10px;"></div>
+            </div>
         </div>
     </div>
-</div>
+</div>
\ No newline at end of file
index 8b3619c..e059f81 100644 (file)
@@ -52,7 +52,7 @@
                     <div class="icon-size-4 d-flex align-self-center">
                         {{{icon}}}
                     </div>
-                    <div class="w-100 line-height-3 text-truncate">
+                    <div class="w-100 line-height-3 text-truncate ml-2">
                         <h6 class="mb-0">{{{name}}}</h6>
                         <small class="text-muted m-b-0">{{{coursename}}}</small>
                     </div>
index bf42e6c..feaefb3 100644 (file)
@@ -2584,6 +2584,6 @@ function blocks_add_default_system_blocks() {
     }
 
     $newblocks = array('timeline', 'private_files', 'online_users', 'badges', 'calendar_month', 'calendar_upcoming');
-    $newcontent = array('lp', 'myoverview');
+    $newcontent = array('lp', 'recentlyaccessedcourses', 'myoverview');
     $page->blocks->add_blocks(array(BLOCK_POS_RIGHT => $newblocks, 'content' => $newcontent), 'my-index', $subpagepattern);
 }
index 175582e..a934008 100644 (file)
@@ -1719,7 +1719,7 @@ class core_plugin_manager {
                 'login', 'lp', 'mentees', 'mnet_hosts', 'myoverview', 'myprofile',
                 'navigation', 'news_items', 'online_users', 'participants',
                 'private_files', 'quiz_results', 'recent_activity', 'recentlyaccesseditems',
-                'rss_client', 'search_forums', 'section_links',
+                'recentlyaccessedcourses', 'rss_client', 'search_forums', 'section_links',
                 'selfcompletion', 'settings', 'site_main_menu',
                 'social_activities', 'starredcourses', 'tag_flickr', 'tag_youtube', 'tags', 'timeline'
             ),
index 31bf165..dcbdfe4 100644 (file)
@@ -82,7 +82,9 @@ $card-gutter : $card-deck-margin * 2;
 }
 
 .block_myoverview,
-.block_starredcourses {
+.block_starredcourses,
+.block_recentlyaccesseditems,
+.block_recentlyaccessedcourses {
     .course-info-container {
         padding: 0.8rem;
     }
@@ -112,7 +114,9 @@ $card-gutter : $card-deck-margin * 2;
     }
 }
 
-.block_starredcourses {
+.block_starredcourses,
+.block_recentlyaccesseditems,
+.block_recentlyaccessedcourses {
     .dashboard-card-deck {
         flex-flow: nowrap;
         overflow-y: scroll;
@@ -125,45 +129,6 @@ $card-gutter : $card-deck-margin * 2;
     background-size: cover;
 }
 
-[data-region="blocks-column"] {
-    .block_recentlyaccesseditems {
-        @include media-breakpoint-up(xl) {
-            .dashboard-card-deck {
-                height: unset;
-            }
-        }
-    }
-}
-
-.block_recentlyaccesseditems {
-    [data-region="recentlyaccesseditems-view-content"] {
-        overflow-x: hidden;
-    }
-    .dashboard-card {
-        height: 75px;
-    }
-    .dashboard-card-deck {
-        @include media-breakpoint-up(sm) {
-            height: 75px;
-            overflow: hidden;
-        }
-    }
-    .course-info-container {
-        padding: 0.8rem;
-    }
-    .empty-placeholder-image-lg {
-        height: 125px;
-    }
-    a,
-    a:hover {
-        text-decoration: none;
-        color: unset;
-    }
-    .block-controls ~ .content {
-        margin-top: 2rem !important;
-    }
-}
-
 .dashboard-card-deck .dashboard-card {
     margin-bottom: $card-gutter;
     flex-basis: 100%;
@@ -284,4 +249,4 @@ body.drawer-open-left #region-main.has-blocks {
     .icon {
         margin-right: 2px;
     }
-}
+}
\ No newline at end of file
index 11c7520..4670378 100644 (file)
@@ -11141,26 +11141,38 @@ div.editor_atto_toolbar button .icon {
   height: 125px; }
 
 .block_myoverview .course-info-container,
-.block_starredcourses .course-info-container {
+.block_starredcourses .course-info-container,
+.block_recentlyaccesseditems .course-info-container,
+.block_recentlyaccessedcourses .course-info-container {
   padding: 0.8rem; }
 
 .block_myoverview .progress,
-.block_starredcourses .progress {
+.block_starredcourses .progress,
+.block_recentlyaccesseditems .progress,
+.block_recentlyaccessedcourses .progress {
   height: 0.5rem; }
 
 .block_myoverview .course-summaryitem,
-.block_starredcourses .course-summaryitem {
+.block_starredcourses .course-summaryitem,
+.block_recentlyaccesseditems .course-summaryitem,
+.block_recentlyaccessedcourses .course-summaryitem {
   border: 1px solid #dee2e6;
   background-color: #fff; }
 
 .block_myoverview .icon,
-.block_starredcourses .icon {
+.block_starredcourses .icon,
+.block_recentlyaccesseditems .icon,
+.block_recentlyaccessedcourses .icon {
   margin-right: 0; }
 
 .block_myoverview a,
 .block_myoverview .btn-link,
 .block_starredcourses a,
-.block_starredcourses .btn-link {
+.block_starredcourses .btn-link,
+.block_recentlyaccesseditems a,
+.block_recentlyaccesseditems .btn-link,
+.block_recentlyaccessedcourses a,
+.block_recentlyaccessedcourses .btn-link {
   color: inherit; }
 
 .block_myoverview .btn.btn-link.btn-icon, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion,
@@ -11170,7 +11182,21 @@ div.editor_atto_toolbar button .icon {
 .block_starredcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon,
 #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_starredcourses input.btn-link.btn-icon,
 .block_starredcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion,
-#rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion {
+#rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion,
+.block_recentlyaccesseditems .btn.btn-link.btn-icon,
+.block_recentlyaccesseditems #page-grade-grading-manage .actions .btn-link.btn-icon.action,
+#page-grade-grading-manage .actions .block_recentlyaccesseditems .btn-link.btn-icon.action,
+.block_recentlyaccesseditems #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon,
+#rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccesseditems input.btn-link.btn-icon,
+.block_recentlyaccesseditems #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion,
+#rubric-rubric.gradingform_rubric .block_recentlyaccesseditems .btn-link.btn-icon.addcriterion,
+.block_recentlyaccessedcourses .btn.btn-link.btn-icon,
+.block_recentlyaccessedcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action,
+#page-grade-grading-manage .actions .block_recentlyaccessedcourses .btn-link.btn-icon.action,
+.block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon,
+#rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccessedcourses input.btn-link.btn-icon,
+.block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion,
+#rubric-rubric.gradingform_rubric .block_recentlyaccessedcourses .btn-link.btn-icon.addcriterion {
   height: 36px;
   width: 36px;
   padding: 0;
@@ -11189,10 +11215,40 @@ div.editor_atto_toolbar button .icon {
   .block_starredcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus,
   #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_starredcourses input.btn-link.btn-icon:focus,
   .block_starredcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus,
-  #rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion:focus {
+  #rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion:focus,
+  .block_recentlyaccesseditems .btn.btn-link.btn-icon:hover,
+  .block_recentlyaccesseditems #page-grade-grading-manage .actions .btn-link.btn-icon.action:hover,
+  #page-grade-grading-manage .actions .block_recentlyaccesseditems .btn-link.btn-icon.action:hover,
+  .block_recentlyaccesseditems #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:hover,
+  #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccesseditems input.btn-link.btn-icon:hover,
+  .block_recentlyaccesseditems #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:hover,
+  #rubric-rubric.gradingform_rubric .block_recentlyaccesseditems .btn-link.btn-icon.addcriterion:hover,
+  .block_recentlyaccesseditems .btn.btn-link.btn-icon:focus,
+  .block_recentlyaccesseditems #page-grade-grading-manage .actions .btn-link.btn-icon.action:focus,
+  #page-grade-grading-manage .actions .block_recentlyaccesseditems .btn-link.btn-icon.action:focus,
+  .block_recentlyaccesseditems #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus,
+  #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccesseditems input.btn-link.btn-icon:focus,
+  .block_recentlyaccesseditems #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus,
+  #rubric-rubric.gradingform_rubric .block_recentlyaccesseditems .btn-link.btn-icon.addcriterion:focus,
+  .block_recentlyaccessedcourses .btn.btn-link.btn-icon:hover,
+  .block_recentlyaccessedcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action:hover,
+  #page-grade-grading-manage .actions .block_recentlyaccessedcourses .btn-link.btn-icon.action:hover,
+  .block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:hover,
+  #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccessedcourses input.btn-link.btn-icon:hover,
+  .block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:hover,
+  #rubric-rubric.gradingform_rubric .block_recentlyaccessedcourses .btn-link.btn-icon.addcriterion:hover,
+  .block_recentlyaccessedcourses .btn.btn-link.btn-icon:focus,
+  .block_recentlyaccessedcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action:focus,
+  #page-grade-grading-manage .actions .block_recentlyaccessedcourses .btn-link.btn-icon.action:focus,
+  .block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus,
+  #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_recentlyaccessedcourses input.btn-link.btn-icon:focus,
+  .block_recentlyaccessedcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus,
+  #rubric-rubric.gradingform_rubric .block_recentlyaccessedcourses .btn-link.btn-icon.addcriterion:focus {
     background-color: #e9ecef; }
 
-.block_starredcourses .dashboard-card-deck {
+.block_starredcourses .dashboard-card-deck,
+.block_recentlyaccesseditems .dashboard-card-deck,
+.block_recentlyaccessedcourses .dashboard-card-deck {
   flex-flow: nowrap;
   overflow-y: scroll; }
 
@@ -11201,35 +11257,6 @@ div.editor_atto_toolbar button .icon {
   background-position: center;
   background-size: cover; }
 
-@media (min-width: 1200px) {
-  [data-region="blocks-column"] .block_recentlyaccesseditems .dashboard-card-deck {
-    height: unset; } }
-
-.block_recentlyaccesseditems [data-region="recentlyaccesseditems-view-content"] {
-  overflow-x: hidden; }
-
-.block_recentlyaccesseditems .dashboard-card {
-  height: 75px; }
-
-@media (min-width: 576px) {
-  .block_recentlyaccesseditems .dashboard-card-deck {
-    height: 75px;
-    overflow: hidden; } }
-
-.block_recentlyaccesseditems .course-info-container {
-  padding: 0.8rem; }
-
-.block_recentlyaccesseditems .empty-placeholder-image-lg {
-  height: 125px; }
-
-.block_recentlyaccesseditems a,
-.block_recentlyaccesseditems a:hover {
-  text-decoration: none;
-  color: unset; }
-
-.block_recentlyaccesseditems .block-controls ~ .content {
-  margin-top: 2rem !important; }
-
 .dashboard-card-deck .dashboard-card {
   margin-bottom: 0.5rem;
   flex-basis: 100%;
index 85ef793..7edeaa7 100644 (file)
 }
 
 .block_starredcourses,
+.block_recentlyaccesseditems,
+.block_recentlyaccessedcourses,
 .block_myoverview {
-
     .empty-placeholder-image-lg {
         height: 125px;
     }
     }
 }
 
-.block_starredcourses {
+.block_starredcourses,
+.block_recentlyaccesseditems,
+.block_recentlyaccessedcourses {
     .dashboard-card-deck {
         flex-flow: nowrap;
         overflow-y: scroll;
 }
 
 .block_recentlyaccesseditems {
-    [data-region="recentlyaccesseditems-view-content"] {
-        overflow-x: hidden;
-    }
-    .dashboard-card {
-        height: 75px;
-    }
-    .dashboard-card-deck {
-        @media (min-width: 576px) {
-            height: 75px;
-            overflow: hidden;
-        }
-    }
-    .empty-placeholder-image-lg {
-        height: 125px;
-    }
-    .course-info-container {
-        flex: 1 1 auto;
-        padding: 0.8rem;
-    }
     .icon-size-4 .icon {
         height: auto;
         width: auto;
index 99854a3..230c0b0 100644 (file)
@@ -16547,15 +16547,21 @@ body {
   width: 35px;
 }
 .block_starredcourses .empty-placeholder-image-lg,
+.block_recentlyaccesseditems .empty-placeholder-image-lg,
+.block_recentlyaccessedcourses .empty-placeholder-image-lg,
 .block_myoverview .empty-placeholder-image-lg {
   height: 125px;
 }
 .block_starredcourses .course-info-container,
+.block_recentlyaccesseditems .course-info-container,
+.block_recentlyaccessedcourses .course-info-container,
 .block_myoverview .course-info-container {
   flex: 1 1 auto;
   padding: 0.8rem;
 }
 .block_starredcourses .dashboard-card-footer,
+.block_recentlyaccesseditems .dashboard-card-footer,
+.block_recentlyaccessedcourses .dashboard-card-footer,
 .block_myoverview .dashboard-card-footer {
   padding: 0.8rem;
   background-color: #f5f5f5;
@@ -16568,15 +16574,21 @@ body {
   border-bottom-left-radius: 4px;
 }
 .block_starredcourses .progress,
+.block_recentlyaccesseditems .progress,
+.block_recentlyaccessedcourses .progress,
 .block_myoverview .progress {
   height: 0.5rem;
   margin-bottom: 0;
 }
 .block_starredcourses .list-group,
+.block_recentlyaccesseditems .list-group,
+.block_recentlyaccessedcourses .list-group,
 .block_myoverview .list-group {
   margin: 0;
 }
 .block_starredcourses .course-listitem,
+.block_recentlyaccesseditems .course-listitem,
+.block_recentlyaccessedcourses .course-listitem,
 .block_myoverview .course-listitem {
   display: block;
   padding: 0.75rem 1.25rem;
@@ -16588,6 +16600,8 @@ body {
   border-radius: 4px;
 }
 .block_starredcourses .course-summaryitem,
+.block_recentlyaccesseditems .course-summaryitem,
+.block_recentlyaccessedcourses .course-summaryitem,
 .block_myoverview .course-summaryitem {
   padding: 0.5rem;
   background-color: #fff;
@@ -16597,38 +16611,25 @@ body {
   border-radius: 4px;
 }
 .block_starredcourses .summary img,
+.block_recentlyaccesseditems .summary img,
+.block_recentlyaccessedcourses .summary img,
 .block_myoverview .summary img {
   max-width: 100%;
 }
 @media (max-width: 576px) {
   .block_starredcourses .summaryimage,
+  .block_recentlyaccesseditems .summaryimage,
+  .block_recentlyaccessedcourses .summaryimage,
   .block_myoverview .summaryimage {
     max-height: 7rem;
   }
 }
-.block_starredcourses .dashboard-card-deck {
+.block_starredcourses .dashboard-card-deck,
+.block_recentlyaccesseditems .dashboard-card-deck,
+.block_recentlyaccessedcourses .dashboard-card-deck {
   flex-flow: nowrap;
   overflow-y: scroll;
 }
-.block_recentlyaccesseditems [data-region="recentlyaccesseditems-view-content"] {
-  overflow-x: hidden;
-}
-.block_recentlyaccesseditems .dashboard-card {
-  height: 75px;
-}
-@media (min-width: 576px) {
-  .block_recentlyaccesseditems .dashboard-card-deck {
-    height: 75px;
-    overflow: hidden;
-  }
-}
-.block_recentlyaccesseditems .empty-placeholder-image-lg {
-  height: 125px;
-}
-.block_recentlyaccesseditems .course-info-container {
-  flex: 1 1 auto;
-  padding: 0.8rem;
-}
 .block_recentlyaccesseditems .icon-size-4 .icon {
   height: auto;
   width: auto;