Skip to content

feat(dashboard): redesign org home with two-column layout, facepile, and favorites#3014

Open
simplesagar wants to merge 13 commits into
mainfrom
worktree-org-home-redesign
Open

feat(dashboard): redesign org home with two-column layout, facepile, and favorites#3014
simplesagar wants to merge 13 commits into
mainfrom
worktree-org-home-redesign

Conversation

@simplesagar
Copy link
Copy Markdown
Member

@simplesagar simplesagar commented May 22, 2026

Summary

Redesigns the org home page (/<orgSlug>) into a two-column layout inspired by Vercel's org overview, while staying inside our existing dashboard styling (no Tobias in product UI, no decorative mono kickers).

Left rail (sticky on lg+)

  • Compressed Recent challenges (top 3, RBAC-gated)
  • Compressed Recent activity — first ~8 entries of the org-wide audit log

Main column

  • Heading + description + search (search bar untouched per request)
  • New Add new ▾ dropdown — Project / Team member / Role, all gated by org:admin. Team member routes to /team; Role routes to /access/roles; Project opens the existing inline dialog.
  • Your favorites section (only when populated) — projects you've starred, separated from the main list
  • Project list as a thin rectangular stack. Each row shows:
    • Project avatar, name, slug
    • Vercel-style action block — most recent audit-log verb prominent, with Xm ago · actor below and a hover tooltip showing full UTC + local timestamps
    • Facepile (up to 10) of active contributors, sourced from distinct audit-log actors per project; falls back to the earliest org members (deterministic, sorted by joinedAt) when a project has no audit activity
    • Star toggle to favorite/unfavorite (persisted in localStorage per org ID via the new useProjectFavorites hook)
    • actions affordance (currently a visual stub for future per-row actions)
  • Show all N projects / Show less expand at the bottom
image

Implementation notes

  • A single useAuditLogs() call drives the left-rail preview, the per-project "most recent action" lookup, and the per-project facepile. One useMemo walks the audit log once, building latestActionByProjectSlug and activeActorsByProjectSlug in the same pass — zero extra network calls vs. the previous page.
  • useMembers() is used to map actorId → photo/email/name for facepile avatars.
  • getActorLabel and renderVerb are now exported from OrgAuditLogs.tsx so OrgHome reuses the exact same verb formatting (no parallel implementations to drift).
  • Favorites are intentionally client-side — they're a per-user UI preference, not org state, so localStorage (via the existing useLocalStorageState) is the right home. Cross-tab sync is handled by the underlying hook's storage event listener.

What's not in this PR (deferred on purpose):

  • Wiring the per-row button to a real MoreActions menu (component already exists at components/ui/more-actions.tsx).
  • Server-side favorites — not needed for the affordance.
  • The grid/list view-toggle Vercel shows next to the search bar — out of scope per direction.

Test plan

  • Visit /<orgSlug> — left rail renders Recent challenges (if RBAC + denies exist) + Recent activity; main column shows project rows in a thin stack
  • Each project row shows the latest audit-log verb + "Xm ago · actor"; hover reveals UTC + local timestamps
  • Each project row shows a facepile (up to 10); projects with audit activity surface their actual contributors; projects with no activity show the earliest org members
  • Click the star — project moves into the Your favorites section above; reload preserves it; toggle off returns it to the main list
  • Add new ▾ dropdown shows Project / Team member / Role; Project opens the create dialog, Team member navigates to /team, Role navigates to /access/roles
  • Non-admin (no org:admin scope) sees the page without the Add new menu
  • Searching filters the project list and shows "Create ''" CTA when no match
  • Show more / Show less works when project count > 6
  • Page renders cleanly on narrow viewports (left rail stacks above main column)

…and favorites

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simplesagar simplesagar added the enhancement New feature or request label May 22, 2026
@simplesagar simplesagar requested review from a team as code owners May 22, 2026 23:24
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

🦋 Changeset detected

Latest commit: bd1c0bc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gram-docs-redirect Ready Ready Preview, Comment May 23, 2026 11:22pm

Request Review

Star and kebab buttons no longer hide when the row isn't hovered.
Kebab now opens a MoreActions menu with favorite toggle, project
settings, audit-log link, and copy-slug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Avoids moonshine's dynamic Icon-by-string-name path that was
hitting Vite pre-bundle 504s on first load of `ellipsis-vertical`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Row navigates to project home on click via pointer-events overlay pattern
- New ViewModeToggle (grid / list) next to search; persisted in localStorage
- ProjectCard component for grid view; ProjectGrid 2/3-column responsive layout
- Show more / show less moved outside the list container for visual separation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Search + view toggle + Add New now span the full content width across
the top, so left-rail section labels align with the Projects label on
the right — matching the Vercel reference layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simplesagar simplesagar added the preview Spawn a preview environment label May 23, 2026
@speakeasybot
Copy link
Copy Markdown
Collaborator

speakeasybot commented May 23, 2026

🚀 Preview Environment (PR #3014)

Preview URL: https://pr-3014.dev.getgram.ai

Component Status Details Updated (UTC)
✅ Database Ready Existing database reused 2026-05-23 23:27:12.
✅ Images Available Container images ready 2026-05-23 23:26:55.

Gram Preview Bot

- Recent activity preview now uses ActionDot + ActionBadge (shared
  with /audit-logs) so categories are color-coded identically
- "Projects" header bumped to h4 to match Recent challenges/activity
- Capitalize N in "Add New"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…projects

- New mise task seed-challenges authenticates via dev-IDP and inserts
  synthetic deny challenges directly into ClickHouse so the org home
  Recent challenges box has data to render in local dev
- Add a "All projects" hairline divider between the favorites section
  and the rest of the project list when both are populated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Inserts ~10 fake org members with pravatar photo URLs so the
project-card facepile renders with visible stacking on local dev.
Idempotent — workos_id and email are derived from a hash of the
seed email so reruns upsert in place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mise discovers tasks under .mise-tasks only when the file is
executable. Without this, `mise run seed-challenges` etc. would
fail with "no task found".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The full Table from /access/challenges had 6 columns and was
horizontally overflowing the 320px sidebar. Replaced with a
stacked compact row (avatar + principal + deny pill, then scope ·
attempts · time on a second line) — same divided-list pattern as
Recent activity.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 4 allow buckets (toolset:read, project:read, mcp:read,
environment:read) alongside the existing deny buckets, each with a
populated matched_grants entry so the /access/challenges page shows
realistic data when filtered to approvals.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request preview Spawn a preview environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants