mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 06:32:03 +00:00
fix(day): one entry per medication, one meaning for "Pulse", a quieter panel
Running that day listed a medication, its course and its pause as rows of
their own, so Mounjaro read as "Mounjaro 7.5 mg" above "Mounjaro". The day
read now folds them into one entry per medication: its name with the dose
in effect that day (the last dose change on or before it), the course's
days on the second line, or the paused entry while a pause runs. The
Coach's get_day reads the same loader and gets the same single entry.
The dashboard's pulse widget showed the resting heart rate whenever one
was recorded but called it "Pulse", while the day view's "Pulse" tile
was the day's pulse; one day read 62 on the dashboard and 77 in the day.
The widget is now named by what it shows ("Resting heart rate" with
resting rows, "Pulse" without), and the pulse's latest value is the
latest day's pulse, the mean of its local hours' means through the shared
day-mean helper and the day view's own canonical-source pick, so both
"Pulse" figures are one number. The day view's pulse goes through the
same helper in the record's zone.
The count line above the day ("33 values, 3 entries") and the usual range
repeated beside the focus value ("Your 30 days before") are gone; the
sections and the value tiles already say both. An assessment's score and
band join with a comma, not a middle dot.
This commit is contained in:
1 parent
9f3da5ac7d
commit
cd72317356
12 files changed
+461
-158
No files matched your search
@@ -179,10 +179,12 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
describe("<DayView>", () => {
|
||||
it("names the day and counts what it holds", async () => {
|
||||
it("names the day and carries no count line", async () => {
|
||||
const html = await render();
|
||||
expect(html).toContain("Saturday, January 3, 2026");
|
||||
expect(html).toContain("3 values, 2 entries");
|
||||
// The sections say what the day holds; a count above them repeated it.
|
||||
expect(html).not.toContain("3 values, 2 entries");
|
||||
expect(html).not.toContain('data-slot="day-meta"');
|
||||
});
|
||||
|
||||
it("lists what ran through the day with its running count", async () => {
|
||||
@@ -284,8 +286,9 @@ describe("<DayView>", () => {
|
||||
},
|
||||
});
|
||||
expect(html).toContain('data-slot="day-focus"');
|
||||
expect(html).toContain("Your 30 days before");
|
||||
expect(html).toContain("121–134/78–86");
|
||||
// The usual range is the tiles' to draw, not repeated beside the value.
|
||||
expect(html).not.toContain("Your 30 days before");
|
||||
expect(html).not.toContain('data-slot="day-focus-compare"');
|
||||
expect(html).toContain('data-selected="true"');
|
||||
expect(html).toContain("Highest daily value since March 2025");
|
||||
});
|
||||
|
||||
@@ -78,18 +78,13 @@ export const DAY_SECTION_LABEL =
|
||||
|
||||
/* ─── Focus ───────────────────────────────────────────────────────────── */
|
||||
|
||||
export function DayFocusCard({
|
||||
focus,
|
||||
usual,
|
||||
}: {
|
||||
focus: DayFocus;
|
||||
/** The usual range of the focus type that day, when the server has one. */
|
||||
usual: string | null;
|
||||
}) {
|
||||
const { t } = useTranslations();
|
||||
const compare =
|
||||
focus.compare ??
|
||||
(usual ? { label: t("day.usualLabel"), value: usual } : null);
|
||||
/**
|
||||
* The value the person came from. A comparison shows only when the opening
|
||||
* surface brings one (an earlier lab result); the usual range of the 30 days
|
||||
* before is not repeated here, because the value tiles below draw it.
|
||||
*/
|
||||
export function DayFocusCard({ focus }: { focus: DayFocus }) {
|
||||
const compare = focus.compare ?? null;
|
||||
return (
|
||||
<div
|
||||
data-slot="day-focus"
|
||||
@@ -264,7 +259,7 @@ export function dayMeta(
|
||||
: null;
|
||||
const bandKey = bands && band ? keyOf(bands, band) : undefined;
|
||||
const bandText = bandKey ? t(bandKey) : null;
|
||||
return [score, bandText].filter(Boolean).join(" · ") || null;
|
||||
return [score, bandText].filter(Boolean).join(", ") || null;
|
||||
}
|
||||
case "symptom":
|
||||
return t("symptoms.intensityPill", { value: meta });
|
||||
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
DayValues,
|
||||
} from "./day-sections";
|
||||
import { DayScores } from "./day-scores";
|
||||
import { curateDayValues, tileKeyOf } from "./day-values-model";
|
||||
import { tileKeyOf } from "./day-values-model";
|
||||
import { shiftDateKey } from "./day-url";
|
||||
import { useDay, usePrefetchDay } from "./use-day";
|
||||
import { useDayValueFormat } from "./use-day-value-format";
|
||||
@@ -124,7 +124,7 @@ export function DayView({
|
||||
above,
|
||||
headerClassName,
|
||||
}: DayViewProps) {
|
||||
const { t, tCount } = useTranslations();
|
||||
const { t } = useTranslations();
|
||||
const longLabel = useLongDayLabel();
|
||||
// "Mo., 5. Okt. 2026" in the phone sheet's header: a September Thursday
|
||||
// spelled out in full does not fit beside the arrows at 360 px, and a
|
||||
@@ -132,7 +132,7 @@ export function DayView({
|
||||
const shortLabel = useLongDayLabel("short");
|
||||
const pathname = usePathname();
|
||||
const day = useDay(date);
|
||||
const { labelFor, formatTile } = useDayValueFormat();
|
||||
const { labelFor } = useDayValueFormat();
|
||||
const timelineOn = useModuleEnabled("timeline");
|
||||
const coach = useAiCapability("coach");
|
||||
const capabilities = useRecordCapabilities();
|
||||
@@ -163,12 +163,6 @@ export function DayView({
|
||||
data?.notable.filter(
|
||||
(n) => !(n.type !== null && focusKeys.has(tileKeyOf(n.type))),
|
||||
) ?? [];
|
||||
const focusTile =
|
||||
focus && data
|
||||
? curateDayValues(data.values, focusTypes).curated.find((tile) =>
|
||||
focusKeys.has(tile.key),
|
||||
)
|
||||
: undefined;
|
||||
const isEmpty =
|
||||
data !== undefined &&
|
||||
data.values.length === 0 &&
|
||||
@@ -178,12 +172,6 @@ export function DayView({
|
||||
const notShared = data
|
||||
? Object.values(data.sections).some((s) => s?.reason === "not_shared")
|
||||
: false;
|
||||
const meta = data
|
||||
? [
|
||||
tCount("day.countValues", data.counts.values),
|
||||
tCount("day.countEntries", data.counts.entries),
|
||||
].join(", ")
|
||||
: null;
|
||||
const compact = shell === "bottom";
|
||||
const closeLabel = shell === "docked" ? t("day.hidePanel") : t("day.close");
|
||||
|
||||
@@ -299,20 +287,9 @@ export function DayView({
|
||||
compact ? "gap-6 px-4 pt-0.5 pb-4" : "gap-6 px-6 pt-4 pb-6",
|
||||
)}
|
||||
>
|
||||
{/* What the day holds, as meta under the header. The line keeps its
|
||||
height while the day loads, so nothing below it moves. */}
|
||||
<p
|
||||
className="text-muted-foreground -mb-3 text-xs tabular-nums"
|
||||
data-slot="day-meta"
|
||||
>
|
||||
{meta ?? <span className="invisible">0</span>}
|
||||
</p>
|
||||
{focus ? (
|
||||
<div className="space-y-2.5">
|
||||
<DayFocusCard
|
||||
focus={focus}
|
||||
usual={focusTile ? formatTile(focusTile).usual : null}
|
||||
/>
|
||||
<DayFocusCard focus={focus} />
|
||||
<DayNotableLines
|
||||
notables={focusNotables}
|
||||
labelFor={labelFor}
|
||||
|
||||
Reference in new issue
Block a user