feat(dashboard): grid/table views, sorting & filtering for Projects - #86
Merged
Conversation
Add a tiles/table view toggle to the Projects page, plus name search and external/local type filters that apply to both views, and sortable Name / Last indexed / Added columns in the table view. All client-side over the existing /api/v1/projects response — no backend changes. - New lib/projectList.ts: shared isExternal / label / filter / sort helpers (never-indexed rows always sort last; query-cache array is copied, never mutated in place) - New lib/viewPreference.ts: persist the view choice in localStorage, mirroring the editorPreference.ts pattern (default 'grid' = no change) - New ProjectsTable: shadcn Table with chevron-sortable headers, type + status/drift badges, and a per-row Sync button for external repos - ProjectCard now reuses the shared basename/STATUS_VARIANT/isExternal helpers so cards and table can't drift apart (no visual change) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ProjectsTable: make rows keyboard-accessible — the name is now a real
<Link> (focusable, Cmd/Ctrl-click → new tab); the whole-row onClick
bails on defaultPrevented and modified/non-left clicks so it neither
double-navigates nor hijacks open-in-new-tab.
- sortProjects: name column sorts case-insensitively (localeCompare
sensitivity:'base'); extract compareTimes() so created and
last_indexed sink missing timestamps to the bottom identically.
- isExternal: widen to a structural { host_path } param and route the
two remaining inline host_path.startsWith('github.com/') copies
(ProjectDetailPage, WorkspaceProjectRow) through it — now the single
source of truth for the whole dashboard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds list ergonomics to the dashboard Projects page. All client-side — no backend, OpenAPI, or
gen:apichanges (the/api/v1/projectsresponse already carries every field used).localStorage(cix.projects.view, defaultgrid= prior behaviour)."Last indexed" sorts on
last_indexed_at(the same value cards show as "Indexed X ago"); "Added" sorts oncreated_at. External vs local uses the existinghost_pathgithub.com/prefix convention.Changes
lib/projectList.ts— sharedisExternal/projectLabel/filterProjects/sortProjects+basename/STATUS_VARIANT. Sort copies the array; the React Query cache is never mutated in place.lib/viewPreference.ts— localStorage view preference, mirroringeditorPreference.ts.components/ProjectsTable.tsx— shadcnTable: sortable headers, type + status/drift badges, languages, file/symbol counts, clickable rows → detail, per-row Sync for external repos (click-guarded so it doesn't navigate).ProjectsListPage.tsx— toolbar (search + typeSelect+ view toggle),useMemofilter→sort, grid/table branch, a distinct "No projects match your filters" state, and a "Showing X of Y" subtitle while filtered.ProjectCard.tsx— reuses the shared helpers instead of its own copies (no visual change).Verification
npm run typecheck— clean.npm run build(tsc -b && vite build) — success;dist/.gitkeeppreserved.cix-serverwith indexed projects — runcd server/dashboard && npm run devagainst it.🤖 Generated with Claude Code