From 92d6d09b8f3e3acc93cd7d226d633ac2a8e7a441 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 20 Mar 2019 14:31:33 +0100 Subject: [PATCH 1/4] MOBILE-2915 completion: Display warning for teachers viewing own --- scripts/langindex.json | 1 + .../report/addon-course-completion-report.html | 11 ++++++++--- .../coursecompletion/components/report/report.ts | 11 +++++++++-- src/addon/coursecompletion/lang/en.json | 1 + src/assets/lang/en.json | 1 + 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/scripts/langindex.json b/scripts/langindex.json index da66b6940..2bbbdb083 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -145,6 +145,7 @@ "addon.coursecompletion.criteriarequiredany": "completion", "addon.coursecompletion.inprogress": "completion", "addon.coursecompletion.manualselfcompletion": "completion", + "addon.coursecompletion.nottracked": "completion", "addon.coursecompletion.notyetstarted": "completion", "addon.coursecompletion.pending": "completion", "addon.coursecompletion.required": "moodle", diff --git a/src/addon/coursecompletion/components/report/addon-course-completion-report.html b/src/addon/coursecompletion/components/report/addon-course-completion-report.html index b4a6a25eb..2b4b92070 100644 --- a/src/addon/coursecompletion/components/report/addon-course-completion-report.html +++ b/src/addon/coursecompletion/components/report/addon-course-completion-report.html @@ -3,7 +3,7 @@ - +

{{ 'addon.coursecompletion.status' | translate }}

{{ completion.statusText | translate }}

@@ -14,7 +14,7 @@

{{ 'addon.coursecompletion.criteriarequiredany' | translate }}

- + {{ 'addon.coursecompletion.requiredcriteria' | translate }}

@@ -41,11 +41,16 @@
- + {{ 'addon.coursecompletion.manualselfcompletion' | translate }} + +
+ + {{ 'addon.coursecompletion.nottracked' | translate }} +
diff --git a/src/addon/coursecompletion/components/report/report.ts b/src/addon/coursecompletion/components/report/report.ts index 69583770f..50d12cf90 100644 --- a/src/addon/coursecompletion/components/report/report.ts +++ b/src/addon/coursecompletion/components/report/report.ts @@ -31,6 +31,7 @@ export class AddonCourseCompletionReportComponent implements OnInit { completionLoaded = false; completion: any; showSelfComplete: boolean; + tracked = true; // Whether completion is tracked. constructor( private sitesProvider: CoreSitesProvider, @@ -62,8 +63,14 @@ export class AddonCourseCompletionReportComponent implements OnInit { this.completion = completion; this.showSelfComplete = this.courseCompletionProvider.canMarkSelfCompleted(this.userId, completion); - }).catch((message) => { - this.domUtils.showErrorModalDefault(message, 'addon.coursecompletion.couldnotloadreport', true); + this.tracked = true; + }).catch((error) => { + if (error && error.errorcode == 'notenroled') { + // Not enrolled error, probably a teacher. + this.tracked = false; + } else { + this.domUtils.showErrorModalDefault(error, 'addon.coursecompletion.couldnotloadreport', true); + } }); } diff --git a/src/addon/coursecompletion/lang/en.json b/src/addon/coursecompletion/lang/en.json index 7607702c6..81ef0272e 100644 --- a/src/addon/coursecompletion/lang/en.json +++ b/src/addon/coursecompletion/lang/en.json @@ -12,6 +12,7 @@ "criteriarequiredany": "Any criteria below are required", "inprogress": "In progress", "manualselfcompletion": "Manual self completion", + "nottracked": "You are currently not being tracked by completion in this course", "notyetstarted": "Not yet started", "pending": "Pending", "required": "Required", diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index b6072b623..9f14d682a 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -145,6 +145,7 @@ "addon.coursecompletion.criteriarequiredany": "Any criteria below are required", "addon.coursecompletion.inprogress": "In progress", "addon.coursecompletion.manualselfcompletion": "Manual self completion", + "addon.coursecompletion.nottracked": "You are currently not being tracked by completion in this course", "addon.coursecompletion.notyetstarted": "Not yet started", "addon.coursecompletion.pending": "Pending", "addon.coursecompletion.required": "Required", From 2f56db4511350f7ffe8a917b3e8e64348fefcc06 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 20 Mar 2019 14:49:15 +0100 Subject: [PATCH 2/4] MOBILE-2915 core: Fix Uncaught promise error if request fails --- src/classes/site.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/classes/site.ts b/src/classes/site.ts index acdde5a92..26290190f 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -582,7 +582,7 @@ export class CoreSite { }); } - const promise = this.getFromCache(method, data, preSets, false, originalData).catch(() => { + let promise = this.getFromCache(method, data, preSets, false, originalData).catch(() => { // Do not pass those options to the core WS factory. return this.wsProvider.call(method, data, wsPreSets).then((response) => { if (preSets.saveToCache) { @@ -688,12 +688,13 @@ export class CoreSite { }); this.ongoingRequests[cacheId] = promise; + // Clear ongoing request after setting the promise (just in case it's already resolved). - promise.finally(() => { - // Make sure we don't clear the promise of a newer request that ignores the cache. - if (this.ongoingRequests[cacheId] === promise) { - delete this.ongoingRequests[cacheId]; - } + promise = promise.finally(() => { + // Make sure we don't clear the promise of a newer request that ignores the cache. + if (this.ongoingRequests[cacheId] === promise) { + delete this.ongoingRequests[cacheId]; + } }); return promise.then((response) => { From 0d46a6a426858dafb3b9a61c68abcb8153065eda Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 21 Mar 2019 16:00:11 +0100 Subject: [PATCH 3/4] MOBILE-2915 config: Revert file-opener to 2.0.19 --- config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.xml b/config.xml index a8ee57ec4..0a1343541 100644 --- a/config.xml +++ b/config.xml @@ -124,7 +124,7 @@ - + From 0449c63c7110b0733c930c4ad564d1499383d447 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 22 Mar 2019 07:02:08 +0100 Subject: [PATCH 4/4] MOBILE-2915 course: Fix title not displayed for guest courses --- src/core/course/pages/section/section.ts | 4 ++- src/core/course/providers/helper.ts | 27 ++++++++++++++ src/core/courses/providers/courses.ts | 46 ++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/core/course/pages/section/section.ts b/src/core/course/pages/section/section.ts index 65adf6fb4..7246d3fd9 100644 --- a/src/core/course/pages/section/section.ts +++ b/src/core/course/pages/section/section.ts @@ -169,7 +169,9 @@ export class CoreCourseSectionPage implements OnDestroy { */ protected loadData(refresh?: boolean, sync?: boolean): Promise { // First of all, get the course because the data might have changed. - return this.coursesProvider.getUserCourse(this.course.id).catch(() => { + return this.courseHelper.getCourse(this.course.id).then((result) => { + return result.course; + }).catch(() => { // Error getting the course, probably guest access. }).then((course) => { if (course) { diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index 941a2f9c4..aa57300b6 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -767,6 +767,33 @@ export class CoreCourseHelperProvider { }); } + /** + * Get a course. It will first check the user courses, and fallback to another WS if not enrolled. + * + * @param {number} courseId Course ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise<{enrolled: boolean, course: any}>} Promise resolved with the course. + */ + getCourse(courseId: number, siteId?: string): Promise<{enrolled: boolean, course: any}> { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + // Try with enrolled courses first. + return this.coursesProvider.getUserCourse(courseId, false, siteId).then((course) => { + return { enrolled: true, course: course }; + }).catch(() => { + // Not enrolled or an error happened. Try to use another WebService. + return this.coursesProvider.isGetCoursesByFieldAvailableInSite(siteId).then((available) => { + if (available) { + return this.coursesProvider.getCourseByField('id', courseId, siteId); + } else { + return this.coursesProvider.getCourse(courseId, siteId); + } + }).then((course) => { + return { enrolled: false, course: course }; + }); + }); + } + /** * Check if the course has a block with that name. * diff --git a/src/core/courses/providers/courses.ts b/src/core/courses/providers/courses.ts index d4e492aa8..2760b2f0c 100644 --- a/src/core/courses/providers/courses.ts +++ b/src/core/courses/providers/courses.ts @@ -389,6 +389,30 @@ export class CoreCoursesProvider { } } + /** + * Get the first course returned by getCoursesByField. + * + * @param {string} [field] The field to search. Can be left empty for all courses or: + * id: course id. + * ids: comma separated course ids. + * shortname: course short name. + * idnumber: course id number. + * category: category id the course belongs to. + * @param {any} [value] The value to match. + * @param {string} [siteId] Site ID. If not defined, use current site. + * @return {Promise} Promise resolved with the first course. + * @since 3.2 + */ + getCourseByField(field?: string, value?: any, siteId?: string): Promise { + return this.getCoursesByField(field, value, siteId).then((courses) => { + if (courses && courses.length > 0) { + return courses[0]; + } + + return Promise.reject(null); + }); + } + /** * Get courses. They can be filtered by field. * @@ -482,13 +506,29 @@ export class CoreCoursesProvider { } /** - * Check if get courses by field WS is available. + * Check if get courses by field WS is available in a certain site. * + * @param {CoreSite} [site] Site to check. * @return {boolean} Whether get courses by field is available. * @since 3.2 */ - isGetCoursesByFieldAvailable(): boolean { - return this.sitesProvider.wsAvailableInCurrentSite('core_course_get_courses_by_field'); + isGetCoursesByFieldAvailable(site?: CoreSite): boolean { + site = site || this.sitesProvider.getCurrentSite(); + + return site.wsAvailable('core_course_get_courses_by_field'); + } + + /** + * Check if get courses by field WS is available in a certain site, by site ID. + * + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with boolean: whether get courses by field is available. + * @since 3.2 + */ + isGetCoursesByFieldAvailableInSite(siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + return this.isGetCoursesByFieldAvailable(site); + }); } /**