MOBILE-4550 quiz: Display when attempt can be reviewed

main
Dani Palou 2024-04-22 11:32:16 +02:00
parent e0b19ff20a
commit cdb56d172e
5 changed files with 57 additions and 4 deletions

View File

@ -914,6 +914,8 @@
"addon.mod_quiz.mustbesubmittedby": "quiz",
"addon.mod_quiz.noquestions": "quiz",
"addon.mod_quiz.noreviewattempt": "quiz",
"addon.mod_quiz.noreviewuntil": "quiz",
"addon.mod_quiz.noreviewuntilshort": "quiz",
"addon.mod_quiz.notyetgraded": "quiz",
"addon.mod_quiz.opentoc": "local_moodlemobileapp",
"addon.mod_quiz.outof": "quiz",

View File

@ -82,14 +82,13 @@
<ion-icon name="fas-magnifying-glass" slot="start" aria-hidden="true" />
{{ 'addon.mod_quiz.review' | translate }}
</ion-button>
} @else if (attempt.completed) {
} @else if (attempt.completed && attempt.cannotReviewMessage) {
<hr>
<ion-item class="ion-text-wrap addon-mod_quiz-attempt-noreview">
<ion-label>
<p>
<ion-icon name="fas-circle-info" color="info" slot="start" aria-hidden="true" />
{{ 'addon.mod_quiz.noreviewattempt' | translate }}
<!-- TODO: Check if we can calculate the time when the attempt can be reviewed. -->
{{ attempt.cannotReviewMessage }}
</p>
</ion-label>
</ion-item>

View File

@ -622,6 +622,9 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
]);
formattedAttempt.canReview = canReview;
if (!canReview) {
formattedAttempt.cannotReviewMessage = AddonModQuizHelper.getCannotReviewMessage(quiz, attempt, true);
}
if (quiz.showFeedback && attempt.state === AddonModQuizAttemptStates.FINISHED &&
options.someoptions.overallfeedback && isSafeNumber(formattedAttempt.rescaledGrade)) {
@ -698,5 +701,6 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
type QuizAttempt = AddonModQuizAttempt & {
canReview?: boolean;
cannotReviewMessage?: string;
additionalData?: AddonModQuizWSAdditionalData[]; // Additional data to display for the attempt.
};

View File

@ -42,6 +42,8 @@
"mustbesubmittedby": "This attempt must be submitted by {{$a}}.",
"noquestions": "No questions have been added yet",
"noreviewattempt": "You are not allowed to review this attempt.",
"noreviewuntil": "You are not allowed to review this quiz until {{$a}}",
"noreviewuntilshort": "Available {{$a}}",
"notyetgraded": "Not yet graded",
"opentoc": "Open navigation popover",
"outof": "{{$a.grade}} out of {{$a.maxgrade}}",

View File

@ -33,9 +33,14 @@ import {
AddonModQuizQuizWSData,
} from './quiz';
import { AddonModQuizOffline } from './quiz-offline';
import { AddonModQuizAttemptStates, AddonModQuizDisplayOptionsAttemptStates } from '../constants';
import {
ADDON_MOD_QUIZ_IMMEDIATELY_AFTER_PERIOD,
AddonModQuizAttemptStates,
AddonModQuizDisplayOptionsAttemptStates,
} from '../constants';
import { QuestionDisplayOptionsMarks } from '@features/question/constants';
import { CoreGroups } from '@services/groups';
import { CoreTimeUtils } from '@services/utils/time';
/**
* Helper service that provides some features for quiz.
@ -121,6 +126,47 @@ export class AddonModQuizHelperProvider {
}
}
/**
* Get cannot review message.
*
* @param quiz Quiz.
* @param attempt Attempt.
* @param short Whether to use a short message or not.
* @returns Cannot review message, or empty string if no message to display.
*/
getCannotReviewMessage(quiz: AddonModQuizQuizWSData, attempt: AddonModQuizAttemptWSData, short = false): string {
const displayOption = AddonModQuiz.getAttemptStateDisplayOption(quiz, attempt);
let reviewFrom = 0;
switch (displayOption) {
case AddonModQuizDisplayOptionsAttemptStates.DURING:
return '';
case AddonModQuizDisplayOptionsAttemptStates.IMMEDIATELY_AFTER:
// eslint-disable-next-line no-bitwise
if ((quiz.reviewattempt ?? 0) & AddonModQuizDisplayOptionsAttemptStates.LATER_WHILE_OPEN) {
reviewFrom = (attempt.timefinish ?? Date.now()) + ADDON_MOD_QUIZ_IMMEDIATELY_AFTER_PERIOD;
break;
}
// Fall through.
case AddonModQuizDisplayOptionsAttemptStates.LATER_WHILE_OPEN:
// eslint-disable-next-line no-bitwise
if (quiz.timeclose && ((quiz.reviewattempt ?? 0) & AddonModQuizDisplayOptionsAttemptStates.AFTER_CLOSE)) {
reviewFrom = quiz.timeclose;
break;
}
}
if (reviewFrom) {
return Translate.instant('addon.mod_quiz.noreviewuntil' + (short ? 'short' : ''), {
$a: CoreTimeUtils.userDate(reviewFrom * 1000, short ? 'core.strftimedatetimeshort': undefined),
});
} else {
return Translate.instant('addon.mod_quiz.noreviewattempt');
}
}
/**
* Validate a preflight data or show a modal to input the preflight data if required.
* It calls AddonModQuizProvider.startAttempt if a new attempt is needed.