Files
headquarter/apps/web/src/components/features/workspace/workspace-card.tsx
T
Developer 4913cc7297 fix: make workspace project name visible on mobile and desktop cards
- Move the project name below the workspace title row so it reads as a
  distinct line with a project icon.
- Move the status badge into the title row next to the workspace name,
  preventing it from crowding the project label.
- Add .workspace-title-row flex styles and update .workspace-project-name
  to display inline-flex with a brand-colored project icon.

Quality gates: npm run typecheck, npm run lint clean,
npm test -- --run 87 passed.
2026-06-13 19:53:43 +00:00

102 lines
2.6 KiB
TypeScript

/** Card component for displaying a workspace. */
import { Link } from "react-router-dom";
import { Icon } from "../../icon";
import { WorkspaceInstanceChips } from "./workspace-instance-chips";
import type { Workspace } from "../../../types/workspace";
export interface WorkspaceCardProps {
workspace: Workspace;
loading?: boolean;
onStartTool: (workspace: Workspace) => void;
onSync: (workspace: Workspace) => void;
onDelete: (workspace: Workspace) => void;
}
export function WorkspaceCard({
workspace,
loading = false,
onStartTool,
onSync,
onDelete,
}: WorkspaceCardProps) {
const statusClass =
workspace.status === "ready"
? "status-ready"
: workspace.status === "syncing"
? "status-syncing"
: "status-error";
return (
<article className={`card workspace-card ${loading ? "loading" : ""}`}>
<div className="workspace-card-top">
<Link
to={`/workspaces/${workspace.id}`}
className="workspace-title-link"
>
<div className="workspace-title-stack">
<div className="workspace-title-row">
<h4 className="workspace-name">{workspace.name}</h4>
<span className={`status-badge ${statusClass}`}>
{workspace.status}
</span>
</div>
<span className="workspace-project-name">
<Icon name="projects" size="sm" />
{workspace.project_name}
</span>
</div>
</Link>
</div>
<div className="workspace-card-body">
<div className="workspace-meta-row">
<span className="workspace-repo">
<Icon name="repositories" size="sm" />
{workspace.repo_name}
</span>
<span className="workspace-branch">
<Icon name="branch" size="sm" />
{workspace.branch}
</span>
{workspace.instance_count > 0 && (
<span className="workspace-instance-count">
{workspace.instance_count} tool
{workspace.instance_count > 1 ? "s" : ""}
</span>
)}
</div>
<WorkspaceInstanceChips workspaceId={workspace.id} />
</div>
<div className="workspace-actions">
<button
className="btn btn-primary"
onClick={() => onStartTool(workspace)}
disabled={loading}
title="Start a tool in this workspace"
>
<Icon name="play" size="sm" />
Start Tool
</button>
<button
className="ghost-button"
onClick={() => onSync(workspace)}
disabled={loading}
title="Sync workspace"
>
<Icon name="refresh" size="sm" />
</button>
<button
className="ghost-button danger-text"
onClick={() => onDelete(workspace)}
disabled={loading}
title="Delete workspace"
>
<Icon name="delete" size="sm" />
</button>
</div>
</article>
);
}