239 lines
9.1 KiB
TypeScript

// (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 } from '@angular/core';
import { IonicPage, NavParams } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModLessonProvider } from '../../providers/lesson';
import { AddonModLessonHelperProvider } from '../../providers/helper';
/**
* Page that displays a retake made by a certain user.
*/
@IonicPage({ segment: 'addon-mod-lesson-user-retake' })
@Component({
selector: 'page-addon-mod-lesson-user-retake',
templateUrl: 'user-retake.html',
})
export class AddonModLessonUserRetakePage implements OnInit {
component = AddonModLessonProvider.COMPONENT;
lesson: any; // The lesson the retake belongs to.
courseId: number; // Course ID the lesson belongs to.
selectedRetake: number; // The retake to see.
student: any; // Data about the student and his retakes.
retake: any; // Data about the retake.
loaded: boolean; // Whether the data has been loaded.
protected lessonId: number; // The lesson ID the retake belongs to.
protected userId: number; // User ID to see the retakes.
protected retakeNumber: number; // Number of the initial retake to see.
protected previousSelectedRetake: number; // To be able to detect the previous selected retake when it has changed.
constructor(navParams: NavParams, sitesProvider: CoreSitesProvider, protected textUtils: CoreTextUtilsProvider,
protected translate: TranslateService, protected domUtils: CoreDomUtilsProvider,
protected userProvider: CoreUserProvider, protected timeUtils: CoreTimeUtilsProvider,
protected lessonProvider: AddonModLessonProvider, protected lessonHelper: AddonModLessonHelperProvider,
protected utils: CoreUtilsProvider) {
this.lessonId = navParams.get('lessonId');
this.courseId = navParams.get('courseId');
this.userId = navParams.get('userId') || sitesProvider.getCurrentSiteUserId();
this.retakeNumber = navParams.get('retake');
}
/**
* Component being initialized.
*/
ngOnInit(): void {
// Fetch the data.
this.fetchData().finally(() => {
this.loaded = true;
});
}
/**
* Change the retake displayed.
*
* @param retakeNumber The new retake number.
*/
changeRetake(retakeNumber: number): void {
this.loaded = false;
this.setRetake(retakeNumber).catch((error) => {
this.selectedRetake = this.previousSelectedRetake;
this.domUtils.showErrorModal(this.utils.addDataNotDownloadedError(error, 'Error getting attempt.'));
}).finally(() => {
this.loaded = true;
});
}
/**
* Pull to refresh.
*
* @param refresher Refresher.
*/
doRefresh(refresher: any): void {
this.refreshData().finally(() => {
refresher.complete();
});
}
/**
* Get lesson and retake data.
*
* @return Promise resolved when done.
*/
protected fetchData(): Promise<any> {
return this.lessonProvider.getLessonById(this.courseId, this.lessonId).then((lessonData) => {
this.lesson = lessonData;
// Get the retakes overview for all participants.
return this.lessonProvider.getRetakesOverview(this.lesson.id, {
cmId: this.lesson.coursemodule,
});
}).then((data) => {
// Search the student.
let student;
if (data && data.students) {
for (let i = 0; i < data.students.length; i++) {
if (data.students[i].id == this.userId) {
student = data.students[i];
break;
}
}
}
if (!student) {
// Student not found.
return Promise.reject(this.translate.instant('addon.mod_lesson.cannotfinduser'));
}
if (!student.attempts || !student.attempts.length) {
// No retakes.
return Promise.reject(this.translate.instant('addon.mod_lesson.cannotfindattempt'));
}
student.bestgrade = this.textUtils.roundToDecimals(student.bestgrade, 2);
student.attempts.forEach((retake) => {
if (!this.selectedRetake && this.retakeNumber == retake.try) {
// The retake specified as parameter exists. Use it.
this.selectedRetake = this.retakeNumber;
}
retake.label = this.lessonHelper.getRetakeLabel(retake);
});
if (!this.selectedRetake) {
// Retake number not specified or not valid, use the last retake.
this.selectedRetake = student.attempts[student.attempts.length - 1].try;
}
// Get the profile image of the user.
return this.userProvider.getProfile(student.id, this.courseId, true).then((user) => {
student.profileimageurl = user.profileimageurl;
return student;
}).catch(() => {
// Error getting profile, resolve promise without adding any extra data.
return student;
});
}).then((student) => {
this.student = student;
return this.setRetake(this.selectedRetake);
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Error getting data.', true);
});
}
/**
* Refreshes data.
*
* @return Promise resolved when done.
*/
protected refreshData(): Promise<any> {
const promises = [];
promises.push(this.lessonProvider.invalidateLessonData(this.courseId));
if (this.lesson) {
promises.push(this.lessonProvider.invalidateRetakesOverview(this.lesson.id));
promises.push(this.lessonProvider.invalidateUserRetakesForUser(this.lesson.id, this.userId));
}
return Promise.all(promises).catch(() => {
// Ignore errors.
}).then(() => {
return this.fetchData();
});
}
/**
* Set the retake to view and load its data.
*
* @param retakeNumber Retake number to set.
* @return Promise resolved when done.
*/
protected setRetake(retakeNumber: number): Promise<any> {
this.selectedRetake = retakeNumber;
return this.lessonProvider.getUserRetake(this.lessonId, retakeNumber, {
cmId: this.lesson.coursemodule,
userId: this.userId,
}).then((data) => {
if (data && data.completed != -1) {
// Completed.
data.userstats.grade = this.textUtils.roundToDecimals(data.userstats.grade, 2);
data.userstats.timetakenReadable = this.timeUtils.formatTime(data.userstats.timetotake);
}
if (data && data.answerpages) {
// Format pages data.
data.answerpages.forEach((page) => {
if (this.lessonProvider.answerPageIsContent(page)) {
page.isContent = true;
if (page.answerdata && page.answerdata.answers) {
page.answerdata.answers.forEach((answer) => {
// Content pages only have 1 valid field in the answer array.
answer[0] = this.lessonHelper.getContentPageAnswerDataFromHtml(answer[0]);
});
}
} else if (this.lessonProvider.answerPageIsQuestion(page)) {
page.isQuestion = true;
if (page.answerdata && page.answerdata.answers) {
page.answerdata.answers.forEach((answer) => {
// Only the first field of the answer array requires to be parsed.
answer[0] = this.lessonHelper.getQuestionPageAnswerDataFromHtml(answer[0]);
});
}
}
});
}
this.retake = data;
this.previousSelectedRetake = this.selectedRetake;
});
}
}