refactor(org): drop legacy adapterLabels / claude_compat fallback; unify connector label resolution
OrgChart and AgentRoster both carried a `claude_compat`-prefix fallback chained against `adapterLabels[connectorId] ?? connectorId` to paper over the pre-pi-mono connector id space (claude_local / codex_local / gemini_local / claude_compat_2..10). The migration to pi-mono's catalog retired those ids months ago — the fallback is dead code that still runs `String.prototype.startsWith` on every render and forks the label resolution into two subtly different shapes in two files. Replaced with `formatConnectorLabel(connector, fallbackId)` in lib/formatters.ts, used by both OrgChart and AgentRoster. Also in this commit (typography polish bundled because touching the same render paths): - OrgChart connector label: 9px uppercase tracking-0.08em → 11px tracking-tight. The 9px chip was unreadable at default zoom. - OrgChart zoom controls: `+` / `−` / "Fit" mixed text + character ops replaced with Plus / Minus / CornersOut icons (imported from the existing icon barrel) + a focus-visible ring for keyboard users. No rendering changes for the non-cosmetic path (status dots, card layout, edges). The removed `adapterLabels` map was exported from orgTreeLayout.ts and had no other importers. Covers J1 / J3 / J4 / J6 from the team-page audit.
This commit is contained in:
1 parent
41132e2da4
commit
50a7196b3e
5 files changed
+29
-26
No files matched your search
@@ -5,6 +5,7 @@ import type { AgentRecord, ConnectorRecord, WorkspaceRecord } from "@shared/type
|
||||
import { EmptyState, StatusPill } from "../ui"
|
||||
import { useT } from "../../i18n"
|
||||
import { useRovingTabIndex } from "../../lib/keyboard"
|
||||
import { formatConnectorLabel } from "../../lib/formatters"
|
||||
import { BudgetBar } from "./helpers"
|
||||
|
||||
export function AgentRoster({
|
||||
@@ -96,7 +97,7 @@ export function AgentRoster({
|
||||
<StatusPill status={agent.status} />
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-[11px] text-muted-foreground">
|
||||
<span>{t("org.connectorLabel")} {connector?.id.startsWith("claude_compat") && connector.notes ? connector.notes : connector?.label ?? agent.connectorId}</span>
|
||||
<span>{t("org.connectorLabel")} {formatConnectorLabel(connector, agent.connectorId)}</span>
|
||||
{workspace && <span>{t("org.workspaceLabel")} {workspace.name}</span>}
|
||||
</div>
|
||||
<div className="mt-1.5">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Heartbeat } from "../ui/icons";
|
||||
import { CornersOut, Heartbeat, Minus, Plus } from "../ui/icons";
|
||||
import type { AgentRecord, ConnectorRecord } from "@shared/types";
|
||||
import { getAgentInitials } from "../../lib/formatters";
|
||||
import { formatConnectorLabel, getAgentInitials } from "../../lib/formatters";
|
||||
import { EmptyState } from "../ui";
|
||||
import { useT } from "../../i18n";
|
||||
import { buildOrgTree, layoutForest, flattenLayout, collectEdges, statusDotColor, adapterLabels, CARD_W, CARD_H, CHART_PADDING } from "./orgTreeLayout";
|
||||
import { buildOrgTree, layoutForest, flattenLayout, collectEdges, statusDotColor, CARD_W, CARD_H, CHART_PADDING } from "./orgTreeLayout";
|
||||
|
||||
export function OrgChart({ agents, connectors, onSelectAgent }: { agents: AgentRecord[]; connectors?: ConnectorRecord[]; onSelectAgent?: (agentId: string) => void }) {
|
||||
const t = useT();
|
||||
@@ -75,8 +75,14 @@ export function OrgChart({ agents, connectors, onSelectAgent }: { agents: AgentR
|
||||
return (
|
||||
<div ref={containerRef} className="relative min-h-[400px] h-[clamp(400px,60vh,720px)] w-full overflow-hidden rounded-lg border border-border bg-background" style={{ cursor: dragging ? "grabbing" : "grab" }} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} onMouseLeave={handleMouseUp} onWheel={handleWheel}>
|
||||
<div className="absolute right-3 top-3 z-10 flex flex-col gap-1">
|
||||
{[{ label: "+", ariaLabel: t("org.zoomIn"), action: zoomIn }, { label: "\u2212", ariaLabel: t("org.zoomOut"), action: zoomOut }, { label: t("org.fit"), ariaLabel: t("org.fitChart"), action: fitToScreen }].map((btn) => (
|
||||
<button key={btn.ariaLabel} className="flex h-9 w-9 items-center justify-center rounded-lg border border-border bg-card text-[12px] text-foreground transition hover:bg-muted" onClick={btn.action} aria-label={btn.ariaLabel}>{btn.label}</button>
|
||||
{[
|
||||
{ icon: Plus, ariaLabel: t("org.zoomIn"), action: zoomIn },
|
||||
{ icon: Minus, ariaLabel: t("org.zoomOut"), action: zoomOut },
|
||||
{ icon: CornersOut, ariaLabel: t("org.fitChart"), action: fitToScreen },
|
||||
].map(({ icon: Icon, ariaLabel, action }) => (
|
||||
<button key={ariaLabel} className="flex h-9 w-9 items-center justify-center rounded-lg border border-border bg-card text-foreground transition hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" onClick={action} aria-label={ariaLabel}>
|
||||
<Icon size={16} weight="regular" />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<svg className="pointer-events-none absolute inset-0" style={{ width: "100%", height: "100%" }}>
|
||||
@@ -93,9 +99,7 @@ export function OrgChart({ agents, connectors, onSelectAgent }: { agents: AgentR
|
||||
{allNodes.map((node) => {
|
||||
const dotColor = statusDotColor[node.agent.status] ?? "var(--muted-foreground)";
|
||||
const connectorRecord = connectors?.find((c) => c.id === node.agent.connectorId);
|
||||
const connectorLabel = (connectorRecord?.id.startsWith("claude_compat") && connectorRecord.notes)
|
||||
? connectorRecord.notes
|
||||
: adapterLabels[node.agent.connectorId] ?? node.agent.connectorId;
|
||||
const connectorLabel = formatConnectorLabel(connectorRecord, node.agent.connectorId);
|
||||
const initials = getAgentInitials(node.agent.name);
|
||||
const isRunning = node.agent.status === "running";
|
||||
const isActive = node.agent.status === "active" || isRunning;
|
||||
@@ -122,7 +126,7 @@ export function OrgChart({ agents, connectors, onSelectAgent }: { agents: AgentR
|
||||
<span className="truncate text-[14px] font-semibold leading-tight text-foreground">{node.agent.name}</span>
|
||||
<span className="mt-0.5 text-[11px] leading-tight text-muted-foreground">{node.agent.title || node.agent.role}</span>
|
||||
<div className="mt-1.5 flex items-center gap-2">
|
||||
<span className="rounded bg-muted px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">{connectorLabel}</span>
|
||||
<span className="rounded bg-muted px-1.5 py-0.5 text-[11px] font-semibold tracking-tight text-muted-foreground">{connectorLabel}</span>
|
||||
{node.agent.heartbeatEnabled ? <Heartbeat size={10} className="text-success" /> : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -94,19 +94,3 @@ export const statusDotColor: Record<string, string> = {
|
||||
terminated: "var(--muted-foreground)",
|
||||
pending_approval: "var(--destructive)",
|
||||
};
|
||||
|
||||
export const adapterLabels: Record<string, string> = {
|
||||
claude_local: "Claude",
|
||||
claude_compatible: "Compatible",
|
||||
claude_compat_2: "Compatible 2",
|
||||
claude_compat_3: "Compatible 3",
|
||||
claude_compat_4: "Compatible 4",
|
||||
claude_compat_5: "Compatible 5",
|
||||
claude_compat_6: "Compatible 6",
|
||||
claude_compat_7: "Compatible 7",
|
||||
claude_compat_8: "Compatible 8",
|
||||
claude_compat_9: "Compatible 9",
|
||||
claude_compat_10: "Compatible 10",
|
||||
codex_local: "Codex",
|
||||
gemini_local: "Gemini",
|
||||
};
|
||||
@@ -43,6 +43,7 @@ export {
|
||||
Clock,
|
||||
ClockCounterClockwise,
|
||||
Command,
|
||||
CornersOut,
|
||||
Copy,
|
||||
Cpu,
|
||||
CurrencyCircleDollar,
|
||||
|
||||
Reference in new issue
Block a user