mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 06:32:03 +00:00
feat(doctor-report): mark screener totals answered in an unvalidated translation
The report data counts, per screener score type, how many of the window's results were answered in a translation that has not been validated (`screenerUnvalidatedTranslations`, read only when a screener total is in the report). The PDF marks such a row with an asterisk and says under the vitals table how many of how many read as orientation; the clinician share view says the same under the row. To keep the aggregator and the PDF section from growing, the wellness summary and the per-context glucose rows move into helpers; the size ratchets only fall.
This commit is contained in:
1 parent
02cc0631fa
commit
14273051db
22 files changed
+369
-85
No files matched your search
@@ -328,6 +328,28 @@ describe("<ClinicianView>", () => {
|
||||
expect(html).toContain("0.495");
|
||||
});
|
||||
|
||||
it("notes a screener total answered in an unvalidated translation under its row", () => {
|
||||
const stats = {
|
||||
SCI_SCORE: { avg: 18, min: 14, max: 22, count: 3, latest: 20 },
|
||||
PHQ9_SCORE: { avg: 6, min: 4, max: 8, count: 2, latest: 4 },
|
||||
};
|
||||
const selection = selectionFromLeaves(["SCI_SCORE", "PHQ9_SCORE"]);
|
||||
const marked = render(
|
||||
makeReport({ stats, screenerUnvalidatedTranslations: { SCI_SCORE: 2 } }),
|
||||
{ selection },
|
||||
);
|
||||
expect(
|
||||
marked.split('data-slot="clinician-screener-translation-note"').length -
|
||||
1,
|
||||
).toBe(1);
|
||||
expect(marked).toContain("2 of 3 results were answered in a translation");
|
||||
const plain = render(
|
||||
makeReport({ stats, screenerUnvalidatedTranslations: null }),
|
||||
{ selection },
|
||||
);
|
||||
expect(plain).not.toContain("clinician-screener-translation-note");
|
||||
});
|
||||
|
||||
it("renders the fenced wellness card with the descriptive disclaimer", () => {
|
||||
const html = render(makeReport());
|
||||
expect(html).toContain("Wellness scores");
|
||||
|
||||
@@ -245,17 +245,35 @@ export function MeasurementGroups({
|
||||
>
|
||||
{group.rows.map(({ type, stat }) => {
|
||||
const digits = reportStatFractionDigits(type, stat!, glucoseUnit);
|
||||
const label = t(reportMeasurementLabelKey(type));
|
||||
// A screener total answered in a translation that has not been
|
||||
// validated says so under its row, as the PDF does.
|
||||
const unvalidated =
|
||||
report.screenerUnvalidatedTranslations?.[type] ?? 0;
|
||||
return (
|
||||
<StatRow
|
||||
key={type}
|
||||
label={t(reportMeasurementLabelKey(type))}
|
||||
value={statSummary(t, reportStatUnit(type, glucoseUnit, t), {
|
||||
latest: show(type, stat!.latest, digits),
|
||||
avg: show(type, stat!.avg, digits),
|
||||
min: show(type, stat!.min, digits),
|
||||
max: show(type, stat!.max, digits),
|
||||
})}
|
||||
/>
|
||||
<Fragment key={type}>
|
||||
<StatRow
|
||||
label={label}
|
||||
value={statSummary(t, reportStatUnit(type, glucoseUnit, t), {
|
||||
latest: show(type, stat!.latest, digits),
|
||||
avg: show(type, stat!.avg, digits),
|
||||
min: show(type, stat!.min, digits),
|
||||
max: show(type, stat!.max, digits),
|
||||
})}
|
||||
/>
|
||||
{unvalidated > 0 && (
|
||||
<p
|
||||
className="text-muted-foreground text-xs"
|
||||
data-slot="clinician-screener-translation-note"
|
||||
>
|
||||
{t("doctorReport.screenerUnvalidated", {
|
||||
label,
|
||||
count: unvalidated,
|
||||
total: stat!.count,
|
||||
})}
|
||||
</p>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</Section>
|
||||
|
||||
Reference in new issue
Block a user