MOBILE-3833 course: Improve course module type

main
Pau Ferrer Ocaña 2021-12-16 10:46:07 +01:00
parent 13fbaf0b0f
commit 9b19735e51
4 changed files with 100 additions and 71 deletions

View File

@ -96,7 +96,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
this.description = this.module.description; this.description = this.module.description;
this.componentId = this.module.id; this.componentId = this.module.id;
this.externalUrl = this.module.url; this.externalUrl = this.module.url;
this.courseId = this.courseId || this.module.course!; this.courseId = this.courseId || this.module.course;
this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11'); this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
if (this.showCompletion) { if (this.showCompletion) {

View File

@ -71,7 +71,7 @@ export class CoreCourseDownloadModuleMainFileDirective implements OnInit {
await CoreCourseHelper.downloadModuleAndOpenFile( await CoreCourseHelper.downloadModuleAndOpenFile(
this.module, this.module,
courseId ?? this.module.course!, courseId ?? this.module.course,
this.component, this.component,
componentId, componentId,
this.files, this.files,

View File

@ -437,13 +437,14 @@ export class CoreCourseProvider {
// Helper function to do the WS request without processing the result. // Helper function to do the WS request without processing the result.
const doRequest = async ( const doRequest = async (
site: CoreSite, site: CoreSite,
courseId: number,
moduleId: number, moduleId: number,
modName: string | undefined, modName: string | undefined,
includeStealth: boolean, includeStealth: boolean,
preferCache: boolean, preferCache: boolean,
): Promise<CoreCourseWSSection[]> => { ): Promise<CoreCourseGetContentsWSSection[]> => {
const params: CoreCourseGetContentsParams = { const params: CoreCourseGetContentsParams = {
courseid: courseId!, courseid: courseId,
}; };
params.options = []; params.options = [];
@ -480,7 +481,7 @@ export class CoreCourseProvider {
} }
try { try {
const sections = await site.read<CoreCourseWSSection[]>('core_course_get_contents', params, preSets); const sections = await site.read<CoreCourseGetContentsWSResponse>('core_course_get_contents', params, preSets);
return sections; return sections;
} catch { } catch {
@ -488,10 +489,10 @@ export class CoreCourseProvider {
if (!ignoreCache && !CoreApp.isOnline()) { if (!ignoreCache && !CoreApp.isOnline()) {
if (includeStealth) { if (includeStealth) {
// Older versions didn't include the includestealthmodules option. // Older versions didn't include the includestealthmodules option.
return doRequest(site, moduleId, modName, false, true); return doRequest(site, courseId, moduleId, modName, false, true);
} else if (modName) { } else if (modName) {
// Falback to the request for the given moduleId only. // Falback to the request for the given moduleId only.
return doRequest(site, moduleId, undefined, this.canRequestStealthModules(site), true); return doRequest(site, courseId, moduleId, undefined, this.canRequestStealthModules(site), true);
} }
} }
@ -505,13 +506,13 @@ export class CoreCourseProvider {
courseId = module.course; courseId = module.course;
} }
let sections: CoreCourseWSSection[]; let sections: CoreCourseGetContentsWSSection[];
try { try {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
// We have courseId, we can use core_course_get_contents for compatibility. // We have courseId, we can use core_course_get_contents for compatibility.
this.logger.debug(`Getting module ${moduleId} in course ${courseId}`); this.logger.debug(`Getting module ${moduleId} in course ${courseId}`);
sections = await doRequest(site, moduleId, modName, this.canRequestStealthModules(site), preferCache); sections = await doRequest(site, courseId, moduleId, modName, this.canRequestStealthModules(site), preferCache);
} catch { } catch {
// Error getting the module. Try to get all contents (without filtering by module). // Error getting the module. Try to get all contents (without filtering by module).
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
@ -526,7 +527,7 @@ export class CoreCourseProvider {
sections = await this.getSections(courseId, false, false, preSets, siteId); sections = await this.getSections(courseId, false, false, preSets, siteId);
} }
let foundModule: CoreCourseWSModule | undefined; let foundModule: CoreCourseGetContentsWSModule | undefined;
const foundSection = sections.some((section) => { const foundSection = sections.some((section) => {
if (sectionId != null && if (sectionId != null &&
@ -543,9 +544,10 @@ export class CoreCourseProvider {
}); });
if (foundSection && foundModule) { if (foundSection && foundModule) {
foundModule.course = courseId; return {
...foundModule,
return foundModule; course: courseId,
};
} }
throw new CoreError(Translate.instant('core.course.modulenotfound')); throw new CoreError(Translate.instant('core.course.modulenotfound'));
@ -586,7 +588,12 @@ export class CoreCourseProvider {
async getModuleBasicGradeInfo(moduleId: number, siteId?: string): Promise<CoreCourseModuleGradeInfo | undefined> { async getModuleBasicGradeInfo(moduleId: number, siteId?: string): Promise<CoreCourseModuleGradeInfo | undefined> {
const info = await this.getModuleBasicInfo(moduleId, siteId); const info = await this.getModuleBasicInfo(moduleId, siteId);
const grade: CoreCourseModuleGradeInfo = { if (
info.grade !== undefined ||
info.advancedgrading !== undefined ||
info.outcomes !== undefined
) {
return {
advancedgrading: info.advancedgrading, advancedgrading: info.advancedgrading,
grade: info.grade, grade: info.grade,
gradecat: info.gradecat, gradecat: info.gradecat,
@ -594,13 +601,6 @@ export class CoreCourseProvider {
outcomes: info.outcomes, outcomes: info.outcomes,
scale: info.scale, scale: info.scale,
}; };
if (
typeof grade.grade != 'undefined' ||
typeof grade.advancedgrading != 'undefined' ||
typeof grade.outcomes != 'undefined'
) {
return grade;
} }
} }
@ -763,7 +763,8 @@ export class CoreCourseProvider {
const params: CoreCourseGetContentsParams = { const params: CoreCourseGetContentsParams = {
courseid: courseId, courseid: courseId,
options: [ };
params.options = [
{ {
name: 'excludemodules', name: 'excludemodules',
value: excludeModules, value: excludeModules,
@ -772,23 +773,23 @@ export class CoreCourseProvider {
name: 'excludecontents', name: 'excludecontents',
value: excludeContents, value: excludeContents,
}, },
], ];
};
if (this.canRequestStealthModules(site)) { if (this.canRequestStealthModules(site)) {
params.options!.push({ params.options.push({
name: 'includestealthmodules', name: 'includestealthmodules',
value: includeStealthModules, value: includeStealthModules,
}); });
} }
let sections: CoreCourseWSSection[]; let sections: CoreCourseGetContentsWSSection[];
try { try {
sections = await site.read('core_course_get_contents', params, preSets); sections = await site.read('core_course_get_contents', params, preSets);
} catch { } catch {
// Error getting the data, it could fail because we added a new parameter and the call isn't cached. // Error getting the data, it could fail because we added a new parameter and the call isn't cached.
// Retry without the new parameter and forcing cache. // Retry without the new parameter and forcing cache.
preSets.omitExpires = true; preSets.omitExpires = true;
params.options!.splice(-1, 1); params.options.splice(-1, 1);
sections = await site.read('core_course_get_contents', params, preSets); sections = await site.read('core_course_get_contents', params, preSets);
} }
@ -796,15 +797,22 @@ export class CoreCourseProvider {
let showSections = true; let showSections = true;
if (courseId == siteHomeId) { if (courseId == siteHomeId) {
const storedNumSections = site.getStoredConfig('numsections'); const storedNumSections = site.getStoredConfig('numsections');
showSections = typeof storedNumSections != 'undefined' && !!storedNumSections; showSections = storedNumSections !== undefined && !!storedNumSections;
} }
if (typeof showSections != 'undefined' && !showSections && sections.length > 0) { if (showSections !== undefined && !showSections && sections.length > 0) {
// Get only the last section (Main menu block section). // Get only the last section (Main menu block section).
sections.pop(); sections.pop();
} }
return sections; // Add course to all modules.
return sections.map((section) => ({
...section,
modules: section.modules.map((module) => ({
...module,
course: courseId,
})),
}));
} }
/** /**
@ -1474,7 +1482,12 @@ export type CoreCourseGetContentsParams = {
/** /**
* Data returned by core_course_get_contents WS. * Data returned by core_course_get_contents WS.
*/ */
export type CoreCourseWSSection = { type CoreCourseGetContentsWSResponse = CoreCourseGetContentsWSSection[];
/**
* Section data returned by core_course_get_contents WS.
*/
type CoreCourseGetContentsWSSection = {
id: number; // Section ID. id: number; // Section ID.
name: string; // Section name. name: string; // Section name.
visible?: number; // Is the section visible. visible?: number; // Is the section visible.
@ -1484,38 +1497,14 @@ export type CoreCourseWSSection = {
hiddenbynumsections?: number; // Whether is a section hidden in the course format. hiddenbynumsections?: number; // Whether is a section hidden in the course format.
uservisible?: boolean; // Is the section visible for the user?. uservisible?: boolean; // Is the section visible for the user?.
availabilityinfo?: string; // Availability information. availabilityinfo?: string; // Availability information.
modules: CoreCourseWSModule[]; modules: CoreCourseGetContentsWSModule[]; // List of module.
}; };
/** /**
* Params of core_course_get_course_module WS. * Module data returned by core_course_get_contents WS.
*/ */
type CoreCourseGetCourseModuleWSParams = { type CoreCourseGetContentsWSModule = {
cmid: number; // The course module id.
};
/**
* Params of core_course_get_course_module_by_instance WS.
*/
type CoreCourseGetCourseModuleByInstanceWSParams = {
module: string; // The module name.
instance: number; // The module instance id.
};
/**
* Data returned by core_course_get_course_module and core_course_get_course_module_by_instance WS.
*/
export type CoreCourseGetCourseModuleWSResponse = {
cm: CoreCourseModuleBasicInfo;
warnings?: CoreWSExternalWarning[];
};
/**
* Course module data returned by the WS.
*/
export type CoreCourseWSModule = {
id: number; // Activity id. id: number; // Activity id.
course?: number; // The course id.
url?: string; // Activity url. url?: string; // Activity url.
name: string; // Activity module name. name: string; // Activity module name.
instance?: number; // Instance id. instance?: number; // Instance id.
@ -1537,6 +1526,7 @@ export type CoreCourseWSModule = {
completion?: CoreCourseModuleCompletionTracking; // Type of completion tracking: 0 means none, 1 manual, 2 automatic. completion?: CoreCourseModuleCompletionTracking; // Type of completion tracking: 0 means none, 1 manual, 2 automatic.
completiondata?: CoreCourseModuleWSCompletionData; // Module completion data. completiondata?: CoreCourseModuleWSCompletionData; // Module completion data.
contents?: CoreCourseModuleContentFile[]; contents?: CoreCourseModuleContentFile[];
downloadcontent?: number; // @since 4.0 The download content value.
dates?: { dates?: {
label: string; label: string;
timestamp: number; timestamp: number;
@ -1550,6 +1540,43 @@ export type CoreCourseWSModule = {
}; };
}; };
/**
* Data returned by core_course_get_contents WS.
*/
export type CoreCourseWSSection = Omit<CoreCourseGetContentsWSSection, 'modules'> & {
modules: CoreCourseWSModule[]; // List of module.
};
/**
* Params of core_course_get_course_module WS.
*/
type CoreCourseGetCourseModuleWSParams = {
cmid: number; // The course module id.
};
/**
* Params of core_course_get_course_module_by_instance WS.
*/
type CoreCourseGetCourseModuleByInstanceWSParams = {
module: string; // The module name.
instance: number; // The module instance id.
};
/**
* Data returned by core_course_get_course_module and core_course_get_course_module_by_instance WS.
*/
type CoreCourseGetCourseModuleWSResponse = {
cm: CoreCourseModuleBasicInfo;
warnings?: CoreWSExternalWarning[];
};
/**
* Course module data returned by the WS with course added.
*/
export type CoreCourseWSModule = CoreCourseGetContentsWSModule & {
course: number; // The course id.
};
/** /**
* Module completion data. * Module completion data.
*/ */
@ -1649,9 +1676,11 @@ export type CoreCourseModuleBasicInfo = CoreCourseModuleGradeInfo & {
visibleoncoursepage?: number; // If visible on course page. visibleoncoursepage?: number; // If visible on course page.
visibleold?: number; // Visible old. visibleold?: number; // Visible old.
completiongradeitemnumber?: number; // Completion grade item. completiongradeitemnumber?: number; // Completion grade item.
completionpassgrade?: number; // @since 4.0. Completion pass grade setting.
completionview?: number; // Completion view setting. completionview?: number; // Completion view setting.
completionexpected?: number; // Completion time expected. completionexpected?: number; // Completion time expected.
showdescription?: number; // If the description is showed. showdescription?: number; // If the description is showed.
downloadcontent?: number; // @since 4.0. The download content value.
availability?: string; // Availability settings. availability?: string; // Availability settings.
}; };

View File

@ -182,7 +182,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
if (!CoreFilepool.getPackageDownloadPromise(siteId, handler.component, module.id)) { if (!CoreFilepool.getPackageDownloadPromise(siteId, handler.component, module.id)) {
// Not handled, the app was probably restarted or something weird happened. // Not handled, the app was probably restarted or something weird happened.
// Re-start download (files already on queue or already downloaded will be skipped). // Re-start download (files already on queue or already downloaded will be skipped).
handler.prefetch(module, module.course!); handler.prefetch(module, module.course);
} }
} else if (handler.determineStatus) { } else if (handler.determineStatus) {
// The handler implements a determineStatus function. Apply it. // The handler implements a determineStatus function. Apply it.