diff --git a/src/addon/mod/workshop/assessment/accumulative/accumulative.module.ts b/src/addon/mod/workshop/assessment/accumulative/accumulative.module.ts new file mode 100644 index 000000000..f20ce1fec --- /dev/null +++ b/src/addon/mod/workshop/assessment/accumulative/accumulative.module.ts @@ -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); + } +} diff --git a/src/addon/mod/workshop/assessment/accumulative/component/accumulative.html b/src/addon/mod/workshop/assessment/accumulative/component/accumulative.html new file mode 100644 index 000000000..a65046ab6 --- /dev/null +++ b/src/addon/mod/workshop/assessment/accumulative/component/accumulative.html @@ -0,0 +1,27 @@ + + +

{{ field.dimtitle }}

+ +
+ + {{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }} + + {{grade.label}} + + + + +

{{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }}

+ +

{{grade.label}}

+
+
+ + {{ 'addon.mod_workshop_assessment_accumulative.dimensioncommentfor' | translate : {'$a': field.dimtitle } }} + + + +

{{ 'addon.mod_workshop_assessment_accumulative.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}

+

+
+
diff --git a/src/addon/mod/workshop/assessment/accumulative/component/accumulative.ts b/src/addon/mod/workshop/assessment/accumulative/component/accumulative.ts new file mode 100644 index 000000000..962c20068 --- /dev/null +++ b/src/addon/mod/workshop/assessment/accumulative/component/accumulative.ts @@ -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; +} diff --git a/src/addon/mod/workshop/assessment/accumulative/lang/en.json b/src/addon/mod/workshop/assessment/accumulative/lang/en.json new file mode 100644 index 000000000..72c26cfa8 --- /dev/null +++ b/src/addon/mod/workshop/assessment/accumulative/lang/en.json @@ -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" +} diff --git a/src/addon/mod/workshop/assessment/accumulative/providers/handler.ts b/src/addon/mod/workshop/assessment/accumulative/providers/handler.ts new file mode 100644 index 000000000..e0d4496f2 --- /dev/null +++ b/src/addon/mod/workshop/assessment/accumulative/providers/handler.ts @@ -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} Whether or not the handler is enabled on a site level. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * Returns the component to render the plugin. + * + * @return {any|Promise} 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} Promise resolved with original values sorted. + */ + getOriginalValues(form: any, workshopId: number): Promise { + 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} Promise resolved with the data to be sent. Or rejected with the input errors object. + */ + prepareAssessmentData(currentValues: any[], form: any): Promise { + 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); + } +} diff --git a/src/addon/mod/workshop/assessment/assessment.module.ts b/src/addon/mod/workshop/assessment/assessment.module.ts new file mode 100644 index 000000000..3a77823ad --- /dev/null +++ b/src/addon/mod/workshop/assessment/assessment.module.ts @@ -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 {} diff --git a/src/addon/mod/workshop/assessment/comments/comments.module.ts b/src/addon/mod/workshop/assessment/comments/comments.module.ts new file mode 100644 index 000000000..c8f91b558 --- /dev/null +++ b/src/addon/mod/workshop/assessment/comments/comments.module.ts @@ -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); + } +} diff --git a/src/addon/mod/workshop/assessment/comments/component/comments.html b/src/addon/mod/workshop/assessment/comments/component/comments.html new file mode 100644 index 000000000..e161192d8 --- /dev/null +++ b/src/addon/mod/workshop/assessment/comments/component/comments.html @@ -0,0 +1,15 @@ + + +

{{ field.dimtitle }}

+ +
+ + {{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }} + + + + +

{{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}

+

+
+
diff --git a/src/addon/mod/workshop/assessment/comments/component/comments.ts b/src/addon/mod/workshop/assessment/comments/component/comments.ts new file mode 100644 index 000000000..ef464cd8e --- /dev/null +++ b/src/addon/mod/workshop/assessment/comments/component/comments.ts @@ -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; +} diff --git a/src/addon/mod/workshop/assessment/comments/lang/en.json b/src/addon/mod/workshop/assessment/comments/lang/en.json new file mode 100644 index 000000000..6db857323 --- /dev/null +++ b/src/addon/mod/workshop/assessment/comments/lang/en.json @@ -0,0 +1,4 @@ +{ + "dimensioncommentfor": "Comment for {{$a}}", + "dimensionnumber": "Aspect {{$a}}" +} diff --git a/src/addon/mod/workshop/assessment/comments/providers/handler.ts b/src/addon/mod/workshop/assessment/comments/providers/handler.ts new file mode 100644 index 000000000..ad0c525d4 --- /dev/null +++ b/src/addon/mod/workshop/assessment/comments/providers/handler.ts @@ -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} Whether or not the handler is enabled on a site level. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * Returns the component to render the plugin. + * + * @return {any|Promise} 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} Promise resolved with original values sorted. + */ + getOriginalValues(form: any, workshopId: number): Promise { + 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} Promise resolved with the data to be sent. Or rejected with the input errors object. + */ + prepareAssessmentData(currentValues: any[], form: any): Promise { + 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); + } +} diff --git a/src/addon/mod/workshop/assessment/numerrors/component/numerrors.html b/src/addon/mod/workshop/assessment/numerrors/component/numerrors.html new file mode 100644 index 000000000..f98777c83 --- /dev/null +++ b/src/addon/mod/workshop/assessment/numerrors/component/numerrors.html @@ -0,0 +1,28 @@ + + +

{{ field.dimtitle }}

+ +
+ + + {{ 'addon.mod_workshop.yourassessmentfor' | translate : {'$a': field.dimtitle } }} + + + + + + + + + + + + + {{ 'addon.mod_workshop_assessment_numerrors.dimensioncommentfor' | translate : {'$a': field.dimtitle } }} + + + +

{{ 'addon.mod_workshop_assessment_numerrors.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}

+

+
+
diff --git a/src/addon/mod/workshop/assessment/numerrors/component/numerrors.ts b/src/addon/mod/workshop/assessment/numerrors/component/numerrors.ts new file mode 100644 index 000000000..37cc36e72 --- /dev/null +++ b/src/addon/mod/workshop/assessment/numerrors/component/numerrors.ts @@ -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; +} diff --git a/src/addon/mod/workshop/assessment/numerrors/lang/en.json b/src/addon/mod/workshop/assessment/numerrors/lang/en.json new file mode 100644 index 000000000..d12b03206 --- /dev/null +++ b/src/addon/mod/workshop/assessment/numerrors/lang/en.json @@ -0,0 +1,5 @@ +{ + "dimensioncommentfor": "Comment for {{$a}}", + "dimensiongradefor": "Grade for {{$a}}", + "dimensionnumber": "Assertion {{$a}}" +} diff --git a/src/addon/mod/workshop/assessment/numerrors/numerrors.module.ts b/src/addon/mod/workshop/assessment/numerrors/numerrors.module.ts new file mode 100644 index 000000000..d066236cb --- /dev/null +++ b/src/addon/mod/workshop/assessment/numerrors/numerrors.module.ts @@ -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); + } +} diff --git a/src/addon/mod/workshop/assessment/numerrors/providers/handler.ts b/src/addon/mod/workshop/assessment/numerrors/providers/handler.ts new file mode 100644 index 000000000..3f3630c65 --- /dev/null +++ b/src/addon/mod/workshop/assessment/numerrors/providers/handler.ts @@ -0,0 +1,130 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { 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} Whether or not the handler is enabled on a site level. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * Returns the component to render the plugin. + * + * @return {any|Promise} 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} Promise resolved with original values sorted. + */ + getOriginalValues(form: any, workshopId: number): Promise { + 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} Promise resolved with the data to be sent. Or rejected with the input errors object. + */ + prepareAssessmentData(currentValues: any[], form: any): Promise { + 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); + } +} diff --git a/src/addon/mod/workshop/assessment/rubric/component/rubric.html b/src/addon/mod/workshop/assessment/rubric/component/rubric.html new file mode 100644 index 000000000..ad4a76917 --- /dev/null +++ b/src/addon/mod/workshop/assessment/rubric/component/rubric.html @@ -0,0 +1,13 @@ + + +

{{ field.dimtitle }}

+ + +
+ + +

+ +
+
+
diff --git a/src/addon/mod/workshop/assessment/rubric/component/rubric.ts b/src/addon/mod/workshop/assessment/rubric/component/rubric.ts new file mode 100644 index 000000000..4c946500e --- /dev/null +++ b/src/addon/mod/workshop/assessment/rubric/component/rubric.ts @@ -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; +} diff --git a/src/addon/mod/workshop/assessment/rubric/lang/en.json b/src/addon/mod/workshop/assessment/rubric/lang/en.json new file mode 100644 index 000000000..8b0b20c4a --- /dev/null +++ b/src/addon/mod/workshop/assessment/rubric/lang/en.json @@ -0,0 +1,4 @@ +{ + "dimensionnumber": "Criterion {{$a}}", + "mustchooseone": "You have to select one of these items" +} \ No newline at end of file diff --git a/src/addon/mod/workshop/assessment/rubric/providers/handler.ts b/src/addon/mod/workshop/assessment/rubric/providers/handler.ts new file mode 100644 index 000000000..a0cfc563a --- /dev/null +++ b/src/addon/mod/workshop/assessment/rubric/providers/handler.ts @@ -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} Whether or not the handler is enabled on a site level. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * Returns the component to render the plugin. + * + * @return {any|Promise} 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} Promise resolved with original values sorted. + */ + getOriginalValues(form: any, workshopId: number): Promise { + 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} Promise resolved with the data to be sent. Or rejected with the input errors object. + */ + prepareAssessmentData(currentValues: any[], form: any): Promise { + 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); + } +} diff --git a/src/addon/mod/workshop/assessment/rubric/rubric.module.ts b/src/addon/mod/workshop/assessment/rubric/rubric.module.ts new file mode 100644 index 000000000..2b5392f31 --- /dev/null +++ b/src/addon/mod/workshop/assessment/rubric/rubric.module.ts @@ -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); + } +} diff --git a/src/addon/mod/workshop/workshop.module.ts b/src/addon/mod/workshop/workshop.module.ts index 2c1c864e9..b2ab8c4d8 100644 --- a/src/addon/mod/workshop/workshop.module.ts +++ b/src/addon/mod/workshop/workshop.module.ts @@ -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,