feat(invoices): preview invoices and underlag in the browser instead of downloading (#1228)
Reviewing an invoice or a verifikat bilaga meant saving a file and opening it from the Downloads folder (user request, christian@odinaero.se 2026-07-25). - GET /api/invoices/[id]/pdf accepts ?disposition=inline and serves the PDF for in-browser review; anything else keeps the download behaviour every existing caller relies on. The filename still travels in the header, so the browser viewer's own save action produces the same name as the download button, and nosniff pins the content type. - The invoice detail page gets a "Förhandsgranska" action next to "Ladda ner PDF". It resolves the document through the same resolveInvoicePdfSource path as the download, so preview cannot become the shortcut that presents a re-render as the invoice the customer received: the archived delivery wins, a re-render is shown with its caveat, and an unreadable delivery history still asks instead of guessing. The archive dialog now remembers whether the user asked to view or to save, and its fallback does that. - DocumentViewButton (supplier-invoice underlag, staged agent previews) points at the existing /api/documents/:id/inline proxy, so bilagor render in the browser. Navigation now happens straight from the click, so the signed-URL fetch and its popup-blocker workaround are gone. - The three re-render caveat strings and the two archive-dialog descriptions lose their "you downloaded" wording so they stay true for both actions; five new keys in sv + en. Tests: route cases for the default, inline and unknown disposition values; invoiceRerenderUrl cases for both modes and id encoding. npm test 11364 passed, lint 0 errors. Button row screenshotted against the design system (pill outline, Eye icon) via a temporary sandbox route. Closes #1190 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
df29817826
commit
c62d00bcb3
+10
-5
@@ -3127,6 +3127,7 @@
|
||||
"mark_as_paid": "Mark as paid",
|
||||
"copy_invoice": "Copy invoice",
|
||||
"download_pdf": "Download PDF",
|
||||
"preview_pdf": "Preview",
|
||||
"viewer_disabled_tooltip": "You only have read-only access to this company",
|
||||
"customer_card_title": "Customer",
|
||||
"org_number_label": "Org. no: {value}",
|
||||
@@ -3245,15 +3246,19 @@
|
||||
"pdf_downloaded_draft": "The draft has been downloaded",
|
||||
"pdf_download_failed_title": "Could not download PDF",
|
||||
"pdf_rerender_downloaded_title": "Freshly generated PDF downloaded",
|
||||
"pdf_rerender_reason_sent_outside": "The latest send happened outside Accounted, so there is no archived copy of that particular send. The file you downloaded was generated just now, from today's data, template and logo.",
|
||||
"pdf_rerender_reason_no_archive": "No archived copy exists for this invoice; it was sent before delivery history was recorded. The file you downloaded was generated just now, from today's data, template and logo.",
|
||||
"pdf_rerender_reason_archive_unreachable": "The archived copy could not be retrieved. The file you downloaded was generated just now, from today's data, template and logo, and is not necessarily identical to the one the customer received.",
|
||||
"pdf_rerender_preview_title": "Showing a freshly generated PDF",
|
||||
"pdf_preview_blocked_title": "Could not open the preview",
|
||||
"pdf_preview_blocked_description": "Allow pop-up windows for Accounted in your browser and try again.",
|
||||
"pdf_rerender_reason_sent_outside": "The latest send happened outside Accounted, so there is no archived copy of that particular send. The file was generated just now, from today's data, template and logo.",
|
||||
"pdf_rerender_reason_no_archive": "No archived copy exists for this invoice; it was sent before delivery history was recorded. The file was generated just now, from today's data, template and logo.",
|
||||
"pdf_rerender_reason_archive_unreachable": "The archived copy could not be retrieved. The file was generated just now, from today's data, template and logo, and is not necessarily identical to the one the customer received.",
|
||||
"pdf_archive_issue_title": "The archived copy could not be retrieved",
|
||||
"pdf_archive_issue_history_desc": "The delivery history could not be loaded, so Accounted does not know which PDF the customer actually received. Nothing was downloaded. A freshly generated PDF is not the same document: it is built from today's data, template and logo.",
|
||||
"pdf_archive_issue_document_desc": "The archived PDF that was sent to the customer could not be retrieved right now. Nothing was downloaded. A freshly generated PDF is not the same document: it is built from today's data, template and logo.",
|
||||
"pdf_archive_issue_history_desc": "The delivery history could not be loaded, so Accounted does not know which PDF the customer actually received. Nothing was fetched. A freshly generated PDF is not the same document: it is built from today's data, template and logo.",
|
||||
"pdf_archive_issue_document_desc": "The archived PDF that was sent to the customer could not be retrieved right now. Nothing was fetched. A freshly generated PDF is not the same document: it is built from today's data, template and logo.",
|
||||
"pdf_archive_issue_cancel": "Cancel",
|
||||
"pdf_archive_issue_retry": "Try again",
|
||||
"pdf_archive_issue_rerender": "Download freshly generated PDF anyway",
|
||||
"pdf_archive_issue_rerender_preview": "Show the freshly generated PDF anyway",
|
||||
"cancel_failed_fallback": "Could not cancel the invoice",
|
||||
"cancelled_toast_title": "Invoice cancelled",
|
||||
"cancelled_with_number": "Invoice {number} has been cancelled. The number is kept in the series.",
|
||||
|
||||
+10
-5
@@ -3127,6 +3127,7 @@
|
||||
"mark_as_paid": "Markera som betald",
|
||||
"copy_invoice": "Kopiera faktura",
|
||||
"download_pdf": "Ladda ner PDF",
|
||||
"preview_pdf": "Förhandsgranska",
|
||||
"viewer_disabled_tooltip": "Du har endast läsbehörighet i detta företag",
|
||||
"customer_card_title": "Kund",
|
||||
"org_number_label": "Org.nr: {value}",
|
||||
@@ -3245,15 +3246,19 @@
|
||||
"pdf_downloaded_draft": "Utkastet har laddats ner",
|
||||
"pdf_download_failed_title": "Kunde inte ladda ner PDF",
|
||||
"pdf_rerender_downloaded_title": "Nyskapad PDF nedladdad",
|
||||
"pdf_rerender_reason_sent_outside": "Det senaste utskicket gjordes utanför Accounted, så det finns ingen arkiverad kopia av just det utskicket. Filen du laddade ner skapades nyss, utifrån dagens uppgifter, mall och logotyp.",
|
||||
"pdf_rerender_reason_no_archive": "Ingen arkiverad kopia finns för den här fakturan; den skickades innan utskickshistoriken började sparas. Filen du laddade ner skapades nyss, utifrån dagens uppgifter, mall och logotyp.",
|
||||
"pdf_rerender_reason_archive_unreachable": "Den arkiverade kopian kunde inte hämtas. Filen du laddade ner skapades nyss, utifrån dagens uppgifter, mall och logotyp, och är inte nödvändigtvis identisk med den kunden fick.",
|
||||
"pdf_rerender_preview_title": "Nyskapad PDF visas",
|
||||
"pdf_preview_blocked_title": "Kunde inte öppna förhandsgranskningen",
|
||||
"pdf_preview_blocked_description": "Tillåt popupfönster för Accounted i webbläsaren och försök igen.",
|
||||
"pdf_rerender_reason_sent_outside": "Det senaste utskicket gjordes utanför Accounted, så det finns ingen arkiverad kopia av just det utskicket. Filen skapades nyss, utifrån dagens uppgifter, mall och logotyp.",
|
||||
"pdf_rerender_reason_no_archive": "Ingen arkiverad kopia finns för den här fakturan; den skickades innan utskickshistoriken började sparas. Filen skapades nyss, utifrån dagens uppgifter, mall och logotyp.",
|
||||
"pdf_rerender_reason_archive_unreachable": "Den arkiverade kopian kunde inte hämtas. Filen skapades nyss, utifrån dagens uppgifter, mall och logotyp, och är inte nödvändigtvis identisk med den kunden fick.",
|
||||
"pdf_archive_issue_title": "Den arkiverade kopian kunde inte hämtas",
|
||||
"pdf_archive_issue_history_desc": "Utskickshistoriken kunde inte läsas in, så Accounted vet inte vilken PDF kunden faktiskt fick. Ingenting laddades ner. En nyskapad PDF är inte samma dokument: den bygger på dagens uppgifter, mall och logotyp.",
|
||||
"pdf_archive_issue_document_desc": "Den arkiverade PDF:en som skickades till kunden kunde inte hämtas just nu. Ingenting laddades ner. En nyskapad PDF är inte samma dokument: den bygger på dagens uppgifter, mall och logotyp.",
|
||||
"pdf_archive_issue_history_desc": "Utskickshistoriken kunde inte läsas in, så Accounted vet inte vilken PDF kunden faktiskt fick. Ingenting har hämtats. En nyskapad PDF är inte samma dokument: den bygger på dagens uppgifter, mall och logotyp.",
|
||||
"pdf_archive_issue_document_desc": "Den arkiverade PDF:en som skickades till kunden kunde inte hämtas just nu. Ingenting har hämtats. En nyskapad PDF är inte samma dokument: den bygger på dagens uppgifter, mall och logotyp.",
|
||||
"pdf_archive_issue_cancel": "Avbryt",
|
||||
"pdf_archive_issue_retry": "Försök igen",
|
||||
"pdf_archive_issue_rerender": "Ladda ner nyskapad PDF ändå",
|
||||
"pdf_archive_issue_rerender_preview": "Visa nyskapad PDF ändå",
|
||||
"cancel_failed_fallback": "Kunde inte makulera fakturan",
|
||||
"cancelled_toast_title": "Faktura makulerad",
|
||||
"cancelled_with_number": "Faktura {number} har makulerats. Numret behålls i serien.",
|
||||
|
||||
Reference in New Issue
Block a user