MOBILE-3636 assign: Feedback plugins
parent
85f79bb944
commit
c4d37b0074
|
@ -13,8 +13,11 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit, ViewChild, Type } from '@angular/core';
|
import { Component, Input, OnInit, ViewChild, Type } from '@angular/core';
|
||||||
|
import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
|
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
|
||||||
import { CoreWSExternalFile } from '@services/ws';
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
import { ModalController } from '@singletons';
|
||||||
|
import { AddonModAssignFeedbackCommentsPluginData } from '../../feedback/comments/services/handler';
|
||||||
import {
|
import {
|
||||||
AddonModAssignAssign,
|
AddonModAssignAssign,
|
||||||
AddonModAssignSubmission,
|
AddonModAssignSubmission,
|
||||||
|
@ -24,6 +27,7 @@ import {
|
||||||
} from '../../services/assign';
|
} from '../../services/assign';
|
||||||
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
|
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
|
||||||
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||||
|
import { AddonModAssignEditFeedbackModalComponent } from '../edit-feedback-modal/edit-feedback-modal';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays an assignment feedback plugin.
|
* Component that displays an assignment feedback plugin.
|
||||||
|
@ -95,6 +99,47 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a modal to edit the feedback plugin.
|
||||||
|
*
|
||||||
|
* @return Promise resolved with the input data, rejected if cancelled.
|
||||||
|
*/
|
||||||
|
editFeedback(): Promise<AddonModAssignFeedbackCommentsPluginData> {
|
||||||
|
if (!this.canEdit) {
|
||||||
|
throw new CoreError('Cannot edit feedback');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject): void => {
|
||||||
|
this.showEditFeedbackModal(resolve, reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async showEditFeedbackModal(
|
||||||
|
resolve: (value: AddonModAssignFeedbackCommentsPluginData | PromiseLike<AddonModAssignFeedbackCommentsPluginData>) => void,
|
||||||
|
reject: () => void,
|
||||||
|
): Promise < void> {
|
||||||
|
// Create the navigation modal.
|
||||||
|
const modal = await ModalController.instance.create({
|
||||||
|
component: AddonModAssignEditFeedbackModalComponent,
|
||||||
|
componentProps: {
|
||||||
|
assign: this.assign,
|
||||||
|
submission: this.submission,
|
||||||
|
plugin: this.plugin,
|
||||||
|
userId: this.userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await modal.present();
|
||||||
|
|
||||||
|
const result = await modal.onDidDismiss();
|
||||||
|
|
||||||
|
if (typeof result.data == 'undefined') {
|
||||||
|
reject();
|
||||||
|
} else {
|
||||||
|
resolve(result.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate the plugin data.
|
* Invalidate the plugin data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// (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 { AddonModAssignFeedbackCommentsHandler } from './services/handler';
|
||||||
|
import { AddonModAssignFeedbackCommentsComponent } from './component/comments';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
|
||||||
|
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||||
|
import { AddonModAssignSubmissionFileHandler } from '../../submission/file/services/handler';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonModAssignFeedbackCommentsComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreSharedModule,
|
||||||
|
CoreEditorComponentsModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
AddonModAssignFeedbackCommentsHandler,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
multi: true,
|
||||||
|
deps: [],
|
||||||
|
useFactory: () => () => {
|
||||||
|
AddonModAssignFeedbackDelegate.instance.registerHandler(AddonModAssignSubmissionFileHandler.instance);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AddonModAssignFeedbackCommentsComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
AddonModAssignFeedbackCommentsComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackCommentsModule {}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!-- Read only. -->
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="(text || canEdit) && !edit">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ plugin.name }}</h2>
|
||||||
|
<p>
|
||||||
|
<core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true"
|
||||||
|
[fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid"
|
||||||
|
[courseId]="assign.course">
|
||||||
|
</core-format-text>
|
||||||
|
</p>
|
||||||
|
</ion-label>
|
||||||
|
<div slot="end">
|
||||||
|
<div class="ion-text-end">
|
||||||
|
<ion-button fill="clear" *ngIf="canEdit" (click)="editComment()" color="dark">
|
||||||
|
<ion-icon name="fas-pen" slot="icon-only"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</div>
|
||||||
|
<ion-note *ngIf="!isSent" color="dark">
|
||||||
|
<ion-icon name="far-clock"></ion-icon>
|
||||||
|
{{ 'core.notsent' | translate }}
|
||||||
|
</ion-note>
|
||||||
|
</div>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<!-- Edit -->
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="edit && loaded">
|
||||||
|
<ion-label>
|
||||||
|
<core-rich-text-editor item-content [control]="control" [placeholder]="plugin.name"
|
||||||
|
name="assignfeedbackcomments_editor" [component]="component" [componentId]="assign.cmid" [autoSave]="true"
|
||||||
|
contextLevel="module" [contextInstanceId]="assign.cmid" elementId="assignfeedbackcomments_editor"
|
||||||
|
[draftExtraParams]="{userid: userId, action: 'grade'}">
|
||||||
|
</core-rich-text-editor>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
|
@ -0,0 +1,161 @@
|
||||||
|
// (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, OnInit, ElementRef } from '@angular/core';
|
||||||
|
import { FormBuilder, FormControl } from '@angular/forms';
|
||||||
|
import { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||||
|
import { AddonModAssign, AddonModAssignProvider } from '@addons/mod/assign/services/assign';
|
||||||
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import {
|
||||||
|
AddonModAssignFeedbackCommentsDraftData,
|
||||||
|
AddonModAssignFeedbackCommentsHandler,
|
||||||
|
AddonModAssignFeedbackCommentsPluginData,
|
||||||
|
} from '../services/handler';
|
||||||
|
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
|
||||||
|
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
/**
|
||||||
|
* Component to render a comments feedback plugin.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-mod-assign-feedback-comments',
|
||||||
|
templateUrl: 'addon-mod-assign-feedback-comments.html',
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||||
|
|
||||||
|
control?: FormControl;
|
||||||
|
component = AddonModAssignProvider.COMPONENT;
|
||||||
|
text = '';
|
||||||
|
isSent = false;
|
||||||
|
loaded = false;
|
||||||
|
|
||||||
|
protected element: HTMLElement;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
element: ElementRef,
|
||||||
|
protected fb: FormBuilder,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
this.element = element.nativeElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
try {
|
||||||
|
this.text = await this.getText();
|
||||||
|
|
||||||
|
if (!this.canEdit && !this.edit) {
|
||||||
|
// User cannot edit the comment. Show it full when clicked.
|
||||||
|
this.element.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (this.text) {
|
||||||
|
// Open a new state with the text.
|
||||||
|
CoreTextUtils.instance.viewText(this.plugin.name, this.text, {
|
||||||
|
component: this.component,
|
||||||
|
componentId: this.assign.cmid,
|
||||||
|
filter: true,
|
||||||
|
contextLevel: 'module',
|
||||||
|
instanceId: this.assign.cmid,
|
||||||
|
courseId: this.assign.course,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (this.edit) {
|
||||||
|
this.control = this.fb.control(this.text);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit the comment.
|
||||||
|
*/
|
||||||
|
async editComment(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const inputData = await this.editFeedback();
|
||||||
|
const text = AddonModAssignFeedbackCommentsHandler.instance.getTextFromInputData(this.plugin, inputData);
|
||||||
|
|
||||||
|
// Update the text and save it as draft.
|
||||||
|
this.isSent = false;
|
||||||
|
this.text = this.replacePluginfileUrls(text);
|
||||||
|
AddonModAssignFeedbackDelegate.instance.saveFeedbackDraft(this.assign.id, this.userId, this.plugin, {
|
||||||
|
text: text,
|
||||||
|
format: 1,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// User cancelled, nothing to do.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the text for the plugin.
|
||||||
|
*
|
||||||
|
* @return Promise resolved with the text.
|
||||||
|
*/
|
||||||
|
protected async getText(): Promise<string> {
|
||||||
|
// Check if the user already modified the comment.
|
||||||
|
const draft: AddonModAssignFeedbackCommentsDraftData | undefined =
|
||||||
|
await AddonModAssignFeedbackDelegate.instance.getPluginDraftData(this.assign.id, this.userId, this.plugin);
|
||||||
|
|
||||||
|
if (draft) {
|
||||||
|
this.isSent = false;
|
||||||
|
|
||||||
|
return this.replacePluginfileUrls(draft.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is no draft saved. Check if we have anything offline.
|
||||||
|
const offlineData = await CoreUtils.instance.ignoreErrors(
|
||||||
|
AddonModAssignOffline.instance.getSubmissionGrade(this.assign.id, this.userId),
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (offlineData && offlineData.plugindata && offlineData.plugindata.assignfeedbackcomments_editor) {
|
||||||
|
const pluginData = <AddonModAssignFeedbackCommentsPluginData>offlineData.plugindata;
|
||||||
|
|
||||||
|
// Save offline as draft.
|
||||||
|
this.isSent = false;
|
||||||
|
AddonModAssignFeedbackDelegate.instance.saveFeedbackDraft(
|
||||||
|
this.assign.id,
|
||||||
|
this.userId,
|
||||||
|
this.plugin,
|
||||||
|
pluginData.assignfeedbackcomments_editor,
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.replacePluginfileUrls(pluginData.assignfeedbackcomments_editor.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No offline data found, return online text.
|
||||||
|
this.isSent = true;
|
||||||
|
|
||||||
|
return AddonModAssign.instance.getSubmissionPluginText(this.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace @@PLUGINFILE@@ wildcards with the real URL of embedded files.
|
||||||
|
*
|
||||||
|
* @param Text to treat.
|
||||||
|
* @return Treated text.
|
||||||
|
*/
|
||||||
|
replacePluginfileUrls(text: string): string {
|
||||||
|
const files = this.plugin.fileareas && this.plugin.fileareas[0] && this.plugin.fileareas[0].files;
|
||||||
|
|
||||||
|
return CoreTextUtils.instance.replacePluginfileUrls(text, files || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"pluginname": "Feedback comments"
|
||||||
|
}
|
|
@ -0,0 +1,266 @@
|
||||||
|
// (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 {
|
||||||
|
AddonModAssignPlugin,
|
||||||
|
AddonModAssignAssign,
|
||||||
|
AddonModAssignSubmission,
|
||||||
|
AddonModAssign,
|
||||||
|
AddonModAssignSavePluginData,
|
||||||
|
} from '@addons/mod/assign/services/assign';
|
||||||
|
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
|
||||||
|
import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedback-delegate';
|
||||||
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { AddonModAssignFeedbackCommentsComponent } from '../component/comments';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for comments feedback plugin.
|
||||||
|
*/
|
||||||
|
@Injectable( { providedIn: 'root' })
|
||||||
|
export class AddonModAssignFeedbackCommentsHandlerService implements AddonModAssignFeedbackHandler {
|
||||||
|
|
||||||
|
name = 'AddonModAssignFeedbackCommentsHandler';
|
||||||
|
type = 'comments';
|
||||||
|
|
||||||
|
// Store the data in this service so it isn't lost if the user performs a PTR in the page.
|
||||||
|
protected drafts: { [draftId: string]: AddonModAssignFeedbackCommentsDraftData } = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the text to submit.
|
||||||
|
*
|
||||||
|
* @param textUtils Text utils instance.
|
||||||
|
* @param plugin Plugin.
|
||||||
|
* @param inputData Data entered in the feedback edit form.
|
||||||
|
* @return Text to submit.
|
||||||
|
*/
|
||||||
|
getTextFromInputData(plugin: AddonModAssignPlugin, inputData: AddonModAssignFeedbackCommentsPluginData): string {
|
||||||
|
const files = plugin.fileareas && plugin.fileareas[0] ? plugin.fileareas[0].files : [];
|
||||||
|
let text = '';
|
||||||
|
|
||||||
|
// The input data can have a string or an object with text and format. Get the text.
|
||||||
|
if (inputData.assignfeedbackcomments_editor && inputData.assignfeedbackcomments_editor.text) {
|
||||||
|
text = inputData.assignfeedbackcomments_editor.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CoreTextUtils.instance.restorePluginfileUrls(text, files || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discard the draft data of the feedback plugin.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return If the function is async, it should return a Promise resolved when done.
|
||||||
|
*/
|
||||||
|
discardDraft(assignId: number, userId: number, siteId?: string): void {
|
||||||
|
const id = this.getDraftId(assignId, userId, siteId);
|
||||||
|
if (typeof this.drafts[id] != 'undefined') {
|
||||||
|
delete this.drafts[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Component to use to display the plugin data.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
|
*
|
||||||
|
* @return The component (or promise resolved with component) to use, undefined if not found.
|
||||||
|
*/
|
||||||
|
getComponent(): Type<unknown> {
|
||||||
|
return AddonModAssignFeedbackCommentsComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the draft saved data of the feedback plugin.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Data (or promise resolved with the data).
|
||||||
|
*/
|
||||||
|
getDraft(assignId: number, userId: number, siteId?: string): AddonModAssignFeedbackCommentsDraftData | undefined {
|
||||||
|
const id = this.getDraftId(assignId, userId, siteId);
|
||||||
|
|
||||||
|
if (typeof this.drafts[id] != 'undefined') {
|
||||||
|
return this.drafts[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a draft ID.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Draft ID.
|
||||||
|
*/
|
||||||
|
protected getDraftId(assignId: number, userId: number, siteId?: string): string {
|
||||||
|
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
||||||
|
|
||||||
|
return siteId + '#' + assignId + '#' + userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get files used by this plugin.
|
||||||
|
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||||
|
*
|
||||||
|
* @param assign The assignment.
|
||||||
|
* @param submission The submission.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @return The files (or promise resolved with the files).
|
||||||
|
*/
|
||||||
|
getPluginFiles(
|
||||||
|
assign: AddonModAssignAssign,
|
||||||
|
submission: AddonModAssignSubmission,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
): CoreWSExternalFile[] {
|
||||||
|
return AddonModAssign.instance.getSubmissionPluginAttachments(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the feedback data has changed for this plugin.
|
||||||
|
*
|
||||||
|
* @param assign The assignment.
|
||||||
|
* @param submission The submission.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @param inputData Data entered by the user for the feedback.
|
||||||
|
* @param userId User ID of the submission.
|
||||||
|
* @return Boolean (or promise resolved with boolean): whether the data has changed.
|
||||||
|
*/
|
||||||
|
async hasDataChanged(
|
||||||
|
assign: AddonModAssignAssign,
|
||||||
|
submission: AddonModAssignSubmission,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
inputData: AddonModAssignFeedbackCommentsPluginData,
|
||||||
|
userId: number,
|
||||||
|
): Promise<boolean> {
|
||||||
|
// Get it from plugin or offline.
|
||||||
|
const offlineData = await CoreUtils.instance.ignoreErrors(
|
||||||
|
AddonModAssignOffline.instance.getSubmissionGrade(assign.id, userId),
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (offlineData?.plugindata?.assignfeedbackcomments_editor) {
|
||||||
|
const pluginData = <AddonModAssignFeedbackCommentsPluginData>offlineData.plugindata;
|
||||||
|
|
||||||
|
return !!pluginData.assignfeedbackcomments_editor.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No offline data found, get text from plugin.
|
||||||
|
const initialText = AddonModAssign.instance.getSubmissionPluginText(plugin);
|
||||||
|
const newText = AddonModAssignFeedbackCommentsHandler.instance.getTextFromInputData(plugin, inputData);
|
||||||
|
|
||||||
|
if (typeof newText == 'undefined') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if text has changed.
|
||||||
|
return initialText != newText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the plugin has draft data stored.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Boolean or promise resolved with boolean: whether the plugin has draft data.
|
||||||
|
*/
|
||||||
|
hasDraftData(assignId: number, userId: number, siteId?: string): boolean | Promise<boolean> {
|
||||||
|
const draft = this.getDraft(assignId, userId, siteId);
|
||||||
|
|
||||||
|
return !!draft;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the handler is enabled on a site level.
|
||||||
|
*
|
||||||
|
* @return True or promise resolved with true if enabled.
|
||||||
|
*/
|
||||||
|
async isEnabled(): Promise<boolean> {
|
||||||
|
// In here we should check if comments is not disabled in site.
|
||||||
|
// But due to this is not a common comments place and it can be disabled separately into Moodle (disabling the plugin).
|
||||||
|
// We are leaving it always enabled. It's also a teacher's feature.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare and add to pluginData the data to send to the server based on the draft data saved.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @param pluginData Object where to store the data to send.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return If the function is async, it should return a Promise resolved when done.
|
||||||
|
*/
|
||||||
|
prepareFeedbackData(
|
||||||
|
assignId: number,
|
||||||
|
userId: number,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
pluginData: AddonModAssignSavePluginData,
|
||||||
|
siteId?: string,
|
||||||
|
): void {
|
||||||
|
|
||||||
|
const draft = this.getDraft(assignId, userId, siteId);
|
||||||
|
|
||||||
|
if (draft) {
|
||||||
|
// Add some HTML to the text if needed.
|
||||||
|
draft.text = CoreTextUtils.instance.formatHtmlLines(draft.text);
|
||||||
|
|
||||||
|
pluginData.assignfeedbackcomments_editor = draft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save draft data of the feedback plugin.
|
||||||
|
*
|
||||||
|
* @param assignId The assignment ID.
|
||||||
|
* @param userId User ID.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @param data The data to save.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return If the function is async, it should return a Promise resolved when done.
|
||||||
|
*/
|
||||||
|
saveDraft(
|
||||||
|
assignId: number,
|
||||||
|
userId: number,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
data: AddonModAssignFeedbackCommentsDraftData,
|
||||||
|
siteId?: string,
|
||||||
|
): void {
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
this.drafts[this.getDraftId(assignId, userId, siteId)] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export const AddonModAssignFeedbackCommentsHandler = makeSingleton(AddonModAssignFeedbackCommentsHandlerService);
|
||||||
|
|
||||||
|
export type AddonModAssignFeedbackCommentsDraftData = {
|
||||||
|
text: string; // The text for this feedback.
|
||||||
|
format: number; // The format for this feedback.
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddonModAssignFeedbackCommentsPluginData = {
|
||||||
|
// Editor structure.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
assignfeedbackcomments_editor: AddonModAssignFeedbackCommentsDraftData;
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!-- Read only. -->
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="files && files.length">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{plugin.name}}</h2>
|
||||||
|
<ng-container>
|
||||||
|
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid"
|
||||||
|
[alwaysDownload]="true">
|
||||||
|
</core-file>
|
||||||
|
</ng-container>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
|
@ -0,0 +1,41 @@
|
||||||
|
// (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 { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||||
|
import { AddonModAssignProvider, AddonModAssign } from '@addons/mod/assign/services/assign';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to render a edit pdf feedback plugin.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-mod-assign-feedback-edit-pdf',
|
||||||
|
templateUrl: 'addon-mod-assign-feedback-editpdf.html',
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackEditPdfComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||||
|
|
||||||
|
component = AddonModAssignProvider.COMPONENT;
|
||||||
|
files: CoreWSExternalFile[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
if (this.plugin) {
|
||||||
|
this.files = AddonModAssign.instance.getSubmissionPluginAttachments(this.plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// (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 { AddonModAssignFeedbackEditPdfHandler } from './services/handler';
|
||||||
|
import { AddonModAssignFeedbackEditPdfComponent } from './component/editpdf';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonModAssignFeedbackEditPdfComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreSharedModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
AddonModAssignFeedbackEditPdfHandler,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
multi: true,
|
||||||
|
deps: [],
|
||||||
|
useFactory: () => () => {
|
||||||
|
AddonModAssignFeedbackDelegate.instance.registerHandler(AddonModAssignFeedbackEditPdfHandler.instance);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AddonModAssignFeedbackEditPdfComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
AddonModAssignFeedbackEditPdfComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackEditPdfModule {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"pluginname": "Annotate PDF"
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
// (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 {
|
||||||
|
AddonModAssignPlugin,
|
||||||
|
AddonModAssignAssign,
|
||||||
|
AddonModAssignSubmission,
|
||||||
|
AddonModAssign,
|
||||||
|
} from '@addons/mod/assign/services/assign';
|
||||||
|
import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedback-delegate';
|
||||||
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for edit pdf feedback plugin.
|
||||||
|
*/
|
||||||
|
@Injectable( { providedIn: 'root' })
|
||||||
|
export class AddonModAssignFeedbackEditPdfHandlerService implements AddonModAssignFeedbackHandler {
|
||||||
|
|
||||||
|
name = 'AddonModAssignFeedbackEditPdfHandler';
|
||||||
|
type = 'editpdf';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Component to use to display the plugin data.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
|
*
|
||||||
|
* @return The component (or promise resolved with component) to use, undefined if not found.
|
||||||
|
*/
|
||||||
|
getComponent(): Type<unknown> {
|
||||||
|
return AddonModAssignFeedbackEditPdfComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get files used by this plugin.
|
||||||
|
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||||
|
*
|
||||||
|
* @param assign The assignment.
|
||||||
|
* @param submission The submission.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @return The files (or promise resolved with the files).
|
||||||
|
*/
|
||||||
|
getPluginFiles(
|
||||||
|
assign: AddonModAssignAssign,
|
||||||
|
submission: AddonModAssignSubmission,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
): CoreWSExternalFile[] {
|
||||||
|
return AddonModAssign.instance.getSubmissionPluginAttachments(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 const AddonModAssignFeedbackEditPdfHandler = makeSingleton(AddonModAssignFeedbackEditPdfHandlerService);
|
|
@ -0,0 +1,27 @@
|
||||||
|
// (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 { AddonModAssignFeedbackCommentsModule } from './comments/comments.module';
|
||||||
|
import { AddonModAssignFeedbackEditPdfModule } from './editpdf/editpdf.module';
|
||||||
|
import { AddonModAssignFeedbackFileModule } from './file/file.module';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
AddonModAssignFeedbackCommentsModule,
|
||||||
|
AddonModAssignFeedbackEditPdfModule,
|
||||||
|
AddonModAssignFeedbackFileModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackModule { }
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!-- Read only. -->
|
||||||
|
<ion-item class="ion-text-wrap" *ngIf="files && files.length">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{plugin.name}}</h2>
|
||||||
|
<ng-container>
|
||||||
|
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid"
|
||||||
|
[alwaysDownload]="true">
|
||||||
|
</core-file>
|
||||||
|
</ng-container>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
|
@ -0,0 +1,41 @@
|
||||||
|
// (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 { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||||
|
import { AddonModAssign, AddonModAssignProvider } from '@addons/mod/assign/services/assign';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to render a file feedback plugin.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-mod-assign-feedback-file',
|
||||||
|
templateUrl: 'addon-mod-assign-feedback-file.html',
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackFileComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||||
|
|
||||||
|
component = AddonModAssignProvider.COMPONENT;
|
||||||
|
files: CoreWSExternalFile[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component being initialized.
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
if (this.plugin) {
|
||||||
|
this.files = AddonModAssign.instance.getSubmissionPluginAttachments(this.plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// (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 { AddonModAssignFeedbackFileHandler } from './services/handler';
|
||||||
|
import { AddonModAssignFeedbackFileComponent } from './component/file';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonModAssignFeedbackFileComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreSharedModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
AddonModAssignFeedbackFileHandler,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
multi: true,
|
||||||
|
deps: [],
|
||||||
|
useFactory: () => () => {
|
||||||
|
AddonModAssignFeedbackDelegate.instance.registerHandler(AddonModAssignFeedbackFileHandler.instance);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AddonModAssignFeedbackFileComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
AddonModAssignFeedbackFileComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModAssignFeedbackFileModule {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"pluginname": "File feedback"
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
// (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 {
|
||||||
|
AddonModAssignPlugin,
|
||||||
|
AddonModAssignAssign,
|
||||||
|
AddonModAssignSubmission,
|
||||||
|
AddonModAssign,
|
||||||
|
} from '@addons/mod/assign/services/assign';
|
||||||
|
import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedback-delegate';
|
||||||
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
import { CoreWSExternalFile } from '@services/ws';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { AddonModAssignFeedbackFileComponent } from '../component/file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for file feedback plugin.
|
||||||
|
*/
|
||||||
|
@Injectable( { providedIn: 'root' })
|
||||||
|
export class AddonModAssignFeedbackFileHandlerService implements AddonModAssignFeedbackHandler {
|
||||||
|
|
||||||
|
name = 'AddonModAssignFeedbackFileHandler';
|
||||||
|
type = 'file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Component to use to display the plugin data.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
|
*
|
||||||
|
* @return The component (or promise resolved with component) to use, undefined if not found.
|
||||||
|
*/
|
||||||
|
getComponent(): Type<unknown> {
|
||||||
|
return AddonModAssignFeedbackFileComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get files used by this plugin.
|
||||||
|
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||||
|
*
|
||||||
|
* @param assign The assignment.
|
||||||
|
* @param submission The submission.
|
||||||
|
* @param plugin The plugin object.
|
||||||
|
* @return The files (or promise resolved with the files).
|
||||||
|
*/
|
||||||
|
getPluginFiles(
|
||||||
|
assign: AddonModAssignAssign,
|
||||||
|
submission: AddonModAssignSubmission,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
): CoreWSExternalFile[] {
|
||||||
|
return AddonModAssign.instance.getSubmissionPluginAttachments(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 const AddonModAssignFeedbackFileHandler = makeSingleton(AddonModAssignFeedbackFileHandlerService);
|
|
@ -58,7 +58,11 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Data (or promise resolved with the data).
|
* @return Data (or promise resolved with the data).
|
||||||
*/
|
*/
|
||||||
getDraft?(assignId: number, userId: number, siteId?: string): any | Promise<any>;
|
getDraft?(
|
||||||
|
assignId: number,
|
||||||
|
userId: number,
|
||||||
|
siteId?: string,
|
||||||
|
): Record<string, unknown> | Promise<Record<string, unknown> | undefined> | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get files used by this plugin.
|
* Get files used by this plugin.
|
||||||
|
@ -99,7 +103,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
|
||||||
assign: AddonModAssignAssign,
|
assign: AddonModAssignAssign,
|
||||||
submission: AddonModAssignSubmission,
|
submission: AddonModAssignSubmission,
|
||||||
plugin: AddonModAssignPlugin,
|
plugin: AddonModAssignPlugin,
|
||||||
inputData: any,
|
inputData: Record<string, unknown>,
|
||||||
userId: number,
|
userId: number,
|
||||||
): boolean | Promise<boolean>;
|
): boolean | Promise<boolean>;
|
||||||
|
|
||||||
|
@ -158,7 +162,13 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return If the function is async, it should return a Promise resolved when done.
|
* @return If the function is async, it should return a Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
saveDraft?(assignId: number, userId: number, plugin: AddonModAssignPlugin, data: any, siteId?: string): void | Promise<any>;
|
saveDraft?(
|
||||||
|
assignId: number,
|
||||||
|
userId: number,
|
||||||
|
plugin: AddonModAssignPlugin,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
siteId?: string,
|
||||||
|
): void | Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +199,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
|
||||||
userId: number,
|
userId: number,
|
||||||
plugin: AddonModAssignPlugin,
|
plugin: AddonModAssignPlugin,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<any | undefined> {
|
): Promise<void> {
|
||||||
return await this.executeFunctionOnEnabled(plugin.type, 'discardDraft', [assignId, userId, siteId]);
|
return await this.executeFunctionOnEnabled(plugin.type, 'discardDraft', [assignId, userId, siteId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,12 +222,12 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved with the draft data.
|
* @return Promise resolved with the draft data.
|
||||||
*/
|
*/
|
||||||
async getPluginDraftData(
|
async getPluginDraftData<T>(
|
||||||
assignId: number,
|
assignId: number,
|
||||||
userId: number,
|
userId: number,
|
||||||
plugin: AddonModAssignPlugin,
|
plugin: AddonModAssignPlugin,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<any | undefined> {
|
): Promise<T | undefined> {
|
||||||
return await this.executeFunctionOnEnabled(plugin.type, 'getDraft', [assignId, userId, siteId]);
|
return await this.executeFunctionOnEnabled(plugin.type, 'getDraft', [assignId, userId, siteId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +277,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
|
||||||
assign: AddonModAssignAssign,
|
assign: AddonModAssignAssign,
|
||||||
submission: AddonModAssignSubmission | AddonModAssignSubmissionFormatted,
|
submission: AddonModAssignSubmission | AddonModAssignSubmissionFormatted,
|
||||||
plugin: AddonModAssignPlugin,
|
plugin: AddonModAssignPlugin,
|
||||||
inputData: any,
|
inputData: Record<string, unknown>,
|
||||||
userId: number,
|
userId: number,
|
||||||
): Promise<boolean | undefined> {
|
): Promise<boolean | undefined> {
|
||||||
return await this.executeFunctionOnEnabled(
|
return await this.executeFunctionOnEnabled(
|
||||||
|
@ -362,9 +372,9 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
|
||||||
assignId: number,
|
assignId: number,
|
||||||
userId: number,
|
userId: number,
|
||||||
plugin: AddonModAssignPlugin,
|
plugin: AddonModAssignPlugin,
|
||||||
inputData: any,
|
inputData: Record<string, unknown>,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<any> {
|
): Promise<void> {
|
||||||
return await this.executeFunctionOnEnabled(
|
return await this.executeFunctionOnEnabled(
|
||||||
plugin.type,
|
plugin.type,
|
||||||
'saveDraft',
|
'saveDraft',
|
||||||
|
|
|
@ -41,8 +41,9 @@ export class AddonModAssignDefaultFeedbackHandler implements AddonModAssignFeedb
|
||||||
*
|
*
|
||||||
* @return Data (or promise resolved with the data).
|
* @return Data (or promise resolved with the data).
|
||||||
*/
|
*/
|
||||||
getDraft(): void {
|
getDraft(): undefined {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue