flexprice/flexprice-front

add metadata display section in InvoiceDetail

Aberta

#370 aberto em 18 de set. de 2025

 (1 comentário) (0 reação) (1 responsável)TypeScript (106 forks)auto 404
good first issuehacktoberfestjavascriptreact

Métricas do repositório

Stars
 (32 estrelas)
Métricas de merge de PR
 (Mesclagem média 1d 1h) (116 fundiu PRs em 30d)

Description

dd a dedicated Metadata section to the InvoiceDetail view/component to display invoice metadata (arbitrary key/value pairs).
This improves visibility and UX for billing-related metadata such as order ids, external references, or notes.


Goals

  • Show invoice metadata clearly in the Invoice detail page.
  • Provide copy-to-clipboard support for values.
  • Handle empty, long, or sensitive metadata gracefully.

Acceptance Criteria

  1. Section placement

    • Appears in InvoiceDetail below invoice header (or sidebar if layout allows).
    • Title: Metadata.
  2. Data

    • Source: invoice.metadata (Record<string, string | number | null>).
    • Show No metadata available if empty.
  3. Rendering

    • Two-column layout: key (left), value (right).
    • Humanize keys (e.g., external_order_idExternal order id).
    • Truncate long values; show full value in tooltip + allow copy.
  4. Interactions

    • Copy button for each value → copies full string to clipboard.
    • Tooltip on hover shows full value.
    • Accessible via keyboard with aria-labels.
  5. Styling

    • Use Tailwind + shadcn/ui.
    • Compact, scannable layout with consistent spacing.
    • Keys column fixed width; values truncated or wrapped.
  6. Edge cases

    • Null values → render as empty string.
    • Very long values → truncate + tooltip.
    • Sensitive keys (token, secret, password, cvv, ssn) → mask value with Hidden for security.
  7. Tests

    • Renders metadata list.
    • Shows “No metadata available” when empty.
    • Copy button copies correct value.
    • Sensitive keys are masked.

Implementation Notes

  • Create reusable InvoiceMetadata component.
  • Input: metadata?: Record<string, unknown>.
  • Isolated so it can be reused elsewhere.

Minimal Example (React + TS):

function humanizeKey(k: string) {
  return k.replace(/[_-]/g, " ").replace(/\b\w/g, c => c.toUpperCase());
}

function isSensitive(key: string) {
  return /(token|secret|password|ssn|cvv)/i.test(key);
}

Guia do colaborador