MOBILE-2354 workshop: Support assessment plugins in site plugins

main
Dani Palou 2018-06-13 14:46:59 +02:00 committed by Albert Gasset
parent 27c57b01b0
commit 29df582cee
16 changed files with 248 additions and 58 deletions

View File

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { AddonModWorkshopAssessmentStrategyComponentBase } from '../../../classes/assessment-strategy-component';
/**
* Component for accumulative assessment strategy.
@ -21,10 +22,5 @@ import { Component, Input } from '@angular/core';
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;
export class AddonModWorkshopAssessmentStrategyAccumulativeComponent extends AddonModWorkshopAssessmentStrategyComponentBase {
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
@ -37,11 +37,13 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandler implements Ad
}
/**
* Returns the component to render the plugin.
* Return the Component to render the plugin.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): any {
getComponent(injector: Injector): any | Promise<any> {
return AddonModWorkshopAssessmentStrategyAccumulativeComponent;
}

View File

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { AddonModWorkshopAssessmentStrategyComponentBase } from '../../../classes/assessment-strategy-component';
/**
* Component for comments assessment strategy.
@ -21,10 +22,5 @@ import { Component, Input } from '@angular/core';
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;
export class AddonModWorkshopAssessmentStrategyCommentsComponent extends AddonModWorkshopAssessmentStrategyComponentBase {
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
import { AddonModWorkshopAssessmentStrategyCommentsComponent } from '../component/comments';
@ -36,11 +36,13 @@ export class AddonModWorkshopAssessmentStrategyCommentsHandler implements AddonW
}
/**
* Returns the component to render the plugin.
* Return the Component to render the plugin.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): any {
getComponent(injector: Injector): any | Promise<any> {
return AddonModWorkshopAssessmentStrategyCommentsComponent;
}

View File

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { AddonModWorkshopAssessmentStrategyComponentBase } from '../../../classes/assessment-strategy-component';
/**
* Component for numerrors assessment strategy.
@ -21,10 +22,5 @@ import { Component, Input } from '@angular/core';
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;
export class AddonModWorkshopAssessmentStrategyNumErrorsComponent extends AddonModWorkshopAssessmentStrategyComponentBase {
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
import { AddonModWorkshopAssessmentStrategyNumErrorsComponent } from '../component/numerrors';
@ -36,11 +36,13 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandler implements Addon
}
/**
* Returns the component to render the plugin.
* Return the Component to render the plugin.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): any {
getComponent(injector: Injector): any | Promise<any> {
return AddonModWorkshopAssessmentStrategyNumErrorsComponent;
}

View File

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { AddonModWorkshopAssessmentStrategyComponentBase } from '../../../classes/assessment-strategy-component';
/**
* Component for rubric assessment strategy.
@ -21,10 +22,5 @@ import { Component, Input } from '@angular/core';
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;
export class AddonModWorkshopAssessmentStrategyRubricComponent extends AddonModWorkshopAssessmentStrategyComponentBase {
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { AddonWorkshopAssessmentStrategyHandler } from '../../../providers/assessment-strategy-delegate';
import { AddonModWorkshopAssessmentStrategyRubricComponent } from '../component/rubric';
@ -36,11 +36,13 @@ export class AddonModWorkshopAssessmentStrategyRubricHandler implements AddonWor
}
/**
* Returns the component to render the plugin.
* Return the Component to render the plugin.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(): any {
getComponent(injector: Injector): any | Promise<any> {
return AddonModWorkshopAssessmentStrategyRubricComponent;
}

View File

@ -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 { Input } from '@angular/core';
/**
* Base class for component to render an assessment strategy.
*/
export class AddonModWorkshopAssessmentStrategyComponentBase {
@Input() workshopId: number;
@Input() assessment: any;
@Input() edit: boolean;
@Input() selectedValues: any[];
@Input() fieldErrors: any;
@Input() strategy: string;
constructor() {
// Nothing to do.
}
}

View File

@ -16,9 +16,7 @@
</ion-item>
<ion-item stacked *ngIf="edit">
<ion-label stacked [core-mark-required]="overallFeedkbackRequired">{{ 'addon.mod_workshop.feedbackauthor' | translate }}</ion-label>
<core-rich-text-editor item-content [control]="feedbackControl" (contentChanged)="onFeedbackChange($event)"></core-rich-text-editor>
<!-- @todo: Attributes that were passed to RTE in Ionic 1 but now they aren't supported yet:
[component]="component" [componentId]="workshop.coursemodule" -->
<core-rich-text-editor item-content [control]="feedbackControl" [component]="component" [componentId]="workshop.coursemodule" (contentChanged)="onFeedbackChange($event)"></core-rich-text-editor>
<core-input-errors item-content *ngIf="overallFeedkbackRequired && fieldErrors['feedbackauthor']" [errorText]="fieldErrors['feedbackauthor']"></core-input-errors>
</ion-item>
<core-attachments *ngIf="edit && workshop.overallfeedbackfiles" [files]="data.assessment.feedbackattachmentfiles" [maxSize]="workshop.overallfeedbackmaxbytes"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, Injector } from '@angular/core';
import { FormControl } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { CoreSyncProvider } from '@providers/sync';
@ -51,6 +51,7 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit {
edit: false,
selectedValues: [],
fieldErrors: {},
strategy: ''
};
assessmentStrategyLoaded = false;
notSupported = false;
@ -74,6 +75,7 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit {
};
constructor(private translate: TranslateService,
private injector: Injector,
private eventsProvider: CoreEventsProvider,
private fileSessionProvider: CoreFileSessionProvider,
private syncProvider: CoreSyncProvider,
@ -99,8 +101,9 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit {
this.data.workshopId = this.workshop.id;
this.data.edit = this.edit;
this.data.strategy = this.strategy;
this.componentClass = this.strategyDelegate.getComponentForPlugin(this.strategy);
this.componentClass = this.strategyDelegate.getComponentForPlugin(this.injector, this.strategy);
if (this.componentClass) {
this.overallFeedkback = !!this.workshop.overallfeedbackmode;
this.overallFeedkbackRequired = this.workshop.overallfeedbackmode == 2;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
import { CoreEventsProvider } from '@providers/events';
import { CoreLoggerProvider } from '@providers/logger';
@ -29,11 +29,13 @@ export interface AddonWorkshopAssessmentStrategyHandler extends CoreDelegateHand
strategyName: string;
/**
* Returns the component to render the plugin.
* Return the Component to render the plugin.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @return {any} The component to use, undefined if not found.
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent?(): any;
getComponent?(injector: Injector): any | Promise<any>;
/**
* Prepare original values to be shown and compared.
@ -87,14 +89,15 @@ export interface AddonWorkshopAssessmentStrategyHandler extends CoreDelegateHand
return this.hasHandler(workshopStrategy, true);
}
/**
* Get the directive to use for a certain assessment strategy plugin.
*
* @param {string} workshopStrategy Assessment strategy name.
* @return {any} The component, undefined if not found.
*/
getComponentForPlugin(workshopStrategy: string): Promise<any> {
return this.executeFunctionOnEnabled(workshopStrategy, 'getComponent', []);
/**
* Get the directive to use for a certain assessment strategy plugin.
*
* @param {Injector} injector Injector.
* @param {string} workshopStrategy Assessment strategy name.
* @return {any} The component, undefined if not found.
*/
getComponentForPlugin(injector: Injector, workshopStrategy: string): Promise<any> {
return this.executeFunctionOnEnabled(workshopStrategy, 'getComponent', [injector]);
}
/**

View File

@ -0,0 +1,81 @@
// (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 { Injector } from '@angular/core';
import { AddonWorkshopAssessmentStrategyHandler } from '@addon/mod/workshop/providers/assessment-strategy-delegate';
import {
CoreSitePluginsWorkshopAssessmentStrategyComponent
} from '../../components/workshop-assessment-strategy/workshop-assessment-strategy';
/**
* Handler to display a workshop assessment strategy site plugin.
*/
export class CoreSitePluginsWorkshopAssessmentStrategyHandler implements AddonWorkshopAssessmentStrategyHandler {
constructor(public name: string, public strategyName: string) { }
/**
* Return the Component to use to display the plugin data, either in read or in edit mode.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @param {any} plugin The plugin object.
* @param {boolean} [edit] Whether the user is editing.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getComponent(injector: Injector): any | Promise<any> {
return CoreSitePluginsWorkshopAssessmentStrategyComponent;
}
/**
* 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[]> {
return Promise.resolve([]);
}
/**
* 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 {
return false;
}
/**
* 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;
}
/**
* 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> {
return Promise.resolve({});
}
}

View File

@ -0,0 +1 @@
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>

View File

@ -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 { Component, OnInit, Input } from '@angular/core';
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
/**
* Component that displays a workshop assessment strategy plugin created using a site plugin.
*/
@Component({
selector: 'core-siteplugins-workshop-assessment-strategy',
templateUrl: 'core-siteplugins-workshop-assessment-strategy.html',
})
export class CoreSitePluginsWorkshopAssessmentStrategyComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
@Input() workshopId: number;
@Input() assessment: any;
@Input() edit: boolean;
@Input() selectedValues: any[];
@Input() fieldErrors: any;
@Input() strategy: string;
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
super(sitePluginsProvider);
}
/**
* Component being initialized.
*/
ngOnInit(): void {
// Pass the input and output data to the component.
this.jsData = {
workshopId: this.workshopId,
assessment: this.assessment,
edit: this.edit,
selectedValues: this.selectedValues,
fieldErrors: this.fieldErrors,
strategy: this.strategy
};
this.getHandlerData('workshopform_' + this.strategy);
}
}

View File

@ -43,6 +43,7 @@ import { AddonMessageOutputDelegate } from '@addon/messageoutput/providers/deleg
import { AddonModQuizAccessRuleDelegate } from '@addon/mod/quiz/providers/access-rules-delegate';
import { AddonModAssignFeedbackDelegate } from '@addon/mod/assign/providers/feedback-delegate';
import { AddonModAssignSubmissionDelegate } from '@addon/mod/assign/providers/submission-delegate';
import { AddonWorkshopAssessmentStrategyDelegate } from '@addon/mod/workshop/providers/assessment-strategy-delegate';
// Handler classes.
import { CoreSitePluginsCourseFormatHandler } from '../classes/handlers/course-format-handler';
@ -59,6 +60,7 @@ import { CoreSitePluginsMessageOutputHandler } from '../classes/handlers/message
import { CoreSitePluginsQuizAccessRuleHandler } from '../classes/handlers/quiz-access-rule-handler';
import { CoreSitePluginsAssignFeedbackHandler } from '../classes/handlers/assign-feedback-handler';
import { CoreSitePluginsAssignSubmissionHandler } from '../classes/handlers/assign-submission-handler';
import { CoreSitePluginsWorkshopAssessmentStrategyHandler } from '../classes/handlers/workshop-assessment-strategy-handler';
/**
* Helper service to provide functionalities regarding site plugins. It basically has the features to load and register site
@ -85,7 +87,8 @@ export class CoreSitePluginsHelperProvider {
private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider,
private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate,
private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService,
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate) {
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate,
private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate) {
this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
@ -483,6 +486,10 @@ export class CoreSitePluginsHelperProvider {
promise = Promise.resolve(this.registerAssignSubmissionHandler(plugin, handlerName, handlerSchema));
break;
case 'AddonWorkshopAssessmentStrategyDelegate':
promise = Promise.resolve(this.registerWorkshopAssessmentStrategyHandler(plugin, handlerName, handlerSchema));
break;
default:
// Nothing to do.
promise = Promise.resolve();
@ -864,4 +871,24 @@ export class CoreSitePluginsHelperProvider {
return new CoreSitePluginsUserProfileFieldHandler(uniqueName, fieldType);
});
}
/**
* Given a handler in a plugin, register it in the workshop assessment strategy delegate.
*
* @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin.
* @param {any} handlerSchema Data about the handler.
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
*/
protected registerWorkshopAssessmentStrategyHandler(plugin: any, handlerName: string, handlerSchema: any)
: string | Promise<string> {
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.workshopAssessmentStrategyDelegate,
(uniqueName: string, result: any) => {
const strategyName = plugin.component.replace('workshopform_', '');
return new CoreSitePluginsWorkshopAssessmentStrategyHandler(uniqueName, strategyName);
});
}
}