improvement(org): move the People page onto the new design system

Merged
WA
2d ago
+4045-2687

Summary

  • Rebuild People on the embedded design system (same mount as Home, Links, Integrations): org chart, directory, profile, directory sync, connect, import
  • Org chart matches the Paper prototype: person cards, focused state, reporting bus, breadcrumb, zoom and fit controls, four reports per page on desktop, one branch with a compact manager on mobile
  • Find a person is a real search field with two-line results (title and department) and keyboard hints
  • Directory sync is now a page at the existing ?panel=sync URL, with a summary for each state: connected, first sync, syncing, publishing, waiting to retry, failed, paused
  • First use for an admin offers Okta, Entra and SCIM plus Import profiles; a member gets a neutral state pointing at the directory
  • Profile is two columns with Copy profile link; invalid or inaccessible links get a neutral recovery state
  • Page gate moves to canBrowsePeople, so a member withheld the directory gets a 404 from a saved link, matching the sidebar
  • Sync actions share one org-wide in-flight guard, since the page and the connect dialog each hold actions now
  • Initial sync status reads no longer invalidate every People query
  • Move the parsers and sheet reader to lib/people, matching #9687
  • Delete the legacy People views and the ResourceLoadError they orphaned; LinksSurface becomes a shared RedesignPageSurface

Design-system additions, each with a People consumer: SearchCombobox, Avatar row/card/hero, DataTable primary and rowChevron, SearchableSelect variant='text', users and minus glyphs. EmptyState now lays out its own action row instead of restyling any div it is given.

Where the prototype and the #9687 contract disagree, this follows the contract:

  • No row dividers in the directory or profile lists (lines are reserved for surface boundaries)
  • Single-initial avatars
  • Dialogs use the shared Modal chrome
  • Disconnect is the solid destructive button
  • Directory load-more is automatic through the table owner, not a button

Deliberate departures from the prototype:

  • Header keeps Import beside Directory sync once a chart exists, so admins don't lose it
  • Mobile keeps the breadcrumb, so top-level teams stay reachable
  • Profile rows center the avatar as Paper draws them instead of using ActivityRow, whose leading slot can't hold it (the contract asks for first-line alignment)
  • Underline tabs are local to People, as Paper draws them (the contract points horizontal destinations at ControlRow)

Heads up for #9687: its branch has its own people/ tree at many of the same paths, so that rebase needs to pick this implementation.

Type of Change

  • Improvement

Testing

  • test-people-e2e.ts against a running app and real Postgres in hosted mode: 20/20, browser journey updated for the new UI and extended to the header entry points
  • test-org-redesign-e2e.ts People phase updated; runs in CI, not run locally
  • bun run --cwd apps/sim test lib/people and the organization layout test: 56 passed
  • type-check, lint, check:platform-css, check:source-conventions, check:comment-hygiene, check:file-names, check:utils, check:client-boundary, check:explicit-any, check:boundaries, check:test-patterns, block registry
  • Full check:audits and root bun run test left to CI
  • Rendered every state against the Paper artboards: light and dark on the chart, 1440, 1024 and 390 wide. Sync states used a mocked status response
  • Not exercised against a real Okta or Entra tenant

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)