diff --git a/app/globals.css b/app/globals.css index d61eb094..5c725377 100644 --- a/app/globals.css +++ b/app/globals.css @@ -704,3 +704,23 @@ input[type="number"] { opacity: 1; } } + +/* Indeterminate sweep for the receipt hunt. + A pass runs for over two minutes and reports nothing until it lands, so + there is no honest percentage to show inside one. This says "still working" + without inventing progress. Reduced motion holds it still and dims it + rather than removing it: the band still has to read as active. */ +@keyframes hunt-sweep { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(400%); } +} +.hunt-sweep { + animation: hunt-sweep 1.6s ease-in-out infinite; +} +@media (prefers-reduced-motion: reduce) { + .hunt-sweep { + animation: none; + width: 100%; + opacity: 0.35; + } +} diff --git a/components/extensions/general/InvoiceInboxWorkspace.tsx b/components/extensions/general/InvoiceInboxWorkspace.tsx index 9c6bba9f..5a03d373 100644 --- a/components/extensions/general/InvoiceInboxWorkspace.tsx +++ b/components/extensions/general/InvoiceInboxWorkspace.tsx @@ -49,6 +49,7 @@ import { } from 'lucide-react' import Link from 'next/link' import { cn, formatCurrency, formatDate, formatDateLong } from '@/lib/utils' +import { QUIET_LINK_CLASS } from '@/components/ui/dry-table' import { GoogleMark, MicrosoftMark } from '@/components/ui/provider-marks' import EditKonteringDialog from '@/components/extensions/general/EditKonteringDialog' import { WhatsAppMark } from '@/components/extensions/general/WhatsAppMark' @@ -1136,9 +1137,7 @@ export default function InvoiceInboxWorkspace(_props: WorkspaceComponentProps) { {hunting ? ( <> - {huntProgress - ? `Letar… ${huntProgress.fetched} hittade` - : 'Letar…'} + {t('hunt_stop')} ) : ( <> @@ -1168,7 +1167,46 @@ export default function InvoiceInboxWorkspace(_props: WorkspaceComponentProps) { - {huntResult && ( + {/* A pass takes over two minutes and reports nothing until it lands, so + a spinner alone leaves somebody watching a button. This says which + mailboxes are being read, what has been found so far, and keeps + moving while the pass is silent. The bar is deliberately + indeterminate: there is no honest percentage inside a pass, and a + fake one is worse than none. */} + {hunting && ( +
+
+
+
+
+ + + + {t('hunt_reading', { + mailboxes: mailConnections + .filter((c) => c.status === 'active') + .map((c) => c.emailAddress) + .join(', '), + })} + + + + {huntProgress && ( + + {t('hunt_progress', { + pass: huntProgress.passes, + found: huntProgress.fetched, + })} + + )} + +
+
+ )} + + {!hunting && huntResult && (
{huntResult.failed ? ( diff --git a/messages/en.json b/messages/en.json index 48cff1b4..fc560ab4 100644 --- a/messages/en.json +++ b/messages/en.json @@ -3049,6 +3049,9 @@ "mixed_currency_note": "Documents in different currencies cannot be summed into a single amount. Each document is still booked separately, against its matched bank transaction and the amount the bank actually settled in SEK." }, "inbox_workspace": { + "hunt_stop": "Stop", + "hunt_reading": "Reading {mailboxes}", + "hunt_progress": "pass {pass} · {found} fetched", "dialog_no_document": "No document", "sources_one": "{count} source", "sources_many": "{count} sources", diff --git a/messages/sv.json b/messages/sv.json index 62c5038a..ae577235 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -3049,6 +3049,9 @@ "mixed_currency_note": "Underlag i olika valutor kan inte summeras till ett belopp. Varje underlag bokförs ändå var för sig, mot sin matchade banktransaktion och det belopp banken faktiskt drog i SEK." }, "inbox_workspace": { + "hunt_stop": "Avbryt", + "hunt_reading": "Läser {mailboxes}", + "hunt_progress": "omgång {pass} · {found} hämtade", "dialog_no_document": "Ingen handling", "sources_one": "{count} källa", "sources_many": "{count} källor",