mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
feat(dashboard): make the v1.10 additive metrics pinnable to Home
Add eight widget ids (cardio recovery, six-minute walk, stair ascent/descent speed, breathing disturbances, wrist temperature, falls, walking steadiness) to the dashboard widget catalogue + default layout (hidden by default) so they can be pinned via the layout PUT. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1f3b0ff5b0
commit
0949fadfb0
3 files changed
+49
-9
No files matched your search
@@ -132,6 +132,16 @@ const WIDGET_LABEL_KEYS: Record<DashboardWidgetId, string> = {
|
||||
vo2Max: "dashboard.vo2Max",
|
||||
// v1.4.32 — Recent workouts tile (default-on).
|
||||
recentWorkouts: "dashboard.recentWorkouts.title",
|
||||
// v1.11.2 B5 — v1.10 additive HealthKit signals, now pinnable. Each
|
||||
// reuses the existing measurement-type label key.
|
||||
cardioRecovery: "measurements.typeCardioRecovery",
|
||||
sixMinuteWalk: "measurements.typeSixMinuteWalkDistance",
|
||||
stairAscentSpeed: "measurements.typeStairAscentSpeed",
|
||||
stairDescentSpeed: "measurements.typeStairDescentSpeed",
|
||||
breathingDisturbances: "measurements.typeBreathingDisturbances",
|
||||
wristTemperature: "measurements.typeWristTemperature",
|
||||
falls: "measurements.typeFallCount",
|
||||
walkingSteadiness: "measurements.typeWalkingSteadiness",
|
||||
};
|
||||
|
||||
export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
|
||||
@@ -382,11 +382,13 @@ describe("resolveDashboardLayout() — chartOverlayPrefs (v1.4.18)", () => {
|
||||
* iOS-only ids extend it without touching the writable PUT enum.
|
||||
*/
|
||||
describe("DASHBOARD_WIDGET_CATALOGUE_IDS — 27-id catalogue", () => {
|
||||
it("carries exactly 27 distinct ids (16 server-known + 11 iOS-only)", () => {
|
||||
expect(DASHBOARD_WIDGET_IDS).toHaveLength(16);
|
||||
it("carries exactly 35 distinct ids (24 server-known + 11 iOS-only)", () => {
|
||||
// v1.11.2 B5 — the 8 v1.10 additive metrics became web-writable, so
|
||||
// the server-known set grew 16 → 24 and the catalogue 27 → 35.
|
||||
expect(DASHBOARD_WIDGET_IDS).toHaveLength(24);
|
||||
expect(DASHBOARD_IOS_ONLY_WIDGET_IDS).toHaveLength(11);
|
||||
expect(DASHBOARD_WIDGET_CATALOGUE_IDS).toHaveLength(27);
|
||||
expect(new Set(DASHBOARD_WIDGET_CATALOGUE_IDS).size).toBe(27);
|
||||
expect(DASHBOARD_WIDGET_CATALOGUE_IDS).toHaveLength(35);
|
||||
expect(new Set(DASHBOARD_WIDGET_CATALOGUE_IDS).size).toBe(35);
|
||||
});
|
||||
|
||||
it("is a superset of the server-known ids in declaration order", () => {
|
||||
@@ -483,17 +485,17 @@ describe("resolveDashboardLayout() — iOS-only id retention (v1.7.0)", () => {
|
||||
expect(ids).not.toContain("totally-made-up");
|
||||
});
|
||||
|
||||
it("keeps the default layout at the 16 web tiles (no iOS-only seeded)", () => {
|
||||
it("keeps the default layout at the 24 web tiles (no iOS-only seeded)", () => {
|
||||
const ids = DEFAULT_DASHBOARD_LAYOUT.widgets.map((w) => w.id);
|
||||
expect(ids).toHaveLength(16);
|
||||
expect(ids).toHaveLength(24);
|
||||
for (const iosId of DASHBOARD_IOS_ONLY_WIDGET_IDS) {
|
||||
expect(ids).not.toContain(iosId);
|
||||
}
|
||||
});
|
||||
|
||||
it("does NOT auto-append iOS-only ids when a web-only layout is read", () => {
|
||||
// A web account that saved only `weight` must auto-upgrade to the 16
|
||||
// web defaults — never to the 27 catalogue. iOS-only ids appear only
|
||||
// A web account that saved only `weight` must auto-upgrade to the 24
|
||||
// web defaults — never to the 35 catalogue. iOS-only ids appear only
|
||||
// once a native client has explicitly sent them.
|
||||
const partial = {
|
||||
version: 1,
|
||||
@@ -501,7 +503,7 @@ describe("resolveDashboardLayout() — iOS-only id retention (v1.7.0)", () => {
|
||||
};
|
||||
const resolved = resolveDashboardLayout(partial);
|
||||
const ids = resolved.widgets.map((w) => w.id);
|
||||
expect(ids).toHaveLength(16);
|
||||
expect(ids).toHaveLength(24);
|
||||
for (const iosId of DASHBOARD_IOS_ONLY_WIDGET_IDS) {
|
||||
expect(ids).not.toContain(iosId);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,18 @@ export const DASHBOARD_WIDGET_IDS = [
|
||||
// cue is discoverable from the dashboard rather than hidden
|
||||
// behind Settings.
|
||||
"recentWorkouts",
|
||||
// v1.11.2 B5 — the v1.10 additive HealthKit signals become pinnable.
|
||||
// Each maps 1:1 to a MeasurementType the server already stores;
|
||||
// default-invisible so existing dashboards stay unchanged until the
|
||||
// user opts in via Settings → Dashboard.
|
||||
"cardioRecovery",
|
||||
"sixMinuteWalk",
|
||||
"stairAscentSpeed",
|
||||
"stairDescentSpeed",
|
||||
"breathingDisturbances",
|
||||
"wristTemperature",
|
||||
"falls",
|
||||
"walkingSteadiness",
|
||||
] as const;
|
||||
|
||||
export type DashboardWidgetId = (typeof DASHBOARD_WIDGET_IDS)[number];
|
||||
@@ -323,6 +335,22 @@ export const DEFAULT_DASHBOARD_LAYOUT: DashboardLayout = {
|
||||
// workouts list and renders an Apple-Health onboarding hint
|
||||
// otherwise.
|
||||
{ id: "recentWorkouts", visible: true, tileVisible: true, order: 15 },
|
||||
// v1.11.2 B5 — v1.10 additive HealthKit signals, pinnable but
|
||||
// default-invisible on both surfaces. The user opts in via
|
||||
// Settings → Dashboard; each tile self-gates on having any sample.
|
||||
{ id: "cardioRecovery", visible: false, tileVisible: false, order: 16 },
|
||||
{ id: "sixMinuteWalk", visible: false, tileVisible: false, order: 17 },
|
||||
{ id: "stairAscentSpeed", visible: false, tileVisible: false, order: 18 },
|
||||
{ id: "stairDescentSpeed", visible: false, tileVisible: false, order: 19 },
|
||||
{
|
||||
id: "breathingDisturbances",
|
||||
visible: false,
|
||||
tileVisible: false,
|
||||
order: 20,
|
||||
},
|
||||
{ id: "wristTemperature", visible: false, tileVisible: false, order: 21 },
|
||||
{ id: "falls", visible: false, tileVisible: false, order: 22 },
|
||||
{ id: "walkingSteadiness", visible: false, tileVisible: false, order: 23 },
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user