mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
Merge w10/vorsorgedash into release/v1.18.10
Move the Vorsorge cadence into the metric row, link card headings to filtered results, tighten the daily-briefing card rhythm, and invalidate the dashboard snapshot on briefing regenerate and layout save so the Startseite refreshes.
This commit is contained in:
commit
d08e462136
5 files changed
+70
-10
No files matched your search
@@ -302,7 +302,7 @@ function BriefingSkeleton() {
|
||||
return (
|
||||
<div
|
||||
data-slot="daily-briefing-skeleton"
|
||||
className="space-y-4 motion-reduce:animate-none"
|
||||
className="space-y-3 motion-reduce:animate-none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
@@ -367,7 +367,12 @@ export function DailyBriefing({
|
||||
<BriefingSkeleton />
|
||||
</>
|
||||
) : briefing ? (
|
||||
<div className="space-y-4">
|
||||
// v1.18.10 — body block rhythm matches the sibling insights cards
|
||||
// (`correlation-card` uses `space-y-3` between its chart /
|
||||
// interpretation / source blocks). The briefing card carried a
|
||||
// looser `space-y-4`, which read as taller than its neighbours on
|
||||
// the overview. One token, no new spacing scale.
|
||||
<div className="space-y-3">
|
||||
{/* v1.4.27 B1 — the leading narrative paragraph dropped.
|
||||
The hero strip subtitle on `/insights` already renders
|
||||
the same `briefing.paragraph` text directly above this
|
||||
|
||||
@@ -330,6 +330,15 @@ export function useInsightsAdvisorQuery(
|
||||
// their query subtree so the per-section text below the advisor card
|
||||
// re-fetches.
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.insightsRoot() });
|
||||
// v1.18.10 — the dashboard hero surfaces the briefing headline from the
|
||||
// SNAPSHOT (server-lifted `User.insightsCachedText`), not from this
|
||||
// advisor cache. A regenerate rewrites that server cache, so invalidate
|
||||
// the snapshot too — otherwise returning to the Startseite shows the
|
||||
// previous briefing under the greeting until the snapshot's own stale
|
||||
// window lapses. Closes "the briefing doesn't update" on the dashboard.
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.dashboardSnapshot(),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -770,11 +770,19 @@ function VorsorgeCard({
|
||||
? t(`measurementReminders.types.${reminder.measurementType}`)
|
||||
: t("measurementReminders.selfPlanned");
|
||||
|
||||
// v1.18.6.1 — the cadence renders as a chip DIRECTLY to the right of the
|
||||
// metric name (the med-card convention: cadence sits next to the name).
|
||||
const cadenceChip = cadence ? (
|
||||
<Badge variant="secondary">{cadence}</Badge>
|
||||
) : null;
|
||||
// v1.18.10 — the cadence reads as part of the METRIC ROW (the category
|
||||
// line), styled like the metric label itself — same muted weight/colour,
|
||||
// no shaded pill. The card heading stays clean (nothing beside it); the
|
||||
// cadence rides next to "Blutdruck" et al. via `metricMeta` below.
|
||||
const cadenceText = cadence || null;
|
||||
|
||||
// v1.18.10 — a measurement-linked reminder's heading links to the
|
||||
// measurements history pre-filtered to its type (the same target the
|
||||
// "Messergebnisse anzeigen" kebab item uses). A free-text reminder has no
|
||||
// readings to show, so it stays a plain (non-linking) heading.
|
||||
const measurementsHref = isLinked
|
||||
? `/measurements?type=${encodeURIComponent(reminder.measurementType as string)}`
|
||||
: undefined;
|
||||
|
||||
// Provenance / disabled state badges keep their own row below the category.
|
||||
// Omit the row entirely when neither applies (don't render an empty band).
|
||||
@@ -900,13 +908,15 @@ function VorsorgeCard({
|
||||
<span className="truncate font-medium">
|
||||
{resolveReminderLabel(reminder, t)}
|
||||
</span>
|
||||
{cadenceChip}
|
||||
</div>
|
||||
{/* v1.18.10 — cadence rides on the metric line, styled like the
|
||||
metric text (no shaded pill). */}
|
||||
<div className="text-muted-foreground flex flex-wrap items-center gap-x-2 text-xs">
|
||||
<span className="text-foreground">
|
||||
{t(`measurementReminders.${due.key}`, { days: due.days })}
|
||||
</span>
|
||||
<span>{categoryLabel}</span>
|
||||
{cadenceText ? <span>{cadenceText}</span> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
@@ -991,7 +1001,13 @@ function VorsorgeCard({
|
||||
name={resolveReminderLabel(reminder, t)}
|
||||
dose=""
|
||||
categoryLabel={categoryLabel}
|
||||
nameChip={cadenceChip}
|
||||
metricMeta={cadenceText}
|
||||
href={measurementsHref}
|
||||
linkLabel={
|
||||
measurementsHref
|
||||
? t("measurementReminders.showMeasurements")
|
||||
: undefined
|
||||
}
|
||||
stateBadges={stateBadges}
|
||||
actions={headerActions}
|
||||
/>
|
||||
|
||||
@@ -43,6 +43,15 @@ export interface MedicationCardHeaderProps {
|
||||
* from `stateBadges` (which ride their own row below the category).
|
||||
*/
|
||||
nameChip?: ReactNode;
|
||||
/**
|
||||
* v1.18.10 — inline text rendered DIRECTLY beside the category label on
|
||||
* line 2 (e.g. the Vorsorge cadence "alle 7 Tage"). Unlike `nameChip`
|
||||
* (a chip on the title line) this reads as part of the metric row itself,
|
||||
* inheriting the muted line's weight/colour rather than a shaded pill, so
|
||||
* the cadence sits next to the metric name without an alarming grey
|
||||
* background.
|
||||
*/
|
||||
metricMeta?: ReactNode;
|
||||
stateBadges?: ReactNode;
|
||||
actions?: ReactNode;
|
||||
/**
|
||||
@@ -60,6 +69,7 @@ export function MedicationCardHeader({
|
||||
dose,
|
||||
categoryLabel,
|
||||
nameChip,
|
||||
metricMeta,
|
||||
stateBadges,
|
||||
actions,
|
||||
href,
|
||||
@@ -81,10 +91,16 @@ export function MedicationCardHeader({
|
||||
State badges now ride their own row below the category
|
||||
badge so the canonical row stays two lines on narrow
|
||||
viewports. */}
|
||||
<div className="text-muted-foreground flex items-center gap-2 text-sm">
|
||||
<div className="text-muted-foreground flex flex-wrap items-center gap-x-2 gap-y-1 text-sm">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{categoryLabel}
|
||||
</Badge>
|
||||
{/* v1.18.10 — cadence (and any future metric meta) reads as part of
|
||||
the metric line itself: same muted weight/colour as the row, no
|
||||
shaded pill. */}
|
||||
{metricMeta ? (
|
||||
<span className="text-muted-foreground text-xs">{metricMeta}</span>
|
||||
) : null}
|
||||
</div>
|
||||
{stateBadges ? (
|
||||
<div
|
||||
|
||||
@@ -204,6 +204,15 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
},
|
||||
onSuccess: (saved) => {
|
||||
queryClient.setQueryData(queryKeys.dashboardWidgets(), saved);
|
||||
// v1.18.10 — the Startseite reads its layout (tile/chart visibility,
|
||||
// order, comparison baseline, hero toggle) from the dashboard
|
||||
// SNAPSHOT, not from this `dashboardWidgets` key. Without an
|
||||
// invalidation the snapshot keeps its cached layout and the dashboard
|
||||
// looks stale until a manual reload. Invalidate the snapshot so the
|
||||
// next visit (or open tab) re-reads the saved layout immediately.
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.dashboardSnapshot(),
|
||||
});
|
||||
setDraft(null);
|
||||
toast.success(t("dashboard.layoutSaveSuccess"));
|
||||
},
|
||||
@@ -216,6 +225,11 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
},
|
||||
onSuccess: (saved) => {
|
||||
queryClient.setQueryData(queryKeys.dashboardWidgets(), saved);
|
||||
// v1.18.10 — same snapshot invalidation as the save path so a reset
|
||||
// to defaults reflects on the Startseite without a manual reload.
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.dashboardSnapshot(),
|
||||
});
|
||||
setDraft(null);
|
||||
toast.success(t("dashboard.layoutResetSuccess"));
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user