Dashboard & Data Table Design That Survives Real Data

    1

    Dashboards and tables that hold up at 4,000 messy rows: density, columns, filters, bulk actions, and every state.

    $9

    Secure checkout via Stripe

    Money-back guarantee

    Converts to your local currency at checkout

    Security scanned

    Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseDotsDots+21 more

    Dashboard & Data Table Design That Survives Real Data

    Example session with this skill installed

    Design the refunds queue for our payments admin tool. Support agents live in this all day — they work through pending refund requests and approve or reject them.

    Data shape: ~2,000 pending at any time, 40k total. Columns available: refund id, customer email (some are 50+ chars), order id, amount, currency, reason (free text, often empty), status (pending / approved / rejected / failed), requested date, assigned agent (nullable — about 60% unassigned).

    Agents need to filter by status and assignee, search by email or order id, and approve/reject in bulk.

    • Read your context and instructions
    • Compiled the dashboard & data

    Refunds Queue

    Answers the question: what do I work on next, and can I clear a batch of it at once?
    Users: support agents, all day, every day. Power users — density and keyboard matter more than polish.
    Data reality: 2k pending / 40k total · email up to 50+ chars · reason often empty · assigned_agent null ~60% · status cardinality 4
    Next action: approve or reject, individually or in bulk.

    This is an operational worklist, not an analytics dashboard. That decides almost everything below: density over beauty, the queue is the page, and metrics at the top are navigation rather than decoration.


    Layout

    ┌──────────────────────────────────────────────────────┐
    │ Refunds                              [Export] [⚙]    │
    ├──────────────────────────────────────────────────────┤
    │ [Unassigned 1,204] [Mine 87] [Pending 2,041] [Failed 12]│  ← filter tabs, not stat tiles
    ├──────────────────────────────────────────────────────┤
    │ 🔍 search      Status ▾  Assignee ▾  Date ▾   ⚙ 25▾  │
    │ Status: Pending ×   Assignee: Unassigned ×  Clear all │
    ├──────────────────────────────────────────────────────┤
    │ ☐ │ Requested │ Customer │ Order │ Amount │ Status │⋯│
    │ ...                                                   │
    ├──────────────────────────────────────────────────────┤
    │ Showing 1–50 of 1,204            ‹ 1 2 3 … 25 ›      │
    └──────────────────────────────────────────────────────┘
    

    Focal point: the table. It gets everything below the filter bar.

    The counts are tabs, not tiles. An agent doesn't want to know there are 1,204 unassigned — they want to work on them. Making the count clickable collapses "read a number" and "apply a filter" into one action, and removes a whole row of decorative tiles from a screen where vertical space is the scarcest resource.

    Failed gets a red dot when > 0. It's the only one that's an alarm rather than a queue.


    Columns

    7 visible. Everything else behind the column picker.

    #ColumnTypeAlignWidthSortableTruncationNotes
    —Selectcheckbox—44px fixed——Header selects page
    1Requesteddateleft110px fixed✅ default desc—Relative < 7d ("2d ago"), absolute after; exact on hover
    2Customeremailleftflex, max 260px✅Middle-ellipsis + tooltipThe scanning column
    3Orderidleft120px fixed✅—Monospace, links to order
    4Amountcurrencyright110px fixed✅—tabular-nums, 2dp, symbol per row (mixed currency)
    5Statusenumleft110px fixed✅—Badge + label
    6Assigneeuserleft140px fixed✅Avatar + first name— when null, not "Unassigned"
    7Actions—right96px fixed——Approve / Reject inline

    Hidden by default: Refund ID, Reason, Currency code, Payment method, Order total, Customer since

    Middle-ellipsis on email, not end-ellipsis. jonathan.mcallister@… tells you nothing; jonathan.m…@acmecorp.com keeps the domain, which is what agents actually scan for. This is the single highest-value detail in the spec for this particular table.

    Mixed currency means no column-level unit. Symbol goes in the cell (€42.00), and sorting by Amount must sort by a normalised value or it's nonsense — flag to engineering.

    reason stays hidden. Free text that's usually empty is the worst possible default column: it's mostly whitespace and occasionally 400 characters. It belongs in the row expansion.

    Default sort: Requested, descending. Tiebreak: refund id, ascending.


    Density

    Default: compact, 36px rows. Agents live here; 50 rows on screen beats 25 comfortable ones. Offer the density control in the toolbar and persist per user.

    DensityRow height
    Compact (default)36px
    Default44px
    Comfortable56px

    Cell padding-x 12px, first/last 16px. 1px bottom border, no zebra striping — 7 columns doesn't need it.


    Filters & search

    ControlTypeBehaviour
    Searchtext, debounce 300msMatches email and order id. Placeholder: Search email or order ID
    Statusmulti-selectDefault: Pending only
    AssigneeselectMe · Unassigned · any agent · Anyone
    Datepreset + custom7d / 30d / all. Default: all
    • Active filters as removable chips, always visible. Clear all at 2+.

    Filter state in the URL. Agents paste these links to each other constantly — "can you take this batch". Non-negotiable in a support tool.

    • Count: Showing 1–50 of 1,204
    • Spinner goes in the search field, never over the table.

    Pagination

    Pagination, not infinite scroll. Agents process systematically and need to know where they are; infinite scroll also breaks the bulk-action bar. Page sizes 25 / 50 / 100, default 50. First/last jumps.


    Selection & bulk actions

    • Header checkbox selects the page.
    • Full page selected + more matching → All 50 on this page selected. [Select all 1,204 matching]
    • Bulk bar pins to the bottom on selection: 3 selected · Approve · Reject · Assign to me · Clear

    Confirmation names the count and the money: Approve 1,204 refunds totalling €48,210.55? — the amount is the number that stops a mistake.

    • Bulk reject requires a reason (select + optional note). Approve doesn't.
    • Progress past 2s: Approving 340 of 1,204…
    • Partial failure: 1,198 approved, 6 failed. [View failures] — never report "Done" when some failed.
    • Selection survives sort. Clears on filter change, with a toast saying so.

    Row actions

    Approve and Reject as inline buttons — they're 95% of the work, so they don't go in an overflow menu. Overflow (⋯) holds View order · Assign · Copy refund ID · View customer.

    Row click expands inline (reason, payment method, customer history), rather than navigating away. Agents lose their place otherwise.


    States

    StateDesign
    Initial load8 skeleton rows at 36px, real column widths
    RefetchRows stay at 60% opacity, 2px progress bar on the table top edge — never blank
    Slow > 5sStill loading — searching 40,000 refunds + [Cancel]
    Empty — first usen/a (queue is never empty on first use)
    Empty — filteredNo refunds match / Status: Pending · Assignee: me / [Clear filters]
    Empty — all clearQueue clear / Nothing pending. New requests appear here.
    Error — wholeCouldn't load refunds / [Try again] — filter bar and chrome preserved
    Error — partialCounts fail independently of the table; each retries alone
    Error — rowInline on the row: ⚠ Approval failed — card issuer declined · [Retry], row stays
    StaleUpdated 2 min ago · [Refresh] — poll every 60s, never auto-refresh mid-selection
    CappedNot applicable — pagination handles 40k

    The "all clear" empty state matters more than it looks. It's the only moment of the day the agent gets to feel finished. Acknowledge it.


    Responsive

    Agents are on desktop, so optimise there — but support tablet for on-call.

    WidthBehaviour
    < 768pxCard per row: customer + amount on line 1, status + date line 2, actions full-width. Bulk actions disabled.
    768–1280pxPriority columns (Requested, Customer, Amount, Status, Actions), rest behind row expansion
    > 1280pxFull 7 columns

    Keyboard

    Daily-use tool, so this earns its place:

    KeyAction
    /Focus search
    j / kNext / previous row
    xToggle selection
    aApprove focused row
    rReject focused row (opens reason)
    EnterExpand row
    EscClear selection / collapse
    ?Shortcut help

    a and r need a 3-second undo toast, since they're single-keypress and destructive-ish.


    Performance

    • Server-side sort, filter and paginate — 40k rows, non-negotiable.
    • No virtualisation needed at 50 rows/page.
    • Poll 60s, paused while rows are selected or a row is expanded.
    • Target p95 < 400ms for the filtered query; the search index needs to cover email and order id.

    Accessibility

    • Real <table>, <th scope="col">, <caption class="sr-only">Refund requests</caption> ✅
    • aria-sort on the sorted header; sort control is a <button> inside the <th> ✅
    • Sticky header with an explicit background ✅
    • Showing 1–50 of 1,204 in an aria-live="polite" region ✅
    • Approve/Reject reachable by keyboard, never hover-only ✅
    • Status badge = colour + label (failed vs rejected must not rely on red vs grey) ✅
    • Bulk bar announced on appearance; count updates announced politely ✅

    Open decisions

    • DECISION NEEDED: does approving assign the refund to the acting agent automatically? Recommend

    yes — it's an audit trail agents shouldn't have to maintain by hand.

    • DECISION NEEDED: should failed refunds sit in this queue or their own? Recommend

    own view — they need investigation, not approval, and they pollute the working count.

    Connects securely to your tools. The creator never sees your data.

    About this skill

    The problem

    Dashboards look fine with six tidy rows and fall apart with four thousand messy ones. The email that's 60 characters long pushes the actions column off screen. Every filter change blanks the table. Nobody designed the empty state, the loading state, or what happens when one query times out — so the whole page fails.

    What it does

    • Designs the layout from the question the screen answers, not from a 12-column grid: context bar, headline metrics with real comparisons, one focal view, supporting detail.
    • Specifies the table properly — column order and alignment (numbers right, always), how many are visible by default, fixed vs flex widths, truncation per column, sorting with a sensible default and a tiebreak.
    • Covers filters and search as one system: chips for active filters, state in the URL, result counts, debounce timing, and when pagination beats infinite scroll.
    • Enumerates the nine states that get skipped — initial load, refetch, slow query, three kinds of empty, whole-table error, partial failure, row-level error — with the copy for each.
    • Handles responsive honestly: a table doesn't become a smaller table. Card per row, priority columns, or frozen-column scroll — with the tradeoffs.
    • Includes real measurements: row heights by density, cell padding, sticky header CSS, tabular-nums, badge sizing, breakpoint behaviour.

    Why this beats prompting it yourself

    It designs against your actual data shape — row counts, longest values, nullable fields, status cardinality — rather than against the six perfect rows in the example. And it forces the states and the bulk-selection escalation ("select all 1,247 matching") that cause real incidents when they're left unspecified.

    Use cases

    • Building an admin panel or internal tool
    • A SaaS dashboard that needs to be acted on, not just read
    • Fixing a table that works in dev and breaks on production data
    • Speccing a CRUD interface before writing it

    Known limitations

    Chart selection and palette are out of scope — pair it with a data-viz skill. Assumes a web interface; doesn't cover native mobile table patterns.

    Does not provide visual assets or code snippets. Focuses on functional specs and layout logic.

    How to use

    1. 1

      Connect your agent to the Agensi MCP

      Copy the prompt and paste it into Claude, ChatGPT, Cursor or any agent that supports MCP. It sets up the connection for you. Manual setup

    2. 2

      Sign in to Agensi

      Your agent shows a sign-in link. Sign in and click Allow.

    3. 3

      Ask for what you need

      Your agent loads this skill and uses it on your task. It always asks before any payment.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill goes through the trust checks below.

    Security scanned

    Checked by our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    Money-back guarantee

    Doesn't do what its page promises? You get your money back.

    Trust & safety

    Security scan

    Security scan passed 1 month ago

    Permissions

    No special permissions declared or detected

    Listed1 month ago

    What's inside

    Frequently Asked Questions

    You will receive a comprehensive technical requirements document detailing column logic, interaction states, responsive behaviors, and state management rules to hand off directly to engineering.

    Unlike general prompts, this skill enforces specific data-design principles like monospaced numeric alignment and URL-synced filtering to ensure tables remain functional with thousands of real-world records.

    This skill is designed to work with all major LLMs available on our marketplace, provided they support technical specification tasks and long-form text output.

    No, this skill focuses on the functional architecture and UX logic; you will need to apply your own CSS, Tailwind classes, or design system components based on the generated specs.

    Yes, the skill includes logic for responsive grid behaviors, specifying how high-density columns should stack, hide, or transform when viewed on smaller mobile screens.

    Your purchase includes lifetime access to this version of the skill, along with any logic refinements or updates made by the creator to reflect modern dashboard UX standards.

    New in Frontend & Web Apps