Skip to content

Commit 8549063

Browse files
authored
Merge pull request #4529 from crazyserver/MOBILE-4858
MOBILE-4858 quiz: Add certainty help button and alert
2 parents b128242 + 4434141 commit 8549063

File tree

5 files changed

+134
-8
lines changed

5 files changed

+134
-8
lines changed

scripts/langindex.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2378,6 +2378,7 @@
23782378
"core.question.answersaved": "question",
23792379
"core.question.cannotdeterminestatus": "local_moodlemobileapp",
23802380
"core.question.certainty": "qbehaviour_deferredcbm",
2381+
"core.question.certainty_help": "qbehaviour_deferredcbm",
23812382
"core.question.complete": "question",
23822383
"core.question.correct": "question",
23832384
"core.question.errorattachmentsnotsupportedinsite": "local_moodlemobileapp",
@@ -2722,7 +2723,7 @@
27222723
"core.viewer.readingthemehcm": "local_moodlemobileapp",
27232724
"core.viewer.readingthemelight": "local_moodlemobileapp",
27242725
"core.viewer.readingthemesepia": "local_moodlemobileapp",
2725-
"core.viewer.rotateleft": "h5p",
2726+
"core.viewer.rotateleft": "h5p/rotateLeft",
27262727
"core.viewer.showmedia": "zoom",
27272728
"core.viewer.theme": "moodle",
27282729
"core.viewprofile": "moodle",

src/addons/qbehaviour/deferredcbm/component/addon-qbehaviour-deferredcbm.html

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
@if (question && question.behaviourCertaintyOptions && question.behaviourCertaintyOptions.length) {
22
<div>
33
<ion-item class="ion-text-wrap addon-qbehaviour-deferredcbm-certainty-title">
4-
<ion-label>
5-
<p>{{ 'core.question.certainty' | translate }}</p>
4+
<ion-label class="ion-no-margin">
5+
<ion-row class="ion-align-items-center">
6+
<ion-col size="auto" class="ion-no-padding">
7+
<p class="item-heading">
8+
{{ 'core.question.certainty' | translate }}
9+
</p>
10+
</ion-col>
11+
<ion-col class="ion-no-padding">
12+
<ion-button class="addon-qbehaviour-deferredcbm-certainty-help-button" fill="clear"
13+
(click)="showCertaintyHelp()" [ariaLabel]="'core.help' | translate">
14+
<ion-icon slot="icon-only" name="far-circle-question" aria-hidden="true" />
15+
</ion-button>
16+
</ion-col>
17+
</ion-row>
618
</ion-label>
719
</ion-item>
820

921
<ion-radio-group [(ngModel)]="question.behaviourCertaintySelected" [name]="question.behaviourCertaintyOptions[0].name">
10-
<ion-item class="ion-text-wrap" *ngFor="let option of question.behaviourCertaintyOptions">
11-
<ion-radio id="{{option.id}}" [value]="option.value" [disabled]="option.disabled">
12-
{{ option.text }}
13-
</ion-radio>
14-
</ion-item>
22+
@for (option of question.behaviourCertaintyOptions; track option.id) {
23+
<ion-item class="ion-text-wrap">
24+
<ion-radio id="{{option.id}}" [value]="option.value" [disabled]="option.disabled">
25+
{{ option.text }}
26+
</ion-radio>
27+
</ion-item>
28+
}
1529
</ion-radio-group>
1630

1731
<!-- ion-radio doesn't use an input. Create a hidden input to hold the selected value. -->

src/addons/qbehaviour/deferredcbm/component/deferredcbm.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import { Component, Input, Output, EventEmitter } from '@angular/core';
1818

1919
import { CoreQuestionBehaviourButton, CoreQuestionQuestion } from '@features/question/services/question-helper';
2020
import { CoreSharedModule } from '@/core/shared.module';
21+
import { CoreAlerts } from '@services/overlays/alerts';
22+
import { Translate } from '@singletons';
23+
import { CoreMarkdown } from '@singletons/markdown';
2124

2225
/**
2326
* Component to render the deferred CBM in a question.
@@ -44,4 +47,15 @@ export class AddonQbehaviourDeferredCBMComponent {
4447
@Output() buttonClicked = new EventEmitter<CoreQuestionBehaviourButton>(); // Will emit when a behaviour button is clicked.
4548
@Output() onAbort = new EventEmitter<void>(); // Should emit an event if the question should be aborted.
4649

50+
/**
51+
* Show help modal.
52+
*/
53+
showCertaintyHelp(): void {
54+
const message = Translate.instant('core.question.certainty_help');
55+
56+
CoreAlerts.show({
57+
message: CoreMarkdown.toHtml(message),
58+
});
59+
}
60+
4761
}

src/core/features/question/lang.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"answersaved": "Answer saved",
44
"cannotdeterminestatus": "Cannot determine status",
55
"certainty": "Certainty",
6+
"certainty_help": "Certainty-based marking requires you to indicate how reliable you think your answer is. The available levels are:\n\nCertainty level | C=1 (Unsure) | C=2 (Mid) | C=3 (Quite sure)\n------------------- | ------------ | --------- | ----------------\nMark if correct | 1 | 2 | 3\nMark if wrong | 0 | -2 | -6\nProbability correct | <67% | 67-80% | >80%\n\nBest marks are gained by acknowledging uncertainty. For example, if you think there is more than a 1 in 3 chance of being wrong, you should enter C=1 and avoid the risk of a negative mark.",
67
"complete": "Complete",
78
"correct": "Correct",
89
"errorattachmentsnotsupportedinsite": "Your site doesn't support attaching files to answers yet.",

src/core/singletons/markdown.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// (C) Copyright 2015 Moodle Pty Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* Singleton with helper functions for markdown formatting.
17+
*/
18+
export class CoreMarkdown {
19+
20+
// Avoid creating singleton instances.
21+
private constructor() {
22+
// Nothing to do.
23+
}
24+
25+
/**
26+
* Converts Markdown text to HTML, handling only line breaks and tables.
27+
*
28+
* @param markdown - Markdown-formatted text.
29+
* @returns HTML string.
30+
*/
31+
static toHtml(markdown: string): string {
32+
const lines = markdown.trim().split('\n');
33+
const htmlLines: string[] = [];
34+
35+
let inTable = false;
36+
let tableHeaderParsed = false;
37+
let inTbody = false;
38+
39+
for (let i = 0; i < lines.length; i++) {
40+
const line = lines[i].trim();
41+
const isTableRow = line.includes('|');
42+
const isSeparatorRow = /^[:\-| ]+$/.test(line);
43+
44+
if (isTableRow && !isSeparatorRow) {
45+
const cells = line.split('|').map(cell => cell.trim()).filter(Boolean);
46+
47+
if (!inTable) {
48+
htmlLines.push('<table class="core-table">');
49+
inTable = true;
50+
tableHeaderParsed = false;
51+
inTbody = false;
52+
}
53+
54+
if (!tableHeaderParsed) {
55+
// Start the table header
56+
htmlLines.push('<thead>');
57+
htmlLines.push('<tr>' + cells.map(cell => `<th>${cell}</th>`).join('') + '</tr>');
58+
htmlLines.push('</thead>');
59+
tableHeaderParsed = true;
60+
} else {
61+
// Start tbody if not already started
62+
if (!inTbody) {
63+
htmlLines.push('<tbody class="auto-striped">');
64+
inTbody = true;
65+
}
66+
htmlLines.push('<tr>' + cells.map(cell => `<td>${cell}</td>`).join('') + '</tr>');
67+
}
68+
} else if (isSeparatorRow) {
69+
continue; // Skip separator like | --- | --- |
70+
} else {
71+
// If we were in a table, close it
72+
if (inTable) {
73+
if (inTbody) {
74+
htmlLines.push('</tbody>');
75+
}
76+
htmlLines.push('</table>');
77+
inTable = false;
78+
inTbody = false;
79+
}
80+
81+
htmlLines.push(`${line}<br>`);
82+
}
83+
}
84+
85+
// Close open table if still active
86+
if (inTable) {
87+
if (inTbody) {
88+
htmlLines.push('</tbody>');
89+
}
90+
htmlLines.push('</table>');
91+
}
92+
93+
return htmlLines.join('\n');
94+
}
95+
96+
}

0 commit comments

Comments
 (0)