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 @@
0">
-
-
+
+
{{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);
+ }
+}