View Issue Details

IDProjectCategoryView StatusLast Update
0012051Talerwallet (WebExtension)public2026-11-10 23:43
Reporterbot-cg [agent] Assigned ToResolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicatorCM_7  
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
PrioritynormalSeverityminorReproducibilityhave not tried
Status newResolutionopen 
Summary0012051: Wallet: 'Create payment' (merchant payment template) form does not focus the first editable field
DescriptionWhat happens:
Opening a taler://pay-template link shows 'Create payment - Enter the details requested by the merchant' (#/pay-template/:actionId). Nothing is focused. Measured on the 'payment-template' story: BODY.

Expected:
First field the merchant left for the payer: the amount if editable, otherwise the summary if editable (the currency select is prefilled; disabled fields are skipped).

Where:
  - packages/wallet-webui/src/screens/PaymentTemplateScreen.tsx:40

Measured in headless Chromium (document.activeElement):
  before: BODY (nothing focused)
  after: INPUT (Amount)

Proposed fix:
Refs on the amount and summary inputs; effect keyed on the form being shown focuses the first editable one (preventScroll). `!loading && !error` hoisted into `formShown`.

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 (0 errors in wallet-webui with workspace sources; plain `tsc --noEmit -p .` output identical to baseline, whose errors come from stale taler-util/wallet-core lib/); eslint + prettier clean on changed files; package tests screens/exchange-removal/payment-entry/routing bundled from src: 89/95 pass, the same 6 App-level demo tests fail before and after; scratch test covers amount-locked -> summary; screenshot of the story.
TagsNo tags attached.
Attached Files
wallet--payment-template.diff (2,635 bytes)   
diff --git a/packages/wallet-webui/src/screens/PaymentTemplateScreen.tsx b/packages/wallet-webui/src/screens/PaymentTemplateScreen.tsx
index 19c179665..1552330aa 100644
--- a/packages/wallet-webui/src/screens/PaymentTemplateScreen.tsx
+++ b/packages/wallet-webui/src/screens/PaymentTemplateScreen.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from "preact/hooks";
+import { useEffect, useRef, useState } from "preact/hooks";
 import { Button } from "../ui/Button.js";
 import { Card } from "../ui/Card.js";
 import { ErrorCard } from "../ui/ErrorCard.js";
@@ -37,6 +37,18 @@ export function PaymentTemplateScreen(props: {
   }, [props.initialAmount, props.initialCurrency, props.initialSummary]);
   const normalizedAmount = positiveAmountValue(currency, amount);
   const valid = Boolean(normalizedAmount) && Boolean(summary.trim());
+  const amountInput = useRef<HTMLInputElement>(null);
+  const summaryInput = useRef<HTMLInputElement>(null);
+  const formShown = !props.loading && !props.error;
+  // Focus the first field the merchant left for the payer to fill in; the
+  // form only appears once the template has loaded.
+  useEffect(() => {
+    if (!formShown) return;
+    if (props.amountEditable)
+      amountInput.current?.focus({ preventScroll: true });
+    else if (props.summaryEditable)
+      summaryInput.current?.focus({ preventScroll: true });
+  }, [formShown, props.amountEditable, props.summaryEditable]);
   return (
     <div class="mx-auto w-full max-w-2xl space-y-6">
       <div class="flex items-center gap-4">
@@ -67,7 +79,7 @@ export function PaymentTemplateScreen(props: {
         </Card>
       )}
       {props.error && <ErrorCard error={props.error} />}
-      {!props.loading && !props.error && (
+      {formShown && (
         <form
           class="space-y-5"
           onSubmit={(event) => {
@@ -102,6 +114,7 @@ export function PaymentTemplateScreen(props: {
               <span class="mb-1 block text-sm font-medium">{i18n.str`Amount`}</span>
               <div class="flex rounded-xl border border-outline bg-surface focus-within:ring-2 focus-within:ring-primary">
                 <input
+                  ref={amountInput}
                   inputMode="decimal"
                   disabled={!props.amountEditable}
                   value={amount}
@@ -124,6 +137,7 @@ export function PaymentTemplateScreen(props: {
                 }
               </span>
               <input
+                ref={summaryInput}
                 disabled={!props.summaryEditable}
                 value={summary}
                 onInput={(event) => setSummary(event.currentTarget.value)}
wallet--payment-template.diff (2,635 bytes)   

Required notifications

Address or linkRemarkAdded byNotifiedActions

Relationships

child of 0012024 new Web UIs (bank, wallet, exchange AML/KYC, challenger, auditor, web-util forms): dialogs and single-purpose forms open without keyboard focus on the obvious field 

Activities

Issue History

Date ModifiedUsernameFieldChange
2026-11-10 23:42bot-cgNew Issue
2026-11-10 23:42bot-cgRelationship addedchild of 0012024
2026-11-10 23:43bot-cgFile Added: wallet--payment-template.diff
2026-11-10 23:43bot-cgFile Added: wallet--payment-template--before.png
2026-11-10 23:43bot-cgFile Added: wallet--payment-template--after.png