feat(web/ui): rework project pane into flat list with repo/workspace/tool hierarchy
- Add ProjectListItem component with project header actions - Show repositories horizontally with branch labels - List workspaces vertically under each repo - Show running tools per workspace from useSessions - Link workspace names to /workspaces/:id - Link tool names to web URL or terminal page - Keep existing mobile view and dialogs unchanged
This commit is contained in:
@@ -7,11 +7,13 @@ import {
|
||||
import { Icon } from "../components/icon";
|
||||
import { useMobileViewport } from "../hooks/use-mobile-viewport";
|
||||
import { ProjectCard } from "../components/features/project/ProjectCard";
|
||||
import { ProjectListItem } from "../components/features/project/ProjectListItem";
|
||||
import { ProjectDialog } from "../components/features/project/ProjectDialog";
|
||||
import { RepositoryCreateDialog } from "../components/features/project/repository-create-dialog";
|
||||
import { MobileListView } from "../components/features/mobile/mobile-list-view";
|
||||
import { MobileFAB } from "../components/features/mobile/mobile-fab";
|
||||
import { useProjects } from "../hooks/use-projects";
|
||||
import { useSessions } from "../state/sessions";
|
||||
import type { ProjectWithRepos } from "../types";
|
||||
|
||||
type MobileView = "list" | "detail" | "create-project" | "create-repo";
|
||||
@@ -34,8 +36,6 @@ export const ProjectsPage = () => {
|
||||
formError,
|
||||
deleteConfirmId,
|
||||
setDeleteConfirmId,
|
||||
expandedProject,
|
||||
setExpandedProject,
|
||||
creatingWorkspace,
|
||||
setCreatingWorkspace,
|
||||
workspaceLoading,
|
||||
@@ -48,6 +48,7 @@ export const ProjectsPage = () => {
|
||||
handleDeleteWorkspace,
|
||||
} = useProjects();
|
||||
|
||||
const { sessions } = useSessions();
|
||||
const isEmpty = status === "ready" && projects.length === 0;
|
||||
|
||||
/* ── Mobile views ── */
|
||||
@@ -242,45 +243,15 @@ export const ProjectsPage = () => {
|
||||
{status === "ready" && projects.length > 0 && (
|
||||
<div className="project-list">
|
||||
{projects.map((project) => (
|
||||
<ProjectCard
|
||||
<ProjectListItem
|
||||
key={project.id}
|
||||
project={project}
|
||||
expanded={expandedProject === project.id}
|
||||
sessions={sessions}
|
||||
deleteConfirm={deleteConfirmId === project.id}
|
||||
workspaceLoading={workspaceLoading}
|
||||
showCreateForm={
|
||||
creatingWorkspace?.projectId === project.id
|
||||
? creatingWorkspace.repoId
|
||||
: null
|
||||
}
|
||||
onToggle={() =>
|
||||
setExpandedProject(
|
||||
expandedProject === project.id ? null : project.id,
|
||||
)
|
||||
}
|
||||
onEdit={() => openEdit(project)}
|
||||
onDelete={() => setDeleteConfirmId(project.id)}
|
||||
onConfirmDelete={() => void handleDelete(project.id)}
|
||||
onCancelDelete={() => setDeleteConfirmId(null)}
|
||||
onCreateWorkspace={(repoId) =>
|
||||
setCreatingWorkspace({ projectId: project.id, repoId })
|
||||
}
|
||||
onWorkspaceAction={(repoId, workspace, action) => {
|
||||
if (action === "sync") {
|
||||
void handleSyncWorkspace(project.id, repoId, workspace);
|
||||
} else if (action === "delete") {
|
||||
void handleDeleteWorkspace(workspace);
|
||||
}
|
||||
}}
|
||||
onCancelCreate={() => setCreatingWorkspace(null)}
|
||||
onAddRepository={() => {
|
||||
setSelectedProject(project);
|
||||
setMobileView("create-repo");
|
||||
}}
|
||||
onCreated={() => {
|
||||
setCreatingWorkspace(null);
|
||||
reload();
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user