MOBILE-2354 workshop: Integrate assessment strategy and some fixes
parent
e7582678f9
commit
71a5999c60
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
Loading…
Reference in New Issue