PAP-10242 Phase G: implement Team Catalog UI

Add the Team Catalog browse/detail/install experience built on the Phase E
teams-catalog API and the Phase F design spec.

- ui/src/api/teamCatalog.ts: typed client for /teams/catalog list/detail/files
  and the company-scoped preview/install endpoints.
- ui/src/pages/TeamCatalog.tsx: /teams page — toolbar filters (kind/category/
  risk/search, URL-synced), grouped browse list, detail pane (summary grid,
  agent hierarchy, projects, required skills, env inputs, external sources,
  file inventory), and a conditional multi-step install wizard (target manager,
  source policy, prerequisite skills, categorized preview, apply progress,
  success). Surfaces unsafe-source warnings, blocked-apply states, invalid-
  manifest CTA, and API errors. Sidebar "Teams" entry + route registration.
- Derives the design's richer affordances (required steps, source warnings,
  skill plan) client-side and degrades gracefully against the shipped strict
  API schema (design section 7).
- ui/src/pages/TeamCatalog.test.tsx: renders the real components and covers the
  main install preview path (detail render, preview fetch + categorized plan +
  install submit) and target-manager gating.
- scripts/screenshot-pap-10242.mjs: Playwright capture helper for QA (needs a
  valid board session on the running instance).

Verified: ui typecheck (tsc -b), vite build, and vitest (3/3) all pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-06-05 03:00:04 +00:00
1 parent 2b5feda461
commit e0ca97e31c
7 files changed
+2413

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
import type {
CatalogTeam,
CatalogTeamFileDetail,
CatalogTeamImportOptions,
CatalogTeamImportPreviewResult,
CatalogTeamInstallOptions,
CatalogTeamInstallResult,
CatalogTeamKind,
} from "@paperclipai/shared";
import { api } from "./client";
export interface TeamCatalogListQuery {
kind?: CatalogTeamKind;
category?: string;
q?: string;
}
/**
* Client for the Phase E teams-catalog API (server/src/routes/teams-catalog.ts).
*
* The preview/install bodies mirror `catalogTeamPreviewSchema` /
* `catalogTeamInstallSchema` exactly. Several richer fields the Phase F design
* imagined (per-source policy maps, secret values, skill-plan overrides) are not
* accepted by the shipped strict schema, so the UI derives those affordances
* client-side and degrades gracefully — see TeamCatalog.tsx.
*/
export const teamCatalogApi = {
catalogList: (query: TeamCatalogListQuery = {}) => {
const params = new URLSearchParams();
if (query.kind) params.set("kind", query.kind);
if (query.category) params.set("category", query.category);
if (query.q) params.set("q", query.q);
const search = params.toString();
return api.get<CatalogTeam[]>(`/teams/catalog${search ? `?${search}` : ""}`);
},
catalogDetail: (catalogRef: string) =>
api.get<CatalogTeam>(`/teams/catalog/${encodeURIComponent(catalogRef)}`),
catalogFile: (catalogRef: string, relativePath = "TEAM.md") =>
api.get<CatalogTeamFileDetail>(
`/teams/catalog/${encodeURIComponent(catalogRef)}/files?path=${encodeURIComponent(relativePath)}`,
),
preview: (companyId: string, catalogRef: string, options: CatalogTeamImportOptions = {}) =>
api.post<CatalogTeamImportPreviewResult>(
`/companies/${encodeURIComponent(companyId)}/teams/catalog/${encodeURIComponent(catalogRef)}/preview`,
options,
),
install: (companyId: string, catalogRef: string, options: CatalogTeamInstallOptions = {}) =>
api.post<CatalogTeamInstallResult>(
`/companies/${encodeURIComponent(companyId)}/teams/catalog/${encodeURIComponent(catalogRef)}/install`,
options,
),
};