MOBILE-3833 course: Use completion enums
parent
efece1d4ac
commit
13fbaf0b0f
|
@ -100,7 +100,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
|
this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
|
||||||
|
|
||||||
if (this.showCompletion) {
|
if (this.showCompletion) {
|
||||||
CoreCourseHelper.calculateModuleCompletionData(this.module, this.courseId);
|
CoreCourseHelper.calculateModuleCompletionData(this.module);
|
||||||
CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module);
|
CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module);
|
||||||
|
|
||||||
this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_MODULE_VIEWED, async (data) => {
|
this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_MODULE_VIEWED, async (data) => {
|
||||||
|
@ -428,7 +428,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
protected async fetchModule(): Promise<void> {
|
protected async fetchModule(): Promise<void> {
|
||||||
const module = await CoreCourse.getModule(this.module.id, this.courseId);
|
const module = await CoreCourse.getModule(this.module.id, this.courseId);
|
||||||
|
|
||||||
CoreCourseHelper.calculateModuleCompletionData(module, this.courseId);
|
CoreCourseHelper.calculateModuleCompletionData(module);
|
||||||
|
|
||||||
await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, module);
|
await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, module);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp
|
||||||
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
||||||
import {
|
import {
|
||||||
CoreCourse,
|
CoreCourse,
|
||||||
|
CoreCourseModuleCompletionStatus,
|
||||||
CoreCourseProvider,
|
CoreCourseProvider,
|
||||||
} from '@features/course/services/course';
|
} from '@features/course/services/course';
|
||||||
import {
|
import {
|
||||||
|
@ -643,7 +644,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
const moduleProgressPercent = 100 / (completionModules || 1);
|
const moduleProgressPercent = 100 / (completionModules || 1);
|
||||||
// Use min/max here to avoid floating point rounding errors over/under-flowing the progress bar.
|
// Use min/max here to avoid floating point rounding errors over/under-flowing the progress bar.
|
||||||
if (completionData.state === CoreCourseProvider.COMPLETION_COMPLETE) {
|
if (completionData.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
|
||||||
this.course.progress = Math.min(100, this.course.progress + moduleProgressPercent);
|
this.course.progress = Math.min(100, this.course.progress + moduleProgressPercent);
|
||||||
} else {
|
} else {
|
||||||
this.course.progress = Math.max(0, this.course.progress - moduleProgressPercent);
|
this.course.progress = Math.max(0, this.course.progress - moduleProgressPercent);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { CoreUser } from '@features/user/services/user';
|
import { CoreUser } from '@features/user/services/user';
|
||||||
import { CoreCourseProvider } from '@features/course/services/course';
|
import { CoreCourseModuleCompletionStatus, CoreCourseModuleCompletionTracking } from '@features/course/services/course';
|
||||||
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
|
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreCourseModuleCompletionBaseComponent } from '@features/course/classes/module-completion';
|
import { CoreCourseModuleCompletionBaseComponent } from '@features/course/classes/module-completion';
|
||||||
|
@ -52,28 +52,28 @@ export class CoreCourseModuleCompletionLegacyComponent extends CoreCourseModuleC
|
||||||
let langKey: string | undefined;
|
let langKey: string | undefined;
|
||||||
let image: string | undefined;
|
let image: string | undefined;
|
||||||
|
|
||||||
if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_MANUAL &&
|
if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_INCOMPLETE) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
|
||||||
image = 'completion-manual-n';
|
image = 'completion-manual-n';
|
||||||
langKey = 'core.completion-alt-manual-n';
|
langKey = 'core.completion-alt-manual-n';
|
||||||
} else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_MANUAL &&
|
} else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
|
||||||
image = 'completion-manual-y';
|
image = 'completion-manual-y';
|
||||||
langKey = 'core.completion-alt-manual-y';
|
langKey = 'core.completion-alt-manual-y';
|
||||||
} else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC &&
|
} else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_INCOMPLETE) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
|
||||||
image = 'completion-auto-n';
|
image = 'completion-auto-n';
|
||||||
langKey = 'core.completion-alt-auto-n';
|
langKey = 'core.completion-alt-auto-n';
|
||||||
} else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC &&
|
} else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
|
||||||
image = 'completion-auto-y';
|
image = 'completion-auto-y';
|
||||||
langKey = 'core.completion-alt-auto-y';
|
langKey = 'core.completion-alt-auto-y';
|
||||||
} else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC &&
|
} else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE_PASS) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
|
||||||
image = 'completion-auto-pass';
|
image = 'completion-auto-pass';
|
||||||
langKey = 'core.completion-alt-auto-pass';
|
langKey = 'core.completion-alt-auto-pass';
|
||||||
} else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC &&
|
} else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
|
||||||
this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE_FAIL) {
|
this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL) {
|
||||||
image = 'completion-auto-fail';
|
image = 'completion-auto-fail';
|
||||||
langKey = 'core.completion-alt-auto-fail';
|
langKey = 'core.completion-alt-auto-fail';
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
import { CoreCourseModuleCompletionBaseComponent } from '@features/course/classes/module-completion';
|
import { CoreCourseModuleCompletionBaseComponent } from '@features/course/classes/module-completion';
|
||||||
import { CoreCourseModuleWSRuleDetails, CoreCourseProvider } from '@features/course/services/course';
|
import { CoreCourseModuleCompletionStatus, CoreCourseModuleWSRuleDetails } from '@features/course/services/course';
|
||||||
import { CoreUser } from '@features/user/services/user';
|
import { CoreUser } from '@features/user/services/user';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
|
|
||||||
|
@ -51,10 +51,10 @@ export class CoreCourseModuleCompletionComponent extends CoreCourseModuleComplet
|
||||||
|
|
||||||
// Format rules.
|
// Format rules.
|
||||||
this.details = await Promise.all(this.completion.details.map(async (rule: CompletionRule) => {
|
this.details = await Promise.all(this.completion.details.map(async (rule: CompletionRule) => {
|
||||||
rule.statuscomplete = rule.rulevalue.status == CoreCourseProvider.COMPLETION_COMPLETE ||
|
rule.statuscomplete = rule.rulevalue.status == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE ||
|
||||||
rule.rulevalue.status == CoreCourseProvider.COMPLETION_COMPLETE_PASS;
|
rule.rulevalue.status == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS;
|
||||||
rule.statuscompletefail = rule.rulevalue.status == CoreCourseProvider.COMPLETION_COMPLETE_FAIL;
|
rule.statuscompletefail = rule.rulevalue.status == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL;
|
||||||
rule.statusincomplete = rule.rulevalue.status == CoreCourseProvider.COMPLETION_INCOMPLETE;
|
rule.statusincomplete = rule.rulevalue.status == CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE;
|
||||||
rule.accessibleDescription = null;
|
rule.accessibleDescription = null;
|
||||||
|
|
||||||
if (this.completion!.overrideby) {
|
if (this.completion!.overrideby) {
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { CoreCourseSection } from '@features/course/services/course-helper';
|
import { CoreCourseSection } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseProvider } from '@features/course/services/course';
|
import {
|
||||||
|
CoreCourseModuleCompletionStatus,
|
||||||
|
CoreCourseModuleCompletionTracking,
|
||||||
|
CoreCourseProvider,
|
||||||
|
} from '@features/course/services/course';
|
||||||
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { ModalController } from '@singletons';
|
import { ModalController } from '@singletons';
|
||||||
|
@ -56,14 +60,14 @@ export class CoreCourseSectionSelectorComponent implements OnInit {
|
||||||
let complete = 0;
|
let complete = 0;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
section.modules.forEach((module) => {
|
section.modules.forEach((module) => {
|
||||||
if (!module.uservisible || module.completiondata === undefined || module.completiondata.tracking === undefined ||
|
if (!module.uservisible || module.completiondata === undefined ||
|
||||||
module.completiondata.tracking <= CoreCourseProvider.COMPLETION_TRACKING_NONE) {
|
module.completiondata.tracking == CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
total++;
|
total++;
|
||||||
if (module.completiondata.state == CoreCourseProvider.COMPLETION_COMPLETE ||
|
if (module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE ||
|
||||||
module.completiondata.state == CoreCourseProvider.COMPLETION_COMPLETE_PASS) {
|
module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
|
||||||
complete++;
|
complete++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -73,7 +73,7 @@ export class CoreCourseModulePreviewPage implements OnInit {
|
||||||
this.module = await CoreCourse.getModule(this.module.id, this.courseId);
|
this.module = await CoreCourse.getModule(this.module.id, this.courseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreCourseHelper.calculateModuleCompletionData(this.module, this.courseId);
|
CoreCourseHelper.calculateModuleCompletionData(this.module);
|
||||||
|
|
||||||
await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module);
|
await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ import {
|
||||||
CoreCourseWSModule,
|
CoreCourseWSModule,
|
||||||
CoreCourseProvider,
|
CoreCourseProvider,
|
||||||
CoreCourseWSSection,
|
CoreCourseWSSection,
|
||||||
|
CoreCourseModuleCompletionTracking,
|
||||||
|
CoreCourseModuleCompletionStatus,
|
||||||
} from './course';
|
} from './course';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
|
@ -200,8 +202,8 @@ export class CoreCourseHelperProvider {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (module.completiondata) {
|
if (module.completiondata) {
|
||||||
this.calculateModuleCompletionData(module, courseId, courseName);
|
this.calculateModuleCompletionData(module, undefined, courseName);
|
||||||
} else if (completionStatus && typeof completionStatus[module.id] != 'undefined') {
|
} else if (completionStatus && completionStatus[module.id] !== undefined) {
|
||||||
// Should not happen on > 3.6. Check if activity has completions and if it's marked.
|
// Should not happen on > 3.6. Check if activity has completions and if it's marked.
|
||||||
const activityStatus = completionStatus[module.id];
|
const activityStatus = completionStatus[module.id];
|
||||||
|
|
||||||
|
@ -229,18 +231,18 @@ export class CoreCourseHelperProvider {
|
||||||
* Calculate completion data of a module.
|
* Calculate completion data of a module.
|
||||||
*
|
*
|
||||||
* @param module Module.
|
* @param module Module.
|
||||||
* @param courseId Course ID of the module.
|
* @param courseId Not used since 4.0
|
||||||
* @param courseName Course name.
|
* @param courseName Course name.
|
||||||
*/
|
*/
|
||||||
calculateModuleCompletionData(module: CoreCourseModule, courseId: number, courseName?: string): void {
|
calculateModuleCompletionData(module: CoreCourseModule, courseId?: number, courseName?: string): void {
|
||||||
if (!module.completiondata || !module.completion) {
|
if (!module.completiondata || !module.completion) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.completiondata.courseId = courseId;
|
module.completiondata.courseId = module.course;
|
||||||
module.completiondata.courseName = courseName;
|
|
||||||
module.completiondata.tracking = module.completion;
|
module.completiondata.tracking = module.completion;
|
||||||
module.completiondata.cmid = module.id;
|
module.completiondata.cmid = module.id;
|
||||||
|
module.completiondata.courseName = courseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2069,7 +2071,8 @@ export class CoreCourseHelperProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof completion.cmid == 'undefined' || completion.tracking !== 1) {
|
if (completion.cmid === undefined ||
|
||||||
|
completion.tracking !== CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2077,14 +2080,15 @@ export class CoreCourseHelperProvider {
|
||||||
event?.stopPropagation();
|
event?.stopPropagation();
|
||||||
|
|
||||||
const modal = await CoreDomUtils.showModalLoading();
|
const modal = await CoreDomUtils.showModalLoading();
|
||||||
completion.state = completion.state === 1 ? 0 : 1;
|
completion.state = completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE
|
||||||
|
? CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE
|
||||||
|
: CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await CoreCourse.markCompletedManually(
|
const response = await CoreCourse.markCompletedManually(
|
||||||
completion.cmid,
|
completion.cmid,
|
||||||
completion.state === 1,
|
completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE,
|
||||||
completion.courseId!,
|
completion.courseId!,
|
||||||
completion.courseName,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.offline) {
|
if (response.offline) {
|
||||||
|
@ -2093,7 +2097,11 @@ export class CoreCourseHelperProvider {
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
completion.state = completion.state === 1 ? 0 : 1;
|
// Restore previous state.
|
||||||
|
completion.state = completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE
|
||||||
|
? CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE
|
||||||
|
: CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE;
|
||||||
|
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'core.errorchangecompletion', true);
|
CoreDomUtils.showErrorModalDefault(error, 'core.errorchangecompletion', true);
|
||||||
} finally {
|
} finally {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
|
@ -2139,7 +2147,7 @@ export type CoreCourseModule = Omit<CoreCourseWSModule, 'completiondata'> & {
|
||||||
export type CoreCourseModuleCompletionData = CoreCourseModuleWSCompletionData & {
|
export type CoreCourseModuleCompletionData = CoreCourseModuleWSCompletionData & {
|
||||||
courseId?: number;
|
courseId?: number;
|
||||||
courseName?: string;
|
courseName?: string;
|
||||||
tracking?: number;
|
tracking?: CoreCourseModuleCompletionTracking;
|
||||||
cmid?: number;
|
cmid?: number;
|
||||||
offline?: boolean;
|
offline?: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,6 +61,25 @@ declare module '@singletons/events' {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completion status valid values.
|
||||||
|
*/
|
||||||
|
export enum CoreCourseModuleCompletionStatus {
|
||||||
|
COMPLETION_INCOMPLETE = 0,
|
||||||
|
COMPLETION_COMPLETE = 1,
|
||||||
|
COMPLETION_COMPLETE_PASS = 2,
|
||||||
|
COMPLETION_COMPLETE_FAIL = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completion tracking valid values.
|
||||||
|
*/
|
||||||
|
export enum CoreCourseModuleCompletionTracking {
|
||||||
|
COMPLETION_TRACKING_NONE = 0,
|
||||||
|
COMPLETION_TRACKING_MANUAL = 1,
|
||||||
|
COMPLETION_TRACKING_AUTOMATIC = 2,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that provides some features regarding a course.
|
* Service that provides some features regarding a course.
|
||||||
*/
|
*/
|
||||||
|
@ -73,13 +92,34 @@ export class CoreCourseProvider {
|
||||||
static readonly ACCESS_DEFAULT = 'courses_access_default';
|
static readonly ACCESS_DEFAULT = 'courses_access_default';
|
||||||
static readonly ALL_COURSES_CLEARED = -1;
|
static readonly ALL_COURSES_CLEARED = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_TRACKING_NONE = 0;
|
static readonly COMPLETION_TRACKING_NONE = 0;
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_TRACKING_MANUAL = 1;
|
static readonly COMPLETION_TRACKING_MANUAL = 1;
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_TRACKING_AUTOMATIC = 2;
|
static readonly COMPLETION_TRACKING_AUTOMATIC = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_INCOMPLETE = 0;
|
static readonly COMPLETION_INCOMPLETE = 0;
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_COMPLETE = 1;
|
static readonly COMPLETION_COMPLETE = 1;
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_COMPLETE_PASS = 2;
|
static readonly COMPLETION_COMPLETE_PASS = 2;
|
||||||
|
/**
|
||||||
|
* @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL instead.
|
||||||
|
*/
|
||||||
static readonly COMPLETION_COMPLETE_FAIL = 3;
|
static readonly COMPLETION_COMPLETE_FAIL = 3;
|
||||||
|
|
||||||
static readonly COMPONENT = 'CoreCourse';
|
static readonly COMPONENT = 'CoreCourse';
|
||||||
|
@ -151,7 +191,8 @@ export class CoreCourseProvider {
|
||||||
* @param completion Completion status of the module.
|
* @param completion Completion status of the module.
|
||||||
*/
|
*/
|
||||||
checkModuleCompletion(courseId: number, completion?: CoreCourseModuleCompletionData): void {
|
checkModuleCompletion(courseId: number, completion?: CoreCourseModuleCompletionData): void {
|
||||||
if (completion && completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC && completion.state === 0) {
|
if (completion && completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
|
||||||
|
completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
|
||||||
this.invalidateSections(courseId).finally(() => {
|
this.invalidateSections(courseId).finally(() => {
|
||||||
CoreEvents.trigger(CoreEvents.COMPLETION_MODULE_VIEWED, {
|
CoreEvents.trigger(CoreEvents.COMPLETION_MODULE_VIEWED, {
|
||||||
courseId: courseId,
|
courseId: courseId,
|
||||||
|
@ -256,7 +297,7 @@ export class CoreCourseProvider {
|
||||||
const onlineCompletion = completionStatus[offlineCompletion.cmid];
|
const onlineCompletion = completionStatus[offlineCompletion.cmid];
|
||||||
|
|
||||||
// If the activity uses manual completion, override the value with the offline one.
|
// If the activity uses manual completion, override the value with the offline one.
|
||||||
if (onlineCompletion.tracking === 1) {
|
if (onlineCompletion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL) {
|
||||||
onlineCompletion.state = offlineCompletion.completed;
|
onlineCompletion.state = offlineCompletion.completed;
|
||||||
onlineCompletion.offline = true;
|
onlineCompletion.offline = true;
|
||||||
}
|
}
|
||||||
|
@ -986,7 +1027,7 @@ export class CoreCourseProvider {
|
||||||
CoreCourseOffline.markCompletedManually(cmId, completed, courseId, courseName, siteId);
|
CoreCourseOffline.markCompletedManually(cmId, completed, courseId, courseName, siteId);
|
||||||
|
|
||||||
// The offline function requires a courseId and it could be missing because it's a calculated field.
|
// The offline function requires a courseId and it could be missing because it's a calculated field.
|
||||||
if (!CoreApp.isOnline() && courseId) {
|
if (!CoreApp.isOnline()) {
|
||||||
// App is offline, store the action.
|
// App is offline, store the action.
|
||||||
return storeOffline();
|
return storeOffline();
|
||||||
}
|
}
|
||||||
|
@ -996,18 +1037,14 @@ export class CoreCourseProvider {
|
||||||
const result = await this.markCompletedManuallyOnline(cmId, completed, siteId);
|
const result = await this.markCompletedManuallyOnline(cmId, completed, siteId);
|
||||||
|
|
||||||
// Data sent to server, if there is some offline data delete it now.
|
// Data sent to server, if there is some offline data delete it now.
|
||||||
try {
|
await CoreUtils.ignoreErrors(CoreCourseOffline.deleteManualCompletion(cmId, siteId));
|
||||||
await CoreCourseOffline.deleteManualCompletion(cmId, siteId);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors, shouldn't happen.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalidate module now, completion has changed.
|
// Invalidate module now, completion has changed.
|
||||||
await this.invalidateModule(cmId, siteId);
|
await this.invalidateModule(cmId, siteId);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (CoreUtils.isWebServiceError(error) || !courseId) {
|
if (CoreUtils.isWebServiceError(error)) {
|
||||||
// The WebService has thrown an error, this means that responses cannot be submitted.
|
// The WebService has thrown an error, this means that responses cannot be submitted.
|
||||||
throw error;
|
throw error;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1346,7 +1383,7 @@ export type CoreCourseCompletionActivityStatus = {
|
||||||
instance: number; // Instance ID.
|
instance: number; // Instance ID.
|
||||||
state: number; // Completion state value: 0 means incomplete, 1 complete, 2 complete pass, 3 complete fail.
|
state: number; // Completion state value: 0 means incomplete, 1 complete, 2 complete pass, 3 complete fail.
|
||||||
timecompleted: number; // Timestamp for completed activity.
|
timecompleted: number; // Timestamp for completed activity.
|
||||||
tracking: number; // Type of tracking: 0 means none, 1 manual, 2 automatic.
|
tracking: CoreCourseModuleCompletionTracking; // Type of tracking: 0 means none, 1 manual, 2 automatic.
|
||||||
overrideby?: number | null; // The user id who has overriden the status, or null.
|
overrideby?: number | null; // The user id who has overriden the status, or null.
|
||||||
valueused?: boolean; // Whether the completion status affects the availability of another activity.
|
valueused?: boolean; // Whether the completion status affects the availability of another activity.
|
||||||
hascompletion?: boolean; // @since 3.11. Whether this activity module has completion enabled.
|
hascompletion?: boolean; // @since 3.11. Whether this activity module has completion enabled.
|
||||||
|
@ -1497,7 +1534,7 @@ export type CoreCourseWSModule = {
|
||||||
afterlink?: string; // After link info to be displayed.
|
afterlink?: string; // After link info to be displayed.
|
||||||
customdata?: string; // Custom data (JSON encoded).
|
customdata?: string; // Custom data (JSON encoded).
|
||||||
noviewlink?: boolean; // Whether the module has no view page.
|
noviewlink?: boolean; // Whether the module has no view page.
|
||||||
completion?: number; // 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[];
|
||||||
dates?: {
|
dates?: {
|
||||||
|
@ -1517,7 +1554,7 @@ export type CoreCourseWSModule = {
|
||||||
* Module completion data.
|
* Module completion data.
|
||||||
*/
|
*/
|
||||||
export type CoreCourseModuleWSCompletionData = {
|
export type CoreCourseModuleWSCompletionData = {
|
||||||
state: number; // Completion state value: 0 means incomplete, 1 complete, 2 complete pass, 3 complete fail.
|
state: CoreCourseModuleCompletionStatus; // Completion state value.
|
||||||
timecompleted: number; // Timestamp for completion status.
|
timecompleted: number; // Timestamp for completion status.
|
||||||
overrideby: number | null; // The user id who has overriden the status.
|
overrideby: number | null; // The user id who has overriden the status.
|
||||||
valueused?: boolean; // Whether the completion status affects the availability of another activity.
|
valueused?: boolean; // Whether the completion status affects the availability of another activity.
|
||||||
|
|
Loading…
Reference in New Issue