MOBILE-3966 user: Use context+contextId in user delegate
parent
a51e722e74
commit
101faf20aa
|
@ -14,7 +14,12 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreCourseUserAdminOrNavOptionIndexed } from '@features/courses/services/courses';
|
||||
import { CoreUserDelegateService, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserDelegateContext,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandler,
|
||||
CoreUserProfileHandlerData,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonBadges } from '../badges';
|
||||
|
@ -30,22 +35,17 @@ export class AddonBadgesUserHandlerService implements CoreUserProfileHandler {
|
|||
type = CoreUserDelegateService.TYPE_NEW_PAGE;
|
||||
|
||||
/**
|
||||
* Check if handler is enabled.
|
||||
*
|
||||
* @return Always enabled.
|
||||
* @inheritdoc
|
||||
*/
|
||||
isEnabled(): Promise<boolean> {
|
||||
return AddonBadges.isPluginEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if handler is enabled for this user in this context.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param navOptions Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @return True if enabled, false otherwise.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForCourse(
|
||||
async isEnabledForContext(
|
||||
context: CoreUserDelegateContext,
|
||||
courseId: number,
|
||||
navOptions?: CoreCourseUserAdminOrNavOptionIndexed,
|
||||
): Promise<boolean> {
|
||||
|
@ -58,19 +58,17 @@ export class AddonBadgesUserHandlerService implements CoreUserProfileHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return Data needed to render the handler.
|
||||
* @inheritdoc
|
||||
*/
|
||||
getDisplayData(): CoreUserProfileHandlerData {
|
||||
return {
|
||||
icon: 'fas-trophy',
|
||||
title: 'addon.badges.badges',
|
||||
action: (event, user, courseId): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath('/badges', {
|
||||
params: { courseId, userId: user.id },
|
||||
params: { courseId: contextId, userId: user.id },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -43,11 +43,11 @@ export class AddonBlogUserHandlerService implements CoreUserProfileHandler {
|
|||
icon: 'far-newspaper',
|
||||
title: 'addon.blog.blogentries',
|
||||
class: 'addon-blog-handler',
|
||||
action: (event, user, courseId): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath('/blog', {
|
||||
params: { courseId, userId: user.id },
|
||||
params: { courseId: contextId, userId: user.id },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -16,7 +16,12 @@ import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAG
|
|||
import { Injectable } from '@angular/core';
|
||||
import { COURSE_PAGE_NAME } from '@features/course/course.module';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreUserProfileHandler, CoreUserDelegateService, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserProfileHandler,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandlerData,
|
||||
CoreUserDelegateContext,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { PARTICIPANTS_PAGE_NAME } from '@features/user/user.module';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
@ -43,10 +48,10 @@ export class AddonCompetencyUserHandlerService implements CoreUserProfileHandler
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile, courseId?: number): Promise<boolean> {
|
||||
async isEnabledForUser(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): Promise<boolean> {
|
||||
try {
|
||||
if (courseId) {
|
||||
return AddonCompetency.canViewUserCompetenciesInCourse(courseId, user.id);
|
||||
if (context === CoreUserDelegateContext.COURSE) {
|
||||
return await AddonCompetency.canViewUserCompetenciesInCourse(contextId, user.id);
|
||||
} else {
|
||||
const plans = await AddonCompetency.getLearningPlans(user.id);
|
||||
|
||||
|
@ -61,21 +66,8 @@ export class AddonCompetencyUserHandlerService implements CoreUserProfileHandler
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getDisplayData(user: CoreUserProfile, courseId: number): CoreUserProfileHandlerData {
|
||||
if (courseId) {
|
||||
return {
|
||||
icon: 'fas-award',
|
||||
title: 'addon.competency.competencies',
|
||||
class: 'addon-competency-handler',
|
||||
action: (event, user, courseId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath(
|
||||
[COURSE_PAGE_NAME, courseId, PARTICIPANTS_PAGE_NAME, user.id, ADDON_COMPETENCY_COMPETENCIES_PAGE].join('/'),
|
||||
);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
getDisplayData(user: CoreUserProfile, context: CoreUserDelegateContext): CoreUserProfileHandlerData {
|
||||
if (context !== CoreUserDelegateContext.COURSE) {
|
||||
return {
|
||||
icon: 'fas-route',
|
||||
title: 'addon.competency.learningplans',
|
||||
|
@ -89,6 +81,19 @@ export class AddonCompetencyUserHandlerService implements CoreUserProfileHandler
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
icon: 'fas-award',
|
||||
title: 'addon.competency.competencies',
|
||||
class: 'addon-competency-handler',
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath(
|
||||
[COURSE_PAGE_NAME, contextId, PARTICIPANTS_PAGE_NAME, user.id, ADDON_COMPETENCY_COMPETENCIES_PAGE].join('/'),
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreUserProfileHandler, CoreUserDelegateService, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserProfileHandler,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandlerData,
|
||||
CoreUserDelegateContext,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonCourseCompletion } from '../coursecompletion';
|
||||
|
@ -40,15 +45,19 @@ export class AddonCourseCompletionUserHandlerService implements CoreUserProfileH
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForCourse(courseId?: number): Promise<boolean> {
|
||||
async isEnabledForContext(context: CoreUserDelegateContext, courseId: number): Promise<boolean> {
|
||||
if (context !== CoreUserDelegateContext.COURSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddonCourseCompletion.isPluginViewEnabledForCourse(courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile, courseId?: number): Promise<boolean> {
|
||||
return await AddonCourseCompletion.isPluginViewEnabledForUser(courseId!, user.id);
|
||||
async isEnabledForUser(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): Promise<boolean> {
|
||||
return await AddonCourseCompletion.isPluginViewEnabledForUser(contextId, user.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,11 +68,11 @@ export class AddonCourseCompletionUserHandlerService implements CoreUserProfileH
|
|||
icon: 'fas-tasks',
|
||||
title: 'addon.coursecompletion.coursecompletion',
|
||||
class: 'addon-coursecompletion-handler',
|
||||
action: (event, user, courseId): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath('/coursecompletion', {
|
||||
params: { courseId, userId: user.id },
|
||||
params: { courseId: contextId, userId: user.id },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -32,9 +32,7 @@ export class AddonMessagesSendMessageUserHandlerService implements CoreUserProfi
|
|||
type = CoreUserDelegateService.TYPE_COMMUNICATION;
|
||||
|
||||
/**
|
||||
* Check if handler is enabled.
|
||||
*
|
||||
* @return Promise resolved with true if enabled, rejected or resolved with false otherwise.
|
||||
* @inheritdoc
|
||||
*/
|
||||
isEnabled(): Promise<boolean> {
|
||||
return AddonMessages.isPluginEnabled();
|
||||
|
@ -43,15 +41,12 @@ export class AddonMessagesSendMessageUserHandlerService implements CoreUserProfi
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForCourse(): Promise<boolean> {
|
||||
async isEnabledForContext(): Promise<boolean> {
|
||||
return !!CoreSites.getCurrentSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if handler is enabled for this user in this context.
|
||||
*
|
||||
* @param user User to check.
|
||||
* @return Promise resolved with true if enabled, resolved with false otherwise.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile): Promise<boolean> {
|
||||
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreUserProfileHandler, CoreUserDelegateService, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserProfileHandler,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandlerData,
|
||||
CoreUserDelegateContext,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
@ -41,14 +46,14 @@ export class AddonNotesUserHandlerService implements CoreUserProfileHandler {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile, courseId?: number): Promise<boolean> {
|
||||
async isEnabledForUser(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): Promise<boolean> {
|
||||
// Active course required.
|
||||
if (!courseId || user.id == CoreSites.getCurrentSiteUserId()) {
|
||||
if (context !== CoreUserDelegateContext.COURSE || !contextId || user.id == CoreSites.getCurrentSiteUserId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are not using isEnabledForCourse because we need to cache the call.
|
||||
return AddonNotes.isPluginViewNotesEnabledForCourse(courseId);
|
||||
return AddonNotes.isPluginViewNotesEnabledForCourse(contextId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,11 +64,11 @@ export class AddonNotesUserHandlerService implements CoreUserProfileHandler {
|
|||
icon: 'fas-receipt',
|
||||
title: 'addon.notes.notes',
|
||||
class: 'addon-notes-handler',
|
||||
action: (event, user, courseId): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath('/notes', {
|
||||
params: { courseId, userId: user.id },
|
||||
params: { courseId: contextId, userId: user.id },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -16,7 +16,12 @@ import { Injectable } from '@angular/core';
|
|||
|
||||
import { AddonPrivateFiles } from '@/addons/privatefiles/services/privatefiles';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreUserDelegateService, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserDelegateContext,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandler,
|
||||
CoreUserProfileHandlerData,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
|
@ -44,9 +49,9 @@ export class AddonPrivateFilesUserHandlerService implements CoreUserProfileHandl
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile): Promise<boolean> {
|
||||
// Private files only available for the current user.
|
||||
return user.id == CoreSites.getCurrentSiteUserId();
|
||||
async isEnabledForUser(user: CoreUserProfile, context: CoreUserDelegateContext): Promise<boolean> {
|
||||
// Private files only available for the current user in user menu.
|
||||
return user.id == CoreSites.getCurrentSiteUserId() && context === CoreUserDelegateContext.USER_MENU;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ import { GRADES_PAGE_NAME } from '@features/grades/grades.module';
|
|||
import { CoreGrades } from '@features/grades/services/grades';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import {
|
||||
CoreUserDelegateContext,
|
||||
CoreUserDelegateService ,
|
||||
CoreUserProfileHandler,
|
||||
CoreUserProfileHandlerData,
|
||||
|
@ -50,8 +51,8 @@ export class CoreGradesUserHandlerService implements CoreUserProfileHandler {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForCourse(courseId?: number): Promise<boolean> {
|
||||
if (courseId) {
|
||||
async isEnabledForContext(context: CoreUserDelegateContext, courseId: number): Promise<boolean> {
|
||||
if (context === CoreUserDelegateContext.COURSE) {
|
||||
return CoreUtils.ignoreErrors(CoreGrades.isPluginEnabledForCourse(courseId), false);
|
||||
} else {
|
||||
return CoreGrades.isCourseGradesEnabled();
|
||||
|
@ -61,9 +62,9 @@ export class CoreGradesUserHandlerService implements CoreUserProfileHandler {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForUser(user: CoreUserProfile, courseId?: number): Promise<boolean> {
|
||||
if (courseId) {
|
||||
return CoreUtils.promiseWorks(CoreGrades.getCourseGradesTable(courseId, user.id));
|
||||
async isEnabledForUser(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): Promise<boolean> {
|
||||
if (context === CoreUserDelegateContext.COURSE) {
|
||||
return CoreUtils.promiseWorks(CoreGrades.getCourseGradesTable(contextId, user.id));
|
||||
}
|
||||
|
||||
// All course grades only available for the current user.
|
||||
|
@ -73,17 +74,17 @@ export class CoreGradesUserHandlerService implements CoreUserProfileHandler {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getDisplayData(user: CoreUserProfile, courseId?: number): CoreUserProfileHandlerData {
|
||||
if (courseId) {
|
||||
getDisplayData(user: CoreUserProfile, context: CoreUserDelegateContext): CoreUserProfileHandlerData {
|
||||
if (context === CoreUserDelegateContext.COURSE) {
|
||||
return {
|
||||
icon: 'fas-chart-bar',
|
||||
title: 'core.grades.grades',
|
||||
class: 'core-grades-user-handler',
|
||||
action: (event, user, courseId): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
CoreNavigator.navigateToSitePath(
|
||||
[COURSE_PAGE_NAME, courseId, PARTICIPANTS_PAGE_NAME, user.id, GRADES_PAGE_NAME].join('/'),
|
||||
[COURSE_PAGE_NAME, contextId, PARTICIPANTS_PAGE_NAME, user.id, GRADES_PAGE_NAME].join('/'),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -18,7 +18,12 @@ import { CoreSite, CoreSiteInfo } from '@classes/site';
|
|||
import { CoreLoginSitesComponent } from '@features/login/components/sites/sites';
|
||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreUserProfileHandlerData, CoreUserDelegate, CoreUserDelegateService } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserProfileHandlerData,
|
||||
CoreUserDelegate,
|
||||
CoreUserDelegateService,
|
||||
CoreUserDelegateContext,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -64,7 +69,8 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
|
|||
if (this.siteInfo) {
|
||||
this.user = await CoreUser.getProfile(this.siteInfo.userid);
|
||||
|
||||
this.subscription = CoreUserDelegate.getProfileHandlersFor(this.user).subscribe((handlers) => {
|
||||
this.subscription = CoreUserDelegate.getProfileHandlersFor(this.user, CoreUserDelegateContext.USER_MENU)
|
||||
.subscribe((handlers) => {
|
||||
if (!handlers || !this.user) {
|
||||
return;
|
||||
}
|
||||
|
@ -76,7 +82,7 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
|
||||
this.handlersLoaded = CoreUserDelegate.areHandlersLoaded(this.user.id);
|
||||
this.handlersLoaded = CoreUserDelegate.areHandlersLoaded(this.user.id, CoreUserDelegateContext.USER_MENU);
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -150,7 +156,7 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
|
|||
|
||||
await this.close(event);
|
||||
|
||||
handler.action(event, this.user);
|
||||
handler.action(event, this.user, CoreUserDelegateContext.USER_MENU);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,9 +19,13 @@ import {
|
|||
CoreSitePluginsUserHandlerData,
|
||||
} from '@features/siteplugins/services/siteplugins';
|
||||
import { CoreUserProfile } from '@features/user/services/user';
|
||||
import { CoreUserDelegateService, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserDelegateContext,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandler,
|
||||
CoreUserProfileHandlerData,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
|
||||
import { Md5 } from 'ts-md5';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
|
@ -55,11 +59,7 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async isEnabledForCourse(
|
||||
courseId?: number,
|
||||
): Promise<boolean> {
|
||||
courseId = courseId || CoreSites.getCurrentSiteHomeId();
|
||||
|
||||
async isEnabledForContext(context: CoreUserDelegateContext, courseId: number): Promise<boolean> {
|
||||
// Check if it's enabled for the course.
|
||||
return CoreSitePlugins.isHandlerEnabledForCourse(
|
||||
courseId,
|
||||
|
@ -89,12 +89,12 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
|
|||
title: this.title,
|
||||
icon: this.handlerSchema.displaydata?.icon,
|
||||
class: this.handlerSchema.displaydata?.class,
|
||||
action: (event: Event, user: CoreUserProfile, courseId?: number): void => {
|
||||
action: (event, user, context, contextId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const args = {
|
||||
courseid: courseId,
|
||||
courseid: contextId,
|
||||
userid: user.id,
|
||||
};
|
||||
const hash = <string> Md5.hashAsciiStr(JSON.stringify(args));
|
||||
|
|
|
@ -23,7 +23,12 @@ import { CoreDomUtils } from '@services/utils/dom';
|
|||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
import { CoreUser, CoreUserProfile, CoreUserProvider } from '@features/user/services/user';
|
||||
import { CoreUserHelper } from '@features/user/services/user-helper';
|
||||
import { CoreUserDelegate, CoreUserDelegateService, CoreUserProfileHandlerData } from '@features/user/services/user-delegate';
|
||||
import {
|
||||
CoreUserDelegate,
|
||||
CoreUserDelegateContext,
|
||||
CoreUserDelegateService,
|
||||
CoreUserProfileHandlerData,
|
||||
} from '@features/user/services/user-delegate';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreCourses } from '@features/courses/services/courses';
|
||||
|
@ -131,7 +136,9 @@ export class CoreUserProfilePage implements OnInit, OnDestroy {
|
|||
// If there's already a subscription, unsubscribe because we'll get a new one.
|
||||
this.subscription?.unsubscribe();
|
||||
|
||||
this.subscription = CoreUserDelegate.getProfileHandlersFor(user, this.courseId).subscribe((handlers) => {
|
||||
const context = this.courseId ? CoreUserDelegateContext.COURSE : CoreUserDelegateContext.SITE;
|
||||
|
||||
this.subscription = CoreUserDelegate.getProfileHandlersFor(user, context, this.courseId).subscribe((handlers) => {
|
||||
this.actionHandlers = [];
|
||||
this.newPageHandlers = [];
|
||||
this.communicationHandlers = [];
|
||||
|
@ -150,7 +157,7 @@ export class CoreUserProfilePage implements OnInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
|
||||
this.isLoadingHandlers = !CoreUserDelegate.areHandlersLoaded(user.id);
|
||||
this.isLoadingHandlers = !CoreUserDelegate.areHandlersLoaded(user.id, context, this.courseId);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
@ -208,7 +215,8 @@ export class CoreUserProfilePage implements OnInit, OnDestroy {
|
|||
return;
|
||||
}
|
||||
|
||||
handler.action(event, this.user, this.courseId);
|
||||
const context = this.courseId ? CoreUserDelegateContext.COURSE : CoreUserDelegateContext.SITE;
|
||||
handler.action(event, this.user, context, this.courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,7 @@ export class CoreUserProfileMailHandlerService implements CoreUserProfileHandler
|
|||
icon: 'mail',
|
||||
title: 'core.user.sendemail',
|
||||
class: 'core-user-profile-mail',
|
||||
action: (event: Event, user: CoreUserProfile): void => {
|
||||
action: (event, user): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
|
|
|
@ -47,15 +47,17 @@ export interface CoreUserProfileHandler extends CoreDelegateHandler {
|
|||
cacheEnabled?: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled for a course.
|
||||
* Whether or not the handler is enabled for a context.
|
||||
*
|
||||
* @param courseId Course ID where to show.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @param navOptions Navigation options for the course.
|
||||
* @param admOptions Admin options for the course.
|
||||
* @return Whether or not the handler is enabled for a user.
|
||||
*/
|
||||
isEnabledForCourse?(
|
||||
courseId?: number,
|
||||
isEnabledForContext?(
|
||||
context: CoreUserDelegateContext,
|
||||
contextId: number,
|
||||
navOptions?: CoreCourseUserAdminOrNavOptionIndexed,
|
||||
admOptions?: CoreCourseUserAdminOrNavOptionIndexed,
|
||||
): Promise<boolean>;
|
||||
|
@ -64,22 +66,21 @@ export interface CoreUserProfileHandler extends CoreDelegateHandler {
|
|||
* Whether or not the handler is enabled for a user.
|
||||
*
|
||||
* @param user User object.
|
||||
* @param courseId Course ID where to show.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Whether or not the handler is enabled for a user.
|
||||
*/
|
||||
isEnabledForUser?(
|
||||
user: CoreUserProfile,
|
||||
courseId?: number,
|
||||
): Promise<boolean>;
|
||||
isEnabledForUser?(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @param user User object.
|
||||
* @param courseId Course ID where to show.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Data to be shown.
|
||||
*/
|
||||
getDisplayData(user: CoreUserProfile, courseId?: number): CoreUserProfileHandlerData;
|
||||
getDisplayData(user: CoreUserProfile, context: CoreUserDelegateContext, contextId: number): CoreUserProfileHandlerData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,9 +137,10 @@ export interface CoreUserProfileHandlerData {
|
|||
*
|
||||
* @param event Click event.
|
||||
* @param user User object.
|
||||
* @param courseId Course ID being viewed. If not defined, site context.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
*/
|
||||
action(event: Event, user: CoreUserProfile, courseId?: number): void;
|
||||
action(event: Event, user: CoreUserProfile, context: CoreUserDelegateContext, contextId?: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,24 +201,16 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
protected featurePrefix = 'CoreUserDelegate_';
|
||||
|
||||
// Hold the handlers and the observable to notify them for each user.
|
||||
protected userHandlers: {
|
||||
[userId: number]: {
|
||||
loaded: boolean; // Whether the handlers are loaded.
|
||||
handlers: CoreUserProfileHandlerToDisplay[]; // List of handlers.
|
||||
observable: Subject<CoreUserProfileHandlerToDisplay[]>; // Observale to notify the handlers.
|
||||
};
|
||||
} = {};
|
||||
protected userHandlers: Record<number, Record<string, CoreUserDelegateHandlersData>> = {};
|
||||
|
||||
constructor() {
|
||||
super('CoreUserDelegate', true);
|
||||
|
||||
CoreEvents.on(CoreUserDelegateService.UPDATE_HANDLER_EVENT, (data) => {
|
||||
if (!data || !data.handler || !this.userHandlers[data.userId]) {
|
||||
return;
|
||||
}
|
||||
const handlersData = this.getHandlersData(data.userId, data.context, data.contextId);
|
||||
|
||||
// Search the handler.
|
||||
const handler = this.userHandlers[data.userId].handlers.find((userHandler) => userHandler.name == data.handler);
|
||||
const handler = handlersData.handlers.find((userHandler) => userHandler.name == data.handler);
|
||||
|
||||
if (!handler) {
|
||||
return;
|
||||
|
@ -224,7 +218,7 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
|
||||
// Update the data and notify.
|
||||
Object.assign(handler.data, data.data);
|
||||
this.userHandlers[data.userId].observable.next(this.userHandlers[data.userId].handlers);
|
||||
handlersData.observable.next(handlersData.handlers);
|
||||
});
|
||||
|
||||
CoreEvents.on(CoreEvents.LOGOUT, () => {
|
||||
|
@ -232,31 +226,41 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
});
|
||||
|
||||
CoreEvents.on(CoreUserProvider.PROFILE_REFRESHED, (data) => {
|
||||
this.clearHandlerCache(data.courseId, data.userId);
|
||||
const context = data.courseId ? CoreUserDelegateContext.COURSE : CoreUserDelegateContext.SITE;
|
||||
this.clearHandlerCache(data.userId, context, data.courseId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if handlers are loaded.
|
||||
* Check if handlers are loaded for a certain user and context.
|
||||
*
|
||||
* @param userId User ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return True if handlers are loaded, false otherwise.
|
||||
*/
|
||||
areHandlersLoaded(userId: number): boolean {
|
||||
return this.userHandlers[userId]?.loaded;
|
||||
areHandlersLoaded(userId: number, context: CoreUserDelegateContext, contextId?: number): boolean {
|
||||
return this.getHandlersData(userId, context, contextId).loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear current user handlers.
|
||||
*
|
||||
* @param userId The user to clear.
|
||||
* @param userId The user to clear. Undefined for all users.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
*/
|
||||
clearUserHandlers(userId: number): void {
|
||||
const userData = this.userHandlers[userId];
|
||||
clearUserHandlers(userId?: number, context?: CoreUserDelegateContext, contextId?: number): void {
|
||||
if (!userId) {
|
||||
this.userHandlers = {};
|
||||
} else if (!context) {
|
||||
delete this.userHandlers[userId];
|
||||
} else {
|
||||
const handlersData = this.getHandlersData(userId, context, contextId);
|
||||
|
||||
if (userData) {
|
||||
userData.handlers = [];
|
||||
userData.observable.next([]);
|
||||
userData.loaded = false;
|
||||
handlersData.handlers = [];
|
||||
handlersData.observable.next([]);
|
||||
handlersData.loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,58 +268,65 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
* Get the profile handlers for a user.
|
||||
*
|
||||
* @param user The user object.
|
||||
* @param courseId The course ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Resolved with the handlers.
|
||||
*/
|
||||
getProfileHandlersFor(user: CoreUserProfile, courseId?: number): Subject<CoreUserProfileHandlerToDisplay[]> {
|
||||
// Initialize the user handlers if it isn't initialized already.
|
||||
if (!this.userHandlers[user.id]) {
|
||||
this.userHandlers[user.id] = {
|
||||
loaded: false,
|
||||
handlers: [],
|
||||
observable: new BehaviorSubject<CoreUserProfileHandlerToDisplay[]>([]),
|
||||
};
|
||||
}
|
||||
getProfileHandlersFor(
|
||||
user: CoreUserProfile,
|
||||
context: CoreUserDelegateContext,
|
||||
contextId?: number,
|
||||
): Subject<CoreUserProfileHandlerToDisplay[]> {
|
||||
this.calculateUserHandlers(user, context, contextId);
|
||||
|
||||
this.calculateUserHandlers(user, courseId);
|
||||
|
||||
return this.userHandlers[user.id].observable;
|
||||
return this.getHandlersData(user.id, context, contextId).observable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile handlers for a user.
|
||||
*
|
||||
* @param user The user object.
|
||||
* @param courseId The course ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async calculateUserHandlers(user: CoreUserProfile, courseId?: number): Promise<void> {
|
||||
protected async calculateUserHandlers(
|
||||
user: CoreUserProfile,
|
||||
context: CoreUserDelegateContext,
|
||||
contextId?: number,
|
||||
): Promise<void> {
|
||||
// Get course options.
|
||||
const courses = await CoreCourses.getUserCourses(true);
|
||||
const courseIds = courses.map((course) => course.id);
|
||||
|
||||
const options = await CoreCourses.getCoursesAdminAndNavOptions(courseIds);
|
||||
|
||||
// For backwards compatibility we don't modify the courseId.
|
||||
const courseIdForOptions = courseId || CoreSites.getCurrentSiteHomeId();
|
||||
const courseId = context === CoreUserDelegateContext.COURSE && contextId ? contextId : CoreSites.getCurrentSiteHomeId();
|
||||
|
||||
const navOptions = options.navOptions[courseIdForOptions];
|
||||
const admOptions = options.admOptions[courseIdForOptions];
|
||||
const navOptions = options.navOptions[courseId];
|
||||
const admOptions = options.admOptions[courseId];
|
||||
|
||||
const userData = this.userHandlers[user.id];
|
||||
userData.handlers = [];
|
||||
const handlersData = this.getHandlersData(user.id, context, contextId);
|
||||
handlersData.handlers = [];
|
||||
|
||||
await CoreUtils.allPromises(Object.keys(this.enabledHandlers).map(async (name) => {
|
||||
// Checks if the handler is enabled for the user.
|
||||
const handler = this.handlers[name];
|
||||
|
||||
try {
|
||||
const enabled = await this.getAndCacheEnabledForUserFromHandler(handler, user, courseId, navOptions, admOptions);
|
||||
const enabled = await this.getAndCacheEnabledForUserFromHandler(
|
||||
handler,
|
||||
user,
|
||||
context,
|
||||
courseId,
|
||||
navOptions,
|
||||
admOptions,
|
||||
);
|
||||
|
||||
if (enabled) {
|
||||
userData.handlers.push({
|
||||
handlersData.handlers.push({
|
||||
name: name,
|
||||
data: handler.getDisplayData(user, courseId),
|
||||
data: handler.getDisplayData(user, context, courseId),
|
||||
priority: handler.priority || 0,
|
||||
type: handler.type || CoreUserDelegateService.TYPE_NEW_PAGE,
|
||||
});
|
||||
|
@ -326,9 +337,9 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
}));
|
||||
|
||||
// Sort them by priority.
|
||||
userData.handlers.sort((a, b) => b.priority! - a.priority!);
|
||||
userData.loaded = true;
|
||||
userData.observable.next(userData.handlers);
|
||||
handlersData.handlers.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
||||
handlersData.loaded = true;
|
||||
handlersData.observable.next(handlersData.handlers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -336,7 +347,8 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
*
|
||||
* @param handler Handler object.
|
||||
* @param user User object.
|
||||
* @param courseId Course ID where to show.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @param navOptions Navigation options for the course.
|
||||
* @param admOptions Admin options for the course.
|
||||
* @return Whether or not the handler is enabled for a user.
|
||||
|
@ -344,12 +356,13 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
protected async getAndCacheEnabledForUserFromHandler(
|
||||
handler: CoreUserProfileHandler,
|
||||
user: CoreUserProfile,
|
||||
courseId?: number,
|
||||
navOptions?: CoreCourseUserAdminOrNavOptionIndexed,
|
||||
admOptions?: CoreCourseUserAdminOrNavOptionIndexed,
|
||||
context: CoreUserDelegateContext,
|
||||
contextId: number,
|
||||
navOptions: CoreCourseUserAdminOrNavOptionIndexed = {},
|
||||
admOptions: CoreCourseUserAdminOrNavOptionIndexed = {},
|
||||
): Promise<boolean> {
|
||||
if (handler.isEnabledForCourse) {
|
||||
const enabledOnCourse = await handler.isEnabledForCourse(courseId, navOptions, admOptions);
|
||||
if (handler.isEnabledForContext) {
|
||||
const enabledOnCourse = await handler.isEnabledForContext(context, contextId, navOptions, admOptions);
|
||||
|
||||
if (!enabledOnCourse) {
|
||||
// If is not enabled in the course, is not enabled for the user.
|
||||
|
@ -364,14 +377,14 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
return true;
|
||||
}
|
||||
|
||||
return handler.isEnabledForUser(user, courseId);
|
||||
return handler.isEnabledForUser(user, context, contextId);
|
||||
}
|
||||
|
||||
if (this.enabledForUserCache[handler.name] === undefined) {
|
||||
this.enabledForUserCache[handler.name] = {};
|
||||
}
|
||||
|
||||
const cacheKey = this.getCacheKey(courseId, user.id);
|
||||
const cacheKey = this.getCacheKey(user.id, context, contextId);
|
||||
const cache = this.enabledForUserCache[handler.name][cacheKey];
|
||||
|
||||
if (cache !== undefined) {
|
||||
|
@ -380,7 +393,7 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
|
||||
let enabled = true; // Default value.
|
||||
if (handler.isEnabledForUser) {
|
||||
enabled = await handler.isEnabledForUser(user, courseId);
|
||||
enabled = await handler.isEnabledForUser(user, context, contextId);
|
||||
}
|
||||
|
||||
this.enabledForUserCache[handler.name][cacheKey] = enabled;
|
||||
|
@ -390,14 +403,15 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
|
||||
/**
|
||||
* Clear handler enabled for user cache.
|
||||
* If a courseId and userId are specified, it will only delete the entry for that user and course.
|
||||
* If a userId and context are specified, it will only delete the entry for that user and context.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param userId User ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
*/
|
||||
protected clearHandlerCache(courseId?: number, userId?: number): void {
|
||||
if (courseId && userId) {
|
||||
const cacheKey = this.getCacheKey(courseId, userId);
|
||||
protected clearHandlerCache(userId?: number, context?: CoreUserDelegateContext, contextId?: number): void {
|
||||
if (userId && context) {
|
||||
const cacheKey = this.getCacheKey(userId, context, contextId);
|
||||
|
||||
Object.keys(this.enabledHandlers).forEach((name) => {
|
||||
const cache = this.enabledForUserCache[name];
|
||||
|
@ -412,25 +426,81 @@ export class CoreUserDelegateService extends CoreDelegate<CoreUserProfileHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a cache key to identify a course and a user.
|
||||
* Get a cache key to identify a user and context.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param userId User ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Cache key.
|
||||
*/
|
||||
protected getCacheKey(courseId = 0, userId = 0): string {
|
||||
return courseId + '#' + userId;
|
||||
protected getCacheKey(userId: number, context: CoreUserDelegateContext, contextId?: number): string {
|
||||
return `${userId}#${this.getContextKey(context, contextId)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string to identify a context.
|
||||
*
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return String to identify the context.
|
||||
*/
|
||||
protected getContextKey(context: CoreUserDelegateContext, contextId?: number): string {
|
||||
return `${context}#${contextId ?? 0}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get handlers data for a user and context.
|
||||
*
|
||||
* @param userId User ID.
|
||||
* @param context Context.
|
||||
* @param contextId Context ID.
|
||||
* @return Handlers data.
|
||||
*/
|
||||
protected getHandlersData(userId: number, context: CoreUserDelegateContext, contextId?: number): CoreUserDelegateHandlersData {
|
||||
// Initialize the data if it doesn't exist.
|
||||
const contextKey = this.getContextKey(context, contextId);
|
||||
this.userHandlers[userId] = this.userHandlers[userId] || {};
|
||||
|
||||
if (!this.userHandlers[userId][contextKey]) {
|
||||
this.userHandlers[userId][contextKey] = {
|
||||
loaded: false,
|
||||
handlers: [],
|
||||
observable: new BehaviorSubject<CoreUserProfileHandlerToDisplay[]>([]),
|
||||
};
|
||||
}
|
||||
|
||||
return this.userHandlers[userId][contextKey];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CoreUserDelegate = makeSingleton(CoreUserDelegateService);
|
||||
|
||||
/**
|
||||
* Handlers data for a user and context.
|
||||
*/
|
||||
type CoreUserDelegateHandlersData = {
|
||||
loaded: boolean; // Whether the handlers are loaded.
|
||||
handlers: CoreUserProfileHandlerToDisplay[]; // List of handlers.
|
||||
observable: Subject<CoreUserProfileHandlerToDisplay[]>; // Observable to notify the handlers.
|
||||
};
|
||||
|
||||
/**
|
||||
* Context levels enumeration.
|
||||
*/
|
||||
export enum CoreUserDelegateContext {
|
||||
SITE = 'site',
|
||||
COURSE = 'course',
|
||||
USER_MENU = 'user_menu',
|
||||
}
|
||||
|
||||
/**
|
||||
* Data passed to UPDATE_HANDLER_EVENT event.
|
||||
*/
|
||||
export type CoreUserUpdateHandlerData = {
|
||||
handler: string; // Name of the handler.
|
||||
userId: number; // User affected.
|
||||
context: CoreUserDelegateContext; // Context affected.
|
||||
contextId?: number; // ID related to the context.
|
||||
data: Record<string, unknown>; // Data to set to the handler.
|
||||
};
|
||||
|
|
|
@ -11,6 +11,10 @@ information provided here is intended especially for developers.
|
|||
- CoreCourse.getModuleBasicInfoByInstance and CoreCourse.getModuleBasicInfo have been modified to accept an "options" parameter instead of only siteId.
|
||||
- The function CoreFilepool.isFileDownloadingByUrl now returns Promise<boolean> instead of relying on resolve/reject.
|
||||
- downloadEnabled input has been removed from CoreBlockSideBlocksComponent, CoreCourseFormatComponent, CoreCourseFormatSingleActivityComponent and CoreCourseModuleComponent.
|
||||
- There were several breaking changes done in CoreUserDelegate and its handlers:
|
||||
The function CoreUserDelegate.getProfileHandlersFor must now receive a context + contextId instead of a courseId.
|
||||
The user handler function isEnabledForCourse is now called isEnabledForContext and receives a context + contextId instead of a courseId.
|
||||
Some user handler's functions have also changed to accept context + contextId instead of a courseId: isEnabledForUser, getDisplayData, action.
|
||||
|
||||
=== 3.9.5 ===
|
||||
|
||||
|
|
Loading…
Reference in New Issue