View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012021 | 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 | 0012021: Merchant: Templates list 'Delete template' and 'Show QR' dialogs leave focus on the row menu behind them | ||||
| Description | What happens: Templates -> row '•••' -> 'Delete template' or 'Show QR' renders an inline <dialog open> (non-modal, no focus handling). RowActions hands focus back to its trigger, which is behind the overlay; Tab walks the page underneath. Expected: Delete confirmation: focus on Cancel (safe choice). QR preview: focus inside the dialog on Close. Where: - packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx:110 - packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx:318 - packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx:407 Measured in headless Chromium (document.activeElement): before: BUTTON 'Actions for Coffee' (behind the overlay) for both dialogs after: Delete: BUTTON 'Cancel'; QR: BUTTON 'Close' (QR shots: merchant-b--templates-list-qr-dialog--before/after.png) Proposed fix: Refs on the two buttons and one effect per dialog that focuses them when deletingTemplate / previewQrTemplate is set. 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; screenshots confirm | ||||
| Tags | No tags attached. | ||||
| Attached Files | merchant-b--templates-list-dialogs.diff (2,106 bytes)
diff --git a/packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx b/packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx
index 4712104a6..c6139c75e 100644
--- a/packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx
+++ b/packages/taler-merchant-webui/src/screens/TemplatesScreen.tsx
@@ -15,7 +15,7 @@
*/
import type { VNode } from "preact";
-import { useState, useEffect } from "preact/hooks";
+import { useState, useEffect, useRef } from "preact/hooks";
import { useLocation } from "wouter-preact";
import { Header } from "../ui/Header.js";
import { TalerQrCode } from "../ui/TalerQrCode.js";
@@ -104,6 +104,18 @@ export function TemplatesScreen({
}
};
+ // These dialogs are opened from a row's action menu, which hands focus back
+ // to its trigger behind the overlay. Move it into the dialog instead, onto
+ // the choice that changes nothing.
+ const deleteCancel = useRef<HTMLButtonElement>(null);
+ const qrClose = useRef<HTMLButtonElement>(null);
+ useEffect(() => {
+ if (deletingTemplate) deleteCancel.current?.focus();
+ }, [deletingTemplate]);
+ useEffect(() => {
+ if (previewQrTemplate) qrClose.current?.focus();
+ }, [previewQrTemplate]);
+
useEffect(() => {
if (!previewQrTemplate && !viewingTemplate && !deletingTemplate) return;
const handleKeyDown = (e: KeyboardEvent) => {
@@ -303,6 +315,7 @@ export function TemplatesScreen({
</p>
<div class="flex items-center justify-end space-x-3 pt-2">
<button
+ ref={deleteCancel}
type="button"
onClick={() => setDeletingTemplate(null)}
disabled={isDeleting}
@@ -391,6 +404,7 @@ export function TemplatesScreen({
{t`🖨 Print Sheet`}
</button>
<button
+ ref={qrClose}
type="button"
onClick={() => setPreviewQrTemplate(null)}
class="px-5 py-2 text-xs font-semibold rounded-md bg-gray-200 hover:bg-gray-300 text-gray-800 transition-colors cursor-pointer"
| ||||
| 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--templates-list-dialogs.diff | |
| 2026-11-10 23:43 | bot-cg | File Added: merchant-b--templates-list-dialogs--before.png | |
| 2026-11-10 23:43 | bot-cg | File Added: merchant-b--templates-list-dialogs--after.png |