MOBILE-2334 assign: Implement feedback plugins
parent
2aa4a55d17
commit
dc74546f3d
|
@ -28,12 +28,14 @@ import { AddonModAssignModuleHandler } from './providers/module-handler';
|
|||
import { AddonModAssignPrefetchHandler } from './providers/prefetch-handler';
|
||||
import { AddonModAssignSyncCronHandler } from './providers/sync-cron-handler';
|
||||
import { AddonModAssignSubmissionModule } from './submission/submission.module';
|
||||
import { AddonModAssignFeedbackModule } from './feedback/feedback.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
],
|
||||
imports: [
|
||||
AddonModAssignSubmissionModule
|
||||
AddonModAssignSubmissionModule,
|
||||
AddonModAssignFeedbackModule
|
||||
],
|
||||
providers: [
|
||||
AddonModAssignProvider,
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Input } from '@angular/core';
|
||||
import { ModalController } from 'ionic-angular';
|
||||
|
||||
/**
|
||||
* Base class for component to render a feedback plugin.
|
||||
*/
|
||||
export class AddonModAssignFeedbackPluginComponent {
|
||||
@Input() assign: any; // The assignment.
|
||||
@Input() submission: any; // The submission.
|
||||
@Input() plugin: any; // The plugin object.
|
||||
@Input() userId: number; // The user ID of the submission.
|
||||
@Input() configs: any; // The configs for the plugin.
|
||||
@Input() canEdit: boolean; // Whether the user can edit.
|
||||
@Input() edit: boolean; // Whether the user is editing.
|
||||
|
||||
constructor(protected modalCtrl: ModalController) { }
|
||||
|
||||
/**
|
||||
* Open a modal to edit the feedback plugin.
|
||||
*
|
||||
* @return {Promise<any>} Promise resolved with the input data, rejected if cancelled.
|
||||
*/
|
||||
editFeedback(): Promise<any> {
|
||||
if (this.canEdit) {
|
||||
return new Promise((resolve, reject): void => {
|
||||
// Create the navigation modal.
|
||||
const modal = this.modalCtrl.create('AddonModAssignEditFeedbackModalPage', {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
userId: this.userId
|
||||
});
|
||||
|
||||
modal.present();
|
||||
modal.onDidDismiss((data) => {
|
||||
if (typeof data == 'undefined') {
|
||||
reject();
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return Promise.reject(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the data.
|
||||
*
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidate(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
|
@ -23,12 +23,14 @@ import { CoreCourseComponentsModule } from '@core/course/components/components.m
|
|||
import { AddonModAssignIndexComponent } from './index/index';
|
||||
import { AddonModAssignSubmissionComponent } from './submission/submission';
|
||||
import { AddonModAssignSubmissionPluginComponent } from './submission-plugin/submission-plugin';
|
||||
import { AddonModAssignFeedbackPluginComponent } from './feedback-plugin/feedback-plugin';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModAssignIndexComponent,
|
||||
AddonModAssignSubmissionComponent,
|
||||
AddonModAssignSubmissionPluginComponent
|
||||
AddonModAssignSubmissionPluginComponent,
|
||||
AddonModAssignFeedbackPluginComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -44,7 +46,8 @@ import { AddonModAssignSubmissionPluginComponent } from './submission-plugin/sub
|
|||
exports: [
|
||||
AddonModAssignIndexComponent,
|
||||
AddonModAssignSubmissionComponent,
|
||||
AddonModAssignSubmissionPluginComponent
|
||||
AddonModAssignSubmissionPluginComponent,
|
||||
AddonModAssignFeedbackPluginComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModAssignIndexComponent
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
<core-dynamic-component [component]="pluginComponent" [data]="data">
|
||||
<!-- This content will be replaced by the component if found. -->
|
||||
<core-loading [hideUntil]="pluginLoaded">
|
||||
<ion-item text-wrap *ngIf="text.length > 0 || files.length > 0">
|
||||
<h2>{{ plugin.name }}</h2>
|
||||
<ion-badge *ngIf="notSupported" color="primary">
|
||||
{{ 'addon.mod_assign.feedbacknotsupported' | translate }}
|
||||
</ion-badge>
|
||||
<p *ngIf="text">
|
||||
<core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text>
|
||||
</p>
|
||||
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file>
|
||||
</ion-item>
|
||||
</core-loading>
|
||||
</core-dynamic-component>
|
|
@ -0,0 +1,104 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit, Injector, ViewChild } from '@angular/core';
|
||||
import { AddonModAssignProvider } from '../../providers/assign';
|
||||
import { AddonModAssignHelperProvider } from '../../providers/helper';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate';
|
||||
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
|
||||
|
||||
/**
|
||||
* Component that displays an assignment feedback plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-assign-feedback-plugin',
|
||||
templateUrl: 'feedback-plugin.html',
|
||||
})
|
||||
export class AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
@ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent;
|
||||
|
||||
@Input() assign: any; // The assignment.
|
||||
@Input() submission: any; // The submission.
|
||||
@Input() plugin: any; // The plugin object.
|
||||
@Input() userId: number; // The user ID of the submission.
|
||||
@Input() canEdit: boolean | string; // Whether the user can edit.
|
||||
@Input() edit: boolean | string; // Whether the user is editing.
|
||||
|
||||
pluginComponent: any; // Component to render the plugin.
|
||||
data: any; // Data to pass to the component.
|
||||
|
||||
// Data to render the plugin if it isn't supported.
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
text = '';
|
||||
files = [];
|
||||
notSupported: boolean;
|
||||
pluginLoaded: boolean;
|
||||
|
||||
constructor(protected injector: Injector, protected feedbackDelegate: AddonModAssignFeedbackDelegate,
|
||||
protected assignProvider: AddonModAssignProvider, protected assignHelper: AddonModAssignHelperProvider) { }
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (!this.plugin) {
|
||||
this.pluginLoaded = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.plugin.name = this.feedbackDelegate.getPluginName(this.plugin);
|
||||
if (!this.plugin.name) {
|
||||
this.pluginLoaded = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.edit = this.edit && this.edit !== 'false';
|
||||
this.canEdit = this.canEdit && this.canEdit !== 'false';
|
||||
|
||||
// Check if the plugin has defined its own component to render itself.
|
||||
this.feedbackDelegate.getComponentForPlugin(this.injector, this.plugin).then((component) => {
|
||||
this.pluginComponent = component;
|
||||
|
||||
if (component) {
|
||||
// Prepare the data to pass to the component.
|
||||
this.data = {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
userId: this.userId,
|
||||
configs: this.assignHelper.getPluginConfig(this.assign, 'assignfeedback', this.plugin.type),
|
||||
edit: this.edit,
|
||||
canEdit: this.canEdit
|
||||
};
|
||||
} else {
|
||||
// Data to render the plugin.
|
||||
this.text = this.assignProvider.getSubmissionPluginText(this.plugin);
|
||||
this.files = this.assignProvider.getSubmissionPluginAttachments(this.plugin);
|
||||
this.notSupported = this.feedbackDelegate.isPluginSupported(this.plugin.type);
|
||||
this.pluginLoaded = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the plugin data.
|
||||
*
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidate(): Promise<any> {
|
||||
return Promise.resolve(this.dynamicComponent && this.dynamicComponent.callComponentFunction('invalidate', []));
|
||||
}
|
||||
}
|
|
@ -176,7 +176,7 @@
|
|||
<p item-content *ngIf="!canSaveGrades || !outcome.itemNumber">{{ outcome.selected }}</p>
|
||||
</ion-item>
|
||||
|
||||
<!-- @todo <addon-mod-assign-feedback-plugin *ngFor="let plugin of feedback.plugins" assign="assign" submission="userSubmission" userid="submitId" plugin="plugin" can-edit="canSaveGrades"></addon-mod-assign-feedback-plugin> -->
|
||||
<addon-mod-assign-feedback-plugin *ngFor="let plugin of feedback.plugins" [assign]="assign" [submission]="userSubmission" [userId]="submitId" [plugin]="plugin" [canEdit]="canSaveGrades"></addon-mod-assign-feedback-plugin>
|
||||
|
||||
<!-- Workflow status. -->
|
||||
<ion-item text-wrap *ngIf="workflowStatusTranslationId">
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModAssignFeedbackCommentsHandler } from './providers/handler';
|
||||
import { AddonModAssignFeedbackCommentsComponent } from './component/comments';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModAssignFeedbackCommentsComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModAssignFeedbackCommentsHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModAssignFeedbackCommentsComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModAssignFeedbackCommentsComponent
|
||||
]
|
||||
})
|
||||
export class AddonModAssignFeedbackCommentsModule {
|
||||
constructor(feedbackDelegate: AddonModAssignFeedbackDelegate, handler: AddonModAssignFeedbackCommentsHandler) {
|
||||
feedbackDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<!-- Read only. -->
|
||||
<ion-item text-wrap *ngIf="(text || canEdit) && !edit">
|
||||
<h2>{{ plugin.name }}</h2>
|
||||
<p>
|
||||
<core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text>
|
||||
</p>
|
||||
<div item-end>
|
||||
<div text-right>
|
||||
<a ion-button *ngIf="canEdit" (click)="editComment()" color="light">
|
||||
<ion-icon name="create"></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
<ion-note *ngIf="!isSent">
|
||||
<ion-icon name="clock"></ion-icon>
|
||||
{{ 'core.notsent' | translate }}
|
||||
</ion-note>
|
||||
</div>
|
||||
</ion-item>
|
||||
|
||||
<!-- Edit -->
|
||||
<ion-item text-wrap *ngIf="edit && loaded">
|
||||
<!-- @todo: [component]="component" [componentId]="assign.cmid" -->
|
||||
<core-rich-text-editor item-content [control]="control" [placeholder]="plugin.name" name="assignfeedbackcomments_editor"></core-rich-text-editor>
|
||||
</ion-item>
|
|
@ -0,0 +1,148 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, ElementRef } from '@angular/core';
|
||||
import { ModalController } from 'ionic-angular';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../../providers/feedback-delegate';
|
||||
import { AddonModAssignFeedbackPluginComponent } from '../../../classes/feedback-plugin-component';
|
||||
import { AddonModAssignFeedbackCommentsHandler } from '../providers/handler';
|
||||
|
||||
/**
|
||||
* Component to render a comments feedback plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-assign-feedback-comments',
|
||||
templateUrl: 'comments.html'
|
||||
})
|
||||
export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
text: string;
|
||||
isSent: boolean;
|
||||
loaded: boolean;
|
||||
|
||||
protected element: HTMLElement;
|
||||
|
||||
constructor(modalCtrl: ModalController, element: ElementRef, protected domUtils: CoreDomUtilsProvider,
|
||||
protected textUtils: CoreTextUtilsProvider, protected assignOfflineProvider: AddonModAssignOfflineProvider,
|
||||
protected assignProvider: AddonModAssignProvider, protected fb: FormBuilder,
|
||||
protected feedbackDelegate: AddonModAssignFeedbackDelegate) {
|
||||
super(modalCtrl);
|
||||
|
||||
this.element = element.nativeElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
let promise,
|
||||
rteEnabled;
|
||||
|
||||
// Check if rich text editor is enabled.
|
||||
if (this.edit) {
|
||||
promise = this.domUtils.isRichTextEditorEnabled();
|
||||
} else {
|
||||
// We aren't editing, so no rich text editor.
|
||||
promise = Promise.resolve(false);
|
||||
}
|
||||
|
||||
promise.then((enabled) => {
|
||||
rteEnabled = enabled;
|
||||
|
||||
return this.getText(rteEnabled);
|
||||
}).then((text) => {
|
||||
|
||||
this.text = text;
|
||||
|
||||
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.
|
||||
this.textUtils.expandText(this.plugin.name, this.text, this.component, this.assign.cmid);
|
||||
}
|
||||
});
|
||||
} else if (this.edit) {
|
||||
this.control = this.fb.control(text);
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the comment.
|
||||
*/
|
||||
editComment(): void {
|
||||
this.editFeedback().then((inputData) => {
|
||||
const text = AddonModAssignFeedbackCommentsHandler.getTextFromInputData(this.textUtils, this.plugin, inputData);
|
||||
|
||||
// Update the text and save it as draft.
|
||||
this.isSent = false;
|
||||
this.text = text;
|
||||
this.feedbackDelegate.saveFeedbackDraft(this.assign.id, this.userId, this.plugin, {
|
||||
text: text,
|
||||
format: 1
|
||||
});
|
||||
}).catch(() => {
|
||||
// User cancelled, nothing to do.
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for the plugin.
|
||||
*
|
||||
* @param {boolean} rteEnabled Whether Rich Text Editor is enabled.
|
||||
* @return {Promise<string>} Promise resolved with the text.
|
||||
*/
|
||||
protected getText(rteEnabled: boolean): Promise<string> {
|
||||
// Check if the user already modified the comment.
|
||||
return this.feedbackDelegate.getPluginDraftData(this.assign.id, this.userId, this.plugin).then((draft) => {
|
||||
if (draft) {
|
||||
this.isSent = false;
|
||||
|
||||
return draft.text;
|
||||
} else {
|
||||
// There is no draft saved. Check if we have anything offline.
|
||||
return this.assignOfflineProvider.getSubmissionGrade(this.assign.id, this.userId).catch(() => {
|
||||
// No offline data found.
|
||||
}).then((offlineData) => {
|
||||
if (offlineData && offlineData.plugindata && offlineData.plugindata.assignfeedbackcomments_editor) {
|
||||
// Save offline as draft.
|
||||
this.isSent = false;
|
||||
this.feedbackDelegate.saveFeedbackDraft(this.assign.id, this.userId, this.plugin,
|
||||
offlineData.plugindata.assignfeedbackcomments_editor);
|
||||
|
||||
return offlineData.plugindata.assignfeedbackcomments_editor.text;
|
||||
}
|
||||
|
||||
// No offline data found, return online text.
|
||||
this.isSent = true;
|
||||
|
||||
return this.assignProvider.getSubmissionPluginText(this.plugin, this.edit && !rteEnabled);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"pluginname": "Feedback comments"
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
|
||||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline';
|
||||
import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate';
|
||||
import { AddonModAssignFeedbackCommentsComponent } from '../component/comments';
|
||||
|
||||
/**
|
||||
* Handler for comments feedback plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeedbackHandler {
|
||||
name = 'AddonModAssignFeedbackCommentsHandler';
|
||||
type = 'comments';
|
||||
|
||||
protected drafts = {}; // Store the data in this service so it isn't lost if the user performs a PTR in the page.
|
||||
|
||||
constructor(private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
|
||||
private textUtils: CoreTextUtilsProvider, private assignProvider: AddonModAssignProvider,
|
||||
private assignOfflineProvider: AddonModAssignOfflineProvider) { }
|
||||
|
||||
/**
|
||||
* Discard the draft data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
discardDraft(assignId: number, userId: number, siteId?: string): void | Promise<any> {
|
||||
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, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModAssignFeedbackCommentsComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft saved data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {any|Promise<any>} Data (or promise resolved with the data).
|
||||
*/
|
||||
getDraft(assignId: number, userId: number, siteId?: string): any | Promise<any> {
|
||||
const id = this.getDraftId(assignId, userId, siteId);
|
||||
|
||||
if (typeof this.drafts[id] != 'undefined') {
|
||||
return this.drafts[id];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a draft ID.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {string} Draft ID.
|
||||
*/
|
||||
protected getDraftId(assignId: number, userId: number, siteId?: string): string {
|
||||
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
return siteId + '#' + assignId + '#' + userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text to submit.
|
||||
*
|
||||
* @param {CoreTextUtilsProvider} textUtils Text utils instance.
|
||||
* @param {any} plugin Plugin.
|
||||
* @param {any} inputData Data entered in the feedback edit form.
|
||||
* @return {string} Text to submit.
|
||||
*/
|
||||
static getTextFromInputData(textUtils: CoreTextUtilsProvider, plugin: any, inputData: any): string {
|
||||
const files = plugin.fileareas && plugin.fileareas[0] ? plugin.fileareas[0].files : [];
|
||||
let text = inputData.assignfeedbackcomments_editor;
|
||||
|
||||
// The input data can have a string or an object with text and format. Get the text.
|
||||
if (text && text.text) {
|
||||
text = text.text;
|
||||
}
|
||||
|
||||
return textUtils.restorePluginfileUrls(text, files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the feedback data has changed for this plugin.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} inputData Data entered by the user for the feedback.
|
||||
* @param {number} userId User ID of the submission.
|
||||
* @return {boolean|Promise<boolean>} Boolean (or promise resolved with boolean): whether the data has changed.
|
||||
*/
|
||||
hasDataChanged(assign: any, submission: any, plugin: any, inputData: any, userId: number): boolean | Promise<boolean> {
|
||||
// Get it from plugin or offline.
|
||||
return this.assignOfflineProvider.getSubmissionGrade(assign.id, userId).catch(() => {
|
||||
// No offline data found.
|
||||
}).then((data) => {
|
||||
if (data && data.plugindata && data.plugindata.assignfeedbackcomments_editor) {
|
||||
return data.plugindata.assignfeedbackcomments_editor.text;
|
||||
}
|
||||
|
||||
// No offline data found, get text from plugin.
|
||||
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
|
||||
return this.assignProvider.getSubmissionPluginText(plugin, !enabled);
|
||||
});
|
||||
}).then((initialText) => {
|
||||
const newText = AddonModAssignFeedbackCommentsHandler.getTextFromInputData(this.textUtils, 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 {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {boolean|Promise<boolean>} 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 {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled for edit on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} Whether or not the handler is enabled for edit on a site level.
|
||||
*/
|
||||
isEnabledForEdit(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and add to pluginData the data to send to the server based on the draft data saved.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} pluginData Object where to store the data to send.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
prepareFeedbackData(assignId: number, userId: number, plugin: any, pluginData: any, siteId?: string): void | Promise<any> {
|
||||
const draft = this.getDraft(assignId, userId, siteId);
|
||||
|
||||
if (draft) {
|
||||
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
|
||||
if (!enabled) {
|
||||
// Rich text editor not enabled, add some HTML to the text if needed.
|
||||
draft.text = this.textUtils.formatHtmlLines(draft.text);
|
||||
}
|
||||
|
||||
pluginData.assignfeedbackcomments_editor = draft;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save draft data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} data The data to save.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
saveDraft(assignId: number, userId: number, plugin: any, data: any, siteId?: string): void | Promise<any> {
|
||||
if (data) {
|
||||
this.drafts[this.getDraftId(assignId, userId, siteId)] = data;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<!-- Read only. -->
|
||||
<ion-item text-wrap *ngIf="files && files.length">
|
||||
<h2>{{plugin.name}}</h2>
|
||||
<div no-lines>
|
||||
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file>
|
||||
</div>
|
||||
</ion-item>
|
|
@ -0,0 +1,44 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController } from 'ionic-angular';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignFeedbackPluginComponent } from '../../../classes/feedback-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render a edit pdf feedback plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-assign-feedback-edit-pdf',
|
||||
templateUrl: 'editpdf.html'
|
||||
})
|
||||
export class AddonModAssignFeedbackEditPdfComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
files: any[];
|
||||
|
||||
constructor(modalCtrl: ModalController, protected assignProvider: AddonModAssignProvider) {
|
||||
super(modalCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.plugin) {
|
||||
this.files = this.assignProvider.getSubmissionPluginAttachments(this.plugin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModAssignFeedbackEditPdfHandler } from './providers/handler';
|
||||
import { AddonModAssignFeedbackEditPdfComponent } from './component/editpdf';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModAssignFeedbackEditPdfComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModAssignFeedbackEditPdfHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModAssignFeedbackEditPdfComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModAssignFeedbackEditPdfComponent
|
||||
]
|
||||
})
|
||||
export class AddonModAssignFeedbackEditPdfModule {
|
||||
constructor(feedbackDelegate: AddonModAssignFeedbackDelegate, handler: AddonModAssignFeedbackEditPdfHandler) {
|
||||
feedbackDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"pluginname": "Annotate PDF"
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate';
|
||||
import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf';
|
||||
|
||||
/**
|
||||
* Handler for edit pdf feedback plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModAssignFeedbackEditPdfHandler implements AddonModAssignFeedbackHandler {
|
||||
name = 'AddonModAssignFeedbackEditPdfHandler';
|
||||
type = 'editpdf';
|
||||
|
||||
constructor(private assignProvider: AddonModAssignProvider) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModAssignFeedbackEditPdfComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files used by this plugin.
|
||||
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {any[]|Promise<any[]>} The files (or promise resolved with the files).
|
||||
*/
|
||||
getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> {
|
||||
return this.assignProvider.getSubmissionPluginAttachments(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AddonModAssignFeedbackCommentsModule } from './comments/comments.module';
|
||||
import { AddonModAssignFeedbackEditPdfModule } from './editpdf/editpdf.module';
|
||||
import { AddonModAssignFeedbackFileModule } from './file/file.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
AddonModAssignFeedbackCommentsModule,
|
||||
AddonModAssignFeedbackEditPdfModule,
|
||||
AddonModAssignFeedbackFileModule
|
||||
],
|
||||
providers: [
|
||||
],
|
||||
exports: []
|
||||
})
|
||||
export class AddonModAssignFeedbackModule { }
|
|
@ -0,0 +1,7 @@
|
|||
<!-- Read only. -->
|
||||
<ion-item text-wrap *ngIf="files && files.length">
|
||||
<h2>{{plugin.name}}</h2>
|
||||
<div no-lines>
|
||||
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file>
|
||||
</div>
|
||||
</ion-item>
|
|
@ -0,0 +1,44 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController } from 'ionic-angular';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignFeedbackPluginComponent } from '../../../classes/feedback-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render a file feedback plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-assign-feedback-file',
|
||||
templateUrl: 'file.html'
|
||||
})
|
||||
export class AddonModAssignFeedbackFileComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
files: any[];
|
||||
|
||||
constructor(modalCtrl: ModalController, protected assignProvider: AddonModAssignProvider) {
|
||||
super(modalCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
if (this.plugin) {
|
||||
this.files = this.assignProvider.getSubmissionPluginAttachments(this.plugin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModAssignFeedbackFileHandler } from './providers/handler';
|
||||
import { AddonModAssignFeedbackFileComponent } from './component/file';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModAssignFeedbackFileComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModAssignFeedbackFileHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModAssignFeedbackFileComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModAssignFeedbackFileComponent
|
||||
]
|
||||
})
|
||||
export class AddonModAssignFeedbackFileModule {
|
||||
constructor(feedbackDelegate: AddonModAssignFeedbackDelegate, handler: AddonModAssignFeedbackFileHandler) {
|
||||
feedbackDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"pluginname": "File feedback"
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { AddonModAssignProvider } from '../../../providers/assign';
|
||||
import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate';
|
||||
import { AddonModAssignFeedbackFileComponent } from '../component/file';
|
||||
|
||||
/**
|
||||
* Handler for file feedback plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModAssignFeedbackFileHandler implements AddonModAssignFeedbackHandler {
|
||||
name = 'AddonModAssignFeedbackFileHandler';
|
||||
type = 'file';
|
||||
|
||||
constructor(private assignProvider: AddonModAssignProvider) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModAssignFeedbackFileComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files used by this plugin.
|
||||
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {any[]|Promise<any[]>} The files (or promise resolved with the files).
|
||||
*/
|
||||
getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> {
|
||||
return this.assignProvider.getSubmissionPluginAttachments(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title><core-format-text [text]="plugin.name"></core-format-text></ion-title>
|
||||
<ion-buttons end>
|
||||
<button ion-button icon-only (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<form name="addon-mod_assign-edit-feedback-form" *ngIf="userId && plugin">
|
||||
<addon-mod-assign-feedback-plugin [assign]="assign" [submission]="submission" [userId]="userId" [plugin]="plugin" [edit]="true"></addon-mod-assign-feedback-plugin>
|
||||
<button ion-button block (click)="done()">{{ 'core.done' | translate }}</button>
|
||||
</form>
|
||||
</ion-content>
|
|
@ -0,0 +1,35 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { IonicPageModule } from 'ionic-angular';
|
||||
import { AddonModAssignEditFeedbackModalPage } from './edit-feedback-modal';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
import { AddonModAssignComponentsModule } from '../../components/components.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModAssignEditFeedbackModalPage
|
||||
],
|
||||
imports: [
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
AddonModAssignComponentsModule,
|
||||
IonicPageModule.forChild(AddonModAssignEditFeedbackModalPage),
|
||||
TranslateModule.forChild()
|
||||
]
|
||||
})
|
||||
export class AddonModAssignEditFeedbackModalPageModule {}
|
|
@ -0,0 +1,103 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { IonicPage, ViewController, NavParams } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate';
|
||||
|
||||
/**
|
||||
* Modal that allows editing a feedback plugin.
|
||||
*/
|
||||
@IonicPage({ segment: 'addon-mod-assign-edit-feedback-modal' })
|
||||
@Component({
|
||||
selector: 'page-addon-mod-assign-edit-feedback-modal',
|
||||
templateUrl: 'edit-feedback-modal.html',
|
||||
})
|
||||
export class AddonModAssignEditFeedbackModalPage {
|
||||
|
||||
@Input() assign: any; // The assignment.
|
||||
@Input() submission: any; // The submission.
|
||||
@Input() plugin: any; // The plugin object.
|
||||
@Input() userId: number; // The user ID of the submission.
|
||||
|
||||
protected forceLeave = false; // To allow leaving the page without checking for changes.
|
||||
|
||||
constructor(params: NavParams, protected viewCtrl: ViewController, protected domUtils: CoreDomUtilsProvider,
|
||||
protected translate: TranslateService, protected feedbackDelegate: AddonModAssignFeedbackDelegate) {
|
||||
|
||||
this.assign = params.get('assign');
|
||||
this.submission = params.get('submission');
|
||||
this.plugin = params.get('plugin');
|
||||
this.userId = params.get('userId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can leave the page or not.
|
||||
*
|
||||
* @return {boolean|Promise<void>} Resolved if we can leave it, rejected if not.
|
||||
*/
|
||||
ionViewCanLeave(): boolean | Promise<void> {
|
||||
if (this.forceLeave) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.hasDataChanged().then((changed) => {
|
||||
if (changed) {
|
||||
return this.domUtils.showConfirm(this.translate.instant('core.confirmcanceledit'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal.
|
||||
*
|
||||
* @param {any} data Data to return to the page.
|
||||
*/
|
||||
closeModal(data: any): void {
|
||||
this.viewCtrl.dismiss(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Done editing.
|
||||
*/
|
||||
done(): void {
|
||||
// Close the modal, sending the input data.
|
||||
this.forceLeave = true;
|
||||
this.closeModal(this.getInputData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input data.
|
||||
*
|
||||
* @return {any} Object with the data.
|
||||
*/
|
||||
protected getInputData(): any {
|
||||
return this.domUtils.getDataFromForm(document.forms['addon-mod_assign-edit-feedback-form']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if data has changed.
|
||||
*
|
||||
* @return {Promise<boolean>} Promise resolved with boolean: whether the data has changed.
|
||||
*/
|
||||
protected hasDataChanged(): Promise<boolean> {
|
||||
return this.feedbackDelegate.hasPluginDataChanged(this.assign, this.userId, this.plugin, this.getInputData(), this.userId)
|
||||
.catch(() => {
|
||||
// Ignore errors.
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue