b6b6c626dff8d512a8f911ab2daa861d3bae79ce
[moodle.git] / blocks / myoverview / amd / src / view.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * Manage the courses view for the overview block.
18  *
19  * @package    block_myoverview
20  * @copyright  2018 Bas Brands <bas@moodle.com>
21  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
24 define(
25 [
26     'jquery',
27     'core/notification',
28     'block_myoverview/repository',
29     'core/paged_content_factory',
30     'core/templates',
31 ],
32 function(
33     $,
34     Notification,
35     Repository,
36     PagedContentFactory,
37     Templates
38 ) {
40     var TEMPLATES = {
41         COURSES_CARDS: 'block_myoverview/view-cards',
42         COURSES_LIST: 'block_myoverview/view-list',
43         COURSES_SUMMARY: 'block_myoverview/view-summary',
44         NOCOURSES: 'block_myoverview/no-courses'
45     };
47     var NUMCOURSES_PERPAGE = [12, 24];
49     var currentCourseList = [];
51     /**
52      * Get filter values from DOM.
53      *
54      * @param {object} root The root element for the courses view.
55      * @return {filters} Set filters.
56      */
57     var getFilterValues = function(root) {
58         var filters = {};
59         filters.display = root.attr('data-display');
60         filters.grouping = root.attr('data-grouping');
61         filters.sort = root.attr('data-sort');
62         return filters;
63     };
65     // We want the paged content controls below the paged content area
66     // and the controls should be ignored while data is loading.
67     var DEFAULT_PAGED_CONTENT_CONFIG = {
68         ignoreControlWhileLoading: true,
69         controlPlacementBottom: true,
70     };
72     /**
73      * Get enrolled courses from backend.
74      *
75      * @param {object} filters The filters for this view.
76      * @param {int} limit The number of courses to show.
77      * @param {int} pageNumber The pagenumber to view.
78      * @return {promise} Resolved with an array of courses.
79      */
80     var getMyCourses = function(filters, limit, pageNumber) {
81         return Repository.getEnrolledCoursesByTimeline({
82             offset:  pageNumber * limit,
83             limit: limit,
84             classification: filters.grouping,
85             sort: filters.sort
86         });
87     };
89     /**
90      * Render the dashboard courses.
91      *
92      * @param {object} root The root element for the courses view.
93      * @param {array} coursesData containing array of returned courses.
94      * @param {object} filters The filters for this view.
95      * @return {promise} jQuery promise resolved after rendering is complete.
96      */
97     var renderCourses = function(root, coursesData, filters) {
99         var currentTemplate = '';
100         if (filters.display == 'cards') {
101             currentTemplate = TEMPLATES.COURSES_CARDS;
102         } else if (filters.display == 'list') {
103             currentTemplate = TEMPLATES.COURSES_LIST;
104         } else {
105             currentTemplate = TEMPLATES.COURSES_SUMMARY;
106         }
108         if (coursesData.courses.length) {
109             return Templates.render(currentTemplate, {
110                 courses: coursesData.courses
111             });
112         } else {
113             var nocoursesimg = root.attr('data-nocoursesimg');
114             return Templates.render(TEMPLATES.NOCOURSES, {
115                 nocoursesimg: nocoursesimg
116             });
117         }
118     };
120     /**
121      * Intialise the courses list and cards views on page load.
122      * 
123      * @param {object} root The root element for the courses view.
124      * @param {object} content The content element for the courses view.
125      */
126     var init = function(root, content) {
128         root = $(root);
130         var filters = getFilterValues(root);
132         var pagedContentPromise = PagedContentFactory.createWithLimit(
133             NUMCOURSES_PERPAGE,
134             function(pagesData, actions) {
135                 var promises = [];
137                 pagesData.forEach(function(pageData) {
138                     var pageNumber = pageData.pageNumber - 1;
140                     var pagePromise = getMyCourses(
141                         filters,
142                         pageData.limit,
143                         pageNumber
144                     ).then(function(coursesData) {
145                         if (coursesData.courses.length < pageData.limit) {
146                             actions.allItemsLoaded(pageData.pageNumber);
147                         }
148                         currentCourseList = coursesData;
149                         return renderCourses(root, coursesData, filters);
150                     })
151                     .catch(Notification.exception);
153                     promises.push(pagePromise);
154                 });
156                 return promises;
157             },
158             DEFAULT_PAGED_CONTENT_CONFIG
159         );
161         pagedContentPromise.then(function(html, js) {
162             return Templates.replaceNodeContents(content, html, js);
163         }).catch(Notification.exception);
164     };
166     /**
167      * Reset the courses views to their original
168      * state on first page load.
169      * 
170      * This is called when configuration has changed for the event lists
171      * to cause them to reload their data.
172      * 
173      * @param {object} root The root element for the timeline view.
174      * @param {object} content The content element for the timeline view.
175      */
176     var reset = function(root, content) {
177         var filters = getFilterValues(root);
178         renderCourses(root, currentCourseList, filters)
179             .then(function(html, js) {
180                 return Templates.replaceNodeContents(content, html, js);
181             }).catch(Notification.exception);
182     };
184     return {
185         init: init,
186         reset: reset
187     };
188 });