fix(ui): reach touch-only actions, confirm before posting, drop a dead ring (#1280)

* fix(ui): reach touch-only actions, confirm before posting, drop a dead ring

Three defects from the UI craft audit where the interface is wrong, not
just inconsistent.

Unreachable on touch: 'Markera klar' on deadlines and the bulk-select
checkbox on /pending were 'opacity-0 group-hover:opacity-100'. Coarse
pointers never fire hover and DeadlineForm has no completion control, so
on a phone there was no way to mark a deadline done at all. Factored the
reveal into HOVER_REVEAL_CLASS, which adds pointer-coarse:opacity-100.

Unguarded ledger writes: 'Bokför' on the journal-entry detail page and on
the invoice detail page posted an immutable verifikat on one click, one
screen after the list confirmed the identical action. Both now open a
ConfirmDialog describing the outcome up front (convention 10), reusing
the list's indicative voucher-number prefetch.

Dead ring: SummaryCard emitted ring-1 ring-primary/40 and ring-1
ring-warning/40 on the same element, so the two set the same custom
property and one silently lost. The override is an exception, so it is a
Badge now (conventions 5 and 12).

Also corrects the design.md primitives table, which named ui/table.tsx as
the data-table primitive while 17 files use ui/dry-table.tsx; building a
list page from the documented row produced ~15% taller rows and a
different hover tint, which had already happened twice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(ui): let the post-confirm dialog close after a successful commit

ConfirmDialog calls onOpenChange(false) immediately after `await onConfirm()`
resolves, but handleCommit/handleBook clear their in-flight flag in a
`finally` block, so the guard's closure still saw isCommitting/isUpdating as
true and swallowed the close: the dialog would sit open over a booking that
had already succeeded.

The guard was redundant as well as wrong. ConfirmDialog already blocks
Radix-initiated closes while pending, via `onOpenChange={(next) => !pending
&& onOpenChange(next)}` on the Dialog itself. Passing the setter directly
matches every other dialog on both pages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-29 12:33:36 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 8571f9235b
commit bc5c673f7d
10 changed files with 120 additions and 20 deletions
+6
View File
@@ -3081,6 +3081,9 @@
},
"invoice_detail": {
"back": "Back",
"confirm_book_title": "Book invoice",
"confirm_book_description": "Will be posted as voucher {voucher}: invoice {number}, {amount}. A posted voucher cannot be edited, only corrected or reversed.",
"confirm_book_description_generic": "Invoice {number} will be posted with the next available voucher number and can then only be corrected or reversed.",
"load_failed_title": "Could not load invoice",
"load_failed_description": "The invoice was not found.",
"status_draft": "Draft",
@@ -4116,6 +4119,9 @@
"error_not_found": "Journal entry not found",
"error_load_failed": "Could not fetch journal entry",
"post": "Post",
"confirm_post_title": "Post voucher",
"confirm_post_description": "Will be posted as voucher {voucher}: {description}, {amount}. A posted voucher cannot be edited, only corrected or reversed.",
"confirm_post_description_generic": "The voucher \"{description}\" will be posted with the next available voucher number and can then only be corrected or reversed.",
"delete_draft": "Delete draft",
"delete_entry": "Delete journal entry",
"create_correction": "Create correction entry",
+6
View File
@@ -3081,6 +3081,9 @@
},
"invoice_detail": {
"back": "Tillbaka",
"confirm_book_title": "Bokför faktura",
"confirm_book_description": "Bokförs som verifikat {voucher}: faktura {number}, {amount}. Verifikatet kan inte ändras i efterhand, bara rättas eller stornas.",
"confirm_book_description_generic": "Faktura {number} bokförs med nästa lediga verifikationsnummer och kan därefter inte ändras, bara rättas eller stornas.",
"load_failed_title": "Kunde inte ladda faktura",
"load_failed_description": "Fakturan hittades inte.",
"status_draft": "Utkast",
@@ -4116,6 +4119,9 @@
"error_not_found": "Verifikation hittades inte",
"error_load_failed": "Kunde inte hämta verifikation",
"post": "Bokför",
"confirm_post_title": "Bokför verifikat",
"confirm_post_description": "Bokförs som verifikat {voucher}: {description}, {amount}. Verifikatet kan inte ändras i efterhand, bara rättas eller stornas.",
"confirm_post_description_generic": "Verifikatet \"{description}\" bokförs med nästa lediga verifikationsnummer och kan därefter inte ändras, bara rättas eller stornas.",
"delete_draft": "Radera utkast",
"delete_entry": "Radera verifikat",
"create_correction": "Skapa ändringsverifikation",