From 2e7394208317b4ab021e24077a70ccd2e2eca3ac Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 2 Jan 2018 12:21:53 +0100 Subject: [PATCH] MOBILE-2310 course: Implement completion and fix PTR issues in section --- .../img/completion/completion-auto-fail.svg | 18 +++ .../completion/completion-auto-n-override.svg | 3 + .../img/completion/completion-auto-n.svg | 15 ++ .../img/completion/completion-auto-pass.svg | 17 ++ .../completion/completion-auto-y-override.svg | 3 + .../img/completion/completion-auto-y.svg | 17 ++ .../completion-manual-n-override.svg | 3 + .../img/completion/completion-manual-n.svg | 14 ++ .../completion-manual-y-override.svg | 3 + .../img/completion/completion-manual-y.svg | 17 ++ .../course/components/components.module.ts | 7 +- src/core/course/components/format/format.html | 3 - src/core/course/components/format/format.ts | 26 ++- .../module-completion/module-completion.html | 3 + .../module-completion/module-completion.ts | 150 ++++++++++++++++++ src/core/course/components/module/module.html | 2 +- src/core/course/pages/section/section.ts | 112 +++++++------ 17 files changed, 352 insertions(+), 61 deletions(-) create mode 100644 src/assets/img/completion/completion-auto-fail.svg create mode 100644 src/assets/img/completion/completion-auto-n-override.svg create mode 100644 src/assets/img/completion/completion-auto-n.svg create mode 100644 src/assets/img/completion/completion-auto-pass.svg create mode 100644 src/assets/img/completion/completion-auto-y-override.svg create mode 100644 src/assets/img/completion/completion-auto-y.svg create mode 100644 src/assets/img/completion/completion-manual-n-override.svg create mode 100644 src/assets/img/completion/completion-manual-n.svg create mode 100644 src/assets/img/completion/completion-manual-y-override.svg create mode 100644 src/assets/img/completion/completion-manual-y.svg create mode 100644 src/core/course/components/module-completion/module-completion.html create mode 100644 src/core/course/components/module-completion/module-completion.ts diff --git a/src/assets/img/completion/completion-auto-fail.svg b/src/assets/img/completion/completion-auto-fail.svg new file mode 100644 index 000000000..771adf36f --- /dev/null +++ b/src/assets/img/completion/completion-auto-fail.svg @@ -0,0 +1,18 @@ + + + +]> + + + + + + diff --git a/src/assets/img/completion/completion-auto-n-override.svg b/src/assets/img/completion/completion-auto-n-override.svg new file mode 100644 index 000000000..6100638d0 --- /dev/null +++ b/src/assets/img/completion/completion-auto-n-override.svg @@ -0,0 +1,3 @@ + +]> \ No newline at end of file diff --git a/src/assets/img/completion/completion-auto-n.svg b/src/assets/img/completion/completion-auto-n.svg new file mode 100644 index 000000000..6a8bc6222 --- /dev/null +++ b/src/assets/img/completion/completion-auto-n.svg @@ -0,0 +1,15 @@ + + + +]> + + + + + diff --git a/src/assets/img/completion/completion-auto-pass.svg b/src/assets/img/completion/completion-auto-pass.svg new file mode 100644 index 000000000..44df83f15 --- /dev/null +++ b/src/assets/img/completion/completion-auto-pass.svg @@ -0,0 +1,17 @@ + + + +]> + + + + + + diff --git a/src/assets/img/completion/completion-auto-y-override.svg b/src/assets/img/completion/completion-auto-y-override.svg new file mode 100644 index 000000000..13cf5d700 --- /dev/null +++ b/src/assets/img/completion/completion-auto-y-override.svg @@ -0,0 +1,3 @@ + +]> \ No newline at end of file diff --git a/src/assets/img/completion/completion-auto-y.svg b/src/assets/img/completion/completion-auto-y.svg new file mode 100644 index 000000000..14822e173 --- /dev/null +++ b/src/assets/img/completion/completion-auto-y.svg @@ -0,0 +1,17 @@ + + + +]> + + + + + + diff --git a/src/assets/img/completion/completion-manual-n-override.svg b/src/assets/img/completion/completion-manual-n-override.svg new file mode 100644 index 000000000..cccfb99cd --- /dev/null +++ b/src/assets/img/completion/completion-manual-n-override.svg @@ -0,0 +1,3 @@ + +]> \ No newline at end of file diff --git a/src/assets/img/completion/completion-manual-n.svg b/src/assets/img/completion/completion-manual-n.svg new file mode 100644 index 000000000..f7750e25a --- /dev/null +++ b/src/assets/img/completion/completion-manual-n.svg @@ -0,0 +1,14 @@ + + + +]> + + + + + diff --git a/src/assets/img/completion/completion-manual-y-override.svg b/src/assets/img/completion/completion-manual-y-override.svg new file mode 100644 index 000000000..69270ba3e --- /dev/null +++ b/src/assets/img/completion/completion-manual-y-override.svg @@ -0,0 +1,3 @@ + +]> \ No newline at end of file diff --git a/src/assets/img/completion/completion-manual-y.svg b/src/assets/img/completion/completion-manual-y.svg new file mode 100644 index 000000000..3b91bdbc7 --- /dev/null +++ b/src/assets/img/completion/completion-manual-y.svg @@ -0,0 +1,17 @@ + + + +]> + + + + + + diff --git a/src/core/course/components/components.module.ts b/src/core/course/components/components.module.ts index 693e245b8..9e521a82b 100644 --- a/src/core/course/components/components.module.ts +++ b/src/core/course/components/components.module.ts @@ -20,11 +20,13 @@ import { CoreComponentsModule } from '../../../components/components.module'; import { CoreDirectivesModule } from '../../../directives/directives.module'; import { CoreCourseFormatComponent } from './format/format'; import { CoreCourseModuleComponent } from './module/module'; +import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion'; @NgModule({ declarations: [ CoreCourseFormatComponent, - CoreCourseModuleComponent + CoreCourseModuleComponent, + CoreCourseModuleCompletionComponent ], imports: [ CommonModule, @@ -37,7 +39,8 @@ import { CoreCourseModuleComponent } from './module/module'; ], exports: [ CoreCourseFormatComponent, - CoreCourseModuleComponent + CoreCourseModuleComponent, + CoreCourseModuleCompletionComponent ] }) export class CoreCourseComponentsModule {} diff --git a/src/core/course/components/format/format.html b/src/core/course/components/format/format.html index 48fa51547..043f659c7 100644 --- a/src/core/course/components/format/format.html +++ b/src/core/course/components/format/format.html @@ -2,9 +2,6 @@
- - - diff --git a/src/core/course/components/format/format.ts b/src/core/course/components/format/format.ts index f341c89a9..7af959cd8 100644 --- a/src/core/course/components/format/format.ts +++ b/src/core/course/components/format/format.ts @@ -92,13 +92,27 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges { * Detect changes on input properties. */ ngOnChanges(changes: {[name: string]: SimpleChange}) { - if (!this.selectedSection && changes.sections && this.sections) { - this.sectionChanged(this.cfDelegate.getCurrentSection(this.course, this.sections)); - } + if (changes.sections && this.sections) { + if (!this.selectedSection) { + // There is no selected section yet, calculate which one to get. + this.sectionChanged(this.cfDelegate.getCurrentSection(this.course, this.sections)); + } else { + // We have a selected section, but the list has changed. Search the section in the list. + let newSection; + for (let i = 0; i < this.sections.length; i++) { + let section = this.sections[i]; + if (this.compareSections(section, this.selectedSection)) { + newSection = section; + break; + } + } - if (!Object.keys(this.componentInstances).length) { - // We haven't created any component dynamically, stop. - return; + if (!newSection) { + // Section not found, calculate which one to use. + newSection = this.cfDelegate.getCurrentSection(this.course, this.sections); + } + this.sectionChanged(newSection); + } } // Apply the changes to the components and call ngOnChanges if it exists. diff --git a/src/core/course/components/module-completion/module-completion.html b/src/core/course/components/module-completion/module-completion.html new file mode 100644 index 000000000..78ef60782 --- /dev/null +++ b/src/core/course/components/module-completion/module-completion.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/core/course/components/module-completion/module-completion.ts b/src/core/course/components/module-completion/module-completion.ts new file mode 100644 index 000000000..1bd9e99a2 --- /dev/null +++ b/src/core/course/components/module-completion/module-completion.ts @@ -0,0 +1,150 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreSitesProvider } from '../../../../providers/sites'; +import { CoreDomUtilsProvider } from '../../../../providers/utils/dom'; +import { CoreTextUtilsProvider } from '../../../../providers/utils/text'; + +/** + * Component to handle activity completion. It shows a checkbox with the current status, and allows manually changing + * the completion if it's allowed. + * + * Example usage: + * + * + */ +@Component({ + selector: 'core-course-module-completion', + templateUrl: 'module-completion.html' +}) +export class CoreCourseModuleCompletionComponent implements OnChanges { + @Input() completion: any; // The completion status. + @Input() moduleName?: string; // The name of the module this completion affects. + @Output() completionChanged?: EventEmitter; // Will emit an event when the completion changes. + + completionImage: string; + completionDescription: string; + + constructor(private textUtils: CoreTextUtilsProvider, private translate: TranslateService, + private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider) { + this.completionChanged = new EventEmitter(); + } + + /** + * Detect changes on input properties. + */ + ngOnChanges(changes: {[name: string]: SimpleChange}) { + if (changes.completion && this.completion) { + this.showStatus(); + } + } + + /** + * Completion clicked. + * + * @param {Event} e The click event. + */ + completionClicked(e: Event) : void { + if (this.completion) { + if (typeof this.completion.cmid == 'undefined' || this.completion.tracking !== 1) { + return; + } + + e.preventDefault(); + e.stopPropagation(); + + let modal = this.domUtils.showModalLoading(), + params = { + cmid: this.completion.cmid, + completed: this.completion.state === 1 ? 0 : 1 + }, + currentSite = this.sitesProvider.getCurrentSite(); + + currentSite.write('core_completion_update_activity_completion_status_manually', params).then((response) => { + if (!response.status) { + return Promise.reject(null); + } + + this.completionChanged.emit(); + }).catch((error) => { + this.domUtils.showErrorModalDefault(error, 'core.errorchangecompletion', true); + }).finally(() => { + modal.dismiss(); + }); + } + } + + /** + * Set image and description to show as completion icon. + */ + protected showStatus() : void { + let langKey, + moduleName = this.moduleName || '', + image; + + if (this.completion.tracking === 1 && this.completion.state === 0) { + image = 'completion-manual-n'; + langKey = 'core.completion-alt-manual-n'; + } else if (this.completion.tracking === 1 && this.completion.state === 1) { + image = 'completion-manual-y'; + langKey = 'core.completion-alt-manual-y'; + } else if (this.completion.tracking === 2 && this.completion.state === 0) { + image = 'completion-auto-n'; + langKey = 'core.completion-alt-auto-n'; + } else if (this.completion.tracking === 2 && this.completion.state === 1) { + image = 'completion-auto-y'; + langKey = 'core.completion-alt-auto-y'; + } else if (this.completion.tracking === 2 && this.completion.state === 2) { + image = 'completion-auto-pass'; + langKey = 'core.completion-alt-auto-pass'; + } else if (this.completion.tracking === 2 && this.completion.state === 3) { + image = 'completion-auto-fail'; + langKey = 'core.completion-alt-auto-fail'; + } + + if (image) { + if (this.completion.overrideby > 0) { + image += '-override'; + } + this.completionImage = 'assets/img/completion/' + image + '.svg'; + } + + if (moduleName) { + this.textUtils.formatText(moduleName, true, true, 50).then((modNameFormatted) => { + let promise; + + if (this.completion.overrideby > 0) { + langKey += '-override'; + + // @todo: Get user profile. + // promise = $mmUser.getProfile(scope.completion.overrideby, scope.completion.courseId, true).then(function(profile) { + // return { + // overrideuser: profile.fullname, + // modname: modNameFormatted + // }; + // }); + } else { + promise = Promise.resolve(modNameFormatted); + } + + return promise.then((translateParams) => { + this.completionDescription = this.translate.instant(langKey, {$a: translateParams}); + }); + }); + } + } +} diff --git a/src/core/course/components/module/module.html b/src/core/course/components/module/module.html index 2b79e0e7e..dd45a23d7 100644 --- a/src/core/course/components/module/module.html +++ b/src/core/course/components/module/module.html @@ -5,7 +5,7 @@
- +