feat(ui): link the Organization cell on the Teams page (#40749)

The Teams table showed a team's organization as plain text, so getting
from a team to the org that owns it meant copying the alias and searching
the Organizations page by hand.

It now uses the same link helper the key tables use, so the cell points
at the org detail page.

Claude-Session: https://claude.ai/code/session_01NfwfQhamRNnSqgXMUjf3h4
This commit is contained in:
ryan-crabbe-berri 2026-09-11 17:47:35 -07:00 committed by GitHub
parent bf146e2cac
commit 4a2edf1702
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 2 deletions

View file

@ -34,6 +34,10 @@ vi.mock("@/app/(dashboard)/hooks/teams/useTeams", () => ({
teamsTableKeys: { all: ["teamsTable"] },
}));
vi.mock("next/navigation", () => ({
useRouter: () => ({ push: vi.fn() }),
}));
vi.mock("@/app/(dashboard)/hooks/organizations/useOrganizations", () => ({
useOrganizations: vi.fn().mockReturnValue({
data: [{ organization_id: "org-1", organization_alias: "Test Organization" }],
@ -306,10 +310,30 @@ describe("column rendering details", () => {
});
});
it("points the organization cell at the org's detail page, aliased or not", async () => {
mockUseTeamsTable.mockReturnValue(
teamsResult([
{ ...mockTeam, team_id: "a", organization_id: "org-1" },
{ ...mockTeam, team_id: "b", team_alias: "Orphan Team", organization_id: "org-unknown" },
]),
);
renderTable();
expect(await screen.findByRole("link", { name: "Test Organization" })).toHaveAttribute(
"href",
"/ui/organizations?org=org-1",
);
expect(screen.getByRole("link", { name: "org-unknown" })).toHaveAttribute(
"href",
"/ui/organizations?org=org-unknown",
);
});
it("renders an em dash for a team with no organization", () => {
mockUseTeamsTable.mockReturnValue(teamsResult([{ ...mockTeam, organization_id: null as unknown as string }]));
renderTable();
expect(screen.getByText("—")).toBeInTheDocument();
expect(screen.queryByRole("link", { name: /organization/i })).not.toBeInTheDocument();
});
it("falls back to keys.length when keys_count is absent", () => {

View file

@ -15,6 +15,7 @@ import {
} from "@/components/ui/dropdown-menu";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/cva.config";
import { orgDetailHref } from "@/utils/entityLinks";
import { copyToClipboard, formatNumberWithCommas } from "@/utils/dataUtils";
import { Team } from "../key_team_helpers/key_list";
@ -183,8 +184,8 @@ export const getTeamTableColumns = ({
const displayValue = org?.organization_alias || orgId;
const width = info.cell.column.getSize();
return (
<span className="block truncate text-sm" style={{ maxWidth: width }} title={displayValue}>
{displayValue}
<span className="block" style={{ maxWidth: width }} title={displayValue}>
<IdentityCell title={displayValue} titleClassName="text-sm font-normal" href={orgDetailHref(orgId)} />
</span>
);
},