nexus/ui/src/components/projects/tabs/TabPlaceholder.tsx
Nexus Dev d10c5b991e feat(nexus): add thin wrappers for per-project tabs (phase 11)
Wires the 6 Builder tab content components:

• IssuesTab — thin wrapper around IssuesList (which already accepts a
  projectId prop, so this is a full wiring).
• GatesTab / AgentsTab / CostsTab / ActivityTab / OrgTab — render a
  shared TabPlaceholder marking the Phase 11 data gap. None of the
  underlying list components accept a projectId filter today, and the
  Phase 11 plan forbids modifying them unilaterally. The placeholders
  are explicit (never fabricate per-project data) and carry the
  follow-up description the controller will turn into a ticket.

GatesTab is named "Gates" everywhere visible (display-only rename per
spec §7.2.4 / plan §5); approvalsApi / Approval type / /api/approvals
endpoints are all untouched.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:21:33 +00:00

44 lines
1.7 KiB
TypeScript

// [nexus] Phase 11 — shared placeholder for Builder tabs whose underlying
// list components do not (yet) accept a `projectId` filter prop.
//
// Per the Phase 11 plan, Phase 11 MAY NOT modify existing list components
// (AgentList, ApprovalsList, CostsBreakdown, etc.). The plan also says
// STOP/BLOCKED if the components don't already accept a projectId filter.
// The shared `Approval` type has no `projectId` field, there is no
// standalone `CostsBreakdown` component, Activity filtering at the API
// level only accepts entityType/entityId, and the Agents page does not
// expose an AgentList with a project filter.
//
// Rather than fabricate per-project data or duplicate the global pages,
// Phase 11 ships explicit placeholder tabs that mark each data gap. The
// Phase 11 report enumerates the gaps and the controller will schedule
// follow-up tickets to add projectId props post-Wave.
import type { ReactNode } from "react";
export interface TabPlaceholderProps {
testId: string;
title: string;
gapReason: ReactNode;
}
export function TabPlaceholder({ testId, title, gapReason }: TabPlaceholderProps) {
return (
<section
data-testid={testId}
className="rounded-lg border border-border p-6"
>
<h3 className="mb-2 text-[12px] font-bold uppercase tracking-[0.12em] text-muted-foreground">
{title}
</h3>
<p className="text-[14px] text-muted-foreground">
<span
data-testid={`${testId}-gap`}
className="inline-block rounded border border-[#f4f692]/40 bg-[#f4f692]/5 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-[0.1em] text-[#f4f692]"
>
Phase 11 data gap
</span>
<span className="ml-2">{gapReason}</span>
</p>
</section>
);
}