Skip to content

feat(web): unify Invoice Detail Page with OrderInvoicePanel redesign#1514

Merged
piotrswierzy merged 1 commit into
mainfrom
1462-invoice-detail-page-redesign
Jul 14, 2026
Merged

feat(web): unify Invoice Detail Page with OrderInvoicePanel redesign#1514
piotrswierzy merged 1 commit into
mainfrom
1462-invoice-detail-page-redesign

Conversation

@jakubretajczykBD

@jakubretajczykBD jakubretajczykBD commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator
image

Summary

Wrap the Document fields block and the invoiceDetailSection provider region in one host card (border/radius/shadow chrome reused from OrderInvoicePanel, #1449), and migrate the bespoke

to the shared KeyValueList primitive. The provider region is now inset by the card's own padding instead of stretching full-width, with a divider + "Provider region" label separating it from the fields above.

Layout/framing only — invoiceDetailSection/invoiceCorrectionFlow plugin contract, .invoice-detail__grid column proportions, and the right-column timeline/actions are unchanged.

Related issues

Closes #1462

Quality gate

  • pnpm lint passes (zero errors)
  • pnpm type-check passes (zero errors)
  • pnpm test passes (all unit tests green)
  • Optional, Docker required: pnpm test:integration passes — needed
    only if you touched apps/api/test/integration/** or any plugin's
    infrastructure/adapters/.

By submitting this pull request, I confirm that my contributions
are made under the terms of the Apache License 2.0, and I
certify the Developer Certificate of Origin
by signing off my commits.

Wrap the Document fields block and the invoiceDetailSection provider
region in one host card (border/radius/shadow chrome reused from
OrderInvoicePanel, #1449), and migrate the bespoke
<dl className="invoice-panel__kv"> to the shared KeyValueList
primitive. The provider region is now inset by the card's own padding
instead of stretching full-width, with a divider + "Provider region"
label separating it from the fields above.

Layout/framing only — invoiceDetailSection/invoiceCorrectionFlow
plugin contract, .invoice-detail__grid column proportions, and the
right-column timeline/actions are unchanged.

Closes #1462

Signed-off-by: jakubret <jakub.retajczyk@blockydevs.com>
@jakubretajczykBD jakubretajczykBD marked this pull request as ready for review July 14, 2026 08:26

@piotrswierzy piotrswierzy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE ✅

Clean, tightly-scoped layout refactor that does exactly what #1462 asks and stays consistent with #1449/#1484. No blockers.

What it does

Wraps the Document fields block + the invoiceDetailSection provider region of InvoiceDetailPage in a single host card (reusing OrderInvoicePanel's card chrome — border/radius/shadow), and migrates the bespoke <dl className="invoice-panel__kv"> to the shared KeyValueList primitive via a new buildInvoiceDetailFieldItems helper. The provider region is now inset by the card padding with a divider + "Provider region" label instead of a tone-fill stretching the full width of the main column. Layout/framing only — plugin contract, grid proportions, and the right-column timeline/actions are untouched.

Assessment (docs/frontend-architecture.md + frontend-ui-style-guide.md)

  • DRY / #1484 consistency — reuses the shared KeyValueList + the buildInvoiceFieldItems-style helper pattern rather than a parallel renderer; card chrome mirrors OrderInvoicePanel. ✔
  • Plugin seam — host owns card chrome + the capability gate (InvoiceDetailSection && connection); zero hardcoded KSeF/Subiekt/inFakt logic; invoiceDetailSection/invoiceCorrectionFlow contract unchanged. ✔
  • Dependency directionpages → features only; the connections import moved from a deep features/connections/hooks/... path to the features/connections public barrel (which re-exports Connection + useConnectionsQuery), matching OrderInvoicePanel. Nice improvement. ✔
  • State ownership — server state stays in the existing TanStack Query hooks; no raw fetch(), no new global state. ✔
  • UI / tokens — all colors/radius/shadow/spacing via var(--…); the raw font-size: 0.6875rem on the caps label matches long-standing precedent across index.css (no font-size token system exists), so not a violation. --tracking-caps, --text-muted, --font-mono used correctly. ✔
  • Naming / types — kebab-case file, PascalCase export, explicit KeyValueItem[] return + typed t; no any. ✔
  • Tests — existing invoice-detail-page.test.tsx (loading / not-found / error / issued / failed+rejected / in-doubt) queries by role/text, so the markup migration keeps assertions green without edits; the linked "Subiekt GT" connection link and "Accepted" clearance still resolve through the new KeyValueList. ✔

BLOCKING

None.

IMPORTANT

None.

SUGGESTION (non-blocking, inline)

  1. buildInvoiceDetailFieldItems duplicates most of the panel's local buildInvoiceFieldItems — defensible since the field sets/labels/order differ; revisit only if a third surface appears. (invoice-detail-page.tsx:60)
  2. The panel renders the provider slot with no divider/label while this page adds both — a small cross-surface framing divergence; reads as a conscious, justified choice given the wider main column. (invoice-detail-page.tsx:284)

Optional: a one-line assertion for the new "Provider region" label / card wrapper would lock in the framing, but the existing semantic coverage is sufficient.

Positives

  • Faithful reuse of #1449's shared primitives instead of a second visual language.
  • Deep-import → public-barrel cleanup for Connection/useConnectionsQuery.
  • Provider capability gate and plugin contract left exactly as-is; genuinely framing-only.

* wrapping markup changed to the shared primitive (#1462, mirrors #1449's
* `buildInvoiceFieldItems` on `OrderInvoicePanel`).
*/
function buildInvoiceDetailFieldItems(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION (DRY): buildInvoiceDetailFieldItems mirrors OrderInvoicePanel's local buildInvoiceFieldItems (#1449) closely. The two field sets genuinely differ though — this page adds a linked Invoiced via, a clearanceRef row, and a different field order/labels ("Document type" vs "Document", "Regulatory clearance" vs "Clearance") — so a straight extraction would need parameterizing all of that, and the issue explicitly scoped this as "mirror the pattern," not literal reuse. Fine to keep as-is. If a third invoice-field surface ever appears, that's the moment to lift a shared, parameterized builder into features/invoicing/lib/. No change required.

{/* Provider extras slot */}
{InvoiceDetailSection && connection ? (
<>
<hr className="invoice-detail__card-divider" />

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION (cross-surface consistency): the redesigned OrderInvoicePanel renders the same invoiceDetailSection slot inline in .order-invoice-panel__body with no divider or label (order-invoice-panel.tsx:368-370), whereas this page adds an <hr className="invoice-detail__card-divider"> + a "Provider region" caps label. #1462 asks for "the same de-emphasised, host-owned framing as #1449," so the two surfaces now diverge slightly. This reads as defensible — the detail page's main column is much wider (3fr 2fr grid) than the panel card, so the label+divider earns its keep in de-emphasising a region that previously stretched full-width. Flagging only so the divergence is a conscious choice; no change required.

@piotrswierzy piotrswierzy merged commit 921c088 into main Jul 14, 2026
22 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TASK] Frontend — unify the Invoice Detail Page with the OrderInvoicePanel redesign (#1449, mockups first)

2 participants