MOBILE-3651 qbehaviour: Implement all question behaviours

main
Dani Palou 2021-02-11 11:27:03 +01:00
parent 14ba4869a3
commit 4917067f8d
36 changed files with 1357 additions and 11 deletions

View File

@ -24,6 +24,7 @@ import { AddonNotificationsModule } from './notifications/notifications.module';
import { AddonMessageOutputModule } from './messageoutput/messageoutput.module'; import { AddonMessageOutputModule } from './messageoutput/messageoutput.module';
import { AddonMessagesModule } from './messages/messages.module'; import { AddonMessagesModule } from './messages/messages.module';
import { AddonModModule } from './mod/mod.module'; import { AddonModModule } from './mod/mod.module';
import { AddonQbehaviourModule } from './qbehaviour/qbehaviour.module';
@NgModule({ @NgModule({
imports: [ imports: [
@ -37,6 +38,7 @@ import { AddonModModule } from './mod/mod.module';
AddonNotificationsModule, AddonNotificationsModule,
AddonMessageOutputModule, AddonMessageOutputModule,
AddonModModule, AddonModModule,
AddonQbehaviourModule,
], ],
}) })
export class AddonsModule {} export class AddonsModule {}

View File

@ -30,7 +30,6 @@ export class AddonBlockRecentlyAccessedItemsHandlerService extends CoreBlockBase
/** /**
* Returns the data needed to render the block. * Returns the data needed to render the block.
* *
* @param injector Injector.
* @param block The block to render. * @param block The block to render.
* @param contextLevel The context where the block will be used. * @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level. * @param instanceId The instance ID associated with the context level.

View File

@ -0,0 +1,33 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourAdaptiveHandler } from './services/handlers/adaptive';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourAdaptiveHandler.instance);
},
},
],
})
export class AddonQbehaviourAdaptiveModule {}

View File

@ -0,0 +1,56 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support adaptive question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourAdaptiveHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourAdaptive';
type = 'adaptive';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void {
// Just extract the button, it doesn't need any specific component.
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourAdaptiveHandler extends makeSingleton(AddonQbehaviourAdaptiveHandlerService) {}

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourAdaptiveNoPenaltyHandler } from './services/handlers/adaptivenopenalty';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourAdaptiveNoPenaltyHandler.instance);
},
},
],
})
export class AddonQbehaviourAdaptiveNoPenaltyModule {}

View File

@ -0,0 +1,56 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support adaptive no penalty question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourAdaptiveNoPenaltyHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourAdaptiveNoPenalty';
type = 'adaptivenopenalty';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void {
// Just extract the button, it doesn't need any specific component.
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourAdaptiveNoPenaltyHandler extends makeSingleton(AddonQbehaviourAdaptiveNoPenaltyHandlerService) {}

View File

@ -0,0 +1,15 @@
<div *ngIf="question && question.behaviourCertaintyOptions && question.behaviourCertaintyOptions.length">
<ion-item class="ion-text-wrap addon-qbehaviour-deferredcbm-certainty-title" >
<ion-label><p>{{ 'core.question.certainty' | translate }}</p></ion-label>
</ion-item>
<ion-radio-group [(ngModel)]="question.behaviourCertaintySelected" [name]="question.behaviourCertaintyOptions[0].name">
<ion-item class="ion-text-wrap" *ngFor="let option of question.behaviourCertaintyOptions">
<ion-label>{{ option.text }}</ion-label>
<ion-radio slot="end" id="{{option.id}}" [value]="option.value" [disabled]="option.disabled"></ion-radio>
</ion-item>
</ion-radio-group>
<!-- ion-radio doesn't use an input. Create a hidden input to hold the selected value. -->
<input type="hidden" [ngModel]="question.behaviourCertaintySelected" [attr.name]="question.behaviourCertaintyOptions[0].name">
</div>

View File

@ -0,0 +1,38 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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, Output, EventEmitter } from '@angular/core';
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
/**
* Component to render the deferred CBM in a question.
*/
@Component({
selector: 'addon-qbehaviour-deferredcbm',
templateUrl: 'addon-qbehaviour-deferredcbm.html',
})
export class AddonQbehaviourDeferredCBMComponent {
@Input() question?: CoreQuestionQuestion; // The question.
@Input() component?: string; // The component the question belongs to.
@Input() componentId?: number; // ID of the component the question belongs to.
@Input() attemptId?: number; // Attempt ID.
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
@Input() contextLevel?: string; // The context level.
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
}

View File

@ -0,0 +1,43 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreSharedModule } from '@/core/shared.module';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourDeferredCBMComponent } from './component/deferredcbm';
import { AddonQbehaviourDeferredCBMHandler } from './services/handlers/deferredcbm';
@NgModule({
declarations: [
AddonQbehaviourDeferredCBMComponent,
],
imports: [
CoreSharedModule,
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourDeferredCBMHandler.instance);
},
},
],
exports: [
AddonQbehaviourDeferredCBMComponent,
],
})
export class AddonQbehaviourDeferredCBMModule {}

View File

@ -0,0 +1,152 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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, Type } from '@angular/core';
import { AddonQbehaviourDeferredFeedbackHandler } from '@addons/qbehaviour/deferredfeedback/services/handlers/deferredfeedback';
import { CoreQuestionBehaviourHandler, CoreQuestionQuestionWithAnswers } from '@features/question/services/behaviour-delegate';
import { makeSingleton } from '@singletons';
import { CoreQuestionQuestionParsed, CoreQuestionsAnswers, CoreQuestionState } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { AddonQbehaviourDeferredCBMComponent } from '../../component/deferredcbm';
import { CoreQuestionDelegate } from '@features/question/services/question-delegate';
/**
* Handler to support deferred CBM question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourDeferredCBMHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourDeferredCBM';
type = 'deferredcbm';
/**
* Determine a question new state based on its answer(s).
*
* @param component Component the question belongs to.
* @param attemptId Attempt ID the question belongs to.
* @param question The question.
* @param componentId Component ID.
* @param siteId Site ID. If not defined, current site.
* @return New state (or promise resolved with state).
*/
determineNewState(
component: string,
attemptId: number,
question: CoreQuestionQuestionWithAnswers,
componentId: string | number,
siteId?: string,
): CoreQuestionState | Promise<CoreQuestionState> {
// Depends on deferredfeedback.
return AddonQbehaviourDeferredFeedbackHandler.instance.determineNewStateDeferred(
component,
attemptId,
question,
componentId,
siteId,
this.isCompleteResponse.bind(this),
this.isSameResponse.bind(this),
);
}
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void | Type<unknown>[] {
if (CoreQuestionHelper.instance.extractQbehaviourCBM(question)) {
return [AddonQbehaviourDeferredCBMComponent];
}
}
/**
* Check if a response is complete.
*
* @param question The question.
* @param answers Object with the question answers (without prefix).
* @param component The component the question is related to.
* @param componentId Component ID.
* @return 1 if complete, 0 if not complete, -1 if cannot determine.
*/
protected isCompleteResponse(
question: CoreQuestionQuestionParsed,
answers: CoreQuestionsAnswers,
component: string,
componentId: string | number,
): number {
// First check if the question answer is complete.
const complete = CoreQuestionDelegate.instance.isCompleteResponse(question, answers, component, componentId);
if (complete > 0) {
// Answer is complete, check the user answered CBM too.
return answers['-certainty'] ? 1 : 0;
}
return complete;
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* Check if two responses are the same.
*
* @param question Question.
* @param prevAnswers Object with the previous question answers.
* @param prevBasicAnswers Object with the previous basic" answers (without sequencecheck, certainty, ...).
* @param newAnswers Object with the new question answers.
* @param newBasicAnswers Object with the previous basic" answers (without sequencecheck, certainty, ...).
* @param component The component the question is related to.
* @param componentId Component ID.
* @return Whether they're the same.
*/
protected isSameResponse(
question: CoreQuestionQuestionParsed,
prevAnswers: CoreQuestionsAnswers,
prevBasicAnswers: CoreQuestionsAnswers,
newAnswers: CoreQuestionsAnswers,
newBasicAnswers: CoreQuestionsAnswers,
component: string,
componentId: string | number,
): boolean {
// First check if the question answer is the same.
const sameResponse = CoreQuestionDelegate.instance.isSameResponse(
question,
prevBasicAnswers,
newBasicAnswers,
component,
componentId,
);
if (sameResponse) {
// Same response, check the CBM is the same too.
return prevAnswers['-certainty'] == newAnswers['-certainty'];
}
return sameResponse;
}
}
export class AddonQbehaviourDeferredCBMHandler extends makeSingleton(AddonQbehaviourDeferredCBMHandlerService) {}

View File

@ -0,0 +1,33 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourDeferredFeedbackHandler } from './services/handlers/deferredfeedback';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourDeferredFeedbackHandler.instance);
},
},
],
})
export class AddonQbehaviourDeferredFeedbackModule {}

View File

@ -0,0 +1,216 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler, CoreQuestionQuestionWithAnswers } from '@features/question/services/behaviour-delegate';
import { CoreQuestionDBRecord } from '@features/question/services/database/question';
import {
CoreQuestion,
CoreQuestionQuestionParsed,
CoreQuestionsAnswers,
CoreQuestionState,
} from '@features/question/services/question';
import { CoreQuestionDelegate } from '@features/question/services/question-delegate';
import { makeSingleton } from '@singletons';
/**
* Handler to support deferred feedback question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourDeferredFeedbackHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourDeferredFeedback';
type = 'deferredfeedback';
/**
* Determine a question new state based on its answer(s).
*
* @param component Component the question belongs to.
* @param attemptId Attempt ID the question belongs to.
* @param question The question.
* @param componentId Component ID.
* @param siteId Site ID. If not defined, current site.
* @return New state (or promise resolved with state).
*/
determineNewState(
component: string,
attemptId: number,
question: CoreQuestionQuestionWithAnswers,
componentId: string | number,
siteId?: string,
): CoreQuestionState | Promise<CoreQuestionState> {
return this.determineNewStateDeferred(component, attemptId, question, componentId, siteId);
}
/**
* Determine a question new state based on its answer(s) for deferred question behaviour.
*
* @param component Component the question belongs to.
* @param attemptId Attempt ID the question belongs to.
* @param question The question.
* @param componentId Component ID.
* @param siteId Site ID. If not defined, current site.
* @param isCompleteFn Function to override the default isCompleteResponse check.
* @param isSameFn Function to override the default isSameResponse check.
* @return Promise resolved with state.
*/
async determineNewStateDeferred(
component: string,
attemptId: number,
question: CoreQuestionQuestionWithAnswers,
componentId: string | number,
siteId?: string,
isCompleteFn?: isCompleteResponseFunction,
isSameFn?: isSameResponseFunction,
): Promise<CoreQuestionState> {
// Check if we have local data for the question.
let dbQuestion: CoreQuestionDBRecord | CoreQuestionQuestionWithAnswers = question;
try {
dbQuestion = await CoreQuestion.instance.getQuestion(component, attemptId, question.slot, siteId);
} catch (error) {
// No entry found, use the original data.
}
const state = CoreQuestion.instance.getState(dbQuestion.state);
if (state.finished || !state.active) {
// Question is finished, it cannot change.
return state;
}
const newBasicAnswers = CoreQuestion.instance.getBasicAnswers(question.answers || {});
if (dbQuestion.state) {
// Question already has a state stored. Check if answer has changed.
const prevAnswersList = await CoreQuestion.instance.getQuestionAnswers(
component,
attemptId,
question.slot,
false,
siteId,
);
const prevAnswers = CoreQuestion.instance.convertAnswersArrayToObject(prevAnswersList, true);
const prevBasicAnswers = CoreQuestion.instance.getBasicAnswers(prevAnswers);
// If answers haven't changed the state is the same.
let sameResponse = false;
if (isSameFn) {
sameResponse = isSameFn(
question,
prevAnswers,
prevBasicAnswers,
question.answers || {},
newBasicAnswers,
component,
componentId,
);
} else {
sameResponse = CoreQuestionDelegate.instance.isSameResponse(
question,
prevBasicAnswers,
newBasicAnswers,
component,
componentId,
);
}
if (sameResponse) {
return state;
}
}
// Answers have changed. Now check if the response is complete and calculate the new state.
let complete: number;
let newState: string;
if (isCompleteFn) {
// Pass all the answers since some behaviours might need the extra data.
complete = isCompleteFn(question, question.answers || {}, component, componentId);
} else {
// Only pass the basic answers since questions should be independent of extra data.
complete = CoreQuestionDelegate.instance.isCompleteResponse(question, newBasicAnswers, component, componentId);
}
if (complete < 0) {
newState = 'cannotdeterminestatus';
} else if (complete > 0) {
newState = 'complete';
} else {
const gradable = CoreQuestionDelegate.instance.isGradableResponse(question, newBasicAnswers, component, componentId);
if (gradable < 0) {
newState = 'cannotdeterminestatus';
} else if (gradable > 0) {
newState = 'invalid';
} else {
newState = 'todo';
}
}
return CoreQuestion.instance.getState(newState);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourDeferredFeedbackHandler extends makeSingleton(AddonQbehaviourDeferredFeedbackHandlerService) {}
/**
* Check if a response is complete.
*
* @param question The question.
* @param answers Object with the question answers (without prefix).
* @param component The component the question is related to.
* @param componentId Component ID.
* @return 1 if complete, 0 if not complete, -1 if cannot determine.
*/
export type isCompleteResponseFunction = (
question: CoreQuestionQuestionParsed,
answers: CoreQuestionsAnswers,
component: string,
componentId: string | number,
) => number;
/**
* Check if two responses are the same.
*
* @param question Question.
* @param prevAnswers Object with the previous question answers.
* @param prevBasicAnswers Object with the previous basic" answers (without sequencecheck, certainty, ...).
* @param newAnswers Object with the new question answers.
* @param newBasicAnswers Object with the previous basic" answers (without sequencecheck, certainty, ...).
* @param component The component the question is related to.
* @param componentId Component ID.
* @return Whether they're the same.
*/
export type isSameResponseFunction = (
question: CoreQuestionQuestionParsed,
prevAnswers: CoreQuestionsAnswers,
prevBasicAnswers: CoreQuestionsAnswers,
newAnswers: CoreQuestionsAnswers,
newBasicAnswers: CoreQuestionsAnswers,
component: string,
componentId: string | number,
) => boolean;

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourImmediateCBMHandler } from './services/handlers/immediatecbm';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourImmediateCBMHandler.instance);
},
},
],
})
export class AddonQbehaviourImmediateCBMModule {}

View File

@ -0,0 +1,61 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { AddonQbehaviourDeferredCBMComponent } from '@addons/qbehaviour/deferredcbm/component/deferredcbm';
import { Injectable, Type } from '@angular/core';
import { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support immediate CBM question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourImmediateCBMHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourImmediateCBM';
type = 'immediatecbm';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void | Type<unknown>[] {
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
if (CoreQuestionHelper.instance.extractQbehaviourCBM(question)) {
// Depends on deferredcbm.
return [AddonQbehaviourDeferredCBMComponent];
}
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourImmediateCBMHandler extends makeSingleton(AddonQbehaviourImmediateCBMHandlerService) {}

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourImmediateFeedbackHandler } from './services/handlers/immediatefeedback';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourImmediateFeedbackHandler.instance);
},
},
],
})
export class AddonQbehaviourImmediateFeedbackModule {}

View File

@ -0,0 +1,58 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support immediate feedback question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourImmediateFeedbackHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourImmediateFeedback';
type = 'immediatefeedback';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void {
// Just extract the button, it doesn't need any specific component.
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
return;
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourImmediateFeedbackHandler extends makeSingleton(AddonQbehaviourImmediateFeedbackHandlerService) {}

View File

@ -0,0 +1,2 @@
<input *ngIf="question && question.behaviourSeenInput" type="hidden" [name]="question.behaviourSeenInput.name"
[value]="question.behaviourSeenInput.value" >

View File

@ -0,0 +1,38 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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, Output, EventEmitter } from '@angular/core';
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
/**
* Component to render a "seen" hidden input for informationitem question behaviour.
*/
@Component({
selector: 'addon-qbehaviour-informationitem',
templateUrl: 'addon-qbehaviour-informationitem.html',
})
export class AddonQbehaviourInformationItemComponent {
@Input() question?: CoreQuestionQuestion; // The question.
@Input() component?: string; // The component the question belongs to.
@Input() componentId?: number; // ID of the component the question belongs to.
@Input() attemptId?: number; // Attempt ID.
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
@Input() contextLevel?: string; // The context level.
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
}

View File

@ -0,0 +1,43 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreSharedModule } from '@/core/shared.module';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourInformationItemComponent } from './component/informationitem';
import { AddonQbehaviourInformationItemHandler } from './services/handlers/informationitem';
@NgModule({
declarations: [
AddonQbehaviourInformationItemComponent,
],
imports: [
CoreSharedModule,
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourInformationItemHandler.instance);
},
},
],
exports: [
AddonQbehaviourInformationItemComponent,
],
})
export class AddonQbehaviourInformationItemModule {}

View File

@ -0,0 +1,80 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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, Type } from '@angular/core';
import { CoreQuestionBehaviourHandler, CoreQuestionQuestionWithAnswers } from '@features/question/services/behaviour-delegate';
import { CoreQuestion, CoreQuestionQuestionParsed, CoreQuestionState } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
import { AddonQbehaviourInformationItemComponent } from '../../component/informationitem';
/**
* Handler to support information item question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourInformationItemHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourInformationItem';
type = 'informationitem';
/**
* Determine a question new state based on its answer(s).
*
* @param component Component the question belongs to.
* @param attemptId Attempt ID the question belongs to.
* @param question The question.
* @param componentId Component ID.
* @param siteId Site ID. If not defined, current site.
* @return New state (or promise resolved with state).
*/
determineNewState(
component: string,
attemptId: number,
question: CoreQuestionQuestionWithAnswers,
): CoreQuestionState | Promise<CoreQuestionState> {
if (question.answers?.['-seen']) {
return CoreQuestion.instance.getState('complete');
}
return CoreQuestion.instance.getState(question.state || 'todo');
}
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void | Type<unknown>[] {
if (CoreQuestionHelper.instance.extractQbehaviourSeenInput(question)) {
return [AddonQbehaviourInformationItemComponent];
}
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourInformationItemHandler extends makeSingleton(AddonQbehaviourInformationItemHandlerService) {}

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourInteractiveHandler } from './services/handlers/interactive';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourInteractiveHandler.instance);
},
},
],
})
export class AddonQbehaviourInteractiveModule {}

View File

@ -0,0 +1,56 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support interactive question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourInteractiveHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourInteractive';
type = 'interactive';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void {
// Just extract the button, it doesn't need any specific component.
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourInteractiveHandler extends makeSingleton(AddonQbehaviourInteractiveHandlerService) {}

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourInteractiveCountbackHandler } from './services/handlers/interactivecountback';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourInteractiveCountbackHandler.instance);
},
},
],
})
export class AddonQbehaviourInteractiveCountbackModule {}

View File

@ -0,0 +1,56 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { CoreQuestionBehaviourHandler } from '@features/question/services/behaviour-delegate';
import { CoreQuestionQuestionParsed } from '@features/question/services/question';
import { CoreQuestionHelper } from '@features/question/services/question-helper';
import { makeSingleton } from '@singletons';
/**
* Handler to support interactive countback question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourInteractiveCountbackHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourInteractiveCountback';
type = 'interactivecountback';
/**
* Handle a question behaviour.
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
* If the behaviour requires to show some extra data, it should return the components to render it.
*
* @param question The question.
* @return Components (or promise resolved with components) to render some extra data in the question
* (e.g. certainty options). Don't return anything if no extra data is required.
*/
handleQuestion(question: CoreQuestionQuestionParsed): void {
// Just extract the button, it doesn't need any specific component.
CoreQuestionHelper.instance.extractQbehaviourButtons(question);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourInteractiveCountbackHandler extends makeSingleton(AddonQbehaviourInteractiveCountbackHandlerService) {}

View File

@ -0,0 +1,34 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { CoreQuestionBehaviourDelegate } from '@features/question/services/behaviour-delegate';
import { AddonQbehaviourManualGradedHandler } from './services/handlers/manualgraded';
@NgModule({
declarations: [
],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreQuestionBehaviourDelegate.instance.registerHandler(AddonQbehaviourManualGradedHandler.instance);
},
},
],
})
export class AddonQbehaviourManualGradedModule {}

View File

@ -0,0 +1,69 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { AddonQbehaviourDeferredFeedbackHandler } from '@addons/qbehaviour/deferredfeedback/services/handlers/deferredfeedback';
import { CoreQuestionBehaviourHandler, CoreQuestionQuestionWithAnswers } from '@features/question/services/behaviour-delegate';
import { CoreQuestionState } from '@features/question/services/question';
import { makeSingleton } from '@singletons';
/**
* Handler to support manual graded question behaviour.
*/
@Injectable({ providedIn: 'root' })
export class AddonQbehaviourManualGradedHandlerService implements CoreQuestionBehaviourHandler {
name = 'AddonQbehaviourManualGraded';
type = 'manualgraded';
/**
* Determine a question new state based on its answer(s).
*
* @param component Component the question belongs to.
* @param attemptId Attempt ID the question belongs to.
* @param question The question.
* @param componentId Component ID.
* @param siteId Site ID. If not defined, current site.
* @return New state (or promise resolved with state).
*/
determineNewState(
component: string,
attemptId: number,
question: CoreQuestionQuestionWithAnswers,
componentId: string | number,
siteId?: string,
): CoreQuestionState | Promise<CoreQuestionState> {
// Same implementation as the deferred feedback. Use that function instead of replicating it.
return AddonQbehaviourDeferredFeedbackHandler.instance.determineNewStateDeferred(
component,
attemptId,
question,
componentId,
siteId,
);
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return True or promise resolved with true if enabled.
*/
async isEnabled(): Promise<boolean> {
return true;
}
}
export class AddonQbehaviourManualGradedHandler extends makeSingleton(AddonQbehaviourManualGradedHandlerService) {}

View File

@ -0,0 +1,45 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { AddonQbehaviourAdaptiveModule } from './adaptive/adaptive.module';
import { AddonQbehaviourAdaptiveNoPenaltyModule } from './adaptivenopenalty/adaptivenopenalty.module';
import { AddonQbehaviourDeferredCBMModule } from './deferredcbm/deferredcbm.module';
import { AddonQbehaviourDeferredFeedbackModule } from './deferredfeedback/deferredfeedback.module';
import { AddonQbehaviourImmediateCBMModule } from './immediatecbm/immediatecbm.module';
import { AddonQbehaviourImmediateFeedbackModule } from './immediatefeedback/immediatefeedback.module';
import { AddonQbehaviourInformationItemModule } from './informationitem/informationitem.module';
import { AddonQbehaviourInteractiveModule } from './interactive/interactive.module';
import { AddonQbehaviourInteractiveCountbackModule } from './interactivecountback/interactivecountback.module';
import { AddonQbehaviourManualGradedModule } from './manualgraded/manualgraded.module';
@NgModule({
declarations: [],
imports: [
AddonQbehaviourAdaptiveModule,
AddonQbehaviourAdaptiveNoPenaltyModule,
AddonQbehaviourDeferredCBMModule,
AddonQbehaviourDeferredFeedbackModule,
AddonQbehaviourImmediateCBMModule,
AddonQbehaviourImmediateFeedbackModule,
AddonQbehaviourInformationItemModule,
AddonQbehaviourInteractiveModule,
AddonQbehaviourInteractiveCountbackModule,
AddonQbehaviourManualGradedModule,
],
providers: [
],
exports: [],
})
export class AddonQbehaviourModule { }

View File

@ -69,7 +69,6 @@ export class AddonUserProfileFieldDatetimeHandlerService implements CoreUserProf
* Return the Component to use to display the user profile field. * Return the Component to use to display the user profile field.
* It's recommended to return the class of the component, but you can also return an instance of the component. * It's recommended to return the class of the component, but you can also return an instance of the component.
* *
* @param injector Injector.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { getComponent(): Type<unknown> | Promise<Type<unknown>> {

View File

@ -76,7 +76,6 @@ export class AddonUserProfileFieldTextareaHandlerService implements CoreUserProf
* Return the Component to use to display the user profile field. * Return the Component to use to display the user profile field.
* It's recommended to return the class of the component, but you can also return an instance of the component. * It's recommended to return the class of the component, but you can also return an instance of the component.
* *
* @param injector Injector.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { getComponent(): Type<unknown> | Promise<Type<unknown>> {

View File

@ -138,7 +138,6 @@ export class CoreBlockDelegateService extends CoreDelegate<CoreBlockHandler> {
/** /**
* Get the display data for a certain block. * Get the display data for a certain block.
* *
* @param injector Injector.
* @param block The block to render. * @param block The block to render.
* @param contextLevel The context where the block will be used. * @param contextLevel The context where the block will be used.
* @param instanceId The instance ID associated with the context level. * @param instanceId The instance ID associated with the context level.
@ -200,4 +199,3 @@ export class CoreBlockDelegateService extends CoreDelegate<CoreBlockHandler> {
} }
export class CoreBlockDelegate extends makeSingleton(CoreBlockDelegateService) {} export class CoreBlockDelegate extends makeSingleton(CoreBlockDelegateService) {}

View File

@ -127,7 +127,6 @@ export class CoreCourseFormatSingleActivityHandlerService implements CoreCourseF
* If you want to customize the default format there are several methods to customize parts of it. * If you want to customize the default format there are several methods to customize parts of it.
* It's recommended to return the class of the component, but you can also return an instance of the component. * It's recommended to return the class of the component, but you can also return an instance of the component.
* *
* @param injector Injector.
* @param course The course to render. * @param course The course to render.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */

View File

@ -67,7 +67,6 @@ export class CoreCourseTagAreaHandlerService implements CoreTagAreaHandler {
/** /**
* Get the component to use to display items. * Get the component to use to display items.
* *
* @param injector Injector.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { getComponent(): Type<unknown> | Promise<Type<unknown>> {

View File

@ -109,7 +109,7 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
* @return Whether the refresher should be displayed. * @return Whether the refresher should be displayed.
*/ */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
displayRefresher?(course: CoreCourseAnyCourseData, sections: CoreCourseWSSection[]): boolean { displayRefresher(course: CoreCourseAnyCourseData, sections: CoreCourseWSSection[]): boolean {
return true; return true;
} }

View File

@ -50,7 +50,6 @@ export class CoreCourseModulesTagAreaHandlerService implements CoreTagAreaHandle
/** /**
* Get the component to use to display items. * Get the component to use to display items.
* *
* @param injector Injector.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { getComponent(): Type<unknown> | Promise<Type<unknown>> {

View File

@ -82,7 +82,6 @@ export class CoreUserTagAreaHandlerService implements CoreTagAreaHandler {
/** /**
* Get the component to use to display items. * Get the component to use to display items.
* *
* @param injector Injector.
* @return The component (or promise resolved with component) to use, undefined if not found. * @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { getComponent(): Type<unknown> | Promise<Type<unknown>> {

View File

@ -96,7 +96,6 @@ export class CoreUserProfileFieldDelegateService extends CoreDelegate<CoreUserPr
/** /**
* Get the component to use to display an user field. * Get the component to use to display an user field.
* *
* @param injector Injector.
* @param field User field to get the directive for. * @param field User field to get the directive for.
* @param signup True if user is in signup page. * @param signup True if user is in signup page.
* @return Promise resolved with component to use, undefined if not found. * @return Promise resolved with component to use, undefined if not found.