diff --git a/src/core/course/components/format/core-course-format.html b/src/core/course/components/format/core-course-format.html index 944626d79..618a83d0d 100644 --- a/src/core/course/components/format/core-course-format.html +++ b/src/core/course/components/format/core-course-format.html @@ -7,15 +7,6 @@ - - - - - - - - - @@ -30,6 +21,15 @@ + + + + + + + + +
diff --git a/src/core/course/components/format/format.ts b/src/core/course/components/format/format.ts index f084a9e07..a47d48eee 100644 --- a/src/core/course/components/format/format.ts +++ b/src/core/course/components/format/format.ts @@ -246,7 +246,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { */ showSectionSelector(): void { const modal = this.modalCtrl.create('CoreCourseSectionSelectorPage', - {sections: this.sections, selected: this.selectedSection}); + {course: this.course, sections: this.sections, selected: this.selectedSection}); modal.onDidDismiss((newSection) => { if (newSection) { this.sectionChanged(newSection); diff --git a/src/core/course/components/module-completion/module-completion.ts b/src/core/course/components/module-completion/module-completion.ts index 4d3ef1b6a..9edcd0e88 100644 --- a/src/core/course/components/module-completion/module-completion.ts +++ b/src/core/course/components/module-completion/module-completion.ts @@ -95,22 +95,28 @@ export class CoreCourseModuleCompletionComponent implements OnChanges { let langKey, image; - if (this.completion.tracking === 1 && this.completion.state === 0) { + if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_MANUAL && + this.completion.state === CoreCourseProvider.COMPLETION_INCOMPLETE) { image = 'completion-manual-n'; langKey = 'core.completion-alt-manual-n'; - } else if (this.completion.tracking === 1 && this.completion.state === 1) { + } else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_MANUAL && + this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE) { image = 'completion-manual-y'; langKey = 'core.completion-alt-manual-y'; - } else if (this.completion.tracking === 2 && this.completion.state === 0) { + } else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC && + this.completion.state === CoreCourseProvider.COMPLETION_INCOMPLETE) { image = 'completion-auto-n'; langKey = 'core.completion-alt-auto-n'; - } else if (this.completion.tracking === 2 && this.completion.state === 1) { + } else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC && + this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE) { image = 'completion-auto-y'; langKey = 'core.completion-alt-auto-y'; - } else if (this.completion.tracking === 2 && this.completion.state === 2) { + } else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC && + this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE_PASS) { image = 'completion-auto-pass'; langKey = 'core.completion-alt-auto-pass'; - } else if (this.completion.tracking === 2 && this.completion.state === 3) { + } else if (this.completion.tracking === CoreCourseProvider.COMPLETION_TRACKING_AUTOMATIC && + this.completion.state === CoreCourseProvider.COMPLETION_COMPLETE_FAIL) { image = 'completion-auto-fail'; langKey = 'core.completion-alt-auto-fail'; } diff --git a/src/core/course/pages/section-selector/section-selector.html b/src/core/course/pages/section-selector/section-selector.html index 3939c589f..93d3d8184 100644 --- a/src/core/course/pages/section-selector/section-selector.html +++ b/src/core/course/pages/section-selector/section-selector.html @@ -13,6 +13,7 @@

+ {{ 'core.course.hiddenfromstudents' | translate }}
diff --git a/src/core/course/pages/section-selector/section-selector.scss b/src/core/course/pages/section-selector/section-selector.scss new file mode 100644 index 000000000..a5f45cbdc --- /dev/null +++ b/src/core/course/pages/section-selector/section-selector.scss @@ -0,0 +1,11 @@ +ion-app.app-root page-core-course-section-selector { + core-progress-bar { + .core-progress-text { + line-height: 24px; + @include position(-8px, 10px, null, null); + } + progress { + margin: 8px 0 4px 0; + } + } +} \ No newline at end of file diff --git a/src/core/course/pages/section-selector/section-selector.ts b/src/core/course/pages/section-selector/section-selector.ts index ee504362e..f438ceef9 100644 --- a/src/core/course/pages/section-selector/section-selector.ts +++ b/src/core/course/pages/section-selector/section-selector.ts @@ -34,6 +34,28 @@ export class CoreCourseSectionSelectorPage { constructor(navParams: NavParams, courseHelper: CoreCourseHelperProvider, private viewCtrl: ViewController) { this.sections = navParams.get('sections'); this.selected = navParams.get('selected'); + const course = navParams.get('course'); + + if (course && course.enablecompletion && course.courseformatoptions && course.courseformatoptions.coursedisplay == 1) { + this.sections.forEach((section) => { + let complete = 0, + total = 0; + section.modules && section.modules.forEach((module) => { + if (module.uservisible && typeof module.completiondata != 'undefined' && + module.completiondata.tracking > CoreCourseProvider.COMPLETION_TRACKING_NONE) { + total++; + if (module.completiondata.state == CoreCourseProvider.COMPLETION_COMPLETE || + module.completiondata.state == CoreCourseProvider.COMPLETION_COMPLETE_PASS) { + complete++; + } + } + }); + + if (total > 0) { + section.progress = complete / total * 100; + } + }); + } } /** diff --git a/src/core/course/pages/section/section.ts b/src/core/course/pages/section/section.ts index 39ecb6568..c915b4b4e 100644 --- a/src/core/course/pages/section/section.ts +++ b/src/core/course/pages/section/section.ts @@ -19,6 +19,7 @@ import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; +import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreCourseProvider } from '../../providers/course'; import { CoreCourseHelperProvider } from '../../providers/helper'; import { CoreCourseFormatDelegate } from '../../providers/format-delegate'; @@ -72,7 +73,8 @@ export class CoreCourseSectionPage implements OnDestroy { private translate: TranslateService, private courseHelper: CoreCourseHelperProvider, eventsProvider: CoreEventsProvider, private textUtils: CoreTextUtilsProvider, private coursesProvider: CoreCoursesProvider, sitesProvider: CoreSitesProvider, private navCtrl: NavController, private injector: Injector, - private prefetchDelegate: CoreCourseModulePrefetchDelegate, private syncProvider: CoreCourseSyncProvider) { + private prefetchDelegate: CoreCourseModulePrefetchDelegate, private syncProvider: CoreCourseSyncProvider, + private utils: CoreUtilsProvider) { this.course = navParams.get('course'); this.sectionId = navParams.get('sectionId'); this.sectionNumber = navParams.get('sectionNumber'); @@ -275,6 +277,20 @@ export class CoreCourseSectionPage implements OnDestroy { } })); + // Load the course format options when course completion is enabled to show completion progress on sections. + if (this.course.enablecompletion && this.coursesProvider.isGetCoursesByFieldAvailable()) { + promises.push(this.coursesProvider.getCoursesByField('id', this.course.id).catch(() => { + // Ignore errors. + }).then((courses) => { + courses && courses[0] && Object.assign(this.course, courses[0]); + + if (this.course.courseformatoptions) { + this.course.courseformatoptions = this.utils.objectToKeyValueMap(this.course.courseformatoptions, + 'name', 'value'); + } + })); + } + return Promise.all(promises).catch((error) => { this.domUtils.showErrorModalDefault(error, 'core.course.couldnotloadsectioncontent', true); }); diff --git a/src/core/course/providers/course.ts b/src/core/course/providers/course.ts index 80b34b354..e3b647579 100644 --- a/src/core/course/providers/course.ts +++ b/src/core/course/providers/course.ts @@ -34,6 +34,15 @@ export class CoreCourseProvider { static ACCESS_GUEST = 'courses_access_guest'; static ACCESS_DEFAULT = 'courses_access_default'; + static COMPLETION_TRACKING_NONE = 0; + static COMPLETION_TRACKING_MANUAL = 1; + static COMPLETION_TRACKING_AUTOMATIC = 2; + + static COMPLETION_INCOMPLETE = 0; + static COMPLETION_COMPLETE = 1; + static COMPLETION_COMPLETE_PASS = 2; + static COMPLETION_COMPLETE_FAIL = 3; + protected ROOT_CACHE_KEY = 'mmCourse:'; // Variables for database.