Skip to main content

Org Workspace Collection UX

Why This Exists

The current org pages prove the product model, but they do not yet express the intended day-to-day agency operating experience.

The main issue is not one page. It is the collection pattern across the org surface.

Today, projects, time, and billing mostly render as vertically stacked cards. That was acceptable for proving the schema and workflow spine, but it will break down once an agency has real volume.

Examples of the current gap:

  • project collections are too tall and do not support board-style planning
  • time entries behave like manual notes, not like a true running timer workflow
  • billing and other record-heavy pages do not yet share a stronger dense collection shell
  • quick actions are buried inside page-local buttons instead of staying available as workspace controls

This doc is the product-direction source of truth for the next org-surface UX step.

Non-Negotiable Outcome

The org workspace must feel like a real operations product, not a stack of admin cards.

That means:

  • dense enough to handle dozens of records without becoming visually tall and exhausting
  • consistent between customers, projects, time, billing, and the global drive finder
  • flexible enough to support different collection modes per domain
  • fast to act from, with persistent creation and workflow shortcuts

Shared Collection System

Every record-heavy org page should converge on the same collection shell.

Core parts:

  • page top bar for title and page-level actions
  • collection toolbar for search, segment filters, and view switching
  • a borderless toolbar surface; search remains a fixed compact field on the left within a reserved desktop column
  • density-aware record presentation instead of tall freeform cards
  • selection and bulk-action affordances where the workflow benefits from them
  • empty states that still preserve the surrounding shell
  • a persistent quick-action dock for high-frequency org actions

The styling should remain minimal and restrained, but it should look intentional and operational.

Pagination and scale contract

Every growable record collection must use backend cursor pagination. The first page should normally contain 20–30 records, with an explicit continuation control while the backend reports CanLoadMore. A full collection page must not use .take(...), .slice(0, ...), or a capped preview query as its data source; older records must remain reachable until the cursor is exhausted.

Search and durable filters belong in the paginated backend query so later pages cannot contain hidden matches. Hydration must be scoped to the current page instead of collecting every related table for the organization. Preview strips, dashboard summaries, and compact recommendations may remain intentionally bounded, but their API and copy must identify them as previews rather than full directories.

Counts shown beside a paginated collection must come from a real aggregate or dedicated count projection. Never label results.length as a global total while more pages exist. The collection pagination policy tests protect the primary org routes from regressing to unbounded or silently capped reads.

The page-frame implementation is shared through OrgCollectionPage and CollectionToolbar. Search is the only left-aligned control; filters, view switches, and actions stay right-aligned. The toolbar remains on one row whenever its actual controls fit and wraps naturally only when their combined width requires it, rather than switching layouts at a fixed desktop breakpoint. OperationalList is the only public org record-list API and owns its border directly; its records keep the desktop column grid at every viewport width and the bordered list region scrolls horizontally when those columns do not fit. Do not wrap it in another bordered Surface merely to provide spacing. Domain-specific bodies such as the Files finder, project board, grouped subscription sections, and catalog sections may vary inside that frame without redefining the toolbar or outer page anatomy.

For now, the org sidebar should stay on this grouped structure:

  • Home: Overview, Analytics
  • Accounts: Clients, Portals
  • Work: Projects, Entries, Drive, Contracts
  • Revenue: Quotes, Invoices, Subscriptions

This keeps the primary navigation simple while still separating account management from delivery work.

A lighter alternative IA was explored and is intentionally parked for later evaluation:

  • Home: Overview, Analytics
  • Work: Clients, Portals, Projects, Entries, Drive, Contracts
  • Revenue: Quotes, Invoices, Subscriptions

That three-group version is still a valid future option if the org surface needs a lighter, flatter navigation again.

Explicit Collection Taxonomy

Do not treat every org collection as the same kind of page.

The org workspace now has three collection types. New work should choose one of these deliberately instead of mixing patterns ad hoc.

Within those collection pages and detail tabs, use the composition that matches the record's job:

  • operational records use OperationalList
  • chronological narrative activity uses FeedList
  • repeated inline editors use EditableList
  • dashboard-only rankings and compressed summaries use SummaryList
  • independent decisions, previews, notices, metrics, and spatial board items may remain cards

Lists own one outer border and separator rows. Do not recreate a list by mapping full bordered cards with gaps between them. Portal and platform use their own surface-owned list families rather than importing the org API.

Before choosing a type, separate four concepts that must not be conflated:

  • workspace navigation changes the user's job or operating context and may point to a real route
  • workflow queues switch between a small number of durable, operationally meaningful slices
  • view modes change how the same records are presented because the alternate representation supports a genuinely different job
  • collection controls search, filter, sort, group, select, or update records inside the current job

The secondary bar is scarce navigation space. It may hold workspace navigation, durable workflow queues, or a justified view-mode switch. It must not become a second collection toolbar. When page stats exist, their one valid home is the far right of this bar; stats never move into the primary page header or collection toolbar.

Search, ordinary status filters, client filters, sorting, grouping, density, saved views, selection, and bulk actions belong in the collection toolbar or table. A field being editable does not justify an Organize mode.

1. Queue-switched record lists

Use this when the page is still fundamentally a records table, but operators need a small number of durable workflow queues across the top.

Current examples:

  • time entries
  • billing/invoices
  • portals

Rules:

  • the secondary bar owns the fixed queue switch
  • the queue order is semantic and stable, not user-reorderable
  • search and heavier filters stay in the local collection toolbar
  • the content area is a dense list or table, not a board
  • drag-and-drop is not the interaction model

Examples:

  • entries: All approvals, Draft, Submitted, Approved
  • invoices: All invoices, Draft, Open, Past due, Paid
  • portals: All portals, Live, Unlinked, Disabled, Attention

2. Multi-view operational collections

Use this when the same domain has two genuinely different representations because each supports a different job:

  • a dense review/browse job
  • a spatial planning or sequencing job

Current example:

  • projects

Rules:

  • the secondary bar owns a concrete representation switch, for example Board and List
  • the default is the representation that best matches the domain's primary operational job
  • List uses a dense table with scan-first columns and row actions
  • a board uses visible state lanes and may use drag-and-drop when spatial movement is central to planning
  • search may exist in both modes when it helps find records
  • filters that duplicate the board itself must not appear in board mode
  • do not name a mode Organize; name the actual representation or job

Example:

  • projects board: status lanes for planning delivery work
  • projects list: dense cross-project review with sortable columns and row actions

3. Pure record lists

Use this when the page is a dense operational list without a meaningful board mode or queue switch.

Current examples:

  • clients
  • billing/subscriptions
  • most detail-adjacent record collections

Rules:

  • the secondary bar is usually absent or reserved for page context, not list filtering
  • search, filters, sort, and bulk actions stay local to the collection toolbar
  • the content area defaults to an operational list: one bordered collection, separated rows, a flexible identity column, and stable comparison columns only when the list's own container is wide enough
  • narrower list containers fold metadata beneath the identity instead of forcing routine horizontal scrolling; reserve horizontally scrolling tables for genuinely data-dense comparison work
  • frequent row actions remain visible; overflow menus are for secondary or uncommon actions rather than the primary way to operate a record
  • nested records remain lightweight inline rows rather than full peer cards
  • drag-and-drop is not used
  • mutable lifecycle fields may use inline selects or row actions when permissions allow
  • sortable columns, grouping, saved views, and bulk changes are the scalable organization tools

Drive-specific extension:

  • the org global drive route may add a client finder rail because retrieval across client workspaces is part of the job
  • that client rail does not make the page a multi-view operational collection
  • folder organization belongs primarily inside the client-specific drive tab, not the global finder

Guardrail:

  • do not add drag-and-drop just to make a page feel more interactive
  • only use drag-and-drop when moving items between visible states is itself the primary job

Secondary Bar Decision Rules

For every candidate item, ask these questions in order:

  1. Does it change to a different job or durable workspace? If yes, use a real route when the destination should be addressable and navigable independently.
  2. Is it a small, stable workflow queue operators return to repeatedly? If yes, it may be a secondary-bar queue.
  3. Does it change to a materially different representation that improves a distinct job? If yes, it may be a secondary-bar view mode.
  4. Is it search, filter, sort, grouping, density, saved-view selection, or a record mutation? Keep it in the collection toolbar or row.

Secondary-bar items must be stable and low in count. They should remain useful at both ten records and ten thousand records. Do not place transient filters, user-generated group values, or every lifecycle status there.

Current surface map:

SurfaceSecondary barCollection organization
Clientslifecycle scopes: All, Active, Paused, Inactive, Archivedsearch, sortable columns, direct row status change, eventual bulk assignment/status changes
ProjectsBoard / Listboard for spatial planning; list for sorting, filtering, grouping, and bulk operations
Entriesapproval queuessearch and record filters in toolbar; approval changed inline
Invoicesdurable billing queuesclient/search filters in toolbar; lifecycle actions on rows or detail
Quotescommercial workflow queues only if operators actively work them as queuesotherwise move status to the toolbar
Contractslegal workflow queues only if operators actively work them as queuestype/client filters and sorting in toolbar
Portalsaccess-health queuessearch and client filters in toolbar; access actions on rows/detail
Subscriptionsnonesearch, client/status filters, sorting, row/detail lifecycle actions
Driveclient/retrieval context when neededsearch, type filters, sort, folder operations, selection, and bulk file actions
Catalogproduct/price workspace navigation when those remain distinct jobssearch, active/archive filters, sorting, and row actions

This map is a product decision, not a mandate to make every page visually identical. Consistency comes from placing the same kind of decision at the same layer.

Collection Modes By Surface

Projects

Projects need multiple views, not one canonical tall list.

Required modes:

  • Board as the primary planning view
  • List as the dense operational view

Board expectations:

  • status columns such as planned, active, blocked, complete, archived
  • drag-and-drop between columns
  • compact project cards with only the fields needed for scanning
  • visible tags such as client, priority, target date, owner, visibility, and at-risk signals
  • archived work should not dominate the active board

List expectations:

  • dense row height
  • sortable columns
  • quick filters for active, blocked, complete, archived
  • visible tags instead of verbose body copy
  • rows should open detail quickly without needing tall card bodies

Time

Time should stop behaving like a note-taking list and start behaving like time tracking software.

Time is not a multi-view operational collection. It is a queue-switched record list plus a timer utility route.

Timer expectations:

  • start, pause, resume, stop
  • active timer visible globally while working in the org surface
  • quick project and client assignment
  • running note field that does not require opening a full page dialog
  • timer state should be obvious, persistent, and hard to lose

Entries expectations:

  • secondary bar queue switch for All approvals, Draft, Submitted, Approved
  • dense list or table for review and correction
  • approval state, billable state, project, client, duration, and user shown clearly
  • manual entry still supported, but secondary to live timing
  • easy correction of recent entries without expanding large cards
  • approval changes should use fast inline controls, not drag-and-drop lanes

Timer route expectations:

  • lives as a utility route and shell-level utility affordance, not as a peer collection mode inside the entries workspace

Billing, Drive, Clients, Portals

These should share the same collection shell, but not the same collection type.

Expected behavior:

  • dense rows or compact cards depending on the record type
  • active filters and status segments at the top
  • minimal repeated copy
  • important flags and next actions visible at scan speed

Specific direction:

  • invoices are queue-switched record lists
  • portals are queue-switched record lists for agency-side client portal operations
  • subscriptions are pure record lists
  • the org global drive route is a client-first finder with a client rail plus a dense recent-items table
  • clients are pure record lists with durable lifecycle scopes in the secondary bar and scalable toolbar/table organization

These pages do not all need kanban, but they should still feel like they belong to the same workspace system.

Customers And Portals Ownership Rule

The customer and portal surfaces must not drift into parallel identity models.

Canonical ownership is:

  • clientAccount is the company-level client record
  • clientContact is a person inside that company
  • portal access is state on that person

Surface responsibilities:

  • Customers/[clientId]/people is the canonical company people directory and access-management surface
  • Portals is the cross-client operations workspace that summarizes and filters the same underlying person-level portal access state
  • the portals workspace must not infer readiness from only the client-account toggle or only the primary contact email when person-level access data exists

Quick Action Dock

The org surface should have a persistent quick-action dock in the bottom-right corner.

This is not decorative. It is a workspace control surface.

Initial actions should include:

  • new project
  • track time
  • new client
  • upload file
  • create invoice or open billing action when that workflow exists

Design rules:

  • desktop: floating vertical dock in the lower-right corner
  • mobile: convert to a more compact sticky action surface instead of covering content
  • keep labels concise and action-first
  • avoid turning this into a noisy speed-dial full of rarely used actions

Density Rules

The current tall-card pattern should not remain the default for record-heavy pages.

Collection density rules:

  • prefer rows, tables, board cards, or compact tiles over full-height narrative cards
  • summary text should be optional metadata, not the main layout driver
  • archived or inactive records should move behind a segment, filter, or collapsed group
  • pages with dozens of records must still be scannable without feeling vertically punishing
  • if a page is a record list, default to a responsive operational list and require a workflow reason before introducing board mechanics or a rigid horizontally scrolling table

Package Direction

If packages make this materially better, use them.

The likely direction is:

  • @dnd-kit/core and @dnd-kit/sortable only for justified spatial planning interactions such as the project board
  • @tanstack/react-table if the current table primitives are too thin for dense collection views

The current internal DataTable wrapper is too primitive on its own for the intended end state. It can either be evolved around a stronger table engine or replaced by a better internal abstraction.

Implementation Order

Do not redesign every list independently.

Implementation order:

  1. build the shared org collection shell
  2. build the org quick-action dock
  3. migrate projects first with board plus dense list
  4. migrate time second with real timer workflow plus dense entries view
  5. move billing, the global drive finder, and customers onto the same collection language

Guardrail

Do not keep adding more route-specific list UIs on top of the current stacked-card pattern.

Do not blur collection types once chosen.

  • if a page is a queue-switched record list, do not smuggle organize-board behavior into the table
  • if a page is a multi-view operational collection, keep the representations distinct instead of letting list filters fight the board
  • if a page is a pure record list, do not add a secondary bar queue switch unless there is a durable workflow slice that truly deserves it

Before further heavy org workspace expansion, collection UX needs to become a deliberate system.