This commit is contained in:
Ilya Tregubov
2024-04-04 14:17:15 +08:00
9 changed files with 130 additions and 32 deletions
+1 -1
View File
@@ -5,6 +5,6 @@ define("block_myoverview/repository",["exports","core/ajax"],(function(_exports,
* @module block_myoverview/repository
* @copyright 2018 Bas Brands <base@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setFavouriteCourses=_exports.getEnrolledCoursesByTimeline=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getEnrolledCoursesByTimeline=args=>{const request={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:args};return _ajax.default.call([request])[0]};_exports.setFavouriteCourses=args=>{const request={methodname:"core_course_set_favourite_courses",args:args};return _ajax.default.call([request])[0]}}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setFavouriteCourses=_exports.getEnrolledCoursesByTimeline=_exports.SUMMARY_REQUIRED_FIELDS=_exports.CARDLIST_REQUIRED_FIELDS=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getEnrolledCoursesByTimeline=args=>{const request={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:args};return _ajax.default.call([request])[0]};_exports.setFavouriteCourses=args=>{const request={methodname:"core_course_set_favourite_courses",args:args};return _ajax.default.call([request])[0]};_exports.CARDLIST_REQUIRED_FIELDS=["id","fullname","shortname","showcoursecategory","showshortname","visible","enddate"];_exports.SUMMARY_REQUIRED_FIELDS=["id","fullname","shortname","showcoursecategory","showshortname","visible","enddate","summary","summaryformat"]}));
//# sourceMappingURL=repository.min.js.map
@@ -1 +1 @@
{"version":3,"file":"repository.min.js","sources":["../src/repository.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A javascript module to retrieve enrolled coruses from the server.\n *\n * @module block_myoverview/repository\n * @copyright 2018 Bas Brands <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Retrieve a list of enrolled courses.\n *\n * Valid args are:\n * string classification future, inprogress, past\n * int limit number of records to retreive\n * int Offset offset for pagination\n * int sort sort by lastaccess or name\n *\n * @method getEnrolledCoursesByTimeline\n * @param {object} args The request arguments\n * @return {promise} Resolved with an array of courses\n */\nexport const getEnrolledCoursesByTimeline = args => {\n const request = {\n methodname: 'core_course_get_enrolled_courses_by_timeline_classification',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set the favourite state on a list of courses.\n *\n * Valid args are:\n * Array courses list of course id numbers.\n *\n * @param {Object} args Arguments send to the webservice.\n * @return {Promise} Resolve with warnings.\n */\nexport const setFavouriteCourses = args => {\n const request = {\n methodname: 'core_course_set_favourite_courses',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["args","request","methodname","Ajax","call"],"mappings":";;;;;;;iOAsC4CA,aAClCC,QAAU,CACZC,WAAY,8DACZF,KAAMA,aAGHG,cAAKC,KAAK,CAACH,UAAU,iCAYGD,aACzBC,QAAU,CACZC,WAAY,oCACZF,KAAMA,aAGHG,cAAKC,KAAK,CAACH,UAAU"}
{"version":3,"file":"repository.min.js","sources":["../src/repository.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A javascript module to retrieve enrolled coruses from the server.\n *\n * @module block_myoverview/repository\n * @copyright 2018 Bas Brands <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Retrieve a list of enrolled courses.\n *\n * Valid args are:\n * string classification future, inprogress, past\n * int limit number of records to retreive\n * int Offset offset for pagination\n * int sort sort by lastaccess or name\n *\n * @method getEnrolledCoursesByTimeline\n * @param {object} args The request arguments\n * @return {promise} Resolved with an array of courses\n */\nexport const getEnrolledCoursesByTimeline = args => {\n const request = {\n methodname: 'core_course_get_enrolled_courses_by_timeline_classification',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set the favourite state on a list of courses.\n *\n * Valid args are:\n * Array courses list of course id numbers.\n *\n * @param {Object} args Arguments send to the webservice.\n * @return {Promise} Resolve with warnings.\n */\nexport const setFavouriteCourses = args => {\n const request = {\n methodname: 'core_course_set_favourite_courses',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * These course fields are the only ones needed to be included in the results for the card and list views.\n *\n * @type {string[]}\n */\nexport const CARDLIST_REQUIRED_FIELDS = [\n 'id',\n 'fullname',\n 'shortname',\n 'showcoursecategory',\n 'showshortname',\n 'visible',\n 'enddate',\n];\n\n/**\n * These course fields are the only ones needed to be included in the results for the card and list views.\n *\n * @type {string[]}\n */\nexport const SUMMARY_REQUIRED_FIELDS = [\n 'id',\n 'fullname',\n 'shortname',\n 'showcoursecategory',\n 'showshortname',\n 'visible',\n 'enddate',\n 'summary',\n 'summaryformat',\n];\n"],"names":["args","request","methodname","Ajax","call"],"mappings":";;;;;;;oSAsC4CA,aAClCC,QAAU,CACZC,WAAY,8DACZF,KAAMA,aAGHG,cAAKC,KAAK,CAACH,UAAU,iCAYGD,aACzBC,QAAU,CACZC,WAAY,oCACZF,KAAMA,aAGHG,cAAKC,KAAK,CAACH,UAAU,sCAQQ,CACpC,KACA,WACA,YACA,qBACA,gBACA,UACA,4CAQmC,CACnC,KACA,WACA,YACA,qBACA,gBACA,UACA,UACA,UACA"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+32
View File
@@ -62,3 +62,35 @@ export const setFavouriteCourses = args => {
return Ajax.call([request])[0];
};
/**
* These course fields are the only ones needed to be included in the results for the card and list views.
*
* @type {string[]}
*/
export const CARDLIST_REQUIRED_FIELDS = [
'id',
'fullname',
'shortname',
'showcoursecategory',
'showshortname',
'visible',
'enddate',
];
/**
* These course fields are the only ones needed to be included in the results for the card and list views.
*
* @type {string[]}
*/
export const SUMMARY_REQUIRED_FIELDS = [
'id',
'fullname',
'shortname',
'showcoursecategory',
'showshortname',
'visible',
'enddate',
'summary',
'summaryformat',
];
+58 -14
View File
@@ -63,6 +63,16 @@ let lastLimit = 0;
let namespace = null;
/**
* Whether the summary display has been loaded.
*
* If true, this means that courses have been loaded with the summary text.
* Otherwise, switching to the summary display mode will require course data to be fetched with the summary text.
*
* @type {boolean}
*/
let summaryDisplayLoaded = false;
/**
* Get filter values from DOM.
*
@@ -97,14 +107,21 @@ const DEFAULT_PAGED_CONTENT_CONFIG = {
* @return {promise} Resolved with an array of courses.
*/
const getMyCourses = (filters, limit) => {
return Repository.getEnrolledCoursesByTimeline({
const params = {
offset: courseOffset,
limit: limit,
classification: filters.grouping,
sort: filters.sort,
customfieldname: filters.customfieldname,
customfieldvalue: filters.customfieldvalue
});
customfieldvalue: filters.customfieldvalue,
};
if (filters.display === 'summary') {
params.requiredfields = Repository.SUMMARY_REQUIRED_FIELDS;
summaryDisplayLoaded = true;
} else {
params.requiredfields = Repository.CARDLIST_REQUIRED_FIELDS;
}
return Repository.getEnrolledCoursesByTimeline(params);
};
/**
@@ -116,15 +133,23 @@ const getMyCourses = (filters, limit) => {
* @return {promise} Resolved with an array of courses.
*/
const getSearchMyCourses = (filters, limit, searchValue) => {
return Repository.getEnrolledCoursesByTimeline({
const params = {
offset: courseOffset,
limit: limit,
classification: 'search',
sort: filters.sort,
customfieldname: filters.customfieldname,
customfieldvalue: filters.customfieldvalue,
searchvalue: searchValue
});
searchvalue: searchValue,
};
if (filters.display === 'summary') {
params.requiredfields = Repository.SUMMARY_REQUIRED_FIELDS;
summaryDisplayLoaded = true;
} else {
params.requiredfields = Repository.CARDLIST_REQUIRED_FIELDS;
summaryDisplayLoaded = false;
}
return Repository.getEnrolledCoursesByTimeline(params);
};
/**
@@ -547,7 +572,11 @@ const itemsPerPageFunc = (pagingLimit, root) => {
// Filter out all pagination options which are too large for the amount of courses user is enrolled in.
const totalCourseCount = parseInt(root.find(SELECTORS.courseView.region).attr('data-totalcoursecount'), 10);
return itemsPerPage.filter(pagingOption => {
return pagingOption.value < totalCourseCount || pagingOption.value === 0;
if (pagingOption.value === 0 && totalCourseCount > 100) {
// To minimise performance issues, do not show the "All" option if the user is enrolled in more than 100 courses.
return false;
}
return pagingOption.value < totalCourseCount;
});
};
@@ -669,7 +698,6 @@ const initializePagedContent = (root, promiseFunction, inputValue = null) => {
const pagingLimit = parseInt(root.find(SELECTORS.courseView.region).attr('data-paging'), 10);
let itemsPerPage = itemsPerPageFunc(pagingLimit, root);
const filters = getFilterValues(root);
const config = {...{}, ...DEFAULT_PAGED_CONTENT_CONFIG};
config.eventNamespace = namespace;
@@ -704,6 +732,9 @@ const initializePagedContent = (root, promiseFunction, inputValue = null) => {
}
}
// Get the current applied filters.
const filters = getFilterValues(root);
// Call the curried function that'll handle the course promise and any manipulation of it.
promiseFunction(filters, currentPage, pageData, actions, root, promises, limit, inputValue);
});
@@ -834,12 +865,25 @@ export const init = root => {
*/
export const reset = root => {
if (loadedPages.length > 0) {
loadedPages.forEach((courseList, index) => {
let pagedContentPage = getPagedContentContainer(root, index);
renderCourses(root, courseList).then((html, js) => {
return Templates.replaceNodeContents(pagedContentPage, html, js);
}).catch(Notification.exception);
});
const filters = getFilterValues(root);
// If the display mode is changed to 'summary' but the summary display has not been loaded yet,
// we need to re-fetch the courses to include the course summary text.
if (filters.display === 'summary' && !summaryDisplayLoaded) {
const page = document.querySelector(SELECTORS.region.selectBlock);
const input = page.querySelector(SELECTORS.region.searchInput);
if (input.value !== '') {
initializePagedContent(root, searchFunctionalityCurry(), input.value.trim());
} else {
initializePagedContent(root, standardFunctionalityCurry());
}
} else {
loadedPages.forEach((courseList, index) => {
let pagedContentPage = getPagedContentContainer(root, index);
renderCourses(root, courseList).then((html, js) => {
return Templates.replaceNodeContents(pagedContentPage, html, js);
}).catch(Notification.exception);
});
}
} else {
init(root);
}
+5 -2
View File
@@ -95,10 +95,12 @@ class course_summary_exporter extends \core\external\exporter {
),
'summary' => array(
'type' => PARAM_RAW,
'null' => NULL_ALLOWED
'null' => NULL_ALLOWED,
'default' => null,
),
'summaryformat' => array(
'type' => PARAM_INT,
'default' => FORMAT_MOODLE,
),
'startdate' => array(
'type' => PARAM_INT,
@@ -119,7 +121,8 @@ class course_summary_exporter extends \core\external\exporter {
],
'pdfexportfont' => [
'type' => PARAM_TEXT,
'null' => NULL_ALLOWED
'null' => NULL_ALLOWED,
'default' => null,
],
);
}
+25 -12
View File
@@ -3885,6 +3885,11 @@ class core_course_external extends external_api {
VALUE_DEFAULT, null),
'searchvalue' => new external_value(PARAM_RAW, 'The value a user wishes to search against',
VALUE_DEFAULT, null),
'requiredfields' => new core_external\external_multiple_structure(
new external_value(PARAM_ALPHANUMEXT, 'Field name to be included from the results', VALUE_DEFAULT),
'Array of the only field names that need to be returned. If empty, all fields will be returned.',
VALUE_DEFAULT, []
),
)
);
}
@@ -3903,15 +3908,15 @@ class core_course_external extends external_api {
* c1 is skipped (because the offset applies *before* the classification filtering)
* and c4 and c5 will be return.
*
* @param string $classification past, inprogress, or future
* @param int $limit Result set limit
* @param int $offset Offset the full course set before timeline classification is applied
* @param string $sort SQL sort string for results
* @param string $customfieldname
* @param string $customfieldvalue
* @param string $searchvalue
* @param string $classification past, inprogress, or future
* @param int $limit Result set limit
* @param int $offset Offset the full course set before timeline classification is applied
* @param string|null $sort SQL sort string for results
* @param string|null $customfieldname
* @param string|null $customfieldvalue
* @param string|null $searchvalue
* @param array $requiredfields Array of the only field names that need to be returned. If empty, all fields will be returned.
* @return array list of courses and warnings
* @throws invalid_parameter_exception
*/
public static function get_enrolled_courses_by_timeline_classification(
string $classification,
@@ -3920,7 +3925,8 @@ class core_course_external extends external_api {
string $sort = null,
string $customfieldname = null,
string $customfieldvalue = null,
string $searchvalue = null
string $searchvalue = null,
array $requiredfields = []
) {
global $CFG, $PAGE, $USER;
require_once($CFG->dirroot . '/course/lib.php');
@@ -3933,6 +3939,7 @@ class core_course_external extends external_api {
'sort' => $sort,
'customfieldvalue' => $customfieldvalue,
'searchvalue' => $searchvalue,
'requiredfields' => $requiredfields,
)
);
@@ -3942,6 +3949,7 @@ class core_course_external extends external_api {
$sort = $params['sort'];
$customfieldvalue = $params['customfieldvalue'];
$searchvalue = clean_param($params['searchvalue'], PARAM_TEXT);
$requiredfields = $params['requiredfields'];
switch($classification) {
case COURSE_TIMELINE_ALLINCLUDINGHIDDEN:
@@ -3967,11 +3975,16 @@ class core_course_external extends external_api {
}
self::validate_context(context_user::instance($USER->id));
$exporterfields = array_keys(course_summary_exporter::define_properties());
// Get the required properties from the exporter fields based on the required fields.
$requiredproperties = array_intersect($exporterfields, $requiredfields);
// If the resulting required properties is empty, fall back to the exporter fields.
if (empty($requiredproperties)) {
$requiredproperties = $exporterfields;
}
$requiredproperties = course_summary_exporter::define_properties();
$fields = join(',', array_keys($requiredproperties));
$fields = join(',', $requiredproperties);
$hiddencourses = get_hidden_courses_on_timeline();
$courses = [];
// If the timeline requires really all courses, get really all courses.
if ($classification == COURSE_TIMELINE_ALLINCLUDINGHIDDEN) {
+6
View File
@@ -39,6 +39,12 @@ The colors for all these purposes and the filters applied to outline them are de
- When I am on the "Course > <section> "course > section" page logged in as "<username>". When utilizing 'Section x'
it first searches by section name (Section x). If it's not found, then it searches by the section number (x).
* The template core_course/course_search_form has been removed following its cessation of use upon MDL-69454 in version 3.11.
* New parameter 'requiredfields' added to \core_course_external::get_enrolled_courses_by_timeline_classification() to allow
callers of this function to specify only the required course fields.
* Set default values for the following course_summary_exporter properties:
- summary (null)
- summaryformat (FORMAT_MOODLE)
- pdfexportfont (null)
=== 4.3 ===
* The `core_course_renderer::course_section_cm_completion` method has been removed, and can no longer be used