diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss
index 518b15d5d..06184b922 100644
--- a/htdocs/js/Problem/problem.scss
+++ b/htdocs/js/Problem/problem.scss
@@ -153,6 +153,10 @@
&.partially-correct::before {
content: url("data:image/svg+xml,");
}
+
+ &.unknown::before {
+ content: url("data:image/svg+xml,");
+ }
}
&.with-message::before {
@@ -163,7 +167,7 @@
left: 100%;
border: 1px solid black;
border-radius: 50%;
- background-color: var(--bs-warning);
+ background-color: #ffc107;
padding: 0.25rem;
animation: flash-in 0.75s;
@@ -181,6 +185,75 @@
}
}
+ /* Feedback button colors. */
+ .btn-correct {
+ --bs-btn-color: #fff;
+ --bs-btn-bg: #198754;
+ --bs-btn-border-color: #198754;
+ --bs-btn-hover-color: #fff;
+ --bs-btn-hover-bg: #157347;
+ --bs-btn-hover-border-color: #146c43;
+ --bs-btn-focus-shadow-rgb: 60, 153, 110;
+ --bs-btn-active-color: #fff;
+ --bs-btn-active-bg: #146c43;
+ --bs-btn-active-border-color: #13653f;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #fff;
+ --bs-btn-disabled-bg: #198754;
+ --bs-btn-disabled-border-color: #198754;
+ }
+
+ .btn-incorrect {
+ --bs-btn-color: #fff;
+ --bs-btn-bg: #dc3545;
+ --bs-btn-border-color: #dc3545;
+ --bs-btn-hover-color: #fff;
+ --bs-btn-hover-bg: #bb2d3b;
+ --bs-btn-hover-border-color: #b02a37;
+ --bs-btn-focus-shadow-rgb: 225, 83, 97;
+ --bs-btn-active-color: #fff;
+ --bs-btn-active-bg: #b02a37;
+ --bs-btn-active-border-color: #a52834;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #fff;
+ --bs-btn-disabled-bg: #dc3545;
+ --bs-btn-disabled-border-color: #dc3545;
+ }
+
+ .btn-partially-correct {
+ --bs-btn-color: #000;
+ --bs-btn-bg: #ffc107;
+ --bs-btn-border-color: #ffc107;
+ --bs-btn-hover-color: #000;
+ --bs-btn-hover-bg: #ffca2c;
+ --bs-btn-hover-border-color: #ffc720;
+ --bs-btn-focus-shadow-rgb: 217, 164, 6;
+ --bs-btn-active-color: #000;
+ --bs-btn-active-bg: #ffcd39;
+ --bs-btn-active-border-color: #ffc720;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #000;
+ --bs-btn-disabled-bg: #ffc107;
+ --bs-btn-disabled-border-color: #ffc107;
+ }
+
+ .btn-preview {
+ --bs-btn-color: #000;
+ --bs-btn-bg: #0dcaf0;
+ --bs-btn-border-color: #0dcaf0;
+ --bs-btn-hover-color: #000;
+ --bs-btn-hover-bg: #31d2f2;
+ --bs-btn-hover-border-color: #25cff2;
+ --bs-btn-focus-shadow-rgb: 11, 172, 204;
+ --bs-btn-active-color: #000;
+ --bs-btn-active-bg: #3dd5f3;
+ --bs-btn-active-border-color: #25cff2;
+ --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --bs-btn-disabled-color: #000;
+ --bs-btn-disabled-bg: #0dcaf0;
+ --bs-btn-disabled-border-color: #0dcaf0;
+ }
+
.radio-buttons-container,
.checkboxes-container {
max-width: calc(100% - 1rem - 25px);
@@ -256,7 +329,7 @@
.popover-header {
text-align: center;
cursor: pointer;
- --bs-popover-header-bg: var(--bs-info);
+ --bs-popover-header-bg: #0dcaf0;
--bs-popover-header-color: white;
.btn-close {
@@ -268,21 +341,22 @@
&.correct {
.popover-header {
- --bs-popover-header-bg: var(--bs-success);
+ --bs-popover-header-bg: #198754;
--bs-popover-header-color: white;
}
}
&.incorrect {
.popover-header {
- --bs-popover-header-bg: var(--bs-danger);
+ --bs-popover-header-bg: #dc3545;
--bs-popover-header-color: white;
}
}
- &.partially-correct {
+ &.partially-correct,
+ &.unknown {
.popover-header {
- --bs-popover-header-bg: var(--bs-warning);
+ --bs-popover-header-bg: #ffc107;
--bs-popover-header-color: black;
}
}
diff --git a/macros/PG.pl b/macros/PG.pl
index 316286057..3ff794a80 100644
--- a/macros/PG.pl
+++ b/macros/PG.pl
@@ -845,8 +845,12 @@ =head2 ENDDOCUMENT
=item *
-C: This is the bootstrap button class added to the feedback button.
-By default it is "btn-info", "btn-success", "btn-danger", or "btn-warning"
+C: This is the button class added to the feedback button. These are
+based on bootstrap button styles, but are custom styles for the feedback
+buttons to allow clients to theme the bootstrap buttons without changing the
+feedback styles. By default it is "btn-preview" (coppied from btn-info),
+"btn-correct" (coppied from btn-success), "btn-incorrect" (coppied from
+btn-danger), or "btn-partially-correct" (coppied from btn-warning)
depending on the status of the answer and the type of submission.
=item *
@@ -1059,7 +1063,7 @@ sub ENDDOCUMENT {
my %options = (
resultTitle => maketext('Answer Preview'),
resultClass => '',
- btnClass => 'btn-info',
+ btnClass => 'btn-preview',
btnAddClass => 'ms-2',
feedbackElements => Mojo::Collection->new,
insertElement => undef,
@@ -1108,15 +1112,28 @@ sub ENDDOCUMENT {
} elsif ($answerScore >= 1) {
$options{resultTitle} = maketext('Correct');
$options{resultClass} = 'correct';
- $options{btnClass} = 'btn-success';
+ $options{btnClass} = 'btn-correct';
} elsif ($answerScore == 0) {
$options{resultTitle} = maketext('Incorrect');
$options{resultClass} = 'incorrect';
- $options{btnClass} = 'btn-danger';
+ $options{btnClass} = 'btn-incorrect';
} else {
$options{resultTitle} = maketext('[_1]% correct', round($answerScore * 100));
$options{resultClass} = 'partially-correct';
- $options{btnClass} = 'btn-warning';
+ $options{btnClass} = 'btn-partially-correct';
+ }
+ } elsif ($rh_envir->{showAttemptResults} && !$PG->{flags}{showPartialCorrectAnswers}) {
+ # Partially correct feedback is not being shown, but this is not a preview, so make the
+ # feedback look different than a preview. If the problem score is zero, everything is
+ # incorrect, so mark the whole problem as incorrect. Otherwise mark it as unknown correctness.
+ if ($problemResult->{score}) {
+ $options{resultTitle} = maketext('Unknown');
+ $options{resultClass} = 'unknown';
+ $options{btnClass} = 'btn-partially-correct';
+ } else {
+ $options{resultTitle} = maketext('Incorrect');
+ $options{resultClass} = 'incorrect';
+ $options{btnClass} = 'btn-incorrect';
}
}