+
{{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }}
@@ -70,7 +70,7 @@
{{ 'addon.competency.activities' | translate }}
-
+
{{ 'addon.competency.noactivities' | translate }}
-
+
{{ 'addon.competency.reviewstatus' | translate }}
- {{ competency!.usercompetency!.statusname }}
+ {{ competency.usercompetency!.statusname }}
{{ 'addon.competency.proficient' | translate }}
-
+
{{ 'core.yes' | translate }}
-
+
{{ 'core.no' | translate }}
@@ -107,22 +107,22 @@
{{ 'addon.competency.rating' | translate }}
- {{ userCompetency!.gradename }}
+ {{ userCompetency.gradename }}
{{ 'addon.competency.evidence' | translate }}
-
+
{{ 'addon.competency.noevidence' | translate }}
-
-
+
- {{ evidence.actionuser!.fullname }}
+ {{ evidence.actionuser.fullname }}
{{ evidence.timemodified * 1000 | coreFormatDate }}
diff --git a/src/addons/competency/pages/competency/competency.page.ts b/src/addons/competency/pages/competency/competency.ts
similarity index 99%
rename from src/addons/competency/pages/competency/competency.page.ts
rename to src/addons/competency/pages/competency/competency.ts
index 919281cc4..e4ebe432e 100644
--- a/src/addons/competency/pages/competency/competency.page.ts
+++ b/src/addons/competency/pages/competency/competency.ts
@@ -35,7 +35,7 @@ import { CoreUtils } from '@services/utils/utils';
import { AddonCompetencyMainMenuHandlerService } from '@addons/competency/services/handlers/mainmenu';
/**
- * Page that displays a learning plan.
+ * Page that displays the competency information.
*/
@Component({
selector: 'page-addon-competency-competency',
diff --git a/src/addons/competency/pages/competencysummary/competencysummary.html b/src/addons/competency/pages/competencysummary/competencysummary.html
index 82bd824a2..df05f5428 100644
--- a/src/addons/competency/pages/competencysummary/competencysummary.html
+++ b/src/addons/competency/pages/competencysummary/competencysummary.html
@@ -4,7 +4,7 @@
- {{ competency!.competency.shortname }} {{ competency!.competency.idnumber }}
+ {{ competency.competency.shortname }} {{ competency.competency.idnumber }}
@@ -14,9 +14,9 @@
-
+
-
@@ -24,8 +24,8 @@
{{ 'addon.competency.path' | translate }}
- {{ competency!.comppath.framework.name }}
-
+ {{ competency.comppath.framework.name }}
+
/ {{ ancestor.name }}
diff --git a/src/addons/competency/pages/competencysummary/competencysummary.page.ts b/src/addons/competency/pages/competencysummary/competencysummary.ts
similarity index 98%
rename from src/addons/competency/pages/competencysummary/competencysummary.page.ts
rename to src/addons/competency/pages/competencysummary/competencysummary.ts
index 4a75f8b3a..451d85553 100644
--- a/src/addons/competency/pages/competencysummary/competencysummary.page.ts
+++ b/src/addons/competency/pages/competencysummary/competencysummary.ts
@@ -22,7 +22,7 @@ import { CoreUtils } from '@services/utils/utils';
import { AddonCompetencyMainMenuHandlerService } from '@addons/competency/services/handlers/mainmenu';
/**
- * Page that displays a learning plan.
+ * Page that displays the competency summary.
*/
@Component({
selector: 'page-addon-competency-competency-summary',
diff --git a/src/addons/competency/pages/coursecompetencies/coursecompetencies.html b/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
index ce4a887a6..244afad0f 100644
--- a/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
+++ b/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
@@ -11,27 +11,27 @@
- 0">
-
-
+ 0">
+
+
{{ 'addon.competency.coursecompetencyratingsarepushedtouserplans' | translate }}
-
+
{{ 'addon.competency.coursecompetencyratingsarenotpushedtouserplans' | translate }}
-
+
{{ 'addon.competency.xcompetenciesproficientoutofyincourse' | translate: {$a:
- {x: competencies!.statistics.proficientcompetencycount, y: competencies!.statistics.competencycount} } }}
-
+ {x: competencies.statistics.proficientcompetencycount, y: competencies.statistics.competencycount} } }}
+
0">
+ *ngIf="competencies.statistics.canmanagecoursecompetencies && competencies.statistics.leastproficientcount > 0">
{{ 'addon.competency.competenciesmostoftennotproficientincourse' | translate }}:
-
+
{{ comp.shortname }} - {{ comp.idnumber }}
@@ -40,29 +40,29 @@
- 0">
+ 0">
{{ 'addon.competency.coursecompetencies' | translate }}
- {{ user!.fullname }}
+ {{ user.fullname }}
-
-
+
{{competency.competency.shortname}} {{competency.competency.idnumber}}
-
- {{ competency.usercompetencycourse!.gradename }}
+
+ {{ competency.usercompetencycourse.gradename }}
@@ -92,7 +92,7 @@
/
-
+
{{ 'addon.competency.uponcoursecompletion' | translate }}
{{ ruleoutcome.text }}
diff --git a/src/addons/competency/pages/plan/plan.html b/src/addons/competency/pages/plan/plan.html
index 41d1f3ba7..9b207a7f6 100644
--- a/src/addons/competency/pages/plan/plan.html
+++ b/src/addons/competency/pages/plan/plan.html
@@ -3,7 +3,7 @@
- {{plan!.plan.name}}
+ {{plan.plan.name}}
@@ -15,27 +15,27 @@
- {{ user!.fullname }}
+ {{ user.fullname }}
-
+
-
+
- {{ 'addon.competency.status' | translate }}: {{ plan!.plan.statusname }}
+ {{ 'addon.competency.status' | translate }}: {{ plan.plan.statusname }}
- 0" lines="none">
+ 0" lines="none">
{{ 'addon.competency.duedate' | translate }}:
@@ -43,10 +43,10 @@
-
+
- {{ 'addon.competency.template' | translate }}: {{ plan!.plan.template!.shortname }}
+ {{ 'addon.competency.template' | translate }}: {{ plan.plan.template.shortname }}
diff --git a/src/addons/competency/pages/plan/plan.page.ts b/src/addons/competency/pages/plan/plan.ts
similarity index 100%
rename from src/addons/competency/pages/plan/plan.page.ts
rename to src/addons/competency/pages/plan/plan.ts
diff --git a/src/addons/competency/pages/planlist/planlist.page.ts b/src/addons/competency/pages/planlist/planlist.ts
similarity index 100%
rename from src/addons/competency/pages/planlist/planlist.page.ts
rename to src/addons/competency/pages/planlist/planlist.ts
diff --git a/src/addons/competency/services/competency.ts b/src/addons/competency/services/competency.ts
index 666be85a2..802c7f925 100644
--- a/src/addons/competency/services/competency.ts
+++ b/src/addons/competency/services/competency.ts
@@ -56,6 +56,41 @@ export class AddonCompetencyProvider {
site.isFeatureDisabled('CoreUserDelegate_AddonCompetency');
}
+ /**
+ * Returns whether current user can see another user competencies in a course.
+ *
+ * @param courseId Course ID.
+ * @param userId User ID.
+ * @param siteId Site ID. If not defined, current site.
+ * @return Promise resolved with boolean: whether the user can view the competencies.
+ */
+ async canViewUserCompetenciesInCourse(courseId: number, userId?: number, siteId?: string): Promise {
+ if (!CoreSites.isLoggedIn()) {
+ return false;
+ }
+
+ try {
+ const response = await this.getCourseCompetenciesPage(courseId, siteId);
+
+ if (!response.competencies.length) {
+ // No competencies.
+ return false;
+ }
+
+ if (!userId || userId == CoreSites.getCurrentSiteUserId()) {
+ // Current user.
+ return true;
+ }
+
+ // Check if current user can view any competency of the user.
+ await this.getCompetencyInCourse(courseId, response.competencies[0].competency.id, userId, siteId);
+
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
/**
* Get cache key for user learning plans data WS calls.
*
@@ -290,7 +325,7 @@ export class AddonCompetencyProvider {
}
/**
- * Get all competencies in a course.
+ * Get all competencies in a course for a certain user.
*
* @param courseId ID of the course.
* @param userId ID of the user.
@@ -304,6 +339,38 @@ export class AddonCompetencyProvider {
siteId?: string,
ignoreCache = false,
): Promise {
+
+ const courseCompetencies = await this.getCourseCompetenciesPage(courseId, siteId, ignoreCache);
+
+ if (!userId || userId == CoreSites.getCurrentSiteUserId()) {
+ return courseCompetencies;
+ }
+
+ const userCompetenciesSumaries: AddonCompetencyDataForUserCompetencySummaryInCourseWSResponse[] =
+ await Promise.all(courseCompetencies.competencies.map((competency) =>
+ this.getCompetencyInCourse(courseId, competency.competency.id, userId, siteId)));
+
+ userCompetenciesSumaries.forEach((userCompetenciesSumary, index) => {
+ courseCompetencies.competencies[index].usercompetencycourse =
+ userCompetenciesSumary.usercompetencysummary.usercompetencycourse;
+ });
+
+ return courseCompetencies;
+ }
+
+ /**
+ * Get all competencies in a course.
+ *
+ * @param courseId ID of the course.
+ * @param siteId Site ID. If not defined, current site.
+ * @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down).
+ * @return Promise to be resolved when the course competencies are retrieved.
+ */
+ async getCourseCompetenciesPage(
+ courseId: number,
+ siteId?: string,
+ ignoreCache = false,
+ ): Promise {
const site = await CoreSites.getSite(siteId);
const params: AddonCompetencyDataForCourseCompetenciesPageWSParams = {
@@ -320,26 +387,11 @@ export class AddonCompetencyProvider {
preSets.emergencyCache = false;
}
- const courseCompetencies = await site.read(
+ return site.read(
'tool_lp_data_for_course_competencies_page',
params,
preSets,
);
-
- if (!userId || userId == CoreSites.getCurrentSiteUserId()) {
- return courseCompetencies;
- }
-
- const userCompetenciesSumaries: AddonCompetencyDataForUserCompetencySummaryInCourseWSResponse[] =
- await Promise.all(courseCompetencies.competencies.map((competency) =>
- this.getCompetencyInCourse(courseId, competency.competency.id, userId, siteId)));
-
- userCompetenciesSumaries.forEach((userCompetenciesSumary, index) => {
- courseCompetencies.competencies[index].usercompetencycourse =
- userCompetenciesSumary.usercompetencysummary.usercompetencycourse;
- });
-
- return courseCompetencies;
}
/**
diff --git a/src/addons/competency/services/handlers/course-option.ts b/src/addons/competency/services/handlers/course-option.ts
index e70fe28a4..e5f1e5364 100644
--- a/src/addons/competency/services/handlers/course-option.ts
+++ b/src/addons/competency/services/handlers/course-option.ts
@@ -98,39 +98,41 @@ export class AddonCompetencyCourseOptionHandlerService implements CoreCourseOpti
// Get the competencies in the course.
const competencies = await AddonCompetency.getCourseCompetencies(course.id, undefined, undefined, true);
+ if (!competencies || !competencies.competencies) {
+ return;
+ }
+
const promises: Promise[] = [];
// Prefetch all the competencies.
- if (competencies && competencies.competencies) {
- competencies.competencies.forEach((competency) => {
- promises.push(AddonCompetency.getCompetencyInCourse(
- course.id,
- competency.competency.id,
- undefined,
- undefined,
- true,
- ));
+ competencies.competencies.forEach((competency) => {
+ promises.push(AddonCompetency.getCompetencyInCourse(
+ course.id,
+ competency.competency.id,
+ undefined,
+ undefined,
+ true,
+ ));
- promises.push(AddonCompetency.getCompetencySummary(
- competency.competency.id,
- undefined,
- undefined,
- true,
- ));
+ promises.push(AddonCompetency.getCompetencySummary(
+ competency.competency.id,
+ undefined,
+ undefined,
+ true,
+ ));
- if (competency.coursemodules) {
- competency.coursemodules.forEach((module) => {
- promises.push(CoreFilterHelper.getFilters(ContextLevel.MODULE, module.id, { courseId: course.id }));
- });
- }
+ if (competency.coursemodules) {
+ competency.coursemodules.forEach((module) => {
+ promises.push(CoreFilterHelper.getFilters(ContextLevel.MODULE, module.id, { courseId: course.id }));
+ });
+ }
- if (competency.plans) {
- competency.plans.forEach((plan) => {
- promises.push(CoreFilterHelper.getFilters(ContextLevel.USER, plan.userid));
- });
- }
- });
- }
+ if (competency.plans) {
+ competency.plans.forEach((plan) => {
+ promises.push(CoreFilterHelper.getFilters(ContextLevel.USER, plan.userid));
+ });
+ }
+ });
await Promise.all(promises);
}
diff --git a/src/addons/competency/services/handlers/push-click.ts b/src/addons/competency/services/handlers/push-click.ts
index 0adf67f70..7966bbf66 100644
--- a/src/addons/competency/services/handlers/push-click.ts
+++ b/src/addons/competency/services/handlers/push-click.ts
@@ -54,7 +54,7 @@ export class AddonCompetencyPushClickHandlerService implements CorePushNotificat
// Open the learning plan.
const planId = Number(contextUrlParams.id);
- await CoreUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(planId, notification.site));
+ await CoreUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(planId, notification.site));
await CoreNavigator.navigateToSitePath('/' + AddonCompetencyMainMenuHandlerService.PAGE_NAME + '/' + planId, {
siteId: notification.site,
diff --git a/src/addons/competency/services/handlers/user.ts b/src/addons/competency/services/handlers/user.ts
index 54805ff82..1500085ee 100644
--- a/src/addons/competency/services/handlers/user.ts
+++ b/src/addons/competency/services/handlers/user.ts
@@ -44,9 +44,7 @@ export class AddonCompetencyUserHandlerService implements CoreUserProfileHandler
async isEnabledForUser(user: CoreUserProfile, courseId?: number): Promise {
try {
if (courseId) {
- const response = await AddonCompetency.getCourseCompetencies(courseId, user.id);
-
- return response.competencies.length > 0;
+ return AddonCompetency.canViewUserCompetenciesInCourse(courseId, user.id);
} else {
const plans = await AddonCompetency.getLearningPlans(user.id);