commit
bf16815e68
|
@ -26,7 +26,8 @@
|
|||
"lint": "ionic-app-scripts lint",
|
||||
"ionic:build": "ionic-app-scripts build",
|
||||
"ionic:serve": "gulp watch | ionic-app-scripts serve",
|
||||
"ionic:build:before": "gulp"
|
||||
"ionic:build:before": "gulp",
|
||||
"ionic:watch:before": "gulp"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "^5.2.5",
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// (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 { AddonCompetencyProvider } from './providers/competency';
|
||||
import { AddonCompetencyHelperProvider } from './providers/helper';
|
||||
import { AddonCompetencyCourseOptionHandler } from './providers/course-option-handler';
|
||||
import { AddonCompetencyMainMenuHandler } from './providers/mainmenu-handler';
|
||||
import { AddonCompetencyUserHandler } from './providers/user-handler';
|
||||
import { AddonCompetencyComponentsModule } from './components/components.module';
|
||||
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
|
||||
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
|
||||
import { CoreUserDelegate } from '@core/user/providers/user-delegate';
|
||||
import { CoreUserProvider } from '@core/user/providers/user';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
],
|
||||
imports: [
|
||||
AddonCompetencyComponentsModule
|
||||
],
|
||||
providers: [
|
||||
AddonCompetencyProvider,
|
||||
AddonCompetencyHelperProvider,
|
||||
AddonCompetencyCourseOptionHandler,
|
||||
AddonCompetencyMainMenuHandler,
|
||||
AddonCompetencyUserHandler
|
||||
]
|
||||
})
|
||||
export class AddonCompetencyModule {
|
||||
constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: AddonCompetencyMainMenuHandler,
|
||||
courseOptionsDelegate: CoreCourseOptionsDelegate, courseOptionHandler: AddonCompetencyCourseOptionHandler,
|
||||
userDelegate: CoreUserDelegate, userHandler: AddonCompetencyUserHandler,
|
||||
eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) {
|
||||
|
||||
mainMenuDelegate.registerHandler(mainMenuHandler);
|
||||
courseOptionsDelegate.registerHandler(courseOptionHandler);
|
||||
userDelegate.registerHandler(userHandler);
|
||||
|
||||
eventsProvider.on(CoreEventsProvider.LOGOUT, () => {
|
||||
courseOptionHandler.clearCoursesNavCache();
|
||||
userHandler.clearUsersNavCache();
|
||||
}, sitesProvider.getCurrentSiteId());
|
||||
|
||||
eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED, () => {
|
||||
courseOptionHandler.clearCoursesNavCache();
|
||||
}, sitesProvider.getCurrentSiteId());
|
||||
|
||||
eventsProvider.on(CoreUserProvider.PROFILE_REFRESHED, () => {
|
||||
userHandler.clearUsersNavCache();
|
||||
}, sitesProvider.getCurrentSiteId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// (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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } 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 { AddonCompetencyCourseComponent } from './course/course';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonCompetencyCourseComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
CorePipesModule
|
||||
],
|
||||
providers: [
|
||||
],
|
||||
exports: [
|
||||
AddonCompetencyCourseComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonCompetencyCourseComponent
|
||||
]
|
||||
})
|
||||
export class AddonCompetencyComponentsModule {}
|
|
@ -0,0 +1,73 @@
|
|||
<ion-content>
|
||||
<ion-refresher [enabled]="competenciesLoaded" (ionRefresh)="refreshCourseCompetencies($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="competenciesLoaded">
|
||||
<ion-card *ngIf="!user && competencies && competencies.statistics.competencycount > 0">
|
||||
<ion-item text-wrap *ngIf="competencies.settings.pushratingstouserplans">
|
||||
{{ 'addon.competency.coursecompetencyratingsarepushedtouserplans' | translate }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="!competencies.settings.pushratingstouserplans">
|
||||
{{ 'addon.competency.coursecompetencyratingsarenotpushedtouserplans' | translate }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.progress' | translate }}</strong>:
|
||||
{{ 'addon.competency.xcompetenciesproficientoutofyincourse' | translate:{$a: {x: competencies.statistics.proficientcompetencycount, y: competencies.statistics.competencycount} } }} ({{ competencies.statistics.proficientcompetencypercentageformatted }}%)
|
||||
<core-progress-bar [progress]="competencies.statistics.proficientcompetencypercentage"></core-progress-bar>
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="competencies.statistics.leastproficientcount > 0">
|
||||
<strong>{{ 'addon.competency.competenciesmostoftennotproficientincourse' | translate }}</strong>:
|
||||
<p *ngFor="let comp of competencies.statistics.leastproficient">
|
||||
<a (click)="openCompetencySummary(comp.id)">
|
||||
{{ comp.shortname }} - {{ comp.idnumber }}
|
||||
</a>
|
||||
</p>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<h3 margin-horizontal *ngIf="competencies && competencies.statistics.competencycount > 0">{{ 'addon.competency.competencies' | translate }}</h3>
|
||||
<ion-card *ngIf="user">
|
||||
<ion-item text-wrap>
|
||||
<ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start>
|
||||
<img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content>
|
||||
</ion-avatar>
|
||||
<span *ngIf="user.profileimageurl === true" item-start>
|
||||
<ion-icon name="person"></ion-icon>
|
||||
</span>
|
||||
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<core-empty-box *ngIf="competencies && competencies.statistics.competencycount == 0" icon="ribbon" message="{{ 'addon.competency.nocompetencies' | translate }}"></core-empty-box>
|
||||
|
||||
<div *ngIf="competencies">
|
||||
<ion-card *ngFor="let competency of competencies.competencies">
|
||||
<a ion-item text-wrap (click)="openCompetency(competency.competency.id)" [title]="competency.competency.shortname">
|
||||
{{competency.competency.shortname}} <small>{{competency.competency.idnumber}}</small>
|
||||
<ion-badge item-end *ngIf="competency.usercompetencycourse && competency.usercompetencycourse.gradename" [color]="competency.usercompetencycourse.proficiency ? 'success' : 'danger'">{{ competency.usercompetencycourse.gradename }}</ion-badge>
|
||||
</a>
|
||||
<ion-item text-wrap>
|
||||
<div *ngIf="competency.competency.description">
|
||||
<core-format-text [text]=" competency.competency.description "></core-format-text>
|
||||
</div>
|
||||
<div>
|
||||
<strong>{{ 'addon.competency.path' | translate }}</strong>:
|
||||
{{ competency.comppath.framework.name }}
|
||||
<span *ngFor="let ancestor of competency.comppath.ancestors">
|
||||
/ <a (click)="openCompetencySummary(ancestor.id)">{{ ancestor.name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<strong>{{ 'addon.competency.activities' | translate }}</strong>:
|
||||
<span *ngIf="competency.coursemodules.length == 0">
|
||||
{{ 'addon.competency.noactivities' | translate }}
|
||||
</span>
|
||||
<a ion-item text-wrap *ngFor="let activity of competency.coursemodules" [href]="activity.url" [title]="activity.name">
|
||||
<img item-start [src]="activity.iconurl" core-external-content alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon">
|
||||
<core-format-text [text]="activity.name"></core-format-text>
|
||||
</a>
|
||||
</div>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
</div>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -0,0 +1,104 @@
|
|||
// (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, ViewChild, Input } from '@angular/core';
|
||||
import { Content, NavController } from 'ionic-angular';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { AddonCompetencyProvider } from '../../providers/competency';
|
||||
import { AddonCompetencyHelperProvider } from '../../providers/helper';
|
||||
|
||||
/**
|
||||
* Component that displays the competencies of a course.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-competency-course',
|
||||
templateUrl: 'course.html',
|
||||
})
|
||||
export class AddonCompetencyCourseComponent {
|
||||
@ViewChild(Content) content: Content;
|
||||
|
||||
@Input() courseId: number;
|
||||
@Input() userId: number;
|
||||
|
||||
competenciesLoaded = false;
|
||||
competencies: any;
|
||||
user: any;
|
||||
|
||||
constructor(private navCtrl: NavController, private appProvider: CoreAppProvider, private domUtils: CoreDomUtilsProvider,
|
||||
private competencyProvider: AddonCompetencyProvider, private helperProvider: AddonCompetencyHelperProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.fetchCourseCompetencies().finally(() => {
|
||||
this.competenciesLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the competencies and updates the view.
|
||||
*
|
||||
* @return {Promise<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchCourseCompetencies(): Promise<void> {
|
||||
return this.competencyProvider.getCourseCompetencies(this.courseId, this.userId).then((competencies) => {
|
||||
this.competencies = competencies;
|
||||
|
||||
// Get the user profile image.
|
||||
this.helperProvider.getProfile(this.userId).then((user) => {
|
||||
this.user = user;
|
||||
});
|
||||
}).catch((message) => {
|
||||
this.domUtils.showErrorModalDefault(message, 'Error getting course competencies data.');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a competency.
|
||||
*
|
||||
* @param {number} competencyId
|
||||
*/
|
||||
openCompetency(competencyId: number): void {
|
||||
if (this.appProvider.isWide()) {
|
||||
this.navCtrl.push('AddonCompetencyCompetenciesPage', {competencyId, courseId: this.courseId, userId: this.userId});
|
||||
} else {
|
||||
this.navCtrl.push('AddonCompetencyCompetencyPage', {competencyId, courseId: this.courseId, userId: this.userId});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the summary of a competency.
|
||||
*
|
||||
* @param {number} competencyId
|
||||
*/
|
||||
openCompetencySummary(competencyId: number): void {
|
||||
this.navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the competencies.
|
||||
*
|
||||
* @param {any} refresher Refresher.
|
||||
*/
|
||||
refreshCourseCompetencies(refresher: any): void {
|
||||
this.competencyProvider.invalidateCourseCompetencies(this.courseId, this.userId).finally(() => {
|
||||
this.fetchCourseCompetencies().finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"activities": "Activities",
|
||||
"competencies": "Competencies",
|
||||
"competenciesmostoftennotproficientincourse": "Competencies most often not proficient in this course",
|
||||
"coursecompetencies": "Course competencies",
|
||||
"coursecompetencyratingsarenotpushedtouserplans": "Competency ratings in this course do not affect learning plans.",
|
||||
"coursecompetencyratingsarepushedtouserplans": "Competency ratings in this course are updated immediately in learning plans.",
|
||||
"crossreferencedcompetencies": "Cross-referenced competencies",
|
||||
"duedate": "Due date",
|
||||
"errornocompetenciesfound": "No competencies found",
|
||||
"evidence": "Evidence",
|
||||
"evidence_competencyrule": "The rule of the competency was met.",
|
||||
"evidence_coursecompleted": "The course '{{$a}}' was completed.",
|
||||
"evidence_coursemodulecompleted": "The activity '{{$a}}' was completed.",
|
||||
"evidence_courserestored": "The rating was restored along with the course '{{$a}}'.",
|
||||
"evidence_evidenceofpriorlearninglinked": "The evidence of prior learning '{{$a}}' was linked.",
|
||||
"evidence_evidenceofpriorlearningunlinked": "The evidence of prior learning '{{$a}}' was unlinked.",
|
||||
"evidence_manualoverride": "The competency rating was manually set.",
|
||||
"evidence_manualoverrideincourse": "The competency rating was manually set in the course '{{$a}}'.",
|
||||
"evidence_manualoverrideinplan": "The competency rating was manually set in the learning plan '{{$a}}'.",
|
||||
"learningplancompetencies": "Learning plan competencies",
|
||||
"learningplans": "Learning plans",
|
||||
"myplans": "My learning plans",
|
||||
"noactivities": "No activities",
|
||||
"nocompetencies": "No competencies",
|
||||
"nocrossreferencedcompetencies": "No other competencies have been cross-referenced to this competency.",
|
||||
"noevidence": "No evidence",
|
||||
"noplanswerecreated": "No learning plans were created.",
|
||||
"path": "Path:",
|
||||
"planstatusactive": "Active",
|
||||
"planstatuscomplete": "Complete",
|
||||
"planstatusdraft": "Draft",
|
||||
"planstatusinreview": "In review",
|
||||
"planstatuswaitingforreview": "Waiting for review",
|
||||
"proficient": "Proficient",
|
||||
"progress": "Progress",
|
||||
"rating": "Rating",
|
||||
"reviewstatus": "Review status",
|
||||
"status": "Status",
|
||||
"template": "Learning plan template",
|
||||
"usercompetencystatus_idle": "Idle",
|
||||
"usercompetencystatus_inreview": "In review",
|
||||
"usercompetencystatus_waitingforreview": "Waiting for review",
|
||||
"userplans": "Learning plans",
|
||||
"xcompetenciesproficientoutofy": "{{$a.x}} out of {{$a.y}} competencies are proficient",
|
||||
"xcompetenciesproficientoutofyincourse": "You are proficient in {{$a.x}} out of {{$a.y}} competencies in this course."
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<core-split-view>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="competenciesLoaded" (ionRefresh)="refreshCompetencies($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="competenciesLoaded">
|
||||
<ion-list>
|
||||
<a ion-item text-wrap *ngFor="let competency of competencies" [title]="competency.competency.shortname" (click)="openCompetency(competency.competency.id)" [class.core-split-item-selected]="competency.competency.id == competencyId">
|
||||
{{ competency.competency.shortname }} <small>{{competency.competency.idnumber}}</small>
|
||||
<ion-badge item-end *ngIf="competency.usercompetency" [color]="competency.usercompetency.proficiency ? 'success' : 'danger'">{{ competency.usercompetency.gradename }}</ion-badge>
|
||||
<ion-badge item-end *ngIf="competency.usercompetencycourse" [color]="competency.usercompetencycourse.proficiency ? 'success' : 'danger'">{{ competency.usercompetencycourse.gradename }}</ion-badge>
|
||||
</a>
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
</core-split-view>
|
|
@ -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 { CoreComponentsModule } from '@components/components.module';
|
||||
import { AddonCompetencyCompetenciesPage } from './competencies';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonCompetencyCompetenciesPage,
|
||||
],
|
||||
imports: [
|
||||
CoreComponentsModule,
|
||||
IonicPageModule.forChild(AddonCompetencyCompetenciesPage),
|
||||
TranslateModule.forChild()
|
||||
],
|
||||
})
|
||||
export class AddonCompetencyCompetenciesPageModule {}
|
|
@ -0,0 +1,137 @@
|
|||
// (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, ViewChild } from '@angular/core';
|
||||
import { IonicPage, NavParams } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||
import { AddonCompetencyProvider } from '../../providers/competency';
|
||||
|
||||
/**
|
||||
* Page that displays the list of competencies of a learning plan.
|
||||
*/
|
||||
@IonicPage({ segment: 'addon-competency-competencies' })
|
||||
@Component({
|
||||
selector: 'page-addon-competency-competencies',
|
||||
templateUrl: 'competencies.html',
|
||||
})
|
||||
export class AddonCompetencyCompetenciesPage {
|
||||
@ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent;
|
||||
|
||||
protected planId: number;
|
||||
protected courseId: number;
|
||||
protected competencyId: number;
|
||||
protected userId: number;
|
||||
|
||||
competenciesLoaded = false;
|
||||
competencies = [];
|
||||
title: string;
|
||||
|
||||
constructor(navParams: NavParams, private translate: TranslateService, private domUtils: CoreDomUtilsProvider,
|
||||
private competencyProvider: AddonCompetencyProvider) {
|
||||
this.planId = navParams.get('planId');
|
||||
this.courseId = navParams.get('courseId');
|
||||
this.competencyId = navParams.get('competencyId');
|
||||
this.userId = navParams.get('userId');
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ionViewDidLoad(): void {
|
||||
if (this.competencyId) {
|
||||
// There is a competency to load.
|
||||
this.openCompetency(this.competencyId);
|
||||
}
|
||||
|
||||
this.fetchCompetencies().then(() => {
|
||||
if (!this.competencyId && this.splitviewCtrl.isOn() && this.competencies.length > 0) {
|
||||
// Take first and load it.
|
||||
this.openCompetency(this.competencies[0].id);
|
||||
}
|
||||
}).finally(() => {
|
||||
this.competenciesLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the competencies and updates the view.
|
||||
*
|
||||
* @return {Promise<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchCompetencies(): Promise<void> {
|
||||
let promise;
|
||||
|
||||
if (this.planId) {
|
||||
promise = this.competencyProvider.getLearningPlan(this.planId);
|
||||
} else if (this.courseId) {
|
||||
promise = this.competencyProvider.getCourseCompetencies(this.courseId, this.userId);
|
||||
} else {
|
||||
promise = Promise.reject(null);
|
||||
}
|
||||
|
||||
return promise.then((response) => {
|
||||
if (response.competencycount <= 0) {
|
||||
return Promise.reject(this.translate.instant('addon.competency.errornocompetenciesfound'));
|
||||
}
|
||||
|
||||
if (this.planId) {
|
||||
this.title = response.plan.name;
|
||||
this.userId = response.plan.userid;
|
||||
} else {
|
||||
this.title = this.translate.instant('addon.competency.coursecompetencies');
|
||||
}
|
||||
this.competencies = response.competencies;
|
||||
}).catch((message) => {
|
||||
this.domUtils.showErrorModalDefault(message, 'Error getting competencies data.');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a competency.
|
||||
*
|
||||
* @param {number} competencyId
|
||||
*/
|
||||
openCompetency(competencyId: number): void {
|
||||
this.competencyId = competencyId;
|
||||
let params;
|
||||
if (this.planId) {
|
||||
params = {competencyId, planId: this.planId};
|
||||
} else {
|
||||
params = {competencyId, courseId: this.courseId, userId: this.userId};
|
||||
}
|
||||
this.splitviewCtrl.push('AddonCompetencyCompetencyPage', params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the competencies.
|
||||
*
|
||||
* @param {any} refresher Refresher.
|
||||
*/
|
||||
refreshCompetencies(refresher: any): void {
|
||||
let promise;
|
||||
if (this.planId) {
|
||||
promise = this.competencyProvider.invalidateLearningPlan(this.planId);
|
||||
} else {
|
||||
promise = this.competencyProvider.invalidateCourseCompetencies(this.courseId, this.userId);
|
||||
}
|
||||
|
||||
return promise.finally(() => {
|
||||
this.fetchCompetencies().finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title *ngIf="competency">{{ competency.competency.competency.shortname }} <small>{{ competency.competency.competency.idnumber }}</small></ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="competencyLoaded" (ionRefresh)="refreshCompetency($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="competencyLoaded">
|
||||
<ion-card *ngIf="user">
|
||||
<ion-item text-wrap>
|
||||
<ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start>
|
||||
<img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content>
|
||||
</ion-avatar>
|
||||
<span *ngIf="user.profileimageurl === true" item-start>
|
||||
<ion-icon name="person"></ion-icon>
|
||||
</span>
|
||||
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngIf="competency">
|
||||
<ion-item text-wrap *ngIf="competency.competency.competency.description">
|
||||
<core-format-text [text]="competency.competency.competency.description"></core-format-text>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.path' | translate }}</strong>:
|
||||
{{ competency.competency.comppath.framework.name }}
|
||||
<span *ngFor="let ancestor of competency.competency.comppath.ancestors">
|
||||
/ <a (click)="openCompetencySummary(ancestor.id)">{{ ancestor.name }}</a>
|
||||
</span>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.crossreferencedcompetencies' | translate }}</strong>:
|
||||
<div *ngIf="!competency.competency.hasrelatedcompetencies">{{ 'addon.competency.nocrossreferencedcompetencies' | translate }}</div>
|
||||
<div *ngIf="competency.competency.hasrelatedcompetencies">
|
||||
<p *ngFor="let relatedcomp of competency.competency.relatedcompetencies">
|
||||
<a (click)="openCompetencySummary(relatedcomp.id)">
|
||||
{{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="coursemodules">
|
||||
<strong>{{ 'addon.competency.activities' | translate }}</strong>:
|
||||
<span *ngIf="coursemodules.length == 0">
|
||||
{{ 'addon.competency.noactivities' | translate }}
|
||||
</span>
|
||||
<a ion-item text-wrap *ngFor="let activity of coursemodules" [href]="activity.url" [title]="activity.name">
|
||||
<img item-start core-external-content [src]="activity.iconurl" alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon">
|
||||
<core-format-text [text]="activity.name"></core-format-text>
|
||||
</a>
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="competency.usercompetency.status">
|
||||
<strong>{{ 'addon.competency.reviewstatus' | translate }}</strong>:
|
||||
{{ competency.usercompetency.statusname }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.proficient' | translate }}</strong>:
|
||||
<ion-badge color="success" *ngIf="competency.usercompetency.proficiency">
|
||||
{{ 'core.yes' | translate }}
|
||||
</ion-badge>
|
||||
<ion-badge color="danger" *ngIf="!competency.usercompetency.proficiency">
|
||||
{{ 'core.no' | translate }}
|
||||
</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.rating' | translate }}</strong>:
|
||||
<ion-badge color="dark">{{ competency.usercompetency.gradename }}</ion-badge>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<div *ngIf="competency">
|
||||
<h3 margin-horizontal>{{ 'addon.competency.evidence' | translate }}</h3>
|
||||
<p margin-horizontal *ngIf="competency.evidence.length == 0">
|
||||
{{ 'addon.competency.noevidence' | translate }}
|
||||
</p>
|
||||
<ion-card *ngFor="let evidence of competency.evidence">
|
||||
<a ion-item text-wrap *ngIf="evidence.actionuser" (click)="openUserProfile(evidence.actionuser.id)">
|
||||
<ion-avatar item-start>
|
||||
<img core-external-content [src]="evidence.actionuser.profileimageurlsmall" [alt]="'core.pictureof' | translate:{$a: evidence.actionuser.fullname}" role="presentation">
|
||||
</ion-avatar>
|
||||
<h2>{{ evidence.actionuser.fullname }}</h2>
|
||||
<p>{{ evidence.timemodified | coreToLocaleString }}</p>
|
||||
</a>
|
||||
<ion-item text-wrap>
|
||||
<p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p>
|
||||
<p margin-top *ngIf="evidence.description">{{ evidence.description }}</p>
|
||||
<blockquote *ngIf="evidence.note"><core-format-text [text]="evidence.note"></core-format-text></blockquote>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
</div>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -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 {}
|
|
@ -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<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchCompetency(): Promise<void> {
|
||||
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});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title *ngIf="competency">{{ competency.competency.shortname }} <small>{{ competency.competency.idnumber }}</small></ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="competencyLoaded" (ionRefresh)="refreshCompetency($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="competencyLoaded">
|
||||
<ion-card *ngIf="competency">
|
||||
<ion-item text-wrap *ngIf="competency.competency.description">
|
||||
<core-format-text [text]="competency.competency.description"></core-format-text>
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.path' | translate }}</strong>:
|
||||
{{ competency.comppath.framework.name }}
|
||||
<span *ngFor="let ancestor of competency.comppath.ancestors">
|
||||
/ <a (click)="openCompetencySummary(ancestor.id)">{{ ancestor.name }}</a>
|
||||
</span>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -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 {}
|
|
@ -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<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchCompetency(): Promise<void> {
|
||||
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});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{ 'addon.competency.coursecompetencies' | translate }}</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<addon-competency-course class="core-avoid-header" [courseId]="courseId" [userId]="userId"></addon-competency-course>
|
|
@ -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 {}
|
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title *ngIf="plan">{{plan.plan.name}}</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="planLoaded" (ionRefresh)="refreshLearningPlan($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="planLoaded">
|
||||
<ion-card *ngIf="user">
|
||||
<ion-item text-wrap>
|
||||
<ion-avatar *ngIf="user.profileimageurl && user.profileimageurl !== true" item-start>
|
||||
<img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content>
|
||||
</ion-avatar>
|
||||
<span *ngIf="user.profileimageurl === true" item-start>
|
||||
<ion-icon name="person"></ion-icon>
|
||||
</span>
|
||||
<h2><core-format-text [text]="user.fullname"></core-format-text></h2>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<ion-card *ngIf="plan">
|
||||
<ion-list>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.status' | translate }}</strong>:
|
||||
{{ plan.plan.statusname }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="plan.plan.duedate > 0">
|
||||
<strong>{{ 'addon.competency.duedate' | translate }}</strong>:
|
||||
{{ plan.plan.duedate | coreToLocaleString }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="plan.plan.template">
|
||||
<strong>{{ 'addon.competency.template' | translate }}</strong>:
|
||||
{{ plan.plan.template.shortname }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap>
|
||||
<strong>{{ 'addon.competency.progress' | translate }}</strong>:
|
||||
{{ 'addon.competency.xcompetenciesproficientoutofy' | translate: {$a: {x: plan.proficientcompetencycount, y: plan.competencycount} } }}
|
||||
<core-progress-bar [progress]="plan.proficientcompetencypercentage" [text]="plan.proficientcompetencypercentageformatted"></core-progress-bar>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-card>
|
||||
<ion-card *ngIf="plan">
|
||||
<ion-card-header text-wrap>{{ 'addon.competency.learningplancompetencies' | translate }}</ion-card-header>
|
||||
<ion-list>
|
||||
<ion-item text-wrap *ngIf="plan.competencycount == 0">
|
||||
{{ 'addon.competency.nocompetencies' | translate }}
|
||||
</ion-item>
|
||||
<a ion-item text-wrap *ngFor="let competency of plan.competencies" (click)="openCompetency(competency.competency.id)" [title]="competency.competency.shortname">
|
||||
{{competency.competency.shortname}} <small>{{competency.competency.idnumber}}</small>
|
||||
<ion-badge item-end [color]="competency.usercompetency.proficiency ? 'success' : 'danger'">{{ competency.usercompetency.gradename }}</ion-badge>
|
||||
</a>
|
||||
</ion-list>
|
||||
</ion-card>
|
||||
</core-loading>
|
||||
</ion-content>
|
|
@ -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 {}
|
|
@ -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<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchLearningPlan(): Promise<void> {
|
||||
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();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{ 'addon.competency.userplans' | translate }}</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<core-split-view>
|
||||
<ion-content>
|
||||
<ion-refresher [enabled]="plansLoaded" (ionRefresh)="refreshLearningPlans($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="plansLoaded">
|
||||
<core-empty-box *ngIf="plans.length == 0" icon="map" [message]="'addon.competency.noplanswerecreated' | translate">
|
||||
</core-empty-box>
|
||||
<ion-list *ngIf="plans.length > 0" no-margin>
|
||||
<a ion-item text-wrap *ngFor="let plan of plans" [title]="plan.name" (click)="openPlan(plan.id)" [class.core-split-item-selected]="plan.id == planId">
|
||||
<h2>{{ plan.name }}</h2>
|
||||
<p *ngIf="plan.duedate > 0">{{ 'addon.competency.duedate' | translate }}: {{ plan.duedate | coreToLocaleString }}</p>
|
||||
</a>
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
</core-split-view>
|
|
@ -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 { CorePipesModule } from '@pipes/pipes.module';
|
||||
import { AddonCompetencyPlanListPage } from './planlist';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonCompetencyPlanListPage,
|
||||
],
|
||||
imports: [
|
||||
CoreComponentsModule,
|
||||
CorePipesModule,
|
||||
IonicPageModule.forChild(AddonCompetencyPlanListPage),
|
||||
TranslateModule.forChild()
|
||||
],
|
||||
})
|
||||
export class AddonCompetencyPlanListPageModule {}
|
|
@ -0,0 +1,95 @@
|
|||
// (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, ViewChild } from '@angular/core';
|
||||
import { IonicPage, 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 the list of learning plans.
|
||||
*/
|
||||
@IonicPage({ segment: 'addon-competency-planlist' })
|
||||
@Component({
|
||||
selector: 'page-addon-competency-planlist',
|
||||
templateUrl: 'planlist.html',
|
||||
})
|
||||
export class AddonCompetencyPlanListPage {
|
||||
@ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent;
|
||||
|
||||
protected userId: number;
|
||||
protected planId: number;
|
||||
plansLoaded = false;
|
||||
plans = [];
|
||||
|
||||
constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private competencyProvider: AddonCompetencyProvider) {
|
||||
this.userId = navParams.get('userId');
|
||||
}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ionViewDidLoad(): void {
|
||||
if (this.planId) {
|
||||
// There is a learning plan to load.
|
||||
this.openPlan(this.planId);
|
||||
}
|
||||
|
||||
this.fetchLearningPlans().then(() => {
|
||||
if (!this.planId && this.splitviewCtrl.isOn() && this.plans.length > 0) {
|
||||
// Take first and load it.
|
||||
this.openPlan(this.plans[0].id);
|
||||
}
|
||||
}).finally(() => {
|
||||
this.plansLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the learning plans and updates the view.
|
||||
*
|
||||
* @return {Promise<void>} Promise resolved when done.
|
||||
*/
|
||||
protected fetchLearningPlans(): Promise<void> {
|
||||
return this.competencyProvider.getLearningPlans(this.userId).then((plans) => {
|
||||
this.plans = plans;
|
||||
}).catch((message) => {
|
||||
this.domUtils.showErrorModalDefault(message, 'Error getting learning plans data.');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the learning plans.
|
||||
*
|
||||
* @param {any} refresher Refresher.
|
||||
*/
|
||||
refreshLearningPlans(refresher: any): void {
|
||||
this.competencyProvider.invalidateLearningPlans(this.userId).finally(() => {
|
||||
this.fetchLearningPlans().finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a learning plan.
|
||||
*
|
||||
* @param {number} planId Learning plan to load.
|
||||
*/
|
||||
openPlan(planId: number): void {
|
||||
this.planId = planId;
|
||||
this.splitviewCtrl.push('AddonCompetencyPlanPage', { planId });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,519 @@
|
|||
// (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 { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
|
||||
/**
|
||||
* Service to handle caompetency learning plans.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonCompetencyProvider {
|
||||
|
||||
static STATUS_DRAFT = 0;
|
||||
static STATUS_ACTIVE = 1;
|
||||
static STATUS_COMPLETE = 2;
|
||||
static STATUS_WAITIN_GFOR_REVIEW = 3;
|
||||
static STATUS_IN_REVIEW = 4;
|
||||
static REVIEW_STATUS_IDLE = 0;
|
||||
static REVIEW_STATUS_WAITING_FOR_REVIEW = 1;
|
||||
static REVIEW_STATUS_IN_REVIEW = 2;
|
||||
protected ROOT_CACHE_KEY = 'mmaCompetency:';
|
||||
|
||||
protected logger;
|
||||
|
||||
constructor(loggerProvider: CoreLoggerProvider, private sitesProvider: CoreSitesProvider) {
|
||||
this.logger = loggerProvider.getInstance('AddonCompetencyProvider');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for user learning plans data WS calls.
|
||||
*
|
||||
* @param {number} userId User ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getLearningPlansCacheKey(userId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'userplans:' + userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for learning plan data WS calls.
|
||||
*
|
||||
* @param {number} planId Plan ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getLearningPlanCacheKey(planId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'learningplan:' + planId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for competency in plan data WS calls.
|
||||
*
|
||||
* @param {number} planId Plan ID.
|
||||
* @param {number} competencyId Competency ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getCompetencyInPlanCacheKey(planId: number, competencyId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'plancompetency:' + planId + ':' + competencyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for competency in course data WS calls.
|
||||
*
|
||||
* @param {number} courseId Course ID.
|
||||
* @param {number} competencyId Competency ID.
|
||||
* @param {number} userId User ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getCompetencyInCourseCacheKey(courseId: number, competencyId: number, userId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'coursecompetency:' + userId + ':' + courseId + ':' + competencyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for competency summary data WS calls.
|
||||
*
|
||||
* @param {number} competencyId Competency ID.
|
||||
* @param {number} userId User ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getCompetencySummaryCacheKey(competencyId: number, userId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'competencysummary:' + userId + ':' + competencyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for course competencies data WS calls.
|
||||
*
|
||||
* @param {number} courseId Course ID.
|
||||
* @return {string} Cache key.
|
||||
*/
|
||||
protected getCourseCompetenciesCacheKey(courseId: number): string {
|
||||
return this.ROOT_CACHE_KEY + 'coursecompetencies:' + courseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether competencies are enabled.
|
||||
*
|
||||
* @param {number} courseId Course ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} competencies if enabled for the given course, false otherwise.
|
||||
*/
|
||||
isPluginForCourseEnabled(courseId: number, siteId?: string): Promise<any> {
|
||||
if (!this.sitesProvider.isLoggedIn()) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
return this.getCourseCompetencies(courseId, 0, siteId).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plans for a certain user.
|
||||
*
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the plans are retrieved.
|
||||
*/
|
||||
getLearningPlans(userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
this.logger.debug('Get plans for user ' + userId);
|
||||
|
||||
const params = {
|
||||
userid: userId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getLearningPlansCacheKey(userId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_plans_page', params, preSets).then((response) => {
|
||||
if (response.plans) {
|
||||
return response.plans;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a certain plan.
|
||||
*
|
||||
* @param {number} planId ID of the plan.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the plans are retrieved.
|
||||
*/
|
||||
getLearningPlan(planId: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
|
||||
this.logger.debug('Get plan ' + planId);
|
||||
|
||||
const params = {
|
||||
planid: planId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getLearningPlanCacheKey(planId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_plan_page', params, preSets).then((response) => {
|
||||
if (response.plan) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a certain competency in a plan.
|
||||
*
|
||||
* @param {number} planId ID of the plan.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the plans are retrieved.
|
||||
*/
|
||||
getCompetencyInPlan(planId: number, competencyId: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
|
||||
this.logger.debug('Get competency ' + competencyId + ' in plan ' + planId);
|
||||
|
||||
const params = {
|
||||
planid: planId,
|
||||
competencyid: competencyId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getCompetencyInPlanCacheKey(planId, competencyId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_user_competency_summary_in_plan', params, preSets).then((response) => {
|
||||
if (response.usercompetencysummary) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a certain competency in a course.
|
||||
*
|
||||
* @param {number} courseId ID of the course.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the plans are retrieved.
|
||||
*/
|
||||
getCompetencyInCourse(courseId: number, competencyId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
this.logger.debug('Get competency ' + competencyId + ' in course ' + courseId);
|
||||
|
||||
const params = {
|
||||
courseid: courseId,
|
||||
competencyid: competencyId,
|
||||
userid: userId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getCompetencyInCourseCacheKey(courseId, competencyId, userId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_user_competency_summary_in_course', params, preSets).then((response) => {
|
||||
if (response.usercompetencysummary) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a certain competency summary.
|
||||
*
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the plans are retrieved.
|
||||
*/
|
||||
getCompetencySummary(competencyId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
this.logger.debug('Get competency ' + competencyId + ' summary for user' + userId);
|
||||
|
||||
const params = {
|
||||
competencyid: competencyId,
|
||||
userid: userId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getCompetencySummaryCacheKey(competencyId, userId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_user_competency_summary', params, preSets).then((response) => {
|
||||
if (response.competency) {
|
||||
return response.competency;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all competencies in a course.
|
||||
*
|
||||
* @param {number} courseId ID of the course.
|
||||
* @param {number} [userId] ID of the user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise to be resolved when the course competencies are retrieved.
|
||||
*/
|
||||
getCourseCompetencies(courseId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
|
||||
this.logger.debug('Get course competencies for course ' + courseId);
|
||||
|
||||
const params = {
|
||||
courseid: courseId
|
||||
},
|
||||
preSets = {
|
||||
cacheKey: this.getCourseCompetenciesCacheKey(courseId)
|
||||
};
|
||||
|
||||
return site.read('tool_lp_data_for_course_competencies_page', params, preSets).then((response) => {
|
||||
if (response.competencies) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
});
|
||||
|
||||
}).then((response) => {
|
||||
|
||||
if (!userId || userId == this.sitesProvider.getCurrentSiteUserId()) {
|
||||
return response;
|
||||
}
|
||||
|
||||
const promises = response.competencies.map((competency) =>
|
||||
this.getCompetencyInCourse(courseId, competency.competency.id, userId, siteId)
|
||||
);
|
||||
|
||||
return Promise.all(promises).then((responses: any[]) => {
|
||||
responses.forEach((resp, index) => {
|
||||
response.competencies[index].usercompetencycourse = resp.usercompetencysummary.usercompetencycourse;
|
||||
});
|
||||
|
||||
return response;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates User Learning Plans data.
|
||||
*
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateLearningPlans(userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
return site.invalidateWsCacheForKey(this.getLearningPlansCacheKey(userId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates Learning Plan data.
|
||||
*
|
||||
* @param {number} planId ID of the plan.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateLearningPlan(planId: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
return site.invalidateWsCacheForKey(this.getLearningPlanCacheKey(planId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates Competency in Plan data.
|
||||
*
|
||||
* @param {number} planId ID of the plan.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateCompetencyInPlan(planId: number, competencyId: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
return site.invalidateWsCacheForKey(this.getCompetencyInPlanCacheKey(planId, competencyId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates Competency in Course data.
|
||||
*
|
||||
* @param {number} courseId ID of the course.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateCompetencyInCourse(courseId: number, competencyId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
return site.invalidateWsCacheForKey(this.getCompetencyInCourseCacheKey(courseId, competencyId, userId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates Competency Summary data.
|
||||
*
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} [userId] ID of the user. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateCompetencySummary(competencyId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
return site.invalidateWsCacheForKey(this.getCompetencySummaryCacheKey(competencyId, userId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates Course Competencies data.
|
||||
*
|
||||
* @param {number} courseId ID of the course.
|
||||
* @param {number} [userId] ID of the user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
||||
*/
|
||||
invalidateCourseCompetencies(courseId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
return site.invalidateWsCacheForKey(this.getCourseCompetenciesCacheKey(courseId));
|
||||
}).then(() => {
|
||||
if (!userId || userId == this.sitesProvider.getCurrentSiteUserId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Competencies for other users are fetched with getCompetencyInCourse (and saved in their own cache).
|
||||
We need to fecth the list of competencies to know which ones to invalidate. We can pass 0 as userId
|
||||
to getCourseCompetencies, we just need the competency IDs and this way we avid extra WS calls. */
|
||||
return this.getCourseCompetencies(courseId, 0, siteId).then((competencies) => {
|
||||
const promises = competencies.competencies.map((competency) => {
|
||||
return this.invalidateCompetencyInCourse(courseId, competency.competency.id, userId, siteId);
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the competency as being viewed in plan.
|
||||
*
|
||||
* @param {number} planId ID of the plan.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} planStatus Current plan Status to decide what action should be logged.
|
||||
* @param {number} [userId] User ID. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the WS call is successful.
|
||||
*/
|
||||
logCompetencyInPlanView(planId: number, competencyId: number, planStatus: number, userId?: number, siteId?: string)
|
||||
: Promise<any> {
|
||||
if (planId && competencyId) {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
const params = {
|
||||
planid: planId,
|
||||
competencyid: competencyId,
|
||||
userid: userId
|
||||
},
|
||||
preSets = {
|
||||
typeExpected: 'boolean'
|
||||
};
|
||||
|
||||
if (planStatus == AddonCompetencyProvider.STATUS_COMPLETE) {
|
||||
return site.write('core_competency_user_competency_plan_viewed', params, preSets);
|
||||
} else {
|
||||
return site.write('core_competency_user_competency_viewed_in_plan', params, preSets);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the competency as being viewed in course.
|
||||
*
|
||||
* @param {number} courseId ID of the course.
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {number} [userId] User ID. If not defined, current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the WS call is successful.
|
||||
*/
|
||||
logCompetencyInCourseView(courseId: number, competencyId: number, userId?: number, siteId?: string): Promise<any> {
|
||||
if (courseId && competencyId) {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
userId = userId || site.getUserId();
|
||||
|
||||
const params = {
|
||||
courseid: courseId,
|
||||
competencyid: competencyId,
|
||||
userid: userId
|
||||
};
|
||||
const preSets = {
|
||||
typeExpected: 'boolean'
|
||||
};
|
||||
|
||||
return site.write('core_competency_user_competency_viewed_in_course', params, preSets);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the competency as being viewed.
|
||||
*
|
||||
* @param {number} competencyId ID of the competency.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the WS call is successful.
|
||||
*/
|
||||
logCompetencyView(competencyId: number, siteId?: string): Promise<any> {
|
||||
if (competencyId) {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const params = {
|
||||
id: competencyId,
|
||||
};
|
||||
const preSets = {
|
||||
typeExpected: 'boolean'
|
||||
};
|
||||
|
||||
return site.write('core_competency_competency_viewed', params, preSets);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
// (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, Injector } from '@angular/core';
|
||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { AddonCompetencyCourseComponent } from '../components/course/course';
|
||||
import { AddonCompetencyProvider } from '../providers/competency';
|
||||
|
||||
/**
|
||||
* Course nav handler.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonCompetencyCourseOptionHandler implements CoreCourseOptionsHandler {
|
||||
name = 'AddonCompetency';
|
||||
priority = 700;
|
||||
|
||||
protected coursesNavEnabledCache = {};
|
||||
|
||||
constructor(private competencyProvider: AddonCompetencyProvider) {}
|
||||
|
||||
/**
|
||||
* Clear courses nav cache.
|
||||
*/
|
||||
clearCoursesNavCache(): void {
|
||||
this.coursesNavEnabledCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled ona site level.
|
||||
* @return {boolean|Promise<boolean>} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled for a certain course.
|
||||
*
|
||||
* @param {number} courseId The course ID.
|
||||
* @param {any} accessData Access type and data. Default, guest, ...
|
||||
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabledForCourse(courseId: number, accessData: any, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
||||
if (accessData && accessData.type == CoreCourseProvider.ACCESS_GUEST) {
|
||||
return false; // Not enabled for guests.
|
||||
}
|
||||
|
||||
if (navOptions && typeof navOptions.competencies != 'undefined') {
|
||||
return navOptions.competencies;
|
||||
}
|
||||
|
||||
if (typeof this.coursesNavEnabledCache[courseId] != 'undefined') {
|
||||
return this.coursesNavEnabledCache[courseId];
|
||||
}
|
||||
|
||||
return this.competencyProvider.isPluginForCourseEnabled(courseId).then((competencies) => {
|
||||
const enabled = competencies ? !competencies.canmanagecoursecompetencies : false;
|
||||
this.coursesNavEnabledCache[courseId] = enabled;
|
||||
|
||||
return enabled;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {number} courseId The course ID.
|
||||
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
|
||||
*/
|
||||
getDisplayData?(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> {
|
||||
return {
|
||||
title: 'addon.competency.competencies',
|
||||
class: 'addon-competency-course-handler',
|
||||
component: AddonCompetencyCourseComponent
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Should invalidate the data to determine if the handler is enabled for a certain course.
|
||||
*
|
||||
* @param {number} courseId The course ID.
|
||||
* @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions.
|
||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidateEnabledForCourse(courseId: number, navOptions?: any, admOptions?: any): Promise<any> {
|
||||
if (navOptions && typeof navOptions.competencies != 'undefined') {
|
||||
// No need to invalidate anything.
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.competencyProvider.invalidateCourseCompetencies(courseId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// (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 { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreUserProvider } from '@core/user/providers/user';
|
||||
|
||||
/**
|
||||
* Service that provides some features regarding learning plans.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonCompetencyHelperProvider {
|
||||
|
||||
constructor(private sitesProvider: CoreSitesProvider, private userProvider: CoreUserProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient helper to get the user profile image.
|
||||
*
|
||||
* @param {number} userId User Id
|
||||
* @return {Promise<any>} User profile Image URL or true if default icon.
|
||||
*/
|
||||
getProfile(userId: number): Promise<any> {
|
||||
if (!userId || userId == this.sitesProvider.getCurrentSiteUserId()) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// Get the user profile to retrieve the user image.
|
||||
return this.userProvider.getProfile(userId, null, true).then((user) => {
|
||||
user.profileimageurl = user.profileimageurl || true;
|
||||
|
||||
return user;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// (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 { AddonCompetencyProvider } from './competency';
|
||||
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@core/mainmenu/providers/delegate';
|
||||
|
||||
/**
|
||||
* Handler to inject an option into main menu.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonCompetencyMainMenuHandler implements CoreMainMenuHandler {
|
||||
name = 'AddonCompetency';
|
||||
priority = 500;
|
||||
|
||||
constructor(private competencyProvider: AddonCompetencyProvider) { }
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
// Check the user has at least one learn plan available.
|
||||
return this.competencyProvider.getLearningPlans().then((plans) => {
|
||||
return plans.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {CoreMainMenuHandlerData} Data needed to render the handler.
|
||||
*/
|
||||
getDisplayData(): CoreMainMenuHandlerData {
|
||||
return {
|
||||
icon: 'map',
|
||||
title: 'addon.competency.myplans',
|
||||
page: 'AddonCompetencyPlanListPage',
|
||||
class: 'addon-competency-handler'
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
// (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 '@core/user/providers/user-delegate';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||
import { AddonCompetencyProvider } from './competency';
|
||||
|
||||
/**
|
||||
* Profile competencies handler.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonCompetencyUserHandler implements CoreUserProfileHandler {
|
||||
name = 'AddonCompetency';
|
||||
priority = 900;
|
||||
type = CoreUserDelegate.TYPE_NEW_PAGE;
|
||||
participantsNavEnabledCache = {};
|
||||
usersNavEnabledCache = {};
|
||||
|
||||
constructor(private linkHelper: CoreContentLinksHelperProvider, protected sitesProvider: CoreSitesProvider,
|
||||
private competencyProvider: AddonCompetencyProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear users nav cache.
|
||||
*/
|
||||
clearUsersNavCache(): void {
|
||||
this.participantsNavEnabledCache = {};
|
||||
this.usersNavEnabledCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
* @return {boolean|Promise<boolean>} Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<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<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
|
||||
*/
|
||||
isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
|
||||
if (courseId) {
|
||||
const cacheKey = courseId + '.' + user.id;
|
||||
|
||||
// Link on a user course profile.
|
||||
if (typeof this.participantsNavEnabledCache[cacheKey] != 'undefined') {
|
||||
return this.participantsNavEnabledCache[cacheKey];
|
||||
}
|
||||
|
||||
return this.competencyProvider.getCourseCompetencies(courseId, user.id).then((response) => {
|
||||
const enabled = response.competencies.length > 0;
|
||||
this.participantsNavEnabledCache[cacheKey] = enabled;
|
||||
|
||||
return enabled;
|
||||
}).catch((message) => {
|
||||
this.participantsNavEnabledCache[cacheKey] = false;
|
||||
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
// Link on a user site profile.
|
||||
if (typeof this.usersNavEnabledCache[user.id] != 'undefined') {
|
||||
return this.usersNavEnabledCache[user.id];
|
||||
}
|
||||
|
||||
return this.competencyProvider.getLearningPlans(user.id).then((plans) => {
|
||||
// Check the user has at least one learn plan available.
|
||||
const enabled = plans.length > 0;
|
||||
this.usersNavEnabledCache[user.id] = enabled;
|
||||
|
||||
return enabled;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {CoreUserProfileHandlerData} Data needed to render the handler.
|
||||
*/
|
||||
getDisplayData(user: any, courseId: number): CoreUserProfileHandlerData {
|
||||
if (courseId) {
|
||||
return {
|
||||
icon: 'ribbon',
|
||||
title: 'addon.competency.competencies',
|
||||
class: 'addon-competency-handler',
|
||||
action: (event, navCtrl, user, courseId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||
this.linkHelper.goInSite(navCtrl, 'AddonCompetencyCourseCompetenciesPage', {courseId, userId: user.id});
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
icon: 'map',
|
||||
title: 'addon.competency.learningplans',
|
||||
class: 'addon-competency-handler',
|
||||
action: (event, navCtrl, user, courseId): void => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// Always use redirect to make it the new history root (to avoid "loops" in history).
|
||||
this.linkHelper.goInSite(navCtrl, 'AddonCompetencyPlanListPage', {userId: user.id});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { IonicPage, NavParams, NavController } from 'ionic-angular';
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { IonicPage, NavParams } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
|
|
|
@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
|
|||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
||||
import { CoreSite } from '@classes/site';
|
||||
import { Md5 } from 'ts-md5/dist/md5';
|
||||
|
||||
/**
|
||||
* Service to handle my files and site files.
|
||||
|
|
|
@ -18,7 +18,6 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { AddonMessagesProvider } from '../../providers/messages';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import { AddonMessagesBlockContactUserHandler } from './providers/user-block-con
|
|||
import { AddonMessagesDiscussionLinkHandler } from './providers/discussion-link-handler';
|
||||
import { AddonMessagesIndexLinkHandler } from './providers/index-link-handler';
|
||||
import { AddonMessagesSyncCronHandler } from './providers/sync-cron-handler';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreLocalNotificationsProvider } from '@providers/local-notifications';
|
||||
|
|
|
@ -33,8 +33,7 @@ export class AddonMessagesIndexPage implements OnDestroy {
|
|||
protected loadSplitViewObserver: any;
|
||||
protected siteId: string;
|
||||
|
||||
constructor(private eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider,
|
||||
private messagesProvider: AddonMessagesProvider) {
|
||||
constructor(eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) {
|
||||
|
||||
this.siteId = sitesProvider.getCurrentSiteId();
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AddonMessagesProvider } from './messages';
|
||||
import { CoreMainMenuDelegate, CoreMainMenuHandler, CoreMainMenuHandlerToDisplay } from '@core/mainmenu/providers/delegate';
|
||||
import { CoreCronHandler } from '@providers/cron';
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AddonMessagesProvider } from './messages';
|
||||
import { CoreSettingsHandler, CoreSettingsHandlerData } from '@core/settings/providers/delegate';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
|
||||
/**
|
||||
* Message settings handler.
|
||||
|
@ -25,7 +24,7 @@ export class AddonMessagesSettingsHandler implements CoreSettingsHandler {
|
|||
name = 'AddonMessages';
|
||||
priority = 600;
|
||||
|
||||
constructor(private messagesProvider: AddonMessagesProvider, private sitesProvider: CoreSitesProvider) {
|
||||
constructor(private messagesProvider: AddonMessagesProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreCronHandler } from '@providers/cron';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { AddonMessagesSyncProvider } from './sync';
|
||||
|
||||
/**
|
||||
|
@ -24,7 +23,7 @@ import { AddonMessagesSyncProvider } from './sync';
|
|||
export class AddonMessagesSyncCronHandler implements CoreCronHandler {
|
||||
name = 'AddonMessagesSyncCronHandler';
|
||||
|
||||
constructor(private sitesProvider: CoreSitesProvider, private messagesSync: AddonMessagesSyncProvider) {}
|
||||
constructor(private messagesSync: AddonMessagesSyncProvider) {}
|
||||
|
||||
/**
|
||||
* Execute the process.
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||
import { AddonMessagesProvider } from './messages';
|
||||
import { AddonMessagesBlockContactUserHandler } from './user-block-contact-handler';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
|
@ -40,7 +39,7 @@ export class AddonMessagesAddContactUserHandler implements CoreUserProfileHandle
|
|||
protected disabled = false;
|
||||
protected updateObs: any;
|
||||
|
||||
constructor(private linkHelper: CoreContentLinksHelperProvider, protected sitesProvider: CoreSitesProvider,
|
||||
constructor(protected sitesProvider: CoreSitesProvider,
|
||||
private messagesProvider: AddonMessagesProvider, protected eventsProvider: CoreEventsProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private translate: TranslateService) {
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||
import { AddonMessagesProvider } from './messages';
|
||||
import { AddonMessagesAddContactUserHandler } from './user-add-contact-handler';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
|
@ -40,9 +39,9 @@ export class AddonMessagesBlockContactUserHandler implements CoreUserProfileHand
|
|||
protected disabled = false;
|
||||
protected updateObs: any;
|
||||
|
||||
constructor(private linkHelper: CoreContentLinksHelperProvider, protected sitesProvider: CoreSitesProvider,
|
||||
private messagesProvider: AddonMessagesProvider, protected eventsProvider: CoreEventsProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private translate: TranslateService) {
|
||||
constructor(protected sitesProvider: CoreSitesProvider, private messagesProvider: AddonMessagesProvider,
|
||||
protected eventsProvider: CoreEventsProvider, private domUtils: CoreDomUtilsProvider,
|
||||
private translate: TranslateService) {
|
||||
|
||||
this.updateObs = eventsProvider.on(AddonMessagesAddContactUserHandler.UPDATED_EVENT, (data) => {
|
||||
this.checkButton(data.userId);
|
||||
|
|
|
@ -70,6 +70,7 @@ import { CoreCompileModule } from '@core/compile/compile.module';
|
|||
|
||||
// Addon modules.
|
||||
import { AddonCalendarModule } from '@addon/calendar/calendar.module';
|
||||
import { AddonCompetencyModule } from '../addon/competency/competency.module';
|
||||
import { AddonUserProfileFieldModule } from '@addon/userprofilefield/userprofilefield.module';
|
||||
import { AddonFilesModule } from '@addon/files/files.module';
|
||||
import { AddonModBookModule } from '@addon/mod/book/book.module';
|
||||
|
@ -148,6 +149,7 @@ export const CORE_PROVIDERS: any[] = [
|
|||
CoreSitePluginsModule,
|
||||
CoreCompileModule,
|
||||
AddonCalendarModule,
|
||||
AddonCompetencyModule,
|
||||
AddonUserProfileFieldModule,
|
||||
AddonFilesModule,
|
||||
AddonModBookModule,
|
||||
|
|
|
@ -39,7 +39,7 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
|
|||
protected instanceId: string;
|
||||
protected parentContextMenu: CoreContextMenuComponent;
|
||||
|
||||
constructor(private translate: TranslateService, private popoverCtrl: PopoverController, private elementRef: ElementRef,
|
||||
constructor(private translate: TranslateService, private popoverCtrl: PopoverController, elementRef: ElementRef,
|
||||
private domUtils: CoreDomUtilsProvider) {
|
||||
// Create the stream and subscribe to it. We ignore successive changes during 250ms.
|
||||
this.itemsChangedStream = new Subject<void>();
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import { Component, ViewChild, Input, Optional } from '@angular/core';
|
||||
import { Content, NavParams, NavController } from 'ionic-angular';
|
||||
import { CoreGradesProvider } from '../../providers/grades';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreGradesHelperProvider } from '../../providers/helper';
|
||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||
|
@ -39,9 +38,8 @@ export class CoreGradesCourseComponent {
|
|||
gradesTable: any;
|
||||
|
||||
constructor(private gradesProvider: CoreGradesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams,
|
||||
private gradesHelper: CoreGradesHelperProvider, private sitesProvider: CoreSitesProvider,
|
||||
@Optional() private navCtrl: NavController, private appProvider: CoreAppProvider,
|
||||
@Optional() private svComponent: CoreSplitViewComponent) {
|
||||
private gradesHelper: CoreGradesHelperProvider, @Optional() private navCtrl: NavController,
|
||||
private appProvider: CoreAppProvider, @Optional() private svComponent: CoreSplitViewComponent) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreGradesProvider } from './grades';
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSite } from '@classes/site';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreGradesProvider } from './grades';
|
||||
|
@ -33,8 +32,7 @@ export class CoreGradesHelperProvider {
|
|||
constructor(logger: CoreLoggerProvider, private coursesProvider: CoreCoursesProvider,
|
||||
private gradesProvider: CoreGradesProvider, private sitesProvider: CoreSitesProvider,
|
||||
private textUtils: CoreTextUtilsProvider, private courseProvider: CoreCourseProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private translate: TranslateService,
|
||||
private urlUtils: CoreUrlUtilsProvider) {
|
||||
private domUtils: CoreDomUtilsProvider, private urlUtils: CoreUrlUtilsProvider) {
|
||||
this.logger = logger.getInstance('CoreGradesHelperProvider');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { IonicPage, NavController, NavParams, Platform } from 'ionic-angular';
|
||||
import { IonicPage, NavParams, Platform } from 'ionic-angular';
|
||||
import { CoreSettingsDelegate, CoreSettingsHandlerData } from '../../providers/delegate';
|
||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||
|
||||
|
@ -32,8 +32,7 @@ export class CoreSettingsListPage {
|
|||
isIOS: boolean;
|
||||
selectedPage: string;
|
||||
|
||||
constructor(private settingsDelegate: CoreSettingsDelegate, private navCtrl: NavController, platorm: Platform,
|
||||
navParams: NavParams) {
|
||||
constructor(private settingsDelegate: CoreSettingsDelegate, platorm: Platform, navParams: NavParams) {
|
||||
this.isIOS = platorm.is('ios');
|
||||
|
||||
this.selectedPage = navParams.get('page') || false;
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core';
|
||||
import { Directive, OnInit, ElementRef, Optional } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreSitePluginsProvider } from '../providers/siteplugins';
|
||||
import { CoreSitePluginsCallWSBaseDirective } from '../classes/call-ws-directive';
|
||||
import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content';
|
||||
|
|
|
@ -20,7 +20,6 @@ import { CoreLangProvider } from '@providers/lang';
|
|||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreConfigConstants } from '../../../configconstants';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
|
@ -67,8 +66,7 @@ export class CoreSitePluginsProvider {
|
|||
|
||||
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
|
||||
private langProvider: CoreLangProvider, private appProvider: CoreAppProvider, private platform: Platform,
|
||||
private filepoolProvider: CoreFilepoolProvider, private coursesProvider: CoreCoursesProvider,
|
||||
private textUtils: CoreTextUtilsProvider) {
|
||||
private filepoolProvider: CoreFilepoolProvider, private coursesProvider: CoreCoursesProvider) {
|
||||
this.logger = logger.getInstance('CoreUserProvider');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component, ViewChild, Input, OnInit } from '@angular/core';
|
||||
import { Content, NavParams } from 'ionic-angular';
|
||||
import { Content } from 'ionic-angular';
|
||||
import { CoreUserProvider } from '../../providers/user';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreUserProvider } from './user';
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
||||
import { CoreFileHelperProvider } from '@providers/file-helper';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
|
||||
/**
|
||||
* Directive to allow downloading and open a file. When the item with this directive is clicked, the file will be
|
||||
|
|
|
@ -19,7 +19,6 @@ import { Globalization } from '@ionic-native/globalization';
|
|||
import { Platform } from 'ionic-angular';
|
||||
import { CoreConfigProvider } from './config';
|
||||
import { CoreConfigConstants } from '../configconstants';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/*
|
||||
* Service to handle language features, like changing the current language.
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
"no-eval": true,
|
||||
"no-invalid-this": true,
|
||||
"no-this-assignment": true,
|
||||
"no-unused-variable": true,
|
||||
"no-var-keyword": true,
|
||||
"switch-default": true,
|
||||
"typeof-compare": true,
|
||||
|
|
Loading…
Reference in New Issue