diff --git a/messages/de.json b/messages/de.json index c3db429d5..b44fe4387 100644 --- a/messages/de.json +++ b/messages/de.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "heute", "glp1NextInjectionTomorrow": "morgen", "glp1RotationSuggested": "Empfohlen: {site}", - "glp1LogSideEffect": "Nebenwirkung loggen", "sideEffects": { "section": "Nebenwirkungen", "addCta": "Erfassen", diff --git a/messages/en.json b/messages/en.json index d897c04e6..8dee2871b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "today", "glp1NextInjectionTomorrow": "tomorrow", "glp1RotationSuggested": "Recommended next: {site}", - "glp1LogSideEffect": "Log side effect", "sideEffects": { "section": "Side effects", "addCta": "Log", diff --git a/messages/es.json b/messages/es.json index c6c9875ea..34261c62a 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "hoy", "glp1NextInjectionTomorrow": "mañana", "glp1RotationSuggested": "Sugerido: {site}", - "glp1LogSideEffect": "Registrar efecto secundario", "sideEffects": { "section": "Efectos secundarios", "addCta": "Registrar", diff --git a/messages/fr.json b/messages/fr.json index 95779eaa4..63b352e78 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "aujourd’hui", "glp1NextInjectionTomorrow": "demain", "glp1RotationSuggested": "Conseillé : {site}", - "glp1LogSideEffect": "Consigner un effet secondaire", "sideEffects": { "section": "Effets secondaires", "addCta": "Consigner", diff --git a/messages/it.json b/messages/it.json index 1bc25ec4c..940aeb2e9 100644 --- a/messages/it.json +++ b/messages/it.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "oggi", "glp1NextInjectionTomorrow": "domani", "glp1RotationSuggested": "Suggerita: {site}", - "glp1LogSideEffect": "Registra effetto collaterale", "sideEffects": { "section": "Effetti collaterali", "addCta": "Registra", diff --git a/messages/ko.json b/messages/ko.json index 5aeef7e5d..4d05bd352 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "오늘", "glp1NextInjectionTomorrow": "내일", "glp1RotationSuggested": "다음 추천 부위: {site}", - "glp1LogSideEffect": "부작용 기록", "sideEffects": { "section": "부작용", "addCta": "기록", diff --git a/messages/nl.json b/messages/nl.json index e0a3f8535..66e9ad010 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "vandaag", "glp1NextInjectionTomorrow": "morgen", "glp1RotationSuggested": "Volgende aanbevolen plek: {site}", - "glp1LogSideEffect": "Bijwerking vastleggen", "sideEffects": { "section": "Bijwerkingen", "addCta": "Vastleggen", diff --git a/messages/pl.json b/messages/pl.json index d35c7b385..a41d3296f 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "dziś", "glp1NextInjectionTomorrow": "jutro", "glp1RotationSuggested": "Sugerowane: {site}", - "glp1LogSideEffect": "Zapisz działanie niepożądane", "sideEffects": { "section": "Skutki uboczne", "addCta": "Dodaj", diff --git a/messages/pt-BR.json b/messages/pt-BR.json index 05e875766..36ea5e553 100644 --- a/messages/pt-BR.json +++ b/messages/pt-BR.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "hoje", "glp1NextInjectionTomorrow": "amanhã", "glp1RotationSuggested": "Próximo recomendado: {site}", - "glp1LogSideEffect": "Registrar efeito colateral", "sideEffects": { "section": "Efeitos colaterais", "addCta": "Registrar", diff --git a/messages/ru.json b/messages/ru.json index c96b8a0b2..431bdbac2 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -1481,7 +1481,6 @@ "glp1NextInjectionToday": "сегодня", "glp1NextInjectionTomorrow": "завтра", "glp1RotationSuggested": "Рекомендуется следующее: {site}", - "glp1LogSideEffect": "Записать побочный эффект", "sideEffects": { "section": "Побочные эффекты", "addCta": "Записать", diff --git a/src/__tests__/baselines/version-stamp-comments.json b/src/__tests__/baselines/version-stamp-comments.json index 0afbd80b7..95b72ddd6 100644 --- a/src/__tests__/baselines/version-stamp-comments.json +++ b/src/__tests__/baselines/version-stamp-comments.json @@ -1,7 +1,7 @@ { "$comment": "Comment lines that open with a release version, per file under src/. Maintained by src/__tests__/version-stamp-ratchet.test.ts.", "count": 2881, - "total": 9188, + "total": 9185, "entries": { "__tests__/account-payload-consumer-guard.test.ts": 2, "__tests__/acting-account-boundary-guard.test.ts": 7, @@ -1128,7 +1128,7 @@ "components/medications/__tests__/inventory-section-actions.test.tsx": 1, "components/medications/__tests__/inventory-section-summary.test.tsx": 2, "components/medications/__tests__/log-injection-site-dialog.test.tsx": 1, - "components/medications/__tests__/medication-card-glp1.test.tsx": 14, + "components/medications/__tests__/medication-card-glp1.test.tsx": 12, "components/medications/__tests__/medication-card-header.test.tsx": 1, "components/medications/__tests__/medication-card-next-due.test.tsx": 4, "components/medications/__tests__/medication-card-symmetry.test.tsx": 4, @@ -1165,7 +1165,7 @@ "components/medications/log-injection-site-dialog.tsx": 2, "components/medications/log-intake-dialog.tsx": 4, "components/medications/medication-card-header.tsx": 5, - "components/medications/medication-card-menu.tsx": 3, + "components/medications/medication-card-menu.tsx": 2, "components/medications/medication-card.tsx": 37, "components/medications/medication-categories-sheet.tsx": 1, "components/medications/medication-category-add-row.tsx": 1, diff --git a/src/components/__tests__/delegated-write-affordances.test.tsx b/src/components/__tests__/delegated-write-affordances.test.tsx index 7517ab847..623e22bde 100644 --- a/src/components/__tests__/delegated-write-affordances.test.tsx +++ b/src/components/__tests__/delegated-write-affordances.test.tsx @@ -320,20 +320,16 @@ describe("marking a dose", () => { describe("the medication card menu", () => { const node = ( - {}} - onOpenHistory={() => {}} - onLogSideEffect={() => {}} - /> + {}} onOpenHistory={() => {}} /> ); it("renders its trigger in the caller's own record", () => { expect(render(OWN_RECORD, node)).toContain(" { - // One item survives for them — noting a side effect — so the menu stays. - expect(render(WRITABLE, node)).toContain(" { + // Editing and the history editor are owner work; nothing survives. + expect(render(WRITABLE, node)).toBe(""); }); it("disappears entirely for a read-only delegate", () => { diff --git a/src/components/medications/__tests__/medication-card-glp1.test.tsx b/src/components/medications/__tests__/medication-card-glp1.test.tsx index 5a405f085..b043d2e9e 100644 --- a/src/components/medications/__tests__/medication-card-glp1.test.tsx +++ b/src/components/medications/__tests__/medication-card-glp1.test.tsx @@ -465,49 +465,9 @@ describe(" — GLP-1 variant rendering", () => { expect(html).not.toContain("Low stock"); }); - it("folds the side-effect quick-log into the same overflow kebab", () => { - // v1.7.2 — the side-effect quick-log folds into the SAME overflow - // menu as edit / history / advanced, so the GLP-1 header carries one - // kebab whether or not the hand-off is wired (parity with the generic - // card). SSR doesn't open Radix Portal content, so we assert the - // single trigger surfaces and smoke-check the handler payload. - const client = makeClient(); - seedCompliance(client, med7p5.id); - seedGlp1Details(client, med7p5.id, {}); - - const handler = vi.fn(); - const html = render( - {}} - onOpenHistory={() => {}} - onLogSideEffect={handler} - />, - client, - ); - - // Exactly one kebab trigger with the localised aria-label. - const triggers = html.match(/aria-label="More options"/g) ?? []; - expect(triggers).toHaveLength(1); - // The side-effect button must no longer ride alongside - // Eingenommen / Übersprungen in the primary actions row. - expect(html).not.toMatch( - /class="[^"]*flex[^"]*gap-2[^"]*"[^>]*>[\s\S]*?Log side effect/, - ); - - // Invoke the supplied handler the way the menu item's onClick - // would — pins the prefill payload contract for MoodEntry. - handler(med7p5); - expect(handler).toHaveBeenCalledWith( - expect.objectContaining({ name: "Mounjaro", treatmentClass: "GLP1" }), - ); - }); - - it("still renders the single kebab when onLogSideEffect is not supplied", () => { - // v1.7.2 — the kebab is unconditional now (it always carries edit - // / history / advanced); the side-effect item is the only opt-in - // part. Mounjaro and Ramipril therefore share the same one-kebab - // header shape regardless of the hand-off prop. + it("renders the single overflow kebab", () => { + // The kebab carries edit and history, so Mounjaro and Ramipril share + // the same one-kebab header shape. const client = makeClient(); seedCompliance(client, med7p5.id); seedGlp1Details(client, med7p5.id, {}); diff --git a/src/components/medications/__tests__/medication-card-symmetry.test.tsx b/src/components/medications/__tests__/medication-card-symmetry.test.tsx index 5b8ab213f..1343f7103 100644 --- a/src/components/medications/__tests__/medication-card-symmetry.test.tsx +++ b/src/components/medications/__tests__/medication-card-symmetry.test.tsx @@ -190,9 +190,8 @@ describe("medication card symmetry — Ramipril vs Mounjaro", () => { } }); - it("Mounjaro keeps the single kebab even when onLogSideEffect is supplied (GLP-1-only)", () => { - // The side-effect quick-log folds into the SAME overflow menu, so the - // GLP-1 header shape stays byte-symmetric with the generic card: one + it("Mounjaro carries the same single kebab as the generic card", () => { + // The GLP-1 header shape stays byte-symmetric with the generic card: one // kebab trigger, no extra control. const client = makeClient(); seedCompliance(client, mounjaro.id); @@ -203,7 +202,6 @@ describe("medication card symmetry — Ramipril vs Mounjaro", () => { medication={mounjaro} onEdit={() => {}} onOpenHistory={() => {}} - onLogSideEffect={() => {}} />, client, ); @@ -294,7 +292,6 @@ describe("medication card symmetry — Ramipril vs Mounjaro", () => { medication={mounjaro} onEdit={() => {}} onOpenHistory={() => {}} - onLogSideEffect={() => {}} />, client, ); diff --git a/src/components/medications/glp1-medication-card.tsx b/src/components/medications/glp1-medication-card.tsx index 5024217cd..91502183c 100644 --- a/src/components/medications/glp1-medication-card.tsx +++ b/src/components/medications/glp1-medication-card.tsx @@ -178,7 +178,6 @@ interface Glp1MedicationCardProps { * card. The parent owns the navigation. */ onOpenHistory: (med: Glp1Medication) => void; - onLogSideEffect?: (med: Glp1Medication) => void; /** * v1.29.x — briefly ringed when this card is the Today digest's "Log * dose" deep-link target (`/medications?highlight=`). @@ -215,7 +214,6 @@ export function Glp1MedicationCard({ medication, onEdit, onOpenHistory, - onLogSideEffect, highlighted = false, }: Glp1MedicationCardProps) { const queryClient = useQueryClient(); @@ -478,19 +476,11 @@ export function Glp1MedicationCard({ // The four former header icon-buttons (open / edit / history / // advanced) collapse into a SINGLE overflow menu so the GLP-1 card // stays symmetric with the generic medication card. The card header - // itself links to the detail page (the former chevron target). The - // optional side-effect quick-log would fold in as a last menu item - // when `onLogSideEffect` is wired, but the medications list page does - // not wire it — side-effect logging lives on the detail page's - // SideEffectsSection — so the menu renders the same items as the - // generic card. + // itself links to the detail page (the former chevron target). const headerActions = ( onEdit(medication)} onOpenHistory={() => onOpenHistory(medication)} - onLogSideEffect={ - onLogSideEffect ? () => onLogSideEffect(medication) : undefined - } /> ); diff --git a/src/components/medications/medication-card-menu.tsx b/src/components/medications/medication-card-menu.tsx index b26c9c0b1..b9a75fbf1 100644 --- a/src/components/medications/medication-card-menu.tsx +++ b/src/components/medications/medication-card-menu.tsx @@ -14,13 +14,8 @@ * target as the name tap); the structural wizard lives under the detail * page's Erweitert → Lebenszyklus row. * - * The optional `onLogSideEffect` slot exists for the GLP-1 card to fold a - * "Log side effect" item into the SAME menu, but it is NOT wired on the - * medications list page — both card variants there receive only the - * edit / history / advanced handlers, so the item never renders. Side- - * effect logging lives on the detail page's ``. When - * the slot is left undefined the two card variants stay byte-symmetric in - * the header (one kebab, identical items). + * Side-effect logging lives on the detail page's ``, so + * the two card variants carry the same menu (one kebab, identical items). * * The trigger is a 44px ghost icon-button (WCAG 2.5.5); every * `DropdownMenuItem` already carries `min-h-11` from the shadcn @@ -33,14 +28,13 @@ */ import { useRecordCapabilities } from "@/hooks/use-record-capabilities"; -import { History, MoreVertical, Pencil, Stethoscope } from "lucide-react"; +import { History, MoreVertical, Pencil } from "lucide-react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { useTranslations } from "@/lib/i18n/context"; @@ -48,25 +42,19 @@ import { useTranslations } from "@/lib/i18n/context"; export interface MedicationCardMenuProps { onEdit: () => void; onOpenHistory: () => void; - /** GLP-1-only: folds the side-effect quick-log into the same menu. */ - onLogSideEffect?: () => void; } export function MedicationCardMenu({ onEdit, onOpenHistory, - onLogSideEffect, }: MedicationCardMenuProps) { const { t } = useTranslations(); - // v1.36.x — noting a side effect is an admitted delegated write; editing the - // medication and opening its history editor are not. When nothing in the - // menu survives, the trigger goes with it rather than opening onto an empty - // sheet. The card itself is untouched: no wash, no badge, no colour change. - const { canWriteDomain, canManageDomain } = useRecordCapabilities(); - const canAddSideEffect = canWriteDomain("medications"); - const canManageMedications = canManageDomain("medications"); - const showSideEffect = onLogSideEffect != null && canAddSideEffect; - if (!canManageMedications && !showSideEffect) return null; + // Editing the medication and opening its history editor are owner work, not + // delegated writes. Without either, the trigger goes too rather than opening + // onto an empty menu. The card itself is untouched: no wash, no badge, no + // colour change. + const { canManageDomain } = useRecordCapabilities(); + if (!canManageDomain("medications")) return null; return ( @@ -89,27 +77,14 @@ export function MedicationCardMenu({ className="w-56" data-slot="medication-card-menu" > - {canManageMedications && ( - <> - - - {t("common.edit")} - - - - {t("medications.detail.header.historyLabel")} - - - )} - {showSideEffect && onLogSideEffect && ( - <> - {canManageMedications && } - - - {t("medications.glp1LogSideEffect")} - - - )} + + + {t("common.edit")} + + + + {t("medications.detail.header.historyLabel")} + );