mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
Merge branch 'v1424/cards' into release/v1.42.4
This commit is contained in:
commit
f95c2bfd41
60 files changed
+5248
-5087
No files matched your search
@@ -126,12 +126,10 @@ const NO_REFETCH_ALLOWLIST = [
|
||||
// Background integration-sync completion on the Settings surface — the user
|
||||
// is configuring an integration, not acting on the hero; convergence via the
|
||||
// daily reads' own poll/focus refetch is the intended behaviour.
|
||||
"components/settings/integrations/fitbit-card.tsx",
|
||||
"components/settings/integrations/google-health-card.tsx",
|
||||
"components/settings/integrations/integration-actions.tsx",
|
||||
"components/settings/integrations/nightscout-card.tsx",
|
||||
"components/settings/integrations/oauth-provider-card.tsx",
|
||||
"components/settings/integrations/whoop-card.tsx",
|
||||
"components/settings/integrations/withings-card.tsx",
|
||||
"components/settings/integrations/oauth-integration-card.tsx",
|
||||
// Cycle writes: `cycleDependentKeys` carries no daily-read key and neither
|
||||
// the dashboard snapshot nor the Today digest reads cycle rows today, so
|
||||
// the forced refetch would be a no-op round-trip. The bundle is in the
|
||||
|
||||
@@ -616,21 +616,25 @@ const REGISTRY: DestructiveEntry[] = [
|
||||
},
|
||||
|
||||
// ── Integrations ────────────────────────────────────────────────────────
|
||||
...(
|
||||
[
|
||||
["withings-card.tsx", "Withings"],
|
||||
["fitbit-card.tsx", "Fitbit"],
|
||||
["whoop-card.tsx", "WHOOP"],
|
||||
["google-health-card.tsx", "Google Health"],
|
||||
["nightscout-card.tsx", "Nightscout"],
|
||||
["oauth-provider-card.tsx", "the generic OAuth providers"],
|
||||
] as const
|
||||
).map(([f, name]): DestructiveEntry => ({
|
||||
file: `components/settings/integrations/${f}`,
|
||||
destroys: `the stored ${name} credentials — reconnecting means authorising again`,
|
||||
// Every connection renders the shared integration card, whose three-dot
|
||||
// menu raises the confirmation for the destructive entry; the controllers
|
||||
// below only hold the request.
|
||||
{
|
||||
file: "components/settings/integrations/oauth-integration-card.tsx",
|
||||
destroys:
|
||||
"the stored Withings, WHOOP, Fitbit, Google Health, Polar, Oura or Strava grant — reconnecting means authorising again",
|
||||
triggers: ["components/settings/integrations/integration-card.tsx"],
|
||||
recovery: "permanent",
|
||||
confirm: ["AlertDialog"],
|
||||
})),
|
||||
confirm: ["ConfirmDialog"],
|
||||
},
|
||||
{
|
||||
file: "components/settings/integrations/nightscout-card.tsx",
|
||||
destroys:
|
||||
"the stored Nightscout address and token — reconnecting means typing them again",
|
||||
triggers: ["components/settings/integrations/integration-card.tsx"],
|
||||
recovery: "permanent",
|
||||
confirm: ["ConfirmDialog"],
|
||||
},
|
||||
{
|
||||
file: "components/settings/integrations/document-sources-card.tsx",
|
||||
destroys:
|
||||
|
||||
@@ -441,7 +441,7 @@ function assertBucketConsumerLineage(
|
||||
const declaration = file.statements.find(
|
||||
(statement): statement is ts.FunctionDeclaration =>
|
||||
ts.isFunctionDeclaration(statement) &&
|
||||
statement.name?.text === "pillFailurePropsFor",
|
||||
statement.name?.text === "failureStreakFor",
|
||||
);
|
||||
expect(declaration?.body).toBeDefined();
|
||||
let bucketInitializer: string | null = null;
|
||||
@@ -473,7 +473,7 @@ function assertBucketConsumerLineage(
|
||||
for (const kind of kinds) {
|
||||
expect(
|
||||
accesses,
|
||||
`pillFailurePropsFor must read buckets.${kind} from that response value`,
|
||||
`failureStreakFor must read buckets.${kind} from that response value`,
|
||||
).toContain(`buckets.${kind}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,20 +369,26 @@ const PINNED_AFFORDANCES: Record<
|
||||
"src/components/settings/integrations/connections-panel.tsx": {
|
||||
"toast.success": 2,
|
||||
},
|
||||
"src/components/settings/integrations/fitbit-card.tsx": { "text-success": 2 },
|
||||
"src/components/settings/integrations/google-health-card.tsx": {
|
||||
// The saved-credentials confirmation line.
|
||||
"src/components/settings/integrations/credentials-form.tsx": {
|
||||
"text-success": 1,
|
||||
},
|
||||
// "Test connection" from the menu: the same ok line the button shows.
|
||||
"src/components/settings/integrations/integration-actions.tsx": {
|
||||
CheckCircle2: 2,
|
||||
"text-success": 1,
|
||||
},
|
||||
// The "Working" badge tone, and "Copied" beside the diagnostics copy button.
|
||||
"src/components/settings/integrations/integration-card.tsx": {
|
||||
"text-success": 2,
|
||||
},
|
||||
"src/components/settings/integrations/nightscout-card.tsx": {
|
||||
"text-success": 1,
|
||||
},
|
||||
"src/components/settings/integrations/oauth-provider-card.tsx": {
|
||||
// A paused connection resumed.
|
||||
"src/components/settings/integrations/oauth-integration-card.tsx": {
|
||||
"text-success": 1,
|
||||
},
|
||||
"src/components/settings/integrations/whoop-card.tsx": { "text-success": 2 },
|
||||
"src/components/settings/integrations/withings-card.tsx": {
|
||||
"text-success": 2,
|
||||
},
|
||||
"src/components/settings/mcp-section.tsx": {
|
||||
"text-success": 4,
|
||||
"toast.success": 2,
|
||||
@@ -466,9 +472,11 @@ const RESULT_SURFACES: ReadonlyArray<{
|
||||
through: /IntakeImportSkipGroups/,
|
||||
forbidsMarkers: true,
|
||||
},
|
||||
// The seven surfaces that were still gated on the transport.
|
||||
// The provider sync surfaces that were still gated on the transport. Every
|
||||
// integration card reports a sync through the shared action lines; Google
|
||||
// Health keeps its own because a run can outlive its request.
|
||||
{
|
||||
path: "src/components/settings/integrations/fitbit-card.tsx",
|
||||
path: "src/components/settings/integrations/integration-actions.tsx",
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
@@ -477,26 +485,6 @@ const RESULT_SURFACES: ReadonlyArray<{
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
{
|
||||
path: "src/components/settings/integrations/nightscout-card.tsx",
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
{
|
||||
path: "src/components/settings/integrations/whoop-card.tsx",
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
{
|
||||
path: "src/components/settings/integrations/withings-card.tsx",
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
{
|
||||
path: "src/components/settings/integrations/oauth-provider-card.tsx",
|
||||
through: /WrittenOutcomeLine/,
|
||||
forbidsMarkers: false,
|
||||
},
|
||||
{
|
||||
path: "src/components/labs/ocr-review-dialog.tsx",
|
||||
through: /toastWrittenOutcome/,
|
||||
|
||||
@@ -30,7 +30,9 @@ const REQUIRED_KEYS = [
|
||||
"common.networkError",
|
||||
"settings.googleHealthSyncResult",
|
||||
"settings.googleHealthSyncFailed",
|
||||
"settings.googleHealthBackfillInProgress",
|
||||
// `settings.googleHealthBackfillInProgress` left this list in v1.42.4: the
|
||||
// history-loading line became a sentence variant of the shared integration
|
||||
// card (`settings.integrationCard.reason.dataArrivingHistory`).
|
||||
"settings.syncOutcome.empty",
|
||||
"settings.syncOutcome.partial",
|
||||
"settings.syncOutcome.failed",
|
||||
|
||||
@@ -644,7 +644,7 @@ const SYNC_ROUTES: readonly SyncRouteSpec[] = [
|
||||
id: "fitbit",
|
||||
path: join(ROOT, "src/app/api/fitbit/sync/route.ts"),
|
||||
responseClass: "resolved-with-full-sync-echo",
|
||||
card: join(SYNC_CARD_ROOT, "fitbit-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: { fullSync: FULL_SYNC_EXCEPTION },
|
||||
},
|
||||
{
|
||||
@@ -663,42 +663,42 @@ const SYNC_ROUTES: readonly SyncRouteSpec[] = [
|
||||
id: "nightscout",
|
||||
path: join(ROOT, "src/app/api/nightscout/sync/route.ts"),
|
||||
responseClass: "resolved",
|
||||
card: join(SYNC_CARD_ROOT, "nightscout-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: {},
|
||||
},
|
||||
{
|
||||
id: "oura",
|
||||
path: join(ROOT, "src/app/api/oura/sync/route.ts"),
|
||||
responseClass: "resolved",
|
||||
card: join(SYNC_CARD_ROOT, "oauth-provider-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: {},
|
||||
},
|
||||
{
|
||||
id: "polar",
|
||||
path: join(ROOT, "src/app/api/polar/sync/route.ts"),
|
||||
responseClass: "resolved",
|
||||
card: join(SYNC_CARD_ROOT, "oauth-provider-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: {},
|
||||
},
|
||||
{
|
||||
id: "strava",
|
||||
path: join(ROOT, "src/app/api/strava/sync/route.ts"),
|
||||
responseClass: "resolved",
|
||||
card: join(SYNC_CARD_ROOT, "oauth-provider-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: {},
|
||||
},
|
||||
{
|
||||
id: "whoop",
|
||||
path: join(ROOT, "src/app/api/whoop/sync/route.ts"),
|
||||
responseClass: "resolved-with-full-sync-echo",
|
||||
card: join(SYNC_CARD_ROOT, "whoop-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: { fullSync: FULL_SYNC_EXCEPTION },
|
||||
},
|
||||
{
|
||||
id: "withings",
|
||||
path: join(ROOT, "src/app/api/withings/sync/route.ts"),
|
||||
responseClass: "resolved-with-full-sync-echo",
|
||||
card: join(SYNC_CARD_ROOT, "withings-card.tsx"),
|
||||
card: join(SYNC_CARD_ROOT, "integration-actions.tsx"),
|
||||
exceptions: { fullSync: FULL_SYNC_EXCEPTION },
|
||||
},
|
||||
] as const;
|
||||
@@ -908,7 +908,7 @@ function assertSyncCardConsumesFetchedResponse(
|
||||
return;
|
||||
}
|
||||
const endpoint = responseInitializer.arguments[0];
|
||||
const expectedEndpoint = path.endsWith("oauth-provider-card.tsx")
|
||||
const expectedEndpoint = path.endsWith("integration-actions.tsx")
|
||||
? "`/api/${provider}/sync`"
|
||||
: `"/api/${routeId}/sync"`;
|
||||
expect(
|
||||
|
||||
Reference in new issue
Block a user