MOBILE-3651 quiz: Change routes to use cmId
parent
33003da29d
commit
6ae95070d2
|
@ -413,7 +413,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
try {
|
||||
await AddonModQuiz.instance.getAttemptReview(attemptId, { page: -1, cmId: this.module!.id });
|
||||
|
||||
CoreNavigator.instance.navigate(`../../review/${this.courseId}/${this.quiz!.id}/${attemptId}`);
|
||||
await CoreNavigator.instance.navigate(`review/${attemptId}`);
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
protected openQuiz(): void {
|
||||
this.hasPlayed = true;
|
||||
|
||||
CoreNavigator.instance.navigate(`../../player/${this.courseId}/${this.quiz!.id}`, {
|
||||
CoreNavigator.instance.navigate('player', {
|
||||
params: {
|
||||
moduleUrl: this.module?.url,
|
||||
},
|
||||
|
@ -639,10 +639,12 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
// Get gradebook grade.
|
||||
const data = await AddonModQuiz.instance.getGradeFromGradebook(this.courseId!, this.module!.id);
|
||||
|
||||
if (data) {
|
||||
this.gradebookData = {
|
||||
grade: data.graderaw,
|
||||
grade: 'graderaw' in data ? data.graderaw : Number(data.grade),
|
||||
feedback: data.feedback,
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
// Fallback to quiz best grade if failure or not found.
|
||||
this.gradebookData = {
|
||||
|
@ -657,7 +659,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
* @return Promise resolved when done.
|
||||
*/
|
||||
async viewAttempt(attemptId: number): Promise<void> {
|
||||
CoreNavigator.instance.navigate(`../../attempt/${this.courseId}/${this.quiz!.id}/${attemptId}`);
|
||||
CoreNavigator.instance.navigate(`attempt/${attemptId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<h2>{{ 'addon.mod_quiz.feedback' | translate }}</h2>
|
||||
<p>
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="feedback"
|
||||
contextLevel="module" [contextInstanceId]="quiz!.coursemodule" [courseId]="courseId">
|
||||
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
|
||||
</core-format-text>
|
||||
</p>
|
||||
</ion-label>
|
||||
|
|
|
@ -44,15 +44,15 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
loaded = false; // Whether data has been loaded.
|
||||
feedback?: string; // Attempt feedback.
|
||||
showReviewColumn = false;
|
||||
cmId!: number; // Course module id the attempt belongs to.
|
||||
|
||||
protected attemptId!: number; // Attempt to view.
|
||||
protected quizId!: number; // ID of the quiz the attempt belongs to.
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.quizId = CoreNavigator.instance.getRouteNumberParam('quizId')!;
|
||||
this.cmId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
|
||||
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
|
||||
this.attemptId = CoreNavigator.instance.getRouteNumberParam('attemptId')!;
|
||||
|
||||
|
@ -79,7 +79,7 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
*/
|
||||
protected async fetchQuizData(): Promise<void> {
|
||||
try {
|
||||
this.quiz = await AddonModQuiz.instance.getQuizById(this.courseId, this.quizId);
|
||||
this.quiz = await AddonModQuiz.instance.getQuiz(this.courseId, this.cmId);
|
||||
|
||||
this.componentId = this.quiz.coursemodule;
|
||||
|
||||
|
@ -123,7 +123,7 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
*/
|
||||
protected async fetchAttempt(): Promise<AddonModQuizAttemptWSData> {
|
||||
// Get all the attempts and search the one we want.
|
||||
const attempts = await AddonModQuiz.instance.getUserAttempts(this.quizId, { cmId: this.quiz!.coursemodule });
|
||||
const attempts = await AddonModQuiz.instance.getUserAttempts(this.quiz!.id, { cmId: this.cmId });
|
||||
|
||||
const attempt = attempts.find(attempt => attempt.id == this.attemptId);
|
||||
|
||||
|
@ -143,7 +143,7 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async fetchAccessInfo(): Promise<AddonModQuizGetQuizAccessInformationWSResponse> {
|
||||
const accessInfo = await AddonModQuiz.instance.getQuizAccessInformation(this.quizId, { cmId: this.quiz!.coursemodule });
|
||||
const accessInfo = await AddonModQuiz.instance.getQuizAccessInformation(this.quiz!.id, { cmId: this.cmId });
|
||||
|
||||
if (!accessInfo.canreviewmyattempts) {
|
||||
return accessInfo;
|
||||
|
@ -171,13 +171,16 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
const promises: Promise<void>[] = [];
|
||||
|
||||
promises.push(AddonModQuiz.instance.invalidateQuizData(this.courseId));
|
||||
promises.push(AddonModQuiz.instance.invalidateUserAttemptsForUser(this.quizId));
|
||||
promises.push(AddonModQuiz.instance.invalidateQuizAccessInformation(this.quizId));
|
||||
promises.push(AddonModQuiz.instance.invalidateCombinedReviewOptionsForUser(this.quizId));
|
||||
promises.push(AddonModQuiz.instance.invalidateAttemptReview(this.attemptId));
|
||||
|
||||
if (this.quiz) {
|
||||
promises.push(AddonModQuiz.instance.invalidateUserAttemptsForUser(this.quiz.id));
|
||||
promises.push(AddonModQuiz.instance.invalidateQuizAccessInformation(this.quiz.id));
|
||||
promises.push(AddonModQuiz.instance.invalidateCombinedReviewOptionsForUser(this.quiz.id));
|
||||
|
||||
if (this.attempt && typeof this.feedback != 'undefined') {
|
||||
promises.push(AddonModQuiz.instance.invalidateFeedback(this.quizId));
|
||||
promises.push(AddonModQuiz.instance.invalidateFeedback(this.quiz.id));
|
||||
}
|
||||
}
|
||||
|
||||
await CoreUtils.instance.ignoreErrors(Promise.all(promises));
|
||||
|
@ -191,7 +194,7 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
* @return Promise resolved when done.
|
||||
*/
|
||||
async reviewAttempt(): Promise<void> {
|
||||
CoreNavigator.instance.navigate(`../../../../review/${this.courseId}/${this.quiz!.id}/${this.attempt!.id}`);
|
||||
CoreNavigator.instance.navigate(`../../review/${this.attempt!.id}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,8 +78,8 @@
|
|||
|
||||
<!-- Body of the question. -->
|
||||
<core-question class="ion-text-wrap" [question]="question" [component]="component"
|
||||
[componentId]="quiz!.coursemodule" [attemptId]="attempt!.id" [usageId]="attempt!.uniqueid"
|
||||
[offlineEnabled]="offline" contextLevel="module" [contextInstanceId]="quiz!.coursemodule"
|
||||
[componentId]="cmId" [attemptId]="attempt!.id" [usageId]="attempt!.uniqueid"
|
||||
[offlineEnabled]="offline" contextLevel="module" [contextInstanceId]="cmId"
|
||||
[courseId]="courseId" [preferredBehaviour]="quiz!.preferredbehaviour" [review]="false"
|
||||
(onAbort)="abortQuiz()" (buttonClicked)="behaviourButtonClicked($event)">
|
||||
</core-question>
|
||||
|
|
|
@ -80,8 +80,8 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
readableTimeLimit?: string; // Time limit in a readable format.
|
||||
dueDateWarning?: string; // Warning about due date.
|
||||
courseId!: number; // The course ID the quiz belongs to.
|
||||
cmId!: number; // Course module ID.
|
||||
|
||||
protected quizId!: number; // Quiz ID to attempt.
|
||||
protected preflightData: Record<string, string> = {}; // Preflight data to attempt the quiz.
|
||||
protected quizAccessInfo?: AddonModQuizGetQuizAccessInformationWSResponse; // Quiz access information.
|
||||
protected attemptAccessInfo?: AddonModQuizGetAttemptAccessInformationWSResponse; // Attempt access info.
|
||||
|
@ -104,13 +104,10 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.quizId = CoreNavigator.instance.getRouteNumberParam('quizId')!;
|
||||
this.cmId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
|
||||
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
|
||||
this.moduleUrl = CoreNavigator.instance.getRouteParam('moduleUrl');
|
||||
|
||||
// Block the quiz so it cannot be synced.
|
||||
CoreSync.instance.blockOperation(AddonModQuizProvider.COMPONENT, this.quizId);
|
||||
|
||||
// Create the auto save instance.
|
||||
this.autoSave = new AddonModQuizAutoSave(
|
||||
'addon-mod_quiz-player-form',
|
||||
|
@ -136,8 +133,10 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
this.autoSave.stopCheckChangesProcess();
|
||||
this.autoSaveErrorSubscription?.unsubscribe();
|
||||
|
||||
if (this.quiz) {
|
||||
// Unblock the quiz so it can be synced.
|
||||
CoreSync.instance.unblockOperation(AddonModQuizProvider.COMPONENT, this.quizId);
|
||||
CoreSync.instance.unblockOperation(AddonModQuizProvider.COMPONENT, this.quiz.id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,11 +319,13 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
*/
|
||||
protected async fetchData(): Promise<void> {
|
||||
try {
|
||||
// Wait for any ongoing sync to finish. We won't sync a quiz while it's being played.
|
||||
await AddonModQuizSync.instance.waitForSync(this.quizId);
|
||||
this.quiz = await AddonModQuiz.instance.getQuiz(this.courseId, this.cmId);
|
||||
|
||||
// Sync finished, now get the quiz.
|
||||
this.quiz = await AddonModQuiz.instance.getQuizById(this.courseId, this.quizId);
|
||||
// Block the quiz so it cannot be synced.
|
||||
CoreSync.instance.blockOperation(AddonModQuizProvider.COMPONENT, this.quiz.id);
|
||||
|
||||
// Wait for any ongoing sync to finish. We won't sync a quiz while it's being played.
|
||||
await AddonModQuizSync.instance.waitForSync(this.quiz.id);
|
||||
|
||||
this.isSequential = AddonModQuiz.instance.isNavigationSequential(this.quiz);
|
||||
|
||||
|
@ -397,7 +398,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
|
||||
// Trigger an event to notify the attempt was finished.
|
||||
CoreEvents.trigger<AddonModQuizAttemptFinishedData>(AddonModQuizProvider.ATTEMPT_FINISHED_EVENT, {
|
||||
quizId: this.quizId,
|
||||
quizId: this.quiz!.id,
|
||||
attemptId: this.attempt!.id,
|
||||
synced: !this.offline,
|
||||
}, CoreSites.instance.getCurrentSiteId());
|
||||
|
@ -537,7 +538,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
|
||||
// Log summary as viewed.
|
||||
CoreUtils.instance.ignoreErrors(
|
||||
AddonModQuiz.instance.logViewAttemptSummary(this.attempt!.id, this.preflightData, this.quizId, this.quiz!.name),
|
||||
AddonModQuiz.instance.logViewAttemptSummary(this.attempt!.id, this.preflightData, this.quiz!.id, this.quiz!.name),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@
|
|||
<ion-item class="ion-text-wrap" *ngFor="let data of additionalData">
|
||||
<ion-label>
|
||||
<h2>{{ data.title }}</h2>
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="data.content"
|
||||
contextLevel="module" [contextInstanceId]="quiz?.coursemodule" [courseId]="courseId">
|
||||
<core-format-text [component]="component" [componentId]="cmId" [text]="data.content"
|
||||
contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
|
||||
</core-format-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
@ -103,9 +103,9 @@
|
|||
</ion-item-divider>
|
||||
|
||||
<!-- Body of the question. -->
|
||||
<core-question class="ion-text-wrap" [question]="question" [component]="component" [componentId]="componentId"
|
||||
<core-question class="ion-text-wrap" [question]="question" [component]="component" [componentId]="cmId"
|
||||
[attemptId]="attempt.id" [usageId]="attempt.uniqueid" [offlineEnabled]="false" contextLevel="module"
|
||||
[contextInstanceId]="quiz?.coursemodule" [courseId]="courseId" [review]="true"
|
||||
[contextInstanceId]="cmId" [courseId]="courseId" [review]="true"
|
||||
[preferredBehaviour]="quiz?.preferredbehaviour">
|
||||
</core-question>
|
||||
</ion-card>
|
||||
|
|
|
@ -51,7 +51,6 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
|
||||
attempt?: AddonModQuizAttemptWSData; // The attempt being reviewed.
|
||||
component = AddonModQuizProvider.COMPONENT; // Component to link the files to.
|
||||
componentId?: number; // ID to use in conjunction with the component.
|
||||
showAll = false; // Whether to view all questions in the same page.
|
||||
numPages?: number; // Number of pages.
|
||||
showCompleted = false; // Whether to show completed time.
|
||||
|
@ -68,8 +67,8 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
overTime?: string;
|
||||
quiz?: AddonModQuizQuizWSData; // The quiz the attempt belongs to.
|
||||
courseId!: number; // The course ID the quiz belongs to.
|
||||
cmId!: number; // Course module id the attempt belongs to.
|
||||
|
||||
protected quizId!: number; // Quiz ID the attempt belongs to.
|
||||
protected attemptId!: number; // The attempt being reviewed.
|
||||
protected currentPage!: number; // The current page being reviewed.
|
||||
protected options?: AddonModQuizCombinedReviewOptions; // Review options.
|
||||
|
@ -83,7 +82,7 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
* Component being initialized.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.quizId = CoreNavigator.instance.getRouteNumberParam('quizId')!;
|
||||
this.cmId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
|
||||
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
|
||||
this.attemptId = CoreNavigator.instance.getRouteNumberParam('attemptId')!;
|
||||
this.currentPage = CoreNavigator.instance.getRouteNumberParam('page') || -1;
|
||||
|
@ -93,7 +92,7 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
await this.fetchData();
|
||||
|
||||
CoreUtils.instance.ignoreErrors(
|
||||
AddonModQuiz.instance.logViewAttemptReview(this.attemptId, this.quizId, this.quiz!.name),
|
||||
AddonModQuiz.instance.logViewAttemptReview(this.attemptId, this.quiz!.id, this.quiz!.name),
|
||||
);
|
||||
} finally {
|
||||
this.loaded = true;
|
||||
|
@ -144,11 +143,9 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
*/
|
||||
protected async fetchData(): Promise<void> {
|
||||
try {
|
||||
this.quiz = await AddonModQuiz.instance.getQuizById(this.courseId, this.quizId);
|
||||
this.quiz = await AddonModQuiz.instance.getQuiz(this.courseId, this.cmId);
|
||||
|
||||
this.componentId = this.quiz.coursemodule;
|
||||
|
||||
this.options = await AddonModQuiz.instance.getCombinedReviewOptions(this.quizId, { cmId: this.quiz.coursemodule });
|
||||
this.options = await AddonModQuiz.instance.getCombinedReviewOptions(this.quiz.id, { cmId: this.cmId });
|
||||
|
||||
// Load the navigation data.
|
||||
await this.loadNavigation();
|
||||
|
@ -214,11 +211,15 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
* @param refresher Refresher
|
||||
*/
|
||||
async refreshData(refresher: IonRefresher): Promise<void> {
|
||||
await CoreUtils.instance.ignoreErrors(Promise.all([
|
||||
AddonModQuiz.instance.invalidateQuizData(this.courseId),
|
||||
AddonModQuiz.instance.invalidateCombinedReviewOptionsForUser(this.quizId),
|
||||
AddonModQuiz.instance.invalidateAttemptReview(this.attemptId),
|
||||
]));
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
promises.push(AddonModQuiz.instance.invalidateQuizData(this.courseId));
|
||||
promises.push(AddonModQuiz.instance.invalidateAttemptReview(this.attemptId));
|
||||
if (this.quiz) {
|
||||
promises.push(AddonModQuiz.instance.invalidateCombinedReviewOptionsForUser(this.quiz.id));
|
||||
}
|
||||
|
||||
await CoreUtils.instance.ignoreErrors(Promise.all(promises));
|
||||
|
||||
try {
|
||||
await this.fetchData();
|
||||
|
|
|
@ -17,19 +17,19 @@ import { RouterModule, Routes } from '@angular/router';
|
|||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: ':courseId/:cmdId',
|
||||
path: ':courseId/:cmId',
|
||||
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModQuizIndexPageModule),
|
||||
},
|
||||
{
|
||||
path: 'player/:courseId/:quizId',
|
||||
path: ':courseId/:cmId/player',
|
||||
loadChildren: () => import('./pages/player/player.module').then( m => m.AddonModQuizPlayerPageModule),
|
||||
},
|
||||
{
|
||||
path: 'attempt/:courseId/:quizId/:attemptId',
|
||||
path: ':courseId/:cmId/attempt/:attemptId',
|
||||
loadChildren: () => import('./pages/attempt/attempt.module').then( m => m.AddonModQuizAttemptPageModule),
|
||||
},
|
||||
{
|
||||
path: 'review/:courseId/:quizId/:attemptId',
|
||||
path: ':courseId/:cmId/review/:attemptId',
|
||||
loadChildren: () => import('./pages/review/review.module').then( m => m.AddonModQuizReviewPageModule),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -524,7 +524,7 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet
|
|||
try {
|
||||
const gradebookData = await AddonModQuiz.instance.getGradeFromGradebook(quiz.course, quiz.coursemodule, true, siteId);
|
||||
|
||||
if (typeof gradebookData.graderaw != 'undefined') {
|
||||
if (gradebookData && 'graderaw' in gradebookData && gradebookData.graderaw !== undefined) {
|
||||
await AddonModQuiz.instance.getFeedbackForGrade(quiz.id, gradebookData.graderaw, modOptions);
|
||||
}
|
||||
} catch {
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
|||
|
||||
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -232,12 +232,13 @@ export class AddonModQuizHelperProvider {
|
|||
if (!quizId) {
|
||||
quizId = await this.getQuizIdByAttemptId(attemptId, { siteId });
|
||||
}
|
||||
if (!courseId) {
|
||||
courseId = await CoreCourseHelper.instance.getModuleCourseIdByInstance(quizId, 'quiz', siteId);
|
||||
}
|
||||
|
||||
const module = await CoreCourse.instance.getModuleBasicInfoByInstance(quizId, 'quiz', siteId);
|
||||
|
||||
courseId = courseId || module.course;
|
||||
|
||||
// Go to the review page.
|
||||
await CoreNavigator.instance.navigateToSitePath(`mod_quiz/review/${courseId}/${quizId}/${attemptId}`, {
|
||||
await CoreNavigator.instance.navigateToSitePath(`mod_quiz/${courseId}/${module.id}/review/${attemptId}`, {
|
||||
params: {
|
||||
page: page == undefined || isNaN(page) ? -1 : page,
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ import { CoreWSError } from '@classes/errors/wserror';
|
|||
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||
import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
||||
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
||||
import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper';
|
||||
import { CoreGradesFormattedItem, CoreGradesFormattedRow, CoreGradesHelper } from '@features/grades/services/grades-helper';
|
||||
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
||||
import {
|
||||
CoreQuestion,
|
||||
|
@ -634,7 +634,7 @@ export class AddonModQuizProvider {
|
|||
ignoreCache?: boolean,
|
||||
siteId?: string,
|
||||
userId?: number,
|
||||
): Promise<CoreGradesFormattedItem> {
|
||||
): Promise<CoreGradesFormattedItem | CoreGradesFormattedRow | undefined> {
|
||||
|
||||
const items = await CoreGradesHelper.instance.getGradeModuleItems(
|
||||
courseId,
|
||||
|
|
Loading…
Reference in New Issue