MOBILE-2354 workshop: Assessment strategy handlers
parent
f0c80085d8
commit
e7582678f9
|
@ -0,0 +1,51 @@
|
|||
// (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 { AddonModWorkshopAssessmentStrategyAccumulativeComponent } from './component/accumulative';
|
||||
import { AddonModWorkshopAssessmentStrategyAccumulativeHandler } from './providers/handler';
|
||||
import { AddonWorkshopAssessmentStrategyDelegate } from '../../providers/assessment-strategy-delegate';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModWorkshopAssessmentStrategyAccumulativeComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModWorkshopAssessmentStrategyAccumulativeHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModWorkshopAssessmentStrategyAccumulativeComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModWorkshopAssessmentStrategyAccumulativeComponent
|
||||
]
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyAccumulativeModule {
|
||||
constructor(strategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
|
||||
strategyHandler: AddonModWorkshopAssessmentStrategyAccumulativeHandler) {
|
||||
strategyDelegate.registerHandler(strategyHandler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<ion-card *ngFor="let field of assessment.form.fields; let n = index">
|
||||
<ion-item text-wrap>
|
||||
<h2>{{ field.dimtitle }}</h2>
|
||||
<core-format-text [text]="field.description"></core-format-text>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="edit && field.grades">
|
||||
<ion-label [core-mark-required]="true" stacked>{{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }}</ion-label>
|
||||
<ion-select [(ngModel)]="selectedValues[n].grade">
|
||||
<ion-option *ngFor="let grade of field.grades" [value]="grade.value">{{grade.label}}</ion-option>
|
||||
</ion-select>
|
||||
<core-input-errors item-content *ngIf="fieldErrors['grade_' + n]" [errorText]="fieldErrors['grade_' + n]"></core-input-errors>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="!edit && field.grades" text-wrap>
|
||||
<h2>{{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }}</h2>
|
||||
<ng-container *ngFor="let grade of field.grades">
|
||||
<p *ngIf="grade.value === selectedValues[n].grade">{{grade.label}}</p>
|
||||
</ng-container>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="edit">
|
||||
<ion-label stacked>{{ 'addon.mod_workshop_assessment_accumulative.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</ion-label>
|
||||
<ion-textarea aria-multiline="true" [(ngModel)]="selectedValues[n].peercomment" core-auto-rows></ion-textarea>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="!edit" text-wrap>
|
||||
<h2>{{ 'addon.mod_workshop_assessment_accumulative.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</h2>
|
||||
<p><core-format-text [text]="selectedValues[n].peercomment"></core-format-text></p>
|
||||
</ion-item>
|
||||
</ion-card>
|
|
@ -0,0 +1,30 @@
|
|||
// (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, Input } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component for accumulative assessment strategy.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-workshop-assessment-strategy-accumulative',
|
||||
templateUrl: 'accumulative.html',
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyAccumulativeComponent {
|
||||
@Input() workshopId: number;
|
||||
@Input() assessment: any;
|
||||
@Input() edit: boolean;
|
||||
@Input() selectedValues: any[];
|
||||
@Input() fieldErrors: any;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"dimensioncommentfor": "Comment for {{$a}}",
|
||||
"dimensiongradefor": "Grade for {{$a}}",
|
||||
"dimensionnumber": "Aspect {{$a}}",
|
||||
"mustchoosegrade": "You have to select a grade for this aspect"
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
// (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 { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
|
||||
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
|
||||
import { AddonModWorkshopAssessmentStrategyAccumulativeComponent } from '../component/accumulative';
|
||||
|
||||
/**
|
||||
* Handler for accumulative assessment strategy plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModWorkshopAssessmentStrategyAccumulativeHandler implements AddonWorkshopAssessmentStrategyHandler {
|
||||
name = 'AddonModWorkshopAssessmentStrategyAccumulative';
|
||||
strategyName = 'accumulative';
|
||||
|
||||
constructor(private translate: TranslateService, private gradesHelper: CoreGradesHelperProvider) {}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component to render the plugin.
|
||||
*
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(): any {
|
||||
return AddonModWorkshopAssessmentStrategyAccumulativeComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare original values to be shown and compared.
|
||||
*
|
||||
* @param {any} form Original data of the form.
|
||||
* @param {number} workshopId WorkShop Id
|
||||
* @return {Promise<any[]>} Promise resolved with original values sorted.
|
||||
*/
|
||||
getOriginalValues(form: any, workshopId: number): Promise<any[]> {
|
||||
const defaultGrade = this.translate.instant('core.choosedots'),
|
||||
originalValues = [],
|
||||
promises = [];
|
||||
|
||||
form.fields.forEach((field, n) => {
|
||||
field.dimtitle = this.translate.instant(
|
||||
'addon.mod_workshop_assessment_accumulative.dimensionnumber', {$a: field.number});
|
||||
|
||||
const scale = parseInt(field.grade, 10) < 0 ? form.dimensionsinfo[n].scale : null;
|
||||
|
||||
if (!form.current[n]) {
|
||||
form.current[n] = {};
|
||||
}
|
||||
|
||||
originalValues[n] = {
|
||||
peercomment: form.current[n].peercomment || '',
|
||||
number: field.number
|
||||
};
|
||||
|
||||
form.current[n].grade = form.current[n].grade ? parseInt(form.current[n].grade, 10) : -1;
|
||||
|
||||
promises.push(this.gradesHelper.makeGradesMenu(field.grade, workshopId, defaultGrade, -1, scale).then((grades) => {
|
||||
field.grades = grades;
|
||||
originalValues[n].grade = form.current[n].grade;
|
||||
}));
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return originalValues;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the assessment data has changed for a certain submission and workshop for a this strategy plugin.
|
||||
*
|
||||
* @param {any[]} originalValues Original values of the form.
|
||||
* @param {any[]} currentValues Current values of the form.
|
||||
* @return {boolean} True if data has changed, false otherwise.
|
||||
*/
|
||||
hasDataChanged(originalValues: any[], currentValues: any[]): boolean {
|
||||
for (const x in originalValues) {
|
||||
if (originalValues[x].grade != currentValues[x].grade) {
|
||||
return true;
|
||||
}
|
||||
if (originalValues[x].peercomment != currentValues[x].peercomment) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare assessment data to be sent to the server depending on the strategy selected.
|
||||
*
|
||||
* @param {any{}} currentValues Current values of the form.
|
||||
* @param {any} form Assessment form data.
|
||||
* @return {Promise<any>} Promise resolved with the data to be sent. Or rejected with the input errors object.
|
||||
*/
|
||||
prepareAssessmentData(currentValues: any[], form: any): Promise<any> {
|
||||
const data = {};
|
||||
const errors = {};
|
||||
let hasErrors = false;
|
||||
|
||||
form.fields.forEach((field, idx) => {
|
||||
const grade = parseInt(currentValues[idx].grade, 10);
|
||||
if (!isNaN(grade) && grade >= 0) {
|
||||
data['grade__idx_' + idx] = grade;
|
||||
} else {
|
||||
errors['grade_' + idx] = this.translate.instant('addon.mod_workshop_assessment_accumulative.mustchoosegrade');
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
if (currentValues[idx].peercomment) {
|
||||
data['peercomment__idx_' + idx] = currentValues[idx].peercomment;
|
||||
}
|
||||
|
||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
||||
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
|
||||
});
|
||||
|
||||
if (hasErrors) {
|
||||
return Promise.reject(errors);
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// (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 { AddonModWorkshopAssessmentStrategyAccumulativeModule } from './accumulative/accumulative.module';
|
||||
import { AddonModWorkshopAssessmentStrategyCommentsModule } from './comments/comments.module';
|
||||
import { AddonModWorkshopAssessmentStrategyNumErrorsModule } from './numerrors/numerrors.module';
|
||||
import { AddonModWorkshopAssessmentStrategyRubricModule } from './rubric/rubric.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
AddonModWorkshopAssessmentStrategyAccumulativeModule,
|
||||
AddonModWorkshopAssessmentStrategyCommentsModule,
|
||||
AddonModWorkshopAssessmentStrategyNumErrorsModule,
|
||||
AddonModWorkshopAssessmentStrategyRubricModule,
|
||||
]
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyModule {}
|
|
@ -0,0 +1,51 @@
|
|||
// (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 { AddonModWorkshopAssessmentStrategyCommentsComponent } from './component/comments';
|
||||
import { AddonModWorkshopAssessmentStrategyCommentsHandler } from './providers/handler';
|
||||
import { AddonWorkshopAssessmentStrategyDelegate } from '../../providers/assessment-strategy-delegate';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModWorkshopAssessmentStrategyCommentsComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModWorkshopAssessmentStrategyCommentsHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModWorkshopAssessmentStrategyCommentsComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModWorkshopAssessmentStrategyCommentsComponent
|
||||
]
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyCommentsModule {
|
||||
constructor(strategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
|
||||
strategyHandler: AddonModWorkshopAssessmentStrategyCommentsHandler) {
|
||||
strategyDelegate.registerHandler(strategyHandler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<ion-card *ngFor="let field of assessment.form.fields; let n = index">
|
||||
<ion-item text-wrap>
|
||||
<h2>{{ field.dimtitle }}</h2>
|
||||
<core-format-text [text]="field.description"></core-format-text>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="edit">
|
||||
<ion-label stacked [core-mark-required]="true">{{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</ion-label>
|
||||
<ion-textarea aria-multiline="true" [(ngModel)]="selectedValues[n].peercomment" core-auto-rows></ion-textarea>
|
||||
<core-input-errors item-content *ngIf="fieldErrors['peercomment_' + n]" [errorText]="fieldErrors['peercomment_' + n]"></core-input-errors>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="!edit" text-wrap>
|
||||
<h2>{{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</h2>
|
||||
<p><core-format-text [text]="selectedValues[n].peercomment"></core-format-text></p>
|
||||
</ion-item>
|
||||
</ion-card>
|
|
@ -0,0 +1,30 @@
|
|||
// (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, Input } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component for comments assessment strategy.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-workshop-assessment-strategy-comments',
|
||||
templateUrl: 'comments.html',
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyCommentsComponent {
|
||||
@Input() workshopId: number;
|
||||
@Input() assessment: any;
|
||||
@Input() edit: boolean;
|
||||
@Input() selectedValues: any[];
|
||||
@Input() fieldErrors: any;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"dimensioncommentfor": "Comment for {{$a}}",
|
||||
"dimensionnumber": "Aspect {{$a}}"
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
|
||||
import { AddonModWorkshopAssessmentStrategyCommentsComponent } from '../component/comments';
|
||||
|
||||
/**
|
||||
* Handler for comments assessment strategy plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModWorkshopAssessmentStrategyCommentsHandler implements AddonWorkshopAssessmentStrategyHandler {
|
||||
name = 'AddonModWorkshopAssessmentStrategyComments';
|
||||
strategyName = 'comments';
|
||||
|
||||
constructor(private translate: TranslateService) {}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component to render the plugin.
|
||||
*
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(): any {
|
||||
return AddonModWorkshopAssessmentStrategyCommentsComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare original values to be shown and compared.
|
||||
*
|
||||
* @param {any} form Original data of the form.
|
||||
* @param {number} workshopId Workshop Id
|
||||
* @return {Promise<any[]>} Promise resolved with original values sorted.
|
||||
*/
|
||||
getOriginalValues(form: any, workshopId: number): Promise<any[]> {
|
||||
const originalValues = [];
|
||||
|
||||
form.fields.forEach((field, n) => {
|
||||
field.dimtitle = this.translate.instant('addon.mod_workshop_assessment_comments.dimensionnumber', {$a: field.number});
|
||||
|
||||
if (!form.current[n]) {
|
||||
form.current[n] = {};
|
||||
}
|
||||
|
||||
originalValues[n] = {
|
||||
peercomment: form.current[n].peercomment || '',
|
||||
number: field.number
|
||||
};
|
||||
});
|
||||
|
||||
return Promise.resolve(originalValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the assessment data has changed for a certain submission and workshop for a this strategy plugin.
|
||||
*
|
||||
* @param {any[]} originalValues Original values of the form.
|
||||
* @param {any[]} currentValues Current values of the form.
|
||||
* @return {boolean} True if data has changed, false otherwise.
|
||||
*/
|
||||
hasDataChanged(originalValues: any[], currentValues: any[]): boolean {
|
||||
for (const x in originalValues) {
|
||||
if (originalValues[x].peercomment != currentValues[x].peercomment) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare assessment data to be sent to the server depending on the strategy selected.
|
||||
*
|
||||
* @param {any{}} currentValues Current values of the form.
|
||||
* @param {any} form Assessment form data.
|
||||
* @return {Promise<any>} Promise resolved with the data to be sent. Or rejected with the input errors object.
|
||||
*/
|
||||
prepareAssessmentData(currentValues: any[], form: any): Promise<any> {
|
||||
const data = {};
|
||||
const errors = {};
|
||||
let hasErrors = false;
|
||||
|
||||
form.fields.forEach((field, idx) => {
|
||||
if (currentValues[idx].peercomment) {
|
||||
data['peercomment__idx_' + idx] = currentValues[idx].peercomment;
|
||||
} else {
|
||||
errors['peercomment_' + idx] = this.translate.instant('core.err_required');
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
||||
});
|
||||
|
||||
if (hasErrors) {
|
||||
return Promise.reject(errors);
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<ion-card *ngFor="let field of assessment.form.fields; let n = index">
|
||||
<ion-item text-wrap>
|
||||
<h2>{{ field.dimtitle }}</h2>
|
||||
<core-format-text [text]="field.description"></core-format-text>
|
||||
</ion-item>
|
||||
<ion-list radio-group [(ngModel)]="selectedValues[n].grade" [name]="'grade_' + n">
|
||||
<ion-item>
|
||||
<ion-label stacked [core-mark-required]="edit">{{ 'addon.mod_workshop.yourassessmentfor' | translate : {'$a': field.dimtitle } }}</ion-label>
|
||||
<core-input-errors item-content *ngIf="edit && fieldErrors['grade_' + n]" [errorText]="fieldErrors['grade_' + n]"></core-input-errors>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label><core-format-text [text]="field.grade0"></core-format-text></ion-label>
|
||||
<ion-radio [value]="-1" [disabled]="!edit"></ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label><core-format-text [text]="field.grade1"></core-format-text></ion-label>
|
||||
<ion-radio [value]="1" [disabled]="!edit"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-item *ngIf="edit">
|
||||
<ion-label stacked>{{ 'addon.mod_workshop_assessment_numerrors.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</ion-label>
|
||||
<ion-textarea aria-multiline="true" [(ngModel)]="selectedValues[n].peercomment" [name]="'peercomment_' + n" core-auto-rows></ion-textarea>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="!edit" text-wrap>
|
||||
<h2>{{ 'addon.mod_workshop_assessment_numerrors.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</h2>
|
||||
<p><core-format-text [text]="selectedValues[n].peercomment"></core-format-text></p>
|
||||
</ion-item>
|
||||
</ion-card>
|
|
@ -0,0 +1,30 @@
|
|||
// (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, Input } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component for numerrors assessment strategy.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-workshop-assessment-strategy-numerrors',
|
||||
templateUrl: 'numerrors.html',
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyNumErrorsComponent {
|
||||
@Input() workshopId: number;
|
||||
@Input() assessment: any;
|
||||
@Input() edit: boolean;
|
||||
@Input() selectedValues: any[];
|
||||
@Input() fieldErrors: any;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dimensioncommentfor": "Comment for {{$a}}",
|
||||
"dimensiongradefor": "Grade for {{$a}}",
|
||||
"dimensionnumber": "Assertion {{$a}}"
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (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 { AddonModWorkshopAssessmentStrategyNumErrorsComponent } from './component/numerrors';
|
||||
import { AddonModWorkshopAssessmentStrategyNumErrorsHandler } from './providers/handler';
|
||||
import { AddonWorkshopAssessmentStrategyDelegate } from '../../providers/assessment-strategy-delegate';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModWorkshopAssessmentStrategyNumErrorsComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModWorkshopAssessmentStrategyNumErrorsHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModWorkshopAssessmentStrategyNumErrorsComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModWorkshopAssessmentStrategyNumErrorsComponent
|
||||
]
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyNumErrorsModule {
|
||||
constructor(strategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
|
||||
strategyHandler: AddonModWorkshopAssessmentStrategyNumErrorsHandler) {
|
||||
strategyDelegate.registerHandler(strategyHandler);
|
||||
}
|
||||
}
|
|
@ -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 { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
|
||||
import { AddonModWorkshopAssessmentStrategyNumErrorsComponent } from '../component/numerrors';
|
||||
|
||||
/**
|
||||
* Handler for numerrors assessment strategy plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModWorkshopAssessmentStrategyNumErrorsHandler implements AddonWorkshopAssessmentStrategyHandler {
|
||||
name = 'AddonModWorkshopAssessmentStrategyNumErrors';
|
||||
strategyName = 'numerrors';
|
||||
|
||||
constructor(private translate: TranslateService) {}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component to render the plugin.
|
||||
*
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(): any {
|
||||
return AddonModWorkshopAssessmentStrategyNumErrorsComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare original values to be shown and compared.
|
||||
*
|
||||
* @param {any} form Original data of the form.
|
||||
* @param {number} workshopId Workshop Id
|
||||
* @return {Promise<any[]>} Promise resolved with original values sorted.
|
||||
*/
|
||||
getOriginalValues(form: any, workshopId: number): Promise<any[]> {
|
||||
const originalValues = [];
|
||||
|
||||
form.fields.forEach((field, n) => {
|
||||
field.dimtitle = this.translate.instant('addon.mod_workshop_assessment_numerrors.dimensionnumber', {$a: field.number});
|
||||
|
||||
if (!form.current[n]) {
|
||||
form.current[n] = {};
|
||||
}
|
||||
|
||||
originalValues[n] = {
|
||||
peercomment: form.current[n].peercomment || '',
|
||||
number: field.number,
|
||||
grade: form.current[n].grade || ''
|
||||
};
|
||||
});
|
||||
|
||||
return Promise.resolve(originalValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the assessment data has changed for a certain submission and workshop for a this strategy plugin.
|
||||
*
|
||||
* @param {any[]} originalValues Original values of the form.
|
||||
* @param {any[]} currentValues Current values of the form.
|
||||
* @return {boolean} True if data has changed, false otherwise.
|
||||
*/
|
||||
hasDataChanged(originalValues: any[], currentValues: any[]): boolean {
|
||||
for (const x in originalValues) {
|
||||
if (originalValues[x].grade != currentValues[x].grade) {
|
||||
return true;
|
||||
}
|
||||
if (originalValues[x].peercomment != currentValues[x].peercomment) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare assessment data to be sent to the server depending on the strategy selected.
|
||||
*
|
||||
* @param {any{}} currentValues Current values of the form.
|
||||
* @param {any} form Assessment form data.
|
||||
* @return {Promise<any>} Promise resolved with the data to be sent. Or rejected with the input errors object.
|
||||
*/
|
||||
prepareAssessmentData(currentValues: any[], form: any): Promise<any> {
|
||||
const data = {};
|
||||
const errors = {};
|
||||
let hasErrors = false;
|
||||
|
||||
form.fields.forEach((field, idx) => {
|
||||
const grade = parseInt(currentValues[idx].grade);
|
||||
if (!isNaN(grade) && grade >= 0) {
|
||||
data['grade__idx_' + idx] = grade;
|
||||
} else {
|
||||
errors['grade_' + idx] = this.translate.instant('core.required');
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
if (currentValues[idx].peercomment) {
|
||||
data['peercomment__idx_' + idx] = currentValues[idx].peercomment;
|
||||
}
|
||||
|
||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
||||
data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
|
||||
});
|
||||
|
||||
if (hasErrors) {
|
||||
return Promise.reject(errors);
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<ion-card *ngFor="let field of assessment.form.fields; let n = index">
|
||||
<ion-item text-wrap>
|
||||
<h2 [core-mark-required]="edit">{{ field.dimtitle }}</h2>
|
||||
<core-format-text [text]="field.description"></core-format-text>
|
||||
<core-input-errors *ngIf="edit && fieldErrors['chosenlevelid_' + n]" [errorText]="fieldErrors['chosenlevelid_' + n]"></core-input-errors>
|
||||
</ion-item>
|
||||
<ion-list radio-group [(ngModel)]="selectedValues[n].chosenlevelid" [name]="'chosenlevelid_' + n">
|
||||
<ion-item *ngFor="let subfield of field.fields">
|
||||
<ion-label><p><core-format-text [text]="subfield.definition"></core-format-text></p></ion-label>
|
||||
<ion-radio [value]="subfield.levelid" [disabled]="!edit"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-card>
|
|
@ -0,0 +1,30 @@
|
|||
// (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, Input } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component for rubric assessment strategy.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-workshop-assessment-strategy-rubric',
|
||||
templateUrl: 'rubric.html',
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyRubricComponent {
|
||||
@Input() workshopId: number;
|
||||
@Input() assessment: any;
|
||||
@Input() edit: boolean;
|
||||
@Input() selectedValues: any[];
|
||||
@Input() fieldErrors: any;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"dimensionnumber": "Criterion {{$a}}",
|
||||
"mustchooseone": "You have to select one of these items"
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
// (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 { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
|
||||
import { AddonModWorkshopAssessmentStrategyRubricComponent } from '../component/rubric';
|
||||
|
||||
/**
|
||||
* Handler for rubric assessment strategy plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModWorkshopAssessmentStrategyRubricHandler implements AddonWorkshopAssessmentStrategyHandler {
|
||||
name = 'AddonModWorkshopAssessmentStrategyRubric';
|
||||
strategyName = 'rubric';
|
||||
|
||||
constructor(private translate: TranslateService) {}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component to render the plugin.
|
||||
*
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(): any {
|
||||
return AddonModWorkshopAssessmentStrategyRubricComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare original values to be shown and compared.
|
||||
*
|
||||
* @param {any} form Original data of the form.
|
||||
* @param {number} workshopId Workshop Id
|
||||
* @return {Promise<any[]>} Promise resolved with original values sorted.
|
||||
*/
|
||||
getOriginalValues(form: any, workshopId: number): Promise<any[]> {
|
||||
const originalValues = [];
|
||||
|
||||
form.fields.forEach((field, n) => {
|
||||
field.dimtitle = this.translate.instant('addon.mod_workshop_assessment_rubric.dimensionnumber', {$a: field.number});
|
||||
|
||||
if (!form.current[n]) {
|
||||
form.current[n] = {};
|
||||
}
|
||||
|
||||
originalValues[n] = {
|
||||
chosenlevelid: form.current[n].chosenlevelid || '',
|
||||
number: field.number
|
||||
};
|
||||
});
|
||||
|
||||
return Promise.resolve(originalValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the assessment data has changed for a certain submission and workshop for a this strategy plugin.
|
||||
*
|
||||
* @param {any[]} originalValues Original values of the form.
|
||||
* @param {any[]} currentValues Current values of the form.
|
||||
* @return {boolean} True if data has changed, false otherwise.
|
||||
*/
|
||||
hasDataChanged(originalValues: any[], currentValues: any[]): boolean {
|
||||
for (const x in originalValues) {
|
||||
if (originalValues[x].chosenlevelid != (currentValues[x].chosenlevelid || '')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare assessment data to be sent to the server depending on the strategy selected.
|
||||
*
|
||||
* @param {any{}} currentValues Current values of the form.
|
||||
* @param {any} form Assessment form data.
|
||||
* @return {Promise<any>} Promise resolved with the data to be sent. Or rejected with the input errors object.
|
||||
*/
|
||||
prepareAssessmentData(currentValues: any[], form: any): Promise<any> {
|
||||
const data = {};
|
||||
const errors = {};
|
||||
let hasErrors = false;
|
||||
|
||||
form.fields.forEach((field, idx) => {
|
||||
const id = parseInt(currentValues[idx].chosenlevelid, 10);
|
||||
if (!isNaN(id) && id >= 0) {
|
||||
data['chosenlevelid__idx_' + idx] = id;
|
||||
} else {
|
||||
errors['chosenlevelid_' + idx] = this.translate.instant('addon.mod_workshop_assessment_rubric.mustchooseone');
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
|
||||
data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
|
||||
});
|
||||
|
||||
if (hasErrors) {
|
||||
return Promise.reject(errors);
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (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 { AddonModWorkshopAssessmentStrategyRubricComponent } from './component/rubric';
|
||||
import { AddonModWorkshopAssessmentStrategyRubricHandler } from './providers/handler';
|
||||
import { AddonWorkshopAssessmentStrategyDelegate } from '../../providers/assessment-strategy-delegate';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModWorkshopAssessmentStrategyRubricComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModWorkshopAssessmentStrategyRubricHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModWorkshopAssessmentStrategyRubricComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModWorkshopAssessmentStrategyRubricComponent
|
||||
]
|
||||
})
|
||||
export class AddonModWorkshopAssessmentStrategyRubricModule {
|
||||
constructor(strategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
|
||||
strategyHandler: AddonModWorkshopAssessmentStrategyRubricHandler) {
|
||||
strategyDelegate.registerHandler(strategyHandler);
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ import { CoreCronDelegate } from '@providers/cron';
|
|||
import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate';
|
||||
import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
|
||||
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
|
||||
import { AddonModWorkshopAssessmentStrategyModule } from './assessment/assessment.module';
|
||||
import { AddonModWorkshopComponentsModule } from './components/components.module';
|
||||
import { AddonModWorkshopModuleHandler } from './providers/module-handler';
|
||||
import { AddonModWorkshopProvider } from './providers/workshop';
|
||||
|
@ -32,7 +33,8 @@ import { AddonModWorkshopSyncCronHandler } from './providers/sync-cron-handler';
|
|||
declarations: [
|
||||
],
|
||||
imports: [
|
||||
AddonModWorkshopComponentsModule
|
||||
AddonModWorkshopComponentsModule,
|
||||
AddonModWorkshopAssessmentStrategyModule
|
||||
],
|
||||
providers: [
|
||||
AddonModWorkshopProvider,
|
||||
|
|
Loading…
Reference in New Issue