feat: redesign workspace card header and layout

- Swap workspace card header order: project name is now the primary eyebrow,
  workspace name is the bold title below it.
- Restructure workspace card into clean top/body/actions sections with more
  whitespace and clearer hierarchy.
- Replace cramped meta paragraphs with an inline meta row (repo, branch,
  instance count) and dedicated instance chip area.
- Use icon-only ghost buttons for sync/delete to reduce visual noise; keep
  prominent Start Tool button.
- Add top divider for actions, improve hover states, and make long names
  truncate gracefully.
- Update mobile workspace list subtitle to project · workspace name.
- Refresh workspaces.css with new card layout and responsive mobile rules.

Quality gates: npm run typecheck clean, npm run lint clean,
npm test -- --run 87 passed
This commit is contained in:
Developer
2026-06-13 17:00:16 +00:00
parent 2b5b8363ca
commit 4e1477c4be
3 changed files with 182 additions and 51 deletions
@@ -29,47 +29,68 @@ export function WorkspaceCard({
return (
<article className={`card workspace-card ${loading ? "loading" : ""}`}>
<Link
to={`/workspaces/${workspace.id}`}
className="workspace-header-link"
>
<div className="workspace-header">
<h4>{workspace.name}</h4>
<span className={`status-badge ${statusClass}`}>
{workspace.status}
<div className="workspace-card-top">
<Link
to={`/workspaces/${workspace.id}`}
className="workspace-title-link"
>
<div className="workspace-title-stack">
<span className="workspace-project-name">
{workspace.project_name}
</span>
<h4 className="workspace-name">{workspace.name}</h4>
</div>
</Link>
<span className={`status-badge ${statusClass}`}>
{workspace.status}
</span>
</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>
</Link>
<div className="workspace-meta">
<p className="workspace-project">
{workspace.project_name} / {workspace.repo_name}
</p>
<p className="workspace-branch">
<Icon name="branch" size="sm" /> {workspace.branch}
</p>
<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
<Icon name="play" size="sm" />
Start Tool
</button>
<button
className="btn btn-secondary"
className="ghost-button"
onClick={() => onSync(workspace)}
disabled={loading}
title="Sync workspace"
>
<Icon name="refresh" size="sm" /> Sync
<Icon name="refresh" size="sm" />
</button>
<button
className="btn btn-danger"
className="ghost-button danger-text"
onClick={() => onDelete(workspace)}
disabled={loading}
title="Delete workspace"
>
<Icon name="delete" size="sm" /> Delete
<Icon name="delete" size="sm" />
</button>
</div>
</article>