Skip to content

FE: wire Download CSV into the Accounts detail page (events/extrinsics/transfers tabs) #3407

Description

@JSONbored

Context

AccountDetail in apps/ui/src/routes/accounts.$ss58.tsx renders three data tables via AccountEventsSection (Chain events, #events, line 624), AccountExtrinsicsSection (Signed extrinsics, #extrinsics, line 356), and AccountTransfersSection (Transfers, #transfers, line 432) — none of which offer an export affordance. All three backing routes already accept ?format=csv per src/contracts.mjs: GET /api/v1/accounts/{ss58}/events (line 2416), GET /api/v1/accounts/{ss58}/extrinsics (line 2452), and GET /api/v1/accounts/{ss58}/transfers (line 2469), each wrapped in csvRouteQuery(...). No CSV/download UI exists anywhere in apps/ui/src today — this is the first page to wire it up.

Requirement

Add a "Download CSV" affordance to each of the three tabs (SectionAnchor headers for #events, #extrinsics, #transfers) that links to its own backend route with format=csv appended (and, for Events, the current ?kind= filter preserved), so a visitor can export exactly what the table currently shows.

Deliverable

  • File to change: apps/ui/src/routes/accounts.$ss58.tsx — add the affordance to the right={...} slot of the SectionAnchor in AccountExtrinsicsSection (currently only a row-count SectionBadge, line ~364), AccountTransfersSection (line ~440), and inside AccountEventsSection's right={...} slot alongside the existing SelectFilter for kind (lines 672-681).
  • Coordination note (hard dependency, verified as still open/unbuilt): this issue consumes the shared component from FE: add a reusable DownloadCsvButton component (no page wiring) #3402 ("FE: add a reusable DownloadCsvButton component (no page wiring)"), which as of this writing has landed no component anywhere in apps/ui/src — confirmed via a repo-wide search. FE: wire Download CSV into the Accounts detail page (events/extrinsics/transfers tabs) #3407 must not hand-roll its own <a>/button styling independently of FE: add a reusable DownloadCsvButton component (no page wiring) #3402; land or rebase on FE: add a reusable DownloadCsvButton component (no page wiring) #3402 first, then import and use its component here. If FE: add a reusable DownloadCsvButton component (no page wiring) #3402 is still unmerged when this is picked up, block on it rather than duplicating a bespoke download link.
  • URL construction: reuse buildUrl (exported from apps/ui/src/lib/metagraphed/client.ts) to build each download href — it already folds in getApiBase() (runtime-configurable API origin) and applyNetworkPrefix() (mainnet/testnet partitioning) and serializes query params, which is exactly what a correct CSV link needs. Do not hardcode API_BASE/origin directly (that snapshot pattern in endpoint-snippet.tsx skips the network prefix and is not the correct precedent here) or hand-build a query string, since that would reintroduce the href-taint-barrier class of bug this codebase already guards against in config.ts's sanitizeApiBase.
  • Per-tab param mapping:
    • Extrinsics: buildUrl("/api/v1/accounts/{ss58}/extrinsics", { format: "csv" }) (ss58-substituted, matching the existing accountExtrinsicsQuery path).
    • Transfers: buildUrl("/api/v1/accounts/{ss58}/transfers", { format: "csv" }).
    • Events: buildUrl("/api/v1/accounts/{ss58}/events", { format: "csv", kind: search.ev_kind }) — must reflect the currently-applied ev_kind filter (from Route.useSearch(), already in scope in AccountEventsSection) so the export matches what's on screen; omit kind when no filter is active.
  • "Done" is: each of the three sections renders one DownloadCsvButton (or whatever FE: add a reusable DownloadCsvButton component (no page wiring) #3402 names it) pointed at the section's own CSV URL, positioned in the section header's right slot; clicking it downloads/opens text/csv for that tab's current rows (events respecting the active kind filter); no change to the JSON data-fetching (accountExtrinsicsQuery/accountTransfersQuery/accountEventsQuery) paths.

Acceptance criteria

  • apps/ui/src/routes/accounts.$ss58.tsx is in the diff, with a CSV download affordance added to all three of AccountExtrinsicsSection, AccountTransfersSection, and AccountEventsSection
  • Each download link/button targets ?format=csv on that tab's own route (/extrinsics, /transfers, /events respectively) — not a shared or wrong-tab URL
  • The Events tab's CSV link includes the currently-active ev_kind filter when one is set, and omits kind when it isn't
  • The download URL is built via buildUrl from lib/metagraphed/client.ts (or the FE: add a reusable DownloadCsvButton component (no page wiring) #3402 component's internal use of it), not a hand-constructed string or a hardcoded API origin
  • Depends on / consumes FE: add a reusable DownloadCsvButton component (no page wiring) #3402's DownloadCsvButton — no bespoke per-tab download button styling reimplemented in this file
  • No changes to apps/ui/src/lib/metagraphed/queries.ts, client.ts, or any backend file (src/contracts.mjs, workers/csv.mjs) — the CSV routes and their format=csv support already exist and are out of scope here
  • Before/after screenshots included in the PR per the standing UI-change rule (this touches visible markup in accounts.$ss58.tsx)

Non-goals

Size

Size: S — keep this PR small (aim for ≤10 files / ≤1000 LOC).

Part of #2542.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

    Projects

    Status
    In progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions