MOBILE-3028 quiz: Allow attempting quiz with unsupported questions

main
Dani Palou 2019-07-31 11:37:49 +02:00
parent fc9bc6613d
commit 532d1686b3
7 changed files with 42 additions and 10 deletions

View File

@ -730,6 +730,7 @@
"addon.mod_quiz.attemptnumber": "quiz", "addon.mod_quiz.attemptnumber": "quiz",
"addon.mod_quiz.attemptquiznow": "quiz", "addon.mod_quiz.attemptquiznow": "quiz",
"addon.mod_quiz.attemptstate": "quiz", "addon.mod_quiz.attemptstate": "quiz",
"addon.mod_quiz.canattemptbutnotsubmit": "local_moodlemobileapp",
"addon.mod_quiz.cannotsubmitquizdueto": "local_moodlemobileapp", "addon.mod_quiz.cannotsubmitquizdueto": "local_moodlemobileapp",
"addon.mod_quiz.clearchoice": "qtype_multichoice", "addon.mod_quiz.clearchoice": "qtype_multichoice",
"addon.mod_quiz.comment": "quiz", "addon.mod_quiz.comment": "quiz",
@ -802,6 +803,7 @@
"addon.mod_quiz.warningattemptfinished": "local_moodlemobileapp", "addon.mod_quiz.warningattemptfinished": "local_moodlemobileapp",
"addon.mod_quiz.warningdatadiscarded": "local_moodlemobileapp", "addon.mod_quiz.warningdatadiscarded": "local_moodlemobileapp",
"addon.mod_quiz.warningdatadiscardedfromfinished": "local_moodlemobileapp", "addon.mod_quiz.warningdatadiscardedfromfinished": "local_moodlemobileapp",
"addon.mod_quiz.warningquestionsnotsupported": "local_moodlemobileapp",
"addon.mod_quiz.yourfinalgradeis": "quiz", "addon.mod_quiz.yourfinalgradeis": "quiz",
"addon.mod_resource.errorwhileloadingthecontent": "local_moodlemobileapp", "addon.mod_resource.errorwhileloadingthecontent": "local_moodlemobileapp",
"addon.mod_resource.modifieddate": "resource", "addon.mod_resource.modifieddate": "resource",
@ -1318,7 +1320,12 @@
"core.comments.comments": "moodle", "core.comments.comments": "moodle",
"core.comments.commentscount": "moodle", "core.comments.commentscount": "moodle",
"core.comments.commentsnotworking": "local_moodlemobileapp", "core.comments.commentsnotworking": "local_moodlemobileapp",
"core.comments.deletecommentbyon": "moodle",
"core.comments.eventcommentcreated": "moodle",
"core.comments.eventcommentdeleted": "moodle",
"core.comments.nocomments": "moodle", "core.comments.nocomments": "moodle",
"core.comments.savecomment": "moodle",
"core.comments.warningcommentsnotsent": "local_moodlemobileapp",
"core.commentscount": "moodle", "core.commentscount": "moodle",
"core.commentsnotworking": "local_moodlemobileapp", "core.commentsnotworking": "local_moodlemobileapp",
"core.completion-alt-auto-fail": "completion", "core.completion-alt-auto-fail": "completion",

View File

@ -90,7 +90,7 @@
<ion-item text-wrap class="core-danger-item" *ngIf="quiz.hasquestions === 0"> <ion-item text-wrap class="core-danger-item" *ngIf="quiz.hasquestions === 0">
<p>{{ 'addon.mod_quiz.noquestions' | translate }}</p> <p>{{ 'addon.mod_quiz.noquestions' | translate }}</p>
</ion-item> </ion-item>
<ion-item text-wrap class="core-danger-item" *ngIf="unsupportedQuestions && unsupportedQuestions.length"> <ion-item text-wrap class="core-danger-item" *ngIf="!hasSupportedQuestions && unsupportedQuestions && unsupportedQuestions.length">
<p>{{ 'addon.mod_quiz.errorquestionsnotsupported' | translate }}</p> <p>{{ 'addon.mod_quiz.errorquestionsnotsupported' | translate }}</p>
<p *ngFor="let type of unsupportedQuestions">{{ type }}</p> <p *ngFor="let type of unsupportedQuestions">{{ type }}</p>
</ion-item> </ion-item>
@ -109,6 +109,13 @@
{{ 'core.hasdatatosync' | translate: {$a: moduleName} }} {{ 'core.hasdatatosync' | translate: {$a: moduleName} }}
</div> </div>
<!-- Other warnings. -->
<ion-item text-wrap class="core-warning-item" *ngIf="hasSupportedQuestions && unsupportedQuestions && unsupportedQuestions.length">
<p>{{ 'addon.mod_quiz.canattemptbutnotsubmit' | translate }}</p>
<p>{{ 'addon.mod_quiz.warningquestionsnotsupported' | translate }}</p>
<p *ngFor="let type of unsupportedQuestions">{{ type }}</p>
</ion-item>
<!-- Button to start/continue. --> <!-- Button to start/continue. -->
<ion-item *ngIf="buttonText && !showStatusSpinner"> <ion-item *ngIf="buttonText && !showStatusSpinner">
<button ion-button block (click)="attemptQuiz()"> <button ion-button block (click)="attemptQuiz()">
@ -117,7 +124,7 @@
</ion-item> </ion-item>
<!-- Button to open in browser if it cannot be attempted in the app. --> <!-- Button to open in browser if it cannot be attempted in the app. -->
<ion-item *ngIf="!buttonText && ((unsupportedQuestions && unsupportedQuestions.length) || (unsupportedRules && unsupportedRules.length) || behaviourSupported === false)"> <ion-item *ngIf="!buttonText && ((!hasSupportedQuestions && unsupportedQuestions && unsupportedQuestions.length) || (unsupportedRules && unsupportedRules.length) || behaviourSupported === false)">
<a ion-button block [href]="externalUrl" core-link icon-end> <a ion-button block [href]="externalUrl" core-link icon-end>
{{ 'core.openinbrowser' | translate }} {{ 'core.openinbrowser' | translate }}
<ion-icon name="open"></ion-icon> <ion-icon name="open"></ion-icon>

View File

@ -38,6 +38,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
now: number; // Current time. now: number; // Current time.
syncTime: string; // Last synchronization time. syncTime: string; // Last synchronization time.
hasOffline: boolean; // Whether the quiz has offline data. hasOffline: boolean; // Whether the quiz has offline data.
hasSupportedQuestions: boolean; // Whether the quiz has at least 1 supported question.
accessRules: string[]; // List of access rules of the quiz. accessRules: string[]; // List of access rules of the quiz.
unsupportedRules: string[]; // List of unsupported access rules of the quiz. unsupportedRules: string[]; // List of unsupported access rules of the quiz.
unsupportedQuestions: string[]; // List of unsupported question types of the quiz. unsupportedQuestions: string[]; // List of unsupported question types of the quiz.
@ -214,6 +215,9 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
// Get question types in the quiz. // Get question types in the quiz.
return this.quizProvider.getQuizRequiredQtypes(this.quizData.id).then((types) => { return this.quizProvider.getQuizRequiredQtypes(this.quizData.id).then((types) => {
this.unsupportedQuestions = this.quizProvider.getUnsupportedQuestions(types); this.unsupportedQuestions = this.quizProvider.getUnsupportedQuestions(types);
this.hasSupportedQuestions = !!types.find((type) => {
return type != 'random' && this.unsupportedQuestions.indexOf(type) == -1;
});
return this.getAttempts(); return this.getAttempts();
}); });
@ -301,7 +305,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
this.buttonText = ''; this.buttonText = '';
} else if (this.quizAccessInfo.canattempt && this.preventMessages.length) { } else if (this.quizAccessInfo.canattempt && this.preventMessages.length) {
this.buttonText = ''; this.buttonText = '';
} else if (this.unsupportedQuestions.length || this.unsupportedRules.length || !this.behaviourSupported) { } else if (!this.hasSupportedQuestions || this.unsupportedRules.length || !this.behaviourSupported) {
this.buttonText = ''; this.buttonText = '';
} }
} }

View File

@ -5,6 +5,7 @@
"attemptnumber": "Attempt", "attemptnumber": "Attempt",
"attemptquiznow": "Attempt quiz now", "attemptquiznow": "Attempt quiz now",
"attemptstate": "State", "attemptstate": "State",
"canattemptbutnotsubmit": "You can attempt this quiz in the app, but you will need to submit the attempt in browser for the following reasons:",
"cannotsubmitquizdueto": "This quiz attempt cannot be submitted for the following reasons:", "cannotsubmitquizdueto": "This quiz attempt cannot be submitted for the following reasons:",
"clearchoice": "Clear my choice", "clearchoice": "Clear my choice",
"comment": "Comment", "comment": "Comment",
@ -23,7 +24,7 @@
"errorgetquestions": "Error getting questions.", "errorgetquestions": "Error getting questions.",
"errorgetquiz": "Error getting quiz data.", "errorgetquiz": "Error getting quiz data.",
"errorparsequestions": "An error occurred while reading the questions. Please attempt this quiz in a web browser.", "errorparsequestions": "An error occurred while reading the questions. Please attempt this quiz in a web browser.",
"errorquestionsnotsupported": "This quiz can't be attempted in the app because it contains questions not supported by the app:", "errorquestionsnotsupported": "This quiz can't be attempted in the app because it only contains questions not supported by the app:",
"errorrulesnotsupported": "This quiz can't be attempted in the app because it has access rules not supported by the app:", "errorrulesnotsupported": "This quiz can't be attempted in the app because it has access rules not supported by the app:",
"errorsaveattempt": "An error occurred while saving the attempt data.", "errorsaveattempt": "An error occurred while saving the attempt data.",
"feedback": "Feedback", "feedback": "Feedback",
@ -77,5 +78,6 @@
"warningattemptfinished": "Offline attempt discarded as it was finished on the site or not found.", "warningattemptfinished": "Offline attempt discarded as it was finished on the site or not found.",
"warningdatadiscarded": "Some offline answers were discarded because the questions were modified online.", "warningdatadiscarded": "Some offline answers were discarded because the questions were modified online.",
"warningdatadiscardedfromfinished": "Attempt unfinished because some offline answers were discarded. Please review your answers then resubmit the attempt.", "warningdatadiscardedfromfinished": "Attempt unfinished because some offline answers were discarded. Please review your answers then resubmit the attempt.",
"warningquestionsnotsupported": "This quiz contains questions not supported by the app:",
"yourfinalgradeis": "Your final grade for this quiz is {{$a}}." "yourfinalgradeis": "Your final grade for this quiz is {{$a}}."
} }

View File

@ -649,10 +649,18 @@ export class AddonModQuizProvider {
const messages = []; const messages = [];
questions.forEach((question) => { questions.forEach((question) => {
let message = this.questionDelegate.getPreventSubmitMessage(question); if (question.type != 'random' && !this.questionDelegate.isQuestionSupported(question.type)) {
if (message) { // The question isn't supported.
message = this.translate.instant(message); messages.push(this.translate.instant('core.question.questionmessage', {
messages.push(this.translate.instant('core.question.questionmessage', {$a: question.slot, $b: message})); $a: question.slot,
$b: this.translate.instant('core.question.errorquestionnotsupported', {$a: question.type})
}));
} else {
let message = this.questionDelegate.getPreventSubmitMessage(question);
if (message) {
message = this.translate.instant(message);
messages.push(this.translate.instant('core.question.questionmessage', {$a: question.slot, $b: message}));
}
} }
}); });

View File

@ -729,6 +729,7 @@
"addon.mod_quiz.attemptnumber": "Attempt", "addon.mod_quiz.attemptnumber": "Attempt",
"addon.mod_quiz.attemptquiznow": "Attempt quiz now", "addon.mod_quiz.attemptquiznow": "Attempt quiz now",
"addon.mod_quiz.attemptstate": "State", "addon.mod_quiz.attemptstate": "State",
"addon.mod_quiz.canattemptbutnotsubmit": "You can attempt this quiz in the app, but you will need to submit the attempt in browser for the following reasons:",
"addon.mod_quiz.cannotsubmitquizdueto": "This quiz attempt cannot be submitted for the following reasons:", "addon.mod_quiz.cannotsubmitquizdueto": "This quiz attempt cannot be submitted for the following reasons:",
"addon.mod_quiz.clearchoice": "Clear my choice", "addon.mod_quiz.clearchoice": "Clear my choice",
"addon.mod_quiz.comment": "Comment", "addon.mod_quiz.comment": "Comment",
@ -747,7 +748,7 @@
"addon.mod_quiz.errorgetquestions": "Error getting questions.", "addon.mod_quiz.errorgetquestions": "Error getting questions.",
"addon.mod_quiz.errorgetquiz": "Error getting quiz data.", "addon.mod_quiz.errorgetquiz": "Error getting quiz data.",
"addon.mod_quiz.errorparsequestions": "An error occurred while reading the questions. Please attempt this quiz in a web browser.", "addon.mod_quiz.errorparsequestions": "An error occurred while reading the questions. Please attempt this quiz in a web browser.",
"addon.mod_quiz.errorquestionsnotsupported": "This quiz can't be attempted in the app because it contains questions not supported by the app:", "addon.mod_quiz.errorquestionsnotsupported": "This quiz can't be attempted in the app because it only contains questions not supported by the app:",
"addon.mod_quiz.errorrulesnotsupported": "This quiz can't be attempted in the app because it has access rules not supported by the app:", "addon.mod_quiz.errorrulesnotsupported": "This quiz can't be attempted in the app because it has access rules not supported by the app:",
"addon.mod_quiz.errorsaveattempt": "An error occurred while saving the attempt data.", "addon.mod_quiz.errorsaveattempt": "An error occurred while saving the attempt data.",
"addon.mod_quiz.feedback": "Feedback", "addon.mod_quiz.feedback": "Feedback",
@ -801,6 +802,7 @@
"addon.mod_quiz.warningattemptfinished": "Offline attempt discarded as it was finished on the site or not found.", "addon.mod_quiz.warningattemptfinished": "Offline attempt discarded as it was finished on the site or not found.",
"addon.mod_quiz.warningdatadiscarded": "Some offline answers were discarded because the questions were modified online.", "addon.mod_quiz.warningdatadiscarded": "Some offline answers were discarded because the questions were modified online.",
"addon.mod_quiz.warningdatadiscardedfromfinished": "Attempt unfinished because some offline answers were discarded. Please review your answers then resubmit the attempt.", "addon.mod_quiz.warningdatadiscardedfromfinished": "Attempt unfinished because some offline answers were discarded. Please review your answers then resubmit the attempt.",
"addon.mod_quiz.warningquestionsnotsupported": "This quiz contains questions not supported by the app:",
"addon.mod_quiz.yourfinalgradeis": "Your final grade for this quiz is {{$a}}.", "addon.mod_quiz.yourfinalgradeis": "Your final grade for this quiz is {{$a}}.",
"addon.mod_resource.errorwhileloadingthecontent": "Error while loading the content.", "addon.mod_resource.errorwhileloadingthecontent": "Error while loading the content.",
"addon.mod_resource.modifieddate": "Modified {{$a}}", "addon.mod_resource.modifieddate": "Modified {{$a}}",

View File

@ -64,7 +64,7 @@ export class CoreQuestionComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.offlineEnabled = this.utils.isTrueOrOne(this.offlineEnabled); this.offlineEnabled = this.utils.isTrueOrOne(this.offlineEnabled);
if (!this.question) { if (!this.question || (this.question.type != 'random' && !this.questionDelegate.isQuestionSupported(this.question.type))) {
this.loaded = true; this.loaded = true;
return; return;
@ -145,6 +145,8 @@ export class CoreQuestionComponent implements OnInit {
this.questionHelper.extractQuestionFeedback(this.question); this.questionHelper.extractQuestionFeedback(this.question);
this.questionHelper.extractQuestionComment(this.question); this.questionHelper.extractQuestionComment(this.question);
}); });
} else {
this.loaded = true;
} }
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.