feat(ui): TeamsTable to shadcn Button + Tooltip + lucide icons

- @tremor Button/Icon/Text + antd Tooltip + @heroicons PencilAlt/
  Trash \u2192 shadcn Button/Tooltip + lucide Pencil/Trash2. Tremor
  Table/TableHead/Row/Cell preserved (chart/table family whitelist,
  inline eslint-disable).
- Team ID pill preserved as blue-tinted categorical accent; file
  added to .eslintrc.json overrides.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-04-23 14:48:39 +00:00
parent 3224841391
commit 229576f324
No known key found for this signature in database
2 changed files with 77 additions and 35 deletions

View file

@ -71,6 +71,7 @@
"src/components/prompts/prompt_editor_view/PromptEditorHeader.tsx",
"src/components/prompts/prompt_editor_view/VersionHistorySidePanel.tsx",
"src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx",
"src/app/(dashboard)/teams/components/TeamsTable/TeamsTable.tsx",
"src/components/prompts/prompt_editor_view/conversation_panel/MessageBubble.tsx",
"src/components/playground/chat_ui/SessionManagement.tsx",
"src/components/playground/chat_ui/SearchResultsDisplay.tsx",

View file

@ -1,9 +1,26 @@
import { Button, Icon, Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow, Text } from "@tremor/react";
import { Tooltip } from "antd";
// eslint-disable-next-line litellm-ui/no-banned-ui-imports
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
} from "@tremor/react";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { formatNumberWithCommas } from "@/utils/dataUtils";
import { PencilAltIcon, TrashIcon } from "@heroicons/react/outline";
import { Pencil, Trash2 } from "lucide-react";
import React from "react";
import { type KeyResponse, Team } from "@/components/key_team_helpers/key_list";
import {
type KeyResponse,
Team,
} from "@/components/key_team_helpers/key_list";
import { Member, Organization } from "@/components/networking";
import ModelsCell from "@/app/(dashboard)/teams/components/TeamsTable/ModelsCell";
import YourRoleCell from "@/app/(dashboard)/teams/components/TeamsTable/YourRoleCell/YourRoleCell";
@ -61,8 +78,12 @@ const TeamsTable = ({
if (!currentOrg) return true;
return team.organization_id === currentOrg.organization_id;
})
.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())
.map((team: any) => (
.sort(
(a, b) =>
new Date(b.created_at).getTime() -
new Date(a.created_at).getTime(),
)
.map((team: Team) => (
<TableRow key={team.team_id}>
<TableCell
style={{
@ -75,20 +96,21 @@ const TeamsTable = ({
</TableCell>
<TableCell>
<div className="overflow-hidden">
<Tooltip title={team.team_id}>
<Button
size="xs"
variant="light"
className="font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate max-w-[200px]"
data-testid="team-id-cell"
onClick={() => {
// Add click handler
setSelectedTeamId(team.team_id);
}}
>
{team.team_id.slice(0, 7)}...
</Button>
</Tooltip>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
data-testid="team-id-cell"
onClick={() => setSelectedTeamId(team.team_id)}
className="font-mono text-blue-500 bg-blue-50 dark:bg-blue-950/30 hover:bg-blue-100 dark:hover:bg-blue-950/60 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate max-w-[200px] rounded"
>
{team.team_id.slice(0, 7)}...
</button>
</TooltipTrigger>
<TooltipContent>{team.team_id}</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</TableCell>
<TableCell
@ -98,7 +120,9 @@ const TeamsTable = ({
overflow: "hidden",
}}
>
{team.created_at ? new Date(team.created_at).toLocaleDateString() : "N/A"}
{team.created_at
? new Date(team.created_at).toLocaleDateString()
: "N/A"}
</TableCell>
<TableCell
style={{
@ -116,43 +140,60 @@ const TeamsTable = ({
overflow: "hidden",
}}
>
{team["max_budget"] !== null && team["max_budget"] !== undefined ? team["max_budget"] : "No limit"}
{team["max_budget"] !== null &&
team["max_budget"] !== undefined
? team["max_budget"]
: "No limit"}
</TableCell>
<ModelsCell team={team} />
<TableCell>{team.organization_id}</TableCell>
<YourRoleCell team={team} userId={userId} />
<TableCell>
<Text>
<div className="text-sm">
{perTeamInfo &&
team.team_id &&
perTeamInfo[team.team_id] &&
perTeamInfo[team.team_id].keys &&
perTeamInfo[team.team_id].keys.length}{" "}
Keys
</Text>
<Text>
</div>
<div className="text-sm">
{perTeamInfo &&
team.team_id &&
perTeamInfo[team.team_id] &&
perTeamInfo[team.team_id].team_info &&
perTeamInfo[team.team_id].team_info.members_with_roles &&
perTeamInfo[team.team_id].team_info.members_with_roles.length}{" "}
perTeamInfo[team.team_id].team_info
.members_with_roles &&
perTeamInfo[team.team_id].team_info.members_with_roles
.length}{" "}
Members
</Text>
</div>
</TableCell>
<TableCell>
{userRole == "Admin" ? (
<>
<Icon
icon={PencilAltIcon}
size="sm"
<div className="flex gap-1">
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => {
setSelectedTeamId(team.team_id);
setEditTeam(true);
}}
/>
<Icon onClick={() => onDeleteTeam(team.team_id)} icon={TrashIcon} size="sm" />
</>
aria-label="Edit team"
>
<Pencil className="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-6 w-6 text-destructive hover:text-destructive hover:bg-destructive/10"
onClick={() => onDeleteTeam(team.team_id)}
aria-label="Delete team"
>
<Trash2 className="h-3.5 w-3.5" />
</Button>
</div>
) : null}
</TableCell>
</TableRow>