+
+
diff --git a/src/addon/competency/pages/competency/competency.module.ts b/src/addon/competency/pages/competency/competency.module.ts
new file mode 100644
index 000000000..028abfa2d
--- /dev/null
+++ b/src/addon/competency/pages/competency/competency.module.ts
@@ -0,0 +1,35 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { CorePipesModule } from '@pipes/pipes.module';
+import { AddonCompetencyCompetencyPage } from './competency';
+
+@NgModule({
+ declarations: [
+ AddonCompetencyCompetencyPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ CorePipesModule,
+ IonicPageModule.forChild(AddonCompetencyCompetencyPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonCompetencyCompetencyPageModule {}
diff --git a/src/addon/competency/pages/competency/competency.ts b/src/addon/competency/pages/competency/competency.ts
new file mode 100644
index 000000000..0443a66d8
--- /dev/null
+++ b/src/addon/competency/pages/competency/competency.ts
@@ -0,0 +1,178 @@
+// (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 { Component, Optional } from '@angular/core';
+import { IonicPage, NavController, NavParams } from 'ionic-angular';
+import { TranslateService } from '@ngx-translate/core';
+import { CoreSitesProvider } from '@providers/sites';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreSplitViewComponent } from '@components/split-view/split-view';
+import { AddonCompetencyProvider } from '../../providers/competency';
+
+/**
+ * Page that displays a learning plan.
+ */
+@IonicPage({ segment: 'addon-competency-competency' })
+@Component({
+ selector: 'page-addon-competency-competency',
+ templateUrl: 'competency.html',
+})
+export class AddonCompetencyCompetencyPage {
+ competencyLoaded = false;
+ competencyId: number;
+ planId: number;
+ courseId: number;
+ userId: number;
+ planStatus: number;
+ coursemodules: any;
+ user: any;
+ competency: any;
+
+ constructor(private navCtrl: NavController, navParams: NavParams, private translate: TranslateService,
+ private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
+ @Optional() private svComponent: CoreSplitViewComponent, private competencyProvider: AddonCompetencyProvider) {
+ this.competencyId = navParams.get('competencyId');
+ this.planId = navParams.get('planId');
+ this.courseId = navParams.get('courseId');
+ this.userId = navParams.get('userId');
+ }
+
+ /**
+ * View loaded.
+ */
+ ionViewDidLoad(): void {
+ this.fetchCompetency().then(() => {
+ if (this.planId) {
+ this.competencyProvider.logCompetencyInPlanView(this.planId, this.competencyId, this.planStatus, this.userId);
+ } else {
+ this.competencyProvider.logCompetencyInCourseView(this.courseId, this.competencyId, this.userId);
+ }
+ }).finally(() => {
+ this.competencyLoaded = true;
+ });
+ }
+
+ /**
+ * Fetches the competency and updates the view.
+ *
+ * @return {Promise} Promise resolved when done.
+ */
+ protected fetchCompetency(): Promise {
+ let promise;
+ if (this.planId) {
+ this.planStatus = null;
+ promise = this.competencyProvider.getCompetencyInPlan(this.planId, this.competencyId);
+ } else if (this.courseId) {
+ promise = this.competencyProvider.getCompetencyInCourse(this.courseId, this.competencyId, this.userId);
+ } else {
+ promise = Promise.reject(null);
+ }
+
+ return promise.then((competency) => {
+ this.competency = competency.usercompetencysummary;
+
+ if (this.planId) {
+ this.planStatus = competency.plan.status;
+ this.competency.usercompetency.statusname = this.getStatusName(this.competency.usercompetency.status);
+ } else {
+ this.competency.usercompetency = this.competency.usercompetencycourse;
+ this.coursemodules = competency.coursemodules;
+ }
+
+ if (this.competency.user.id != this.sitesProvider.getCurrentSiteUserId()) {
+ this.competency.user.profileimageurl = this.competency.user.profileimageurl || true;
+
+ // Get the user profile image from the returned object.
+ this.user = this.competency.user;
+ }
+
+ this.competency.evidence.forEach((evidence) => {
+ if (evidence.descidentifier) {
+ const key = 'addon.competency.' + evidence.descidentifier;
+ evidence.description = this.translate.instant(key, {$a: evidence.desca});
+ }
+ });
+ }).catch((message) => {
+ this.domUtils.showErrorModalDefault(message, 'Error getting competency data.');
+ });
+ }
+
+ /**
+ * Convenience function to get the review status name translated.
+ *
+ * @param {number} status
+ * @return {string}
+ */
+ protected getStatusName(status: number): string {
+ let statusTranslateName;
+ switch (status) {
+ case AddonCompetencyProvider.REVIEW_STATUS_IDLE:
+ statusTranslateName = 'idle';
+ break;
+ case AddonCompetencyProvider.REVIEW_STATUS_IN_REVIEW:
+ statusTranslateName = 'inreview';
+ break;
+ case AddonCompetencyProvider.REVIEW_STATUS_WAITING_FOR_REVIEW:
+ statusTranslateName = 'waitingforreview';
+ break;
+ default:
+ // We can use the current status name.
+ return String(status);
+ }
+
+ return this.translate.instant('addon.competency.usercompetencystatus_' + statusTranslateName);
+ }
+
+ /**
+ * Refreshes the competency.
+ *
+ * @param {any} refresher Refresher.
+ */
+ refreshCompetency(refresher: any): void {
+ let promise;
+ if (this.planId) {
+ promise = this.competencyProvider.invalidateCompetencyInPlan(this.planId, this.competencyId);
+ } else {
+ promise = this.competencyProvider.invalidateCompetencyInCourse(this.courseId, this.competencyId);
+ }
+
+ return promise.finally(() => {
+ this.fetchCompetency().finally(() => {
+ refresher.complete();
+ });
+ });
+ }
+
+ /**
+ * Opens the summary of a competency.
+ *
+ * @param {number} competencyId
+ */
+ openCompetencySummary(competencyId: number): void {
+ // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
+ const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
+ navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId});
+ }
+
+ /**
+ * Opens the profile of a user.
+ *
+ * @param {number} userId
+ */
+ openUserProfile(userId: number): void {
+ // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
+ const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
+ navCtrl.push('CoreUserProfilePage', {userId, courseId: this.courseId});
+ }
+}
diff --git a/src/addon/competency/pages/competencysummary/competencysummary.html b/src/addon/competency/pages/competencysummary/competencysummary.html
new file mode 100644
index 000000000..5e93f372d
--- /dev/null
+++ b/src/addon/competency/pages/competencysummary/competencysummary.html
@@ -0,0 +1,24 @@
+
+
+ {{ competency.competency.shortname }} {{ competency.competency.idnumber }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'addon.competency.path' | translate }}:
+ {{ competency.comppath.framework.name }}
+
+ / {{ ancestor.name }}
+
+
+
+
+
diff --git a/src/addon/competency/pages/competencysummary/competencysummary.module.ts b/src/addon/competency/pages/competencysummary/competencysummary.module.ts
new file mode 100644
index 000000000..855095dbf
--- /dev/null
+++ b/src/addon/competency/pages/competencysummary/competencysummary.module.ts
@@ -0,0 +1,33 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { AddonCompetencyCompetencySummaryPage } from './competencysummary';
+
+@NgModule({
+ declarations: [
+ AddonCompetencyCompetencySummaryPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ IonicPageModule.forChild(AddonCompetencyCompetencySummaryPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonCompetencyCompetencySummaryPageModule {}
diff --git a/src/addon/competency/pages/competencysummary/competencysummary.ts b/src/addon/competency/pages/competencysummary/competencysummary.ts
new file mode 100644
index 000000000..8464d4312
--- /dev/null
+++ b/src/addon/competency/pages/competencysummary/competencysummary.ts
@@ -0,0 +1,86 @@
+// (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 { Component, Optional } from '@angular/core';
+import { IonicPage, NavController, NavParams } from 'ionic-angular';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreSplitViewComponent } from '@components/split-view/split-view';
+import { AddonCompetencyProvider } from '../../providers/competency';
+
+/**
+ * Page that displays a learning plan.
+ */
+@IonicPage({ segment: 'addon-competency-competency-summary' })
+@Component({
+ selector: 'page-addon-competency-competency-summary',
+ templateUrl: 'competencysummary.html',
+})
+export class AddonCompetencyCompetencySummaryPage {
+ competencyLoaded = false;
+ competencyId: number;
+ competency: any;
+
+ constructor(private navCtrl: NavController, navParams: NavParams, private domUtils: CoreDomUtilsProvider,
+ @Optional() private svComponent: CoreSplitViewComponent, private competencyProvider: AddonCompetencyProvider) {
+ this.competencyId = navParams.get('competencyId');
+ }
+
+ /**
+ * View loaded.
+ */
+ ionViewDidLoad(): void {
+ this.fetchCompetency().then(() => {
+ this.competencyProvider.logCompetencyView(this.competencyId);
+ }).finally(() => {
+ this.competencyLoaded = true;
+ });
+ }
+
+ /**
+ * Fetches the competency summary and updates the view.
+ *
+ * @return {Promise} Promise resolved when done.
+ */
+ protected fetchCompetency(): Promise {
+ return this.competencyProvider.getCompetencySummary(this.competencyId).then((competency) => {
+ this.competency = competency;
+ }).catch((message) => {
+ this.domUtils.showErrorModalDefault(message, 'Error getting competency summary data.');
+ });
+ }
+
+ /**
+ * Refreshes the competency summary.
+ *
+ * @param {any} refresher Refresher.
+ */
+ refreshCompetency(refresher: any): void {
+ this.competencyProvider.invalidateCompetencySummary(this.competencyId).finally(() => {
+ this.fetchCompetency().finally(() => {
+ refresher.complete();
+ });
+ });
+ }
+
+ /**
+ * Opens the summary of a competency.
+ *
+ * @param {number} competencyId
+ */
+ openCompetencySummary(competencyId: number): void {
+ // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
+ const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
+ navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId});
+ }
+}
diff --git a/src/addon/competency/pages/coursecompetencies/coursecompetencies.html b/src/addon/competency/pages/coursecompetencies/coursecompetencies.html
new file mode 100644
index 000000000..e20ac1987
--- /dev/null
+++ b/src/addon/competency/pages/coursecompetencies/coursecompetencies.html
@@ -0,0 +1,6 @@
+
+
+ {{ 'addon.competency.coursecompetencies' | translate }}
+
+
+
\ No newline at end of file
diff --git a/src/addon/competency/pages/coursecompetencies/coursecompetencies.module.ts b/src/addon/competency/pages/coursecompetencies/coursecompetencies.module.ts
new file mode 100644
index 000000000..f5a2298a7
--- /dev/null
+++ b/src/addon/competency/pages/coursecompetencies/coursecompetencies.module.ts
@@ -0,0 +1,31 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonCompetencyComponentsModule } from '../../components/components.module';
+import { AddonCompetencyCourseCompetenciesPage } from './coursecompetencies';
+
+@NgModule({
+ declarations: [
+ AddonCompetencyCourseCompetenciesPage,
+ ],
+ imports: [
+ IonicPageModule.forChild(AddonCompetencyCourseCompetenciesPage),
+ TranslateModule.forChild(),
+ AddonCompetencyComponentsModule
+ ],
+})
+export class AddonCompetencyCourseCompetenciesPageModule {}
diff --git a/src/addon/competency/pages/coursecompetencies/coursecompetencies.ts b/src/addon/competency/pages/coursecompetencies/coursecompetencies.ts
new file mode 100644
index 000000000..42bb83f71
--- /dev/null
+++ b/src/addon/competency/pages/coursecompetencies/coursecompetencies.ts
@@ -0,0 +1,35 @@
+// (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 { Component } from '@angular/core';
+import { IonicPage, NavParams } from 'ionic-angular';
+
+/**
+ * Page that displays the list of competencies of a course.
+ */
+@IonicPage({ segment: 'addon-competency-coursecompetencies' })
+@Component({
+ selector: 'page-addon-competency-coursecompetencies',
+ templateUrl: 'coursecompetencies.html',
+})
+export class AddonCompetencyCourseCompetenciesPage {
+
+ protected courseId: number;
+ protected userId: number;
+
+ constructor(navParams: NavParams) {
+ this.courseId = navParams.get('courseId');
+ this.userId = navParams.get('userId');
+ }
+}
diff --git a/src/addon/competency/pages/plan/plan.html b/src/addon/competency/pages/plan/plan.html
new file mode 100644
index 000000000..74b7756c1
--- /dev/null
+++ b/src/addon/competency/pages/plan/plan.html
@@ -0,0 +1,56 @@
+
+
+ {{plan.plan.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'addon.competency.status' | translate }}:
+ {{ plan.plan.statusname }}
+
+ 0">
+ {{ 'addon.competency.duedate' | translate }}:
+ {{ plan.plan.duedate | coreToLocaleString }}
+
+
+ {{ 'addon.competency.template' | translate }}:
+ {{ plan.plan.template.shortname }}
+
+
+ {{ 'addon.competency.progress' | translate }}:
+ {{ 'addon.competency.xcompetenciesproficientoutofy' | translate: {$a: {x: plan.proficientcompetencycount, y: plan.competencycount} } }}
+
+
+
+
+
+ {{ 'addon.competency.learningplancompetencies' | translate }}
+
+
+ {{ 'addon.competency.nocompetencies' | translate }}
+
+
+ {{competency.competency.shortname}} {{competency.competency.idnumber}}
+ {{ competency.usercompetency.gradename }}
+
+
+
+
+
diff --git a/src/addon/competency/pages/plan/plan.module.ts b/src/addon/competency/pages/plan/plan.module.ts
new file mode 100644
index 000000000..bb7f48038
--- /dev/null
+++ b/src/addon/competency/pages/plan/plan.module.ts
@@ -0,0 +1,35 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { CorePipesModule } from '@pipes/pipes.module';
+import { AddonCompetencyPlanPage } from './plan';
+
+@NgModule({
+ declarations: [
+ AddonCompetencyPlanPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ CorePipesModule,
+ IonicPageModule.forChild(AddonCompetencyPlanPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonCompetencyPlanPageModule {}
diff --git a/src/addon/competency/pages/plan/plan.ts b/src/addon/competency/pages/plan/plan.ts
new file mode 100644
index 000000000..d82c46dcd
--- /dev/null
+++ b/src/addon/competency/pages/plan/plan.ts
@@ -0,0 +1,130 @@
+// (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 { Component, Optional } from '@angular/core';
+import { IonicPage, NavController, NavParams } from 'ionic-angular';
+import { TranslateService } from '@ngx-translate/core';
+import { CoreAppProvider } from '@providers/app';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreSplitViewComponent } from '@components/split-view/split-view';
+import { AddonCompetencyProvider } from '../../providers/competency';
+import { AddonCompetencyHelperProvider } from '../../providers/helper';
+
+/**
+ * Page that displays a learning plan.
+ */
+@IonicPage({ segment: 'addon-competency-plan' })
+@Component({
+ selector: 'page-addon-competency-plan',
+ templateUrl: 'plan.html',
+})
+export class AddonCompetencyPlanPage {
+ protected planId: number;
+ planLoaded = false;
+ plan: any;
+ user: any;
+
+ constructor(private navCtrl: NavController, navParams: NavParams, private translate: TranslateService,
+ private appProvider: CoreAppProvider, private domUtils: CoreDomUtilsProvider,
+ @Optional() private svComponent: CoreSplitViewComponent, private competencyProvider: AddonCompetencyProvider,
+ private competencyHelperProvider: AddonCompetencyHelperProvider) {
+ this.planId = navParams.get('planId');
+ }
+
+ /**
+ * View loaded.
+ */
+ ionViewDidLoad(): void {
+ this.fetchLearningPlan().finally(() => {
+ this.planLoaded = true;
+ });
+ }
+
+ /**
+ * Fetches the learning plan and updates the view.
+ *
+ * @return {Promise} Promise resolved when done.
+ */
+ protected fetchLearningPlan(): Promise {
+ return this.competencyProvider.getLearningPlan(this.planId).then((plan) => {
+ plan.plan.statusname = this.getStatusName(plan.plan.status);
+ // Get the user profile image.
+ this.competencyHelperProvider.getProfile(plan.plan.userid).then((user) => {
+ this.user = user;
+ });
+ this.plan = plan;
+ }).catch((message) => {
+ this.domUtils.showErrorModalDefault(message, 'Error getting learning plan data.');
+ });
+ }
+
+ /**
+ * Navigates to a particular competency.
+ *
+ * @param {number} competencyId
+ */
+ openCompetency(competencyId: number): void {
+ const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
+ if (this.appProvider.isWide()) {
+ navCtrl.push('AddonCompetencyCompetenciesPage', {competencyId, planId: this.planId});
+ } else {
+ navCtrl.push('AddonCompetencyCompetencyPage', {competencyId, planId: this.planId});
+ }
+ }
+
+ /**
+ * Convenience function to get the status name translated.
+ *
+ * @param {number} status
+ * @return {string}
+ */
+ protected getStatusName(status: number): string {
+ let statusTranslateName;
+ switch (status) {
+ case AddonCompetencyProvider.STATUS_DRAFT:
+ statusTranslateName = 'draft';
+ break;
+ case AddonCompetencyProvider.REVIEW_STATUS_IN_REVIEW:
+ statusTranslateName = 'inreview';
+ break;
+ case AddonCompetencyProvider.REVIEW_STATUS_WAITING_FOR_REVIEW:
+ statusTranslateName = 'waitingforreview';
+ break;
+ case AddonCompetencyProvider.STATUS_ACTIVE:
+ statusTranslateName = 'active';
+ break;
+ case AddonCompetencyProvider.STATUS_COMPLETE:
+ statusTranslateName = 'complete';
+ break;
+ default:
+ // We can use the current status name.
+ return String(status);
+ }
+
+ return this.translate.instant('addon.competency.planstatus' + statusTranslateName);
+ }
+
+ /**
+ * Refreshes the learning plan.
+ *
+ * @param {any} refresher Refresher.
+ */
+ refreshLearningPlan(refresher: any): void {
+ this.competencyProvider.invalidateLearningPlan(this.planId).finally(() => {
+ this.fetchLearningPlan().finally(() => {
+ refresher.complete();
+ });
+ });
+ }
+}
diff --git a/src/addon/competency/pages/planlist/planlist.html b/src/addon/competency/pages/planlist/planlist.html
new file mode 100644
index 000000000..446aff30c
--- /dev/null
+++ b/src/addon/competency/pages/planlist/planlist.html
@@ -0,0 +1,22 @@
+
+
+ {{ 'addon.competency.userplans' | translate }}
+
+
+
+
+
+
+
+
+
+
+ 0" no-margin>
+
+