PR: #475: feat(filings): Index of Annexures export — PDF + DOCX [Story-1888] by @ankitmaheshwari-com
View PR →
Story-1888

Index of Annexures, one click

The Annexure Register subtab (Story-1886) already lists a filing's child documents — label, description, pages, copy type — ordered by annexurePosition. This story adds a single Export index control that turns that exact live list into a court-ready Index of Annexures as both a PDF (browser print) and a real .docx (Word). Generated on demand from the current query data, so the export is live with the filing, never a stored snapshot (RFD-DOC-003 D8).

What shipped

Export control in the register header

An outline Export index button (shared Button + DropdownMenu primitives) sits in the AnnexureRegisterTable header with two items: Download PDF and Download Word (.docx). Copy is in Filings.annexures.* for both en and hi.

Same row model as the screen

The export mirrors the on-screen rows one-for-one: Sr. (annexurePosition → falls back to index), Annexure (filingLabel), Description (description → displayName → filename), Pages (pageCount), Copy type (filingCopyType). No second source of truth.

Zero new dependencies

No PDF/DOCX library added (AGENTS.md). PDF is a print-styled HTML document printed from a hidden iframe (→ the browser's Save as PDF). The .docx is a hand-rolled minimal STORED ZIP of three OOXML parts ([Content_Types].xml, _rels/.rels, word/document.xml) — a real WordprocessingML file, not an HTML-as-Word fake.

Pure builders, tested

buildAnnexureIndexDocx and buildAnnexureIndexHtml take no browser APIs and are unit-tested (CRC32 + ZIP structure, row mapping, XML escaping, empty state). The thin download*/print* wrappers do the browser-only side effects on click.

Files

FileChange
src/components/matters/filings/annexure-index-export.ts New. Pure builders (print HTML + .docx bytes via a tiny stored-ZIP/OOXML writer) plus the click-time browser wrappers.
src/components/matters/filings/annexure-register-table.tsx Added the Export index dropdown to the panel header; the register table itself is unchanged.
src/components/matters/filings/annexure-index-export.test.ts New. Builder unit tests (DOCX magic + parts, row mapping, escaping, empty state; HTML fallbacks + positions).
messages/en.json, messages/hi.json Filings.annexures.exportLabel / exportPdf / exportDocx in both locales.

Scope

Token note (justified exception)

The PDF print HTML and the .docx carry plain CSS/OOXML colors (e.g. #1a1a1a) rather than var(--token) design tokens. These are standalone generated documents — the PDF renders in an isolated print iframe and the .docx opens in Word, neither of which can resolve the app's CSS custom properties. No app UI surface uses a color literal; the register header uses only token-backed utilities.

Verify

pnpm lint (0 errors), tsc --noEmit (clean), pnpm test (955 passing, incl. the new builder tests), and pnpm build all green. The generated .docx was round-tripped through unzip -t (no errors) and xmllint (well-formed document.xml and [Content_Types].xml). i18n added to both en and hi.

Files changed

5 file(s), +454 / -7 lines

Path Role + -
messages/en.jsonConfig+4-1
messages/hi.jsonConfig+4-1
src/components/matters/filings/annexure-index-export.test.tsComponent+81-0
src/components/matters/filings/annexure-index-export.tsComponent+317-0
src/components/matters/filings/annexure-register-table.tsxComponent+48-5