MOBILE-2354 workshop: Integrate assessment strategy and some fixes

main
Albert Gasset 2018-06-11 16:18:36 +02:00
parent e7582678f9
commit 71a5999c60
8 changed files with 75 additions and 57 deletions

View File

@ -67,6 +67,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
protected obsSubmissionChanged: any;
protected obsAssessmentSaved: any;
protected appResumeSubscription: any;
protected syncObserver: any;
constructor(injector: Injector, private workshopProvider: AddonModWorkshopProvider, @Optional() content: Content,
private workshopOffline: AddonModWorkshopOfflineProvider, private groupsProvider: CoreGroupsProvider,
@ -92,6 +93,12 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
this.loaded = false;
this.refreshContent(true, false);
});
// Refresh workshop on sync.
this.syncObserver = this.eventsProvider.on(AddonModWorkshopSyncProvider.AUTO_SYNCED, (data) => {
// Update just when all database is synced.
this.eventReceived(data);
}, this.siteId);
}
/**
@ -300,7 +307,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
module: this.module,
access: this.access,
courseId: this.courseId,
submission: this.submission
submissionId: this.submission && this.submission.id
};
this.navCtrl.push('AddonModWorkshopEditSubmissionPage', params);

View File

@ -42,6 +42,7 @@
"submissiongrade": "Grade for submission",
"submissiongradeof": "Grade for submission (of {{$a}})",
"submissionrequiredcontent": "You need to enter some text or add a file.",
"submissionrequiredtitle": "You need to enter a title.",
"submissionsreport": "Workshop submissions report",
"submissiontitle": "Title",
"switchphase10": "Switch to the setup phase",

View File

@ -20,14 +20,13 @@
</ion-avatar>
<h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2>
<p *ngIf="assessment && showGrade(assessment.grade)">
<p *ngIf="workshop && assessment && showGrade(assessment.grade)">
{{ 'addon.mod_workshop.submissiongradeof' | translate:{$a: workshop.grade } }}: {{assessment.grade}}
</p>
<p *ngIf="access.canviewallsubmissions && assessment && showGrade(assessment.gradinggrade)" [class.core-has-overriden-grade]=" showGrade(assessment.gradinggrade)">
<p *ngIf="access && access.canviewallsubmissions && assessment && showGrade(assessment.gradinggrade)" [class.core-has-overriden-grade]=" showGrade(assessment.gradinggrade)">
{{ 'addon.mod_workshop.gradinggradeof' | translate:{$a: workshop.gradinggrade } }}: {{assessment.gradinggrade}}
</p>
<p *ngIf="access.canviewallsubmissions && assessment && showGrade(assessment.gradinggradeover)" class="core-overriden-grade">
<p *ngIf="access && access.canviewallsubmissions && assessment && showGrade(assessment.gradinggradeover)" class="core-overriden-grade">
{{ 'addon.mod_workshop.gradinggradeover' | translate }}: {{assessment.gradinggradeover}}
</p>
<p *ngIf="assessment && assessment.weight && assessment.weight != 1">
@ -38,7 +37,7 @@
</ion-badge>
</ion-item>
<!-- <addon-mod-workshop-assessment-strategy *ngIf="assessment && assessmentId && showGrade(assessment.grade)" [workshop]="workshop" [access]="access" [assessmentId]="assessmentId" [userId]="profile.id" [strategy]="strategy"></addon-mod-workshop-assessment-strategy>-->
<addon-mod-workshop-assessment-strategy *ngIf="assessment && assessmentId && showGrade(assessment.grade) && workshop && access && profile" [workshop]="workshop" [access]="access" [assessmentId]="assessmentId" [userId]="profile.id" [strategy]="strategy"></addon-mod-workshop-assessment-strategy>
<form ion-list [formGroup]="evaluateForm" *ngIf="evaluating">
<ion-item text-wrap>

View File

@ -43,18 +43,21 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
submission: any;
profile: any;
courseId: number;
access: any = {};
access: any;
assessmentId: number;
evaluating = false;
loaded = false;
showGrade: any;
evaluateForm: FormGroup;
maxGrade: number;
workshop: any = {};
workshop: any;
strategy: any;
title: string;
evaluate: any;
evaluate = {
text: '',
grade: -1,
weight: 1
};
weights = [];
evaluateByProfile: any;
evaluationGrades: any;
@ -76,10 +79,10 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
protected domUtils: CoreDomUtilsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected userProvider: CoreUserProvider) {
this.assessment = navParams.get('assessment') || {};
this.assessment = navParams.get('assessment');
this.submission = navParams.get('submission') || {};
this.profile = navParams.get('profile') || {};
this.courseId = navParams.get('courseId') || null;
this.profile = navParams.get('profile');
this.courseId = navParams.get('courseId');
this.assessmentId = this.assessment.assessmentid || this.assessment.id;
this.workshopId = this.submission.workshopid || null;
@ -96,7 +99,7 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
// Refresh workshop on sync.
this.syncObserver = this.eventsProvider.on(AddonModWorkshopSyncProvider.AUTO_SYNCED, (data) => {
// Update just when all database is synced.
if (this.workshopId === data.workshopid) {
if (this.workshopId === data.workshopId) {
this.loaded = false;
this.refreshAllData();
}
@ -166,10 +169,8 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
let defaultGrade, promise;
this.assessment = this.workshopHelper.realGradeValue(this.workshop, assessment);
this.evaluate = {
weight: this.assessment.weight,
text: this.assessment.feedbackreviewer
};
this.evaluate.text = this.assessment.feedbackreviewer || '';
this.evaluate.weight = this.assessment.weight;
if (this.evaluating) {
if (accessData.canallocate) {
@ -195,14 +196,14 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
this.hasOffline = true;
this.evaluate.weight = offlineAssess.weight;
if (accessData.canoverridegrades) {
this.evaluate.text = offlineAssess.feedbacktext;
this.evaluate.text = offlineAssess.feedbacktext || '';
this.evaluate.grade = offlineAssess.gradinggradeover || -1;
}
}).catch(() => {
this.hasOffline = false;
// No offline, load online.
if (accessData.canoverridegrades) {
this.evaluate.text = this.assessment.feedbackreviewer;
this.evaluate.text = this.assessment.feedbackreviewer || '';
this.evaluate.grade = this.assessment.gradinggradeover || -1;
}
});
@ -259,7 +260,7 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
return true;
}
if (this.access.canoverridegrades) {
if (this.access && this.access.canoverridegrades) {
if (this.originalEvaluation.text != inputData.text) {
return true;
}
@ -335,7 +336,6 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
// Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((rteEnabled) => {
const inputData = this.evaluateForm.value;
inputData.grade = inputData.grade >= 0 ? inputData.grade : '';
if (!rteEnabled) {
// Rich text editor not enabled, add some HTML to the message if needed.

View File

@ -40,7 +40,12 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
module: any;
courseId: number;
access: any;
submission: any;
submission = {
id: 0,
title: '',
content: '',
attachmentfiles: [],
};
loaded = false;
component = AddonModWorkshopProvider.COMPONENT;
@ -48,6 +53,7 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
editForm: FormGroup; // The form group.
protected workshopId: number;
protected submissionId: number;
protected userId: number;
protected originalData: any = {};
protected hasOffline = false;
@ -66,7 +72,7 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
this.module = navParams.get('module');
this.courseId = navParams.get('courseId');
this.access = navParams.get('access');
this.submission = navParams.get('submission') || {};
this.submissionId = navParams.get('submissionId');
this.workshopId = this.module.instance;
this.componentId = this.module.id;
@ -127,12 +133,11 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
return this.workshopProvider.getWorkshop(this.courseId, this.module.id).then((workshopData) => {
this.workshop = workshopData;
if (this.submission && this.submission.id > 0) {
if (this.submissionId > 0) {
this.editing = true;
return this.workshopHelper.getSubmissionById(this.workshopId, this.submission.id).then((submissionData) => {
return this.workshopHelper.getSubmissionById(this.workshopId, this.submissionId).then((submissionData) => {
this.submission = submissionData;
this.submission.text = submissionData.content;
const canEdit = (this.userId == submissionData.authorid && this.access.cansubmit &&
this.access.modifyingsubmissionallowed);
@ -155,19 +160,15 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
if (submissionsActions && submissionsActions.length) {
this.hasOffline = true;
const actions = this.workshopHelper.filterSubmissionActions(submissionsActions, this.editing ?
this.submission.id : false);
this.submission.id : 0);
return this.workshopHelper.applyOfflineData(this.submission, actions).then((offlineSubmission) => {
this.submission.title = offlineSubmission.title;
this.submission.text = offlineSubmission.content;
this.submission.attachmentfiles = offlineSubmission.attachmentfiles;
});
return this.workshopHelper.applyOfflineData(this.submission, actions);
} else {
this.hasOffline = false;
}
}).finally(() => {
this.originalData.title = this.submission.title;
this.originalData.content = this.submission.text;
this.originalData.content = this.submission.content;
this.originalData.attachmentfiles = [];
this.submission.attachmentfiles.forEach((file) => {
@ -295,12 +296,12 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
const inputData = this.getInputData();
if (!inputData.title) {
this.domUtils.showAlert('core.notice', 'core.requireduserdatamissing');
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredtitle');
return Promise.reject(null);
}
if (!inputData.content) {
this.domUtils.showAlert('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
return Promise.reject(null);
}
@ -309,13 +310,11 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
saveOffline = false;
const modal = this.domUtils.showModalLoading('core.sending', true),
submissionId = this.submission && (this.submission.id || this.submission.submissionid) || false;
submissionId = this.submission.id;
// Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((rteEnabled) => {
if (rteEnabled) {
inputData.content = this.textUtils.restorePluginfileUrls(inputData.content, this.submission.inlinefiles);
} else {
if (!rteEnabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
}
@ -323,14 +322,14 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
// Upload attachments first if any.
allowOffline = !inputData.attachmentfiles.length;
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, submissionId, inputData.attachmentfiles,
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id, inputData.attachmentfiles,
this.editing, saveOffline).catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
allowOffline = true;
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, submissionId, inputData.attachmentfiles,
this.editing, saveOffline);
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
inputData.attachmentfiles, this.editing, saveOffline);
});
}).then((attachmentsId) => {
if (this.editing) {

View File

@ -93,7 +93,7 @@
</ion-item>
</form>
<!--<addon-mod-workshop-assessment-strategy *ngIf="assessmentId" [workshop]="workshop" [access]="access" [assessmentId]="assessmentId" [userId]="assessmentUserId" [strategy]="strategy" [edit]="access.assessingallowed"></addon-mod-workshop-assessment-strategy>-->
<addon-mod-workshop-assessment-strategy *ngIf="assessmentId" [workshop]="workshop" [access]="access" [assessmentId]="assessmentId" [userId]="assessmentUserId" [strategy]="strategy" [edit]="access.assessingallowed"></addon-mod-workshop-assessment-strategy>
<ion-list *ngIf="assessmentId && !access.assessingallowed && assessment.feedbackreviewer">
<ion-item text-wrap>

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, OnInit, OnDestroy, Optional } from '@angular/core';
import { Component, OnInit, OnDestroy, Optional, ViewChild } from '@angular/core';
import { Content, IonicPage, NavParams, NavController } from 'ionic-angular';
import { FormGroup, FormBuilder } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
@ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreUserProvider } from '@core/user/providers/user';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { AddonModWorkshopAssessmentStrategyComponent } from '../../components/assessment-strategy/assessment-strategy';
import { AddonModWorkshopProvider } from '../../providers/workshop';
import { AddonModWorkshopHelperProvider } from '../../providers/helper';
import { AddonModWorkshopOfflineProvider } from '../../providers/offline';
@ -39,6 +40,8 @@ import { AddonModWorkshopSyncProvider } from '../../providers/sync';
})
export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
@ViewChild(AddonModWorkshopAssessmentStrategyComponent) assessmentStrategy: AddonModWorkshopAssessmentStrategyComponent;
module: any;
workshop: any;
access: any;
@ -69,7 +72,11 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
protected currentUserId: number;
protected userId: number;
protected siteId: string;
protected originalEvaluation: any = {};
protected originalEvaluation = {
published: '',
text: '',
grade: ''
};
protected hasOffline = false;
protected component = AddonModWorkshopProvider.COMPONENT;
protected forceLeave = false;
@ -89,7 +96,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
this.access = navParams.get('access');
this.courseId = navParams.get('courseId');
this.profile = navParams.get('profile');
this.submissionInfo = navParams.get('submission');
this.submissionInfo = navParams.get('submission') || {};
this.assessment = navParams.get('assessment') || null;
this.title = this.module.name;
@ -135,14 +142,11 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
* @return {boolean|Promise<void>} Resolved if we can leave it, rejected if not.
*/
ionViewCanLeave(): boolean | Promise<void> {
if (this.forceLeave || !this.canAddFeedback) {
const assessmentHasChanged = this.assessmentStrategy && this.assessmentStrategy.hasDataChanged();
if (this.forceLeave || (!this.hasEvaluationChanged() && !assessmentHasChanged)) {
return true;
}
if (!this.hasEvaluationChanged()) {
return Promise.resolve();
}
// Show confirmation if some data has been modified.
return this.domUtils.showConfirm(this.translate.instant('core.confirmcanceledit'));
}
@ -155,7 +159,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
module: module,
access: this.access,
courseid: this.courseId,
submission: this.submission
submissionId: this.submission.id
};
this.navCtrl.push('AddonModWorkshopEditSubmissionPage', params);
@ -167,7 +171,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
* @param {any} data Event data received.
*/
protected eventReceived(data: any): void {
if (this.workshopId === data.workshopid) {
if (this.workshopId === data.workshopId) {
this.content && this.content.scrollToTop();
this.loaded = false;
@ -185,6 +189,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
const promises = [];
this.submission = submissionData;
this.submission.attachmentfiles = submissionData.attachmentfiles || [];
this.submission.submissiongrade = this.submissionInfo && this.submissionInfo.submissiongrade;
this.submission.gradinggrade = this.submissionInfo && this.submissionInfo.gradinggrade;
this.submission.submissiongradeover = this.submissionInfo && this.submissionInfo.submissiongradeover;
@ -390,8 +395,16 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
* Save the assessment.
*/
saveAssessment(): void {
// Call trigger to save.
this.eventsProvider.trigger(AddonModWorkshopProvider.ASSESSMENT_SAVE, undefined, this.siteId);
if (this.assessmentStrategy && this.assessmentStrategy.hasDataChanged()) {
this.assessmentStrategy.saveAssessment().then(() => {
this.forceLeavePage();
}).catch(() => {
// Error, stay on the page.
});
} else {
// Nothing to save, just go back.
this.forceLeavePage();
}
}
/**

View File

@ -36,7 +36,6 @@ export class AddonModWorkshopProvider {
static EXAMPLES_BEFORE_ASSESSMENT: 2;
static SUBMISSION_CHANGED = 'addon_mod_workshop_submission_changed';
static ASSESSMENT_SAVE = 'addon_mod_workshop_assessment_save';
static ASSESSMENT_SAVED = 'addon_mod_workshop_assessment_saved';
static ASSESSMENT_INVALIDATED = 'addon_mod_workshop_assessment_invalidated';