View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012019 | Taler | merchant portal webui | public | 2026-11-10 23:41 | 2026-11-10 23:43 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0012019: Merchant: Delete Order confirmation leaves focus behind the overlay (and Escape does nothing) | ||||
| Description | What happens: Order detail -> '•••' (Order actions) -> 'Delete Order' shows a hand-made role=dialog overlay. RowActions returns focus to its '•••' trigger behind the overlay, so focus is outside the dialog; the dialog's Escape handler sits on its own onKeyDown, so Escape did not close it either (measured: still open). Expected: Focus starts inside the confirmation on its safe choice, Cancel (never on 'Confirm Delete'). Where: - packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx:167 - packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx:417 Measured in headless Chromium (document.activeElement): before: BUTTON 'Order actions' (•••, behind the overlay); Escape: dialog stays open after: BUTTON 'Cancel' inside the dialog; Escape closes it Proposed fix: Ref on the Cancel button and an effect on showDeleteModal that focuses it when the dialog opens; as a side effect the dialog's existing Escape handler now works. Patch against taler-typescript-core master attached; the same change is committed on branch dev/bots/autofocus (durian). Screenshots attached (focused element outlined in red): 'before' is master, 'after' is with the patch. Verified: tsc ok for file; screens.test.js passes; screenshot confirms | ||||
| Tags | No tags attached. | ||||
| Attached Files | merchant-b--order-detail-delete-dialog.diff (1,748 bytes)
diff --git a/packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx b/packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx
index ac00362c8..7ed05d14f 100644
--- a/packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx
+++ b/packages/taler-merchant-webui/src/screens/OrderDetailScreen.tsx
@@ -16,7 +16,7 @@
import { useLocation } from "wouter-preact";
import type { VNode } from "preact";
-import { useEffect, useState } from "preact/hooks";
+import { useEffect, useRef, useState } from "preact/hooks";
import { Header } from "../ui/Header.js";
import { TalerQrCode } from "../ui/TalerQrCode.js";
import { ApiErrorBanner } from "../ui/ApiErrorBanner.js";
@@ -162,6 +162,12 @@ export function OrderDetailScreen({
const [forceDelete, setForceDelete] = useState<boolean>(false);
const [isDeleting, setIsDeleting] = useState<boolean>(false);
const [deleteError, setDeleteError] = useState<string>("");
+ // Open the confirmation on its safe choice. The dialog only hears Escape
+ // while focus is inside it, and the menu that opens it leaves focus behind.
+ const deleteCancel = useRef<HTMLButtonElement>(null);
+ useEffect(() => {
+ if (showDeleteModal) deleteCancel.current?.focus();
+ }, [showDeleteModal]);
const [now, setNow] = useState<AbsoluteTimeValue>(
nowProp ?? AbsoluteTime.now(),
@@ -408,6 +414,7 @@ export function OrderDetailScreen({
</label>
<div class="flex space-x-3 pt-2">
<button
+ ref={deleteCancel}
onClick={() => setShowDeleteModal(false)}
class="flex-1 px-4 py-2 text-xs font-bold bg-gray-100 rounded-lg hover:bg-gray-200 cursor-pointer"
>{t`Cancel`}</button>
| ||||
| child of | 0012002 | new | Merchant portal: dialogs, PIN/code prompts and single-purpose forms open without keyboard focus on the obvious field |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-10 23:41 | bot-cg | New Issue | |
| 2026-11-10 23:41 | bot-cg | Relationship added | child of 0012002 |
| 2026-11-10 23:43 | bot-cg | File Added: merchant-b--order-detail-delete-dialog.diff | |
| 2026-11-10 23:43 | bot-cg | File Added: merchant-b--order-detail-delete-dialog--before.png | |
| 2026-11-10 23:43 | bot-cg | File Added: merchant-b--order-detail-delete-dialog--after.png |