mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
feat(medications): give the external API its own settings group
The advanced-settings sheet crammed the external ingest endpoint into the Data group next to CSV import/export — two unrelated audiences sharing one frame. Pull `ApiTokensRow` into a dedicated "Externe API" group so the developer-facing surface reads as a distinct, lowest-frequency block. New group order: Reminders -> Lifecycle -> Data -> Externe API -> Danger. The new group reuses the existing `SettingsGroup` bordered-card chrome, so it stays visually consistent with its siblings. Adds the `externalApi` group label across all six locales and updates the composition test to pin the five-block order plus the API row's new home. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> (cherry picked from commit f9f3a1277b5aad1710815511ddf7f6b210a652b2)
This commit is contained in:
1 parent
f65181bbf2
commit
555138110c
8 files changed
+62
-22
No files matched your search
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Daten",
|
||||
"reminders": "Erinnerungen",
|
||||
"lifecycle": "Lebenszyklus"
|
||||
"lifecycle": "Lebenszyklus",
|
||||
"externalApi": "Externe API"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Data",
|
||||
"reminders": "Reminders",
|
||||
"lifecycle": "Lifecycle"
|
||||
"lifecycle": "Lifecycle",
|
||||
"externalApi": "External API"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Datos",
|
||||
"reminders": "Recordatorios",
|
||||
"lifecycle": "Ciclo de vida"
|
||||
"lifecycle": "Ciclo de vida",
|
||||
"externalApi": "API externa"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Données",
|
||||
"reminders": "Rappels",
|
||||
"lifecycle": "Cycle de vie"
|
||||
"lifecycle": "Cycle de vie",
|
||||
"externalApi": "API externe"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Dati",
|
||||
"reminders": "Promemoria",
|
||||
"lifecycle": "Ciclo di vita"
|
||||
"lifecycle": "Ciclo di vita",
|
||||
"externalApi": "API esterna"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
+2
-1
@@ -1278,7 +1278,8 @@
|
||||
"group": {
|
||||
"data": "Dane",
|
||||
"reminders": "Przypomnienia",
|
||||
"lifecycle": "Cykl życia"
|
||||
"lifecycle": "Cykl życia",
|
||||
"externalApi": "Zewnętrzne API"
|
||||
},
|
||||
"dataPortability": {
|
||||
"import": {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
* v1.7.0 — AdvancedSettingsSheet composition contract.
|
||||
*
|
||||
* The sheet hosts four blocks — Reminders → Lifecycle → Data → Danger
|
||||
* zone — composed from bare section bodies. `<ResponsiveSheet>`
|
||||
* wraps Radix portals that `renderToStaticMarkup` does not materialise,
|
||||
* so we mock it to a passthrough that renders children only when `open`
|
||||
* and echoes `contentWidth`. The bodies are mocked to ordered markers.
|
||||
* The test pins:
|
||||
* - the four blocks render in the documented order;
|
||||
* The sheet hosts five blocks — Reminders → Lifecycle → Data →
|
||||
* Externe API → Danger zone — composed from bare section bodies.
|
||||
* `<ResponsiveSheet>` wraps Radix portals that `renderToStaticMarkup`
|
||||
* does not materialise, so we mock it to a passthrough that renders
|
||||
* children only when `open` and echoes `contentWidth`. The bodies are
|
||||
* mocked to ordered markers. The test pins:
|
||||
* - the five blocks render in the documented order;
|
||||
* - the external-API row lives in its own group, not in Data;
|
||||
* - the sheet opens at the `2xl` width token;
|
||||
* - `onRequestPhaseSheet` threads through to the phases row;
|
||||
* - `onOpenImport` wires the import button (co-located with export);
|
||||
@@ -107,7 +108,7 @@ function baseProps(
|
||||
}
|
||||
|
||||
describe("AdvancedSettingsSheet (v1.7.0)", () => {
|
||||
it("renders the four blocks in Reminders → Lifecycle → Data → Danger order", () => {
|
||||
it("renders the five blocks in Reminders → Lifecycle → Data → Externe API → Danger order", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<AdvancedSettingsSheet
|
||||
{...baseProps(true, { onRequestPhaseSheet: () => {} })}
|
||||
@@ -116,11 +117,26 @@ describe("AdvancedSettingsSheet (v1.7.0)", () => {
|
||||
const reminders = html.indexOf("advanced-group-reminders");
|
||||
const lifecycle = html.indexOf("advanced-group-lifecycle");
|
||||
const data = html.indexOf("advanced-group-data");
|
||||
const externalApi = html.indexOf("advanced-group-external-api");
|
||||
const danger = html.indexOf("mock-danger");
|
||||
expect(reminders).toBeGreaterThan(-1);
|
||||
expect(lifecycle).toBeGreaterThan(reminders);
|
||||
expect(data).toBeGreaterThan(lifecycle);
|
||||
expect(danger).toBeGreaterThan(data);
|
||||
expect(externalApi).toBeGreaterThan(data);
|
||||
expect(danger).toBeGreaterThan(externalApi);
|
||||
});
|
||||
|
||||
it("homes the external-API row in its own group, not in the Data group", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<AdvancedSettingsSheet {...baseProps(true)} />,
|
||||
);
|
||||
// The API row marker must sit after the external-API group opens,
|
||||
// not inside the Data group it used to share.
|
||||
const dataGroup = html.indexOf("advanced-group-data");
|
||||
const externalApiGroup = html.indexOf("advanced-group-external-api");
|
||||
const apiRow = html.indexOf("mock-api-tokens");
|
||||
expect(apiRow).toBeGreaterThan(externalApiGroup);
|
||||
expect(externalApiGroup).toBeGreaterThan(dataGroup);
|
||||
});
|
||||
|
||||
it("opens at the 2xl width token", () => {
|
||||
|
||||
@@ -6,15 +6,21 @@
|
||||
* grid.
|
||||
* v1.8.6 — rebuilt as a single column. The two-column data|reminders
|
||||
* grid read as overloaded; the sheet now narrows to `2xl` (~672px) and
|
||||
* stacks four bordered section cards in most-used-first order:
|
||||
* Reminders → Lifecycle → Data → Danger. One spacing rule throughout —
|
||||
* `space-y-4` between cards, `divide-y` + `py-3` rows inside each card
|
||||
* (the `<SettingsGroup>` card owns the dividers).
|
||||
* stacks bordered section cards in most-used-first order. One spacing
|
||||
* rule throughout — `space-y-4` between cards, `divide-y` + `py-3` rows
|
||||
* inside each card (the `<SettingsGroup>` card owns the dividers).
|
||||
*
|
||||
* v1.9.0 — the Data group split. It had carried both operator data
|
||||
* portability and the developer-facing external API in one frame; the
|
||||
* API endpoint now sits in its own `Externe API` group so the two
|
||||
* audiences no longer share a card. Order: Reminders → Lifecycle →
|
||||
* Data → Externe API → Danger.
|
||||
*
|
||||
* - Reminders: notifications switch + reminder window (grace).
|
||||
* - Lifecycle: pause/resume + end course + phases.
|
||||
* - Data: intake Import + medications CSV Export (co-located) +
|
||||
* external-API endpoint / token.
|
||||
* - Data: intake Import + medications CSV Export (co-located).
|
||||
* - Externe API: the per-medication ingest endpoint + token, with the
|
||||
* request examples collapsed by default.
|
||||
* - Danger zone: purge intake history + delete medication, set off by
|
||||
* its own destructive-tinted card so an irreversible action never
|
||||
* sits next to a routine toggle.
|
||||
@@ -142,7 +148,9 @@ export function AdvancedSettingsSheet({
|
||||
)}
|
||||
</SettingsGroup>
|
||||
|
||||
{/* DATA — import + export + external API */}
|
||||
{/* DATA — import + export. The external API lives in its own
|
||||
group below; this group stays scoped to operator data
|
||||
portability so the two audiences don't share one frame. */}
|
||||
<SettingsGroup
|
||||
label={t("medications.detail.advanced.group.data")}
|
||||
dataSlot="advanced-group-data"
|
||||
@@ -153,6 +161,16 @@ export function AdvancedSettingsSheet({
|
||||
onOpenImport={onOpenImport}
|
||||
/>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
|
||||
{/* EXTERNAL API — the per-medication ingest endpoint + token.
|
||||
Pulled out of the Data group into its own frame so the
|
||||
developer/integration surface reads as a distinct, lowest-
|
||||
frequency block right before the danger zone. */}
|
||||
<SettingsGroup
|
||||
label={t("medications.detail.advanced.group.externalApi")}
|
||||
dataSlot="advanced-group-external-api"
|
||||
>
|
||||
<div className="py-3">
|
||||
<ApiTokensRow
|
||||
medicationId={medicationId}
|
||||
|
||||
Reference in new issue
Block a user