From 9df8e406e0fe2f902886faace2d66389cc4e5af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 7 Feb 2018 15:36:10 +0100 Subject: [PATCH] MOBILE-2326 grades: Add links handlers --- src/core/grades/components/course/course.html | 2 +- src/core/grades/components/course/course.ts | 3 - src/core/grades/grades.module.ts | 32 ++++- src/core/grades/pages/course/course.module.ts | 4 - src/core/grades/pages/courses/courses.html | 4 +- src/core/grades/pages/courses/courses.ts | 2 +- .../pages/coursesplit/coursesplit.module.ts | 2 - src/core/grades/pages/grade/grade.html | 2 +- src/core/grades/pages/grade/grade.ts | 3 - src/core/grades/providers/grades.ts | 2 - src/core/grades/providers/helper.ts | 8 +- .../grades/providers/overview-link-handler.ts | 65 ++++++++++ src/core/grades/providers/user-handler.ts | 120 ++++++++++++++++++ .../grades/providers/user-link-handler.ts | 73 +++++++++++ 14 files changed, 297 insertions(+), 25 deletions(-) create mode 100644 src/core/grades/providers/overview-link-handler.ts create mode 100644 src/core/grades/providers/user-handler.ts create mode 100644 src/core/grades/providers/user-link-handler.ts diff --git a/src/core/grades/components/course/course.html b/src/core/grades/components/course/course.html index ca54f693d..25798e609 100644 --- a/src/core/grades/components/course/course.html +++ b/src/core/grades/components/course/course.html @@ -3,7 +3,7 @@ - +
diff --git a/src/core/grades/components/course/course.ts b/src/core/grades/components/course/course.ts index 5913ac22c..bdbe66489 100644 --- a/src/core/grades/components/course/course.ts +++ b/src/core/grades/components/course/course.ts @@ -35,7 +35,6 @@ export class CoreGradesCourseComponent { @Input() userId: number; @Input() gradeId?: number; - errorMessage: string; gradesLoaded = false; gradesTable: any; @@ -48,7 +47,6 @@ export class CoreGradesCourseComponent { * View loaded. */ ngOnInit(): void { - // Get first participants. this.fetchData().then(() => { if (this.gradeId) { // There is the grade to load. @@ -73,7 +71,6 @@ export class CoreGradesCourseComponent { this.gradesTable = this.gradesHelper.formatGradesTable(table); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'Error loading grades'); - this.errorMessage = error; }); } diff --git a/src/core/grades/grades.module.ts b/src/core/grades/grades.module.ts index 8eb8b7442..44bd085fb 100644 --- a/src/core/grades/grades.module.ts +++ b/src/core/grades/grades.module.ts @@ -20,6 +20,14 @@ import { CoreGradesMainMenuHandler } from './providers/mainmenu-handler'; import { CoreGradesCourseOptionHandler } from './providers/course-option-handler'; import { CoreGradesComponentsModule } from './components/components.module'; import { CoreCourseOptionsDelegate } from '../course/providers/options-delegate'; +import { CoreGradesUserLinkHandler } from './providers/user-link-handler'; +import { CoreGradesOverviewLinkHandler } from './providers/overview-link-handler'; +import { CoreContentLinksDelegate } from '../contentlinks/providers/delegate'; +import { CoreGradesUserHandler } from './providers/user-handler'; +import { CoreUserDelegate } from '../user/providers/user-delegate'; +import { CoreEventsProvider } from '../../providers/events'; +import { CoreSitesProvider } from '../../providers/sites'; +import { CoreUserProvider } from '../user/providers/user'; @NgModule({ declarations: [ @@ -31,13 +39,33 @@ import { CoreCourseOptionsDelegate } from '../course/providers/options-delegate' CoreGradesProvider, CoreGradesHelperProvider, CoreGradesMainMenuHandler, - CoreGradesCourseOptionHandler + CoreGradesCourseOptionHandler, + CoreGradesUserLinkHandler, + CoreGradesOverviewLinkHandler, + CoreGradesUserHandler ] }) export class CoreGradesModule { constructor(mainMenuDelegate: CoreMainMenuDelegate, gradesMenuHandler: CoreGradesMainMenuHandler, - courseOptionHandler: CoreGradesCourseOptionHandler, courseOptionsDelegate: CoreCourseOptionsDelegate) { + courseOptionHandler: CoreGradesCourseOptionHandler, courseOptionsDelegate: CoreCourseOptionsDelegate, + contentLinksDelegate: CoreContentLinksDelegate, userLinkHandler: CoreGradesUserLinkHandler, + overviewLinkHandler: CoreGradesOverviewLinkHandler, userHandler: CoreGradesUserHandler, + userDelegate: CoreUserDelegate, eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) { + + // Register handlers. mainMenuDelegate.registerHandler(gradesMenuHandler); courseOptionsDelegate.registerHandler(courseOptionHandler); + contentLinksDelegate.registerHandler(userLinkHandler); + contentLinksDelegate.registerHandler(overviewLinkHandler); + userDelegate.registerHandler(userHandler); + + // Clear user profile handler cache. + eventsProvider.on(CoreUserProvider.PROFILE_REFRESHED, (data) => { + userHandler.clearViewGradesCache(data.courseId, data.userId); + }, sitesProvider.getCurrentSiteId()); + + eventsProvider.on(CoreEventsProvider.LOGOUT, () => { + userHandler.clearViewGradesCache(); + }, sitesProvider.getCurrentSiteId()); } } diff --git a/src/core/grades/pages/course/course.module.ts b/src/core/grades/pages/course/course.module.ts index 25b0e2f34..903241e3b 100644 --- a/src/core/grades/pages/course/course.module.ts +++ b/src/core/grades/pages/course/course.module.ts @@ -16,8 +16,6 @@ import { NgModule } from '@angular/core'; import { IonicPageModule } from 'ionic-angular'; import { TranslateModule } from '@ngx-translate/core'; import { CoreGradesCoursePage } from './course'; -import { CoreComponentsModule } from '../../../../components/components.module'; -import { CoreDirectivesModule } from '../../../../directives/directives.module'; import { CoreGradesComponentsModule } from '../../components/components.module'; @NgModule({ @@ -26,8 +24,6 @@ import { CoreGradesComponentsModule } from '../../components/components.module'; ], imports: [ CoreGradesComponentsModule, - CoreComponentsModule, - CoreDirectivesModule, IonicPageModule.forChild(CoreGradesCoursePage), TranslateModule.forChild() ], diff --git a/src/core/grades/pages/courses/courses.html b/src/core/grades/pages/courses/courses.html index 9541c0f75..f3de49188 100644 --- a/src/core/grades/pages/courses/courses.html +++ b/src/core/grades/pages/courses/courses.html @@ -13,8 +13,8 @@ - -

+
+

{{grade.grade}}
diff --git a/src/core/grades/pages/courses/courses.ts b/src/core/grades/pages/courses/courses.ts index fd54a58d8..4610fdce7 100644 --- a/src/core/grades/pages/courses/courses.ts +++ b/src/core/grades/pages/courses/courses.ts @@ -95,6 +95,6 @@ export class CoreGradesCoursesPage { */ gotoCourseGrades(courseId: number): void { this.courseId = courseId; - this.splitviewCtrl.push('CoreGradesCoursePage', {courseId: courseId, userId: this.userId, forcephoneview: 1}); + this.splitviewCtrl.push('CoreGradesCoursePage', {courseId: courseId, userId: this.userId}); } } diff --git a/src/core/grades/pages/coursesplit/coursesplit.module.ts b/src/core/grades/pages/coursesplit/coursesplit.module.ts index 57b081e99..fb9bab05a 100644 --- a/src/core/grades/pages/coursesplit/coursesplit.module.ts +++ b/src/core/grades/pages/coursesplit/coursesplit.module.ts @@ -17,7 +17,6 @@ import { IonicPageModule } from 'ionic-angular'; import { TranslateModule } from '@ngx-translate/core'; import { CoreGradesCourseSplitPage } from './coursesplit'; import { CoreComponentsModule } from '../../../../components/components.module'; -import { CoreDirectivesModule } from '../../../../directives/directives.module'; import { CoreGradesComponentsModule } from '../../components/components.module'; @NgModule({ @@ -27,7 +26,6 @@ import { CoreGradesComponentsModule } from '../../components/components.module'; imports: [ CoreGradesComponentsModule, CoreComponentsModule, - CoreDirectivesModule, IonicPageModule.forChild(CoreGradesCourseSplitPage), TranslateModule.forChild() ], diff --git a/src/core/grades/pages/grade/grade.html b/src/core/grades/pages/grade/grade.html index 5f9268c9c..dd9d671a1 100644 --- a/src/core/grades/pages/grade/grade.html +++ b/src/core/grades/pages/grade/grade.html @@ -8,7 +8,7 @@ - + diff --git a/src/core/grades/pages/grade/grade.ts b/src/core/grades/pages/grade/grade.ts index 8ef99c85d..181b1d6f1 100644 --- a/src/core/grades/pages/grade/grade.ts +++ b/src/core/grades/pages/grade/grade.ts @@ -16,7 +16,6 @@ import { Component, ViewChild } from '@angular/core'; import { IonicPage, Content, NavParams } from 'ionic-angular'; import { CoreGradesProvider } from '../../providers/grades'; import { CoreDomUtilsProvider } from '../../../../providers/utils/dom'; -import { CoreSplitViewComponent } from '../../../../components/split-view/split-view'; import { CoreGradesHelperProvider } from '../../providers/helper'; import { CoreSitesProvider } from '../../../../providers/sites'; @@ -35,7 +34,6 @@ export class CoreGradesGradePage { courseId: number; userId: number; gradeId: number; - errormessage: string; gradeLoaded = false; constructor(private gradesProvider: CoreGradesProvider, private domUtils: CoreDomUtilsProvider, @@ -65,7 +63,6 @@ export class CoreGradesGradePage { this.grade = grade; }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'Error loading grade item'); - this.errormessage = error || 'Grade not found'; }); } diff --git a/src/core/grades/providers/grades.ts b/src/core/grades/providers/grades.ts index f4efc010b..21cf6afe3 100644 --- a/src/core/grades/providers/grades.ts +++ b/src/core/grades/providers/grades.ts @@ -16,7 +16,6 @@ import { Injectable } from '@angular/core'; import { CoreLoggerProvider } from '../../../providers/logger'; import { CoreSite } from '../../../classes/site'; import { CoreSitesProvider } from '../../../providers/sites'; -import { CoreUtilsProvider } from '../../../providers/utils/utils'; import { CoreCoursesProvider } from '../../courses/providers/courses'; /** @@ -152,7 +151,6 @@ export class CoreGradesProvider { /** * Get the grades for a certain course. - * Using gradereport_user_get_grades_table in case is not avalaible. * * @param {number} courseId ID of the course to get the grades from. * @param {number} [userId] ID of the user to get the grades from. diff --git a/src/core/grades/providers/helper.ts b/src/core/grades/providers/helper.ts index f0cb2d0f0..8c7a42dfc 100644 --- a/src/core/grades/providers/helper.ts +++ b/src/core/grades/providers/helper.ts @@ -121,7 +121,7 @@ export class CoreGradesHelperProvider { */ protected formatGradeItem(item: any): any { for (const name in item) { - let index = name.indexOf('formatted'); + const index = name.indexOf('formatted'); if (index > 0) { item[name.substr(0, index)] = item[name]; } @@ -194,8 +194,8 @@ export class CoreGradesHelperProvider { /** * Get course data for grades since they only have courseid. * - * @param {Object[]} grades Grades to get the data for. - * @return {Promise} Promise always resolved. Resolve param is the formatted grades. + * @param {any} grades Grades to get the data for. + * @return {Promise} Promise always resolved. Resolve param is the formatted grades. */ getGradesCourseData(grades: any): Promise { // Using cache for performance reasons. @@ -207,7 +207,7 @@ export class CoreGradesHelperProvider { grades.forEach((grade) => { if (typeof indexedCourses[grade.courseid] != 'undefined') { - grade.coursefullname = indexedCourses[grade.courseid].fullname; + grade.courseFullName = indexedCourses[grade.courseid].fullname; } }); diff --git a/src/core/grades/providers/overview-link-handler.ts b/src/core/grades/providers/overview-link-handler.ts new file mode 100644 index 000000000..915b9e2c2 --- /dev/null +++ b/src/core/grades/providers/overview-link-handler.ts @@ -0,0 +1,65 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler'; +import { CoreContentLinksAction } from '../../contentlinks/providers/delegate'; +import { CoreContentLinksHelperProvider } from '../../contentlinks/providers/helper'; +import { CoreGradesProvider } from './grades'; + +/** + * Handler to treat links to overview courses grades. + */ +@Injectable() +export class CoreGradesOverviewLinkHandler extends CoreContentLinksHandlerBase { + name = 'CoreGradesOverviewLinkHandler'; + pattern = /\/grade\/report\/overview\/index.php/; + + constructor(private linkHelper: CoreContentLinksHelperProvider, private gradesProvider: CoreGradesProvider) { + super(); + } + + /** + * Get the list of actions for a link (url). + * + * @param {string[]} siteIds List of sites the URL belongs to. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {CoreContentLinksAction[]|Promise} List of (or promise resolved with list of) actions. + */ + getActions(siteIds: string[], url: string, params: any, courseId?: number): + CoreContentLinksAction[] | Promise { + return [{ + action: (siteId, navCtrl?): void => { + // Always use redirect to make it the new history root (to avoid "loops" in history). + this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursesPage', undefined, siteId); + } + }]; + } + + /** + * Check if the handler is enabled for a certain site (site + user) and a URL. + * If not defined, defaults to true. + * + * @param {string} siteId The site ID. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {boolean|Promise} Whether the handler is enabled for the URL and site. + */ + isEnabled(siteId: string, url: string, params: any, courseId?: number): boolean | Promise { + return this.gradesProvider.isCourseGradesEnabled(siteId); + } +} diff --git a/src/core/grades/providers/user-handler.ts b/src/core/grades/providers/user-handler.ts new file mode 100644 index 000000000..593b7cdab --- /dev/null +++ b/src/core/grades/providers/user-handler.ts @@ -0,0 +1,120 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../user/providers/user-delegate'; +import { CoreSitesProvider } from '../../../providers/sites'; +import { CoreContentLinksHelperProvider } from '../../contentlinks/providers/helper'; +import { CoreGradesProvider } from './grades'; + +/** + * Profile grades handler. + */ +@Injectable() +export class CoreGradesUserHandler implements CoreUserProfileHandler { + name = 'mmGrades'; + priority = 400; + type = CoreUserDelegate.TYPE_NEW_PAGE; + viewGradesEnabledCache = {}; + + constructor(private linkHelper: CoreContentLinksHelperProvider, protected sitesProvider: CoreSitesProvider, + private gradesProvider: CoreGradesProvider) { } + + /** + * Clear view grades cache. + * If a courseId and userId are specified, it will only delete the entry for that user and course. + * + * @param {number} [courseId] Course ID. + * @param {number} [userId] User ID. + */ + clearViewGradesCache(courseId?: number, userId?: number): void { + if (courseId && userId) { + delete this.viewGradesEnabledCache[this.getCacheKey(courseId, userId)]; + } else { + this.viewGradesEnabledCache = {}; + } + } + + /** + * Get a cache key to identify a course and a user. + * + * @param {number} courseId Course ID. + * @param {number} userId User ID. + * @return {string} Cache key. + */ + protected getCacheKey(courseId: number, userId: number): string { + return courseId + '#' + userId; + } + + /** + * Check if handler is enabled. + * + * @return {boolean} Always enabled. + */ + isEnabled(): boolean { + return true; + } + + /** + * Check if handler is enabled for this user in this context. + * + * @param {any} user User to check. + * @param {number} courseId Course ID. + * @param {any} [navOptions] Course navigation options for current user. See $mmCourses#getUserNavigationOptions. + * @param {any} [admOptions] Course admin options for current user. See $mmCourses#getUserAdministrationOptions. + * @return {boolean|Promise} Promise resolved with true if enabled, resolved with false otherwise. + */ + isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise { + const cacheKey = this.getCacheKey(courseId, user.id), + cache = this.viewGradesEnabledCache[cacheKey]; + if (typeof cache != 'undefined') { + return cache; + } + + return this.gradesProvider.isPluginEnabledForCourse(courseId).then(() => { + return this.gradesProvider.getCourseGradesTable(courseId, user.id).then(() => { + this.viewGradesEnabledCache[cacheKey] = true; + + return true; + }).catch(() => { + this.viewGradesEnabledCache[cacheKey] = false; + + return false; + }); + }); + } + + /** + * Returns the data needed to render the handler. + * + * @return {CoreUserProfileHandlerData} Data needed to render the handler. + */ + getDisplayData(user: any, courseId: number): CoreUserProfileHandlerData { + return { + icon: 'stats', + title: 'core.grades.grades', + class: 'core-grades-user-handler', + action: (event, navCtrl, user, courseId): void => { + event.preventDefault(); + event.stopPropagation(); + const pageParams = { + courseId: courseId, + userId: user.id + }; + // Always use redirect to make it the new history root (to avoid "loops" in history). + this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursePage', pageParams); + } + }; + } +} diff --git a/src/core/grades/providers/user-link-handler.ts b/src/core/grades/providers/user-link-handler.ts new file mode 100644 index 000000000..589f258aa --- /dev/null +++ b/src/core/grades/providers/user-link-handler.ts @@ -0,0 +1,73 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler'; +import { CoreContentLinksAction } from '../../contentlinks/providers/delegate'; +import { CoreContentLinksHelperProvider } from '../../contentlinks/providers/helper'; +import { CoreGradesProvider } from './grades'; + +/** + * Handler to treat links to user grades. + */ +@Injectable() +export class CoreGradesUserLinkHandler extends CoreContentLinksHandlerBase { + name = 'CoreGradesUserLinkHandler'; + pattern = /\/grade\/report\/user\/index.php/; + + constructor(private linkHelper: CoreContentLinksHelperProvider, private gradesProvider: CoreGradesProvider) { + super(); + } + + /** + * Get the list of actions for a link (url). + * + * @param {string[]} siteIds List of sites the URL belongs to. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {CoreContentLinksAction[]|Promise} List of (or promise resolved with list of) actions. + */ + getActions(siteIds: string[], url: string, params: any, courseId?: number): + CoreContentLinksAction[] | Promise { + return [{ + action: (siteId, navCtrl?): void => { + const pageParams = { + course: {id: courseId}, + userId: params.userid ? parseInt(params.userid, 10) : false, + }; + // Always use redirect to make it the new history root (to avoid "loops" in history). + this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursePage', pageParams, siteId); + } + }]; + } + + /** + * Check if the handler is enabled for a certain site (site + user) and a URL. + * If not defined, defaults to true. + * + * @param {string} siteId The site ID. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {boolean|Promise} Whether the handler is enabled for the URL and site. + */ + isEnabled(siteId: string, url: string, params: any, courseId?: number): boolean | Promise { + if (!courseId) { + return false; + } + + return this.gradesProvider.isPluginEnabledForCourse(courseId, siteId); + } +}