From bbc6f0b0e0526c81d0f38caeed08ce03d399d185 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 11 Jul 2026 14:03:11 -0700 Subject: [PATCH] fix(claude-code): paginate the skills table instead of unbounded scroll Migrated PluginTable off the ad-hoc Tremor+@tanstack/react-table setup onto the dashboard's shared DataTable (already used elsewhere, e.g. TeamVirtualKeysTable), which has pagination built in. 25 rows per page instead of rendering every skill inline. A bounded-height scroll box was tried first but produced two nested scrollbars (the box plus the outer page) - removed, since pagination alone already caps row count and a single page-level scrollbar is consistent with how the rest of the dashboard behaves. --- ui/litellm-dashboard/eslint-suppressions.json | 809 +++++++++--------- .../skills/_components/plugin_table.tsx | 151 +--- 2 files changed, 439 insertions(+), 521 deletions(-) diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index 2448348bbce..1cf3a90fc35 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -12,6 +12,67 @@ "count": 1 } }, + "src/app/(dashboard)/agents/_components/AgentsPanel.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/add_agent_form.tsx": { + "no-nested-ternary": { + "count": 3 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 2 + }, + "unused-imports/no-unused-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_card_discovery.tsx": { + "react-hooks/refs": { + "count": 3 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_cost_view.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_form_fields.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_info.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx": { + "no-nested-ternary": { + "count": 2 + } + }, "src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx": { "no-restricted-imports": { "count": 1 @@ -164,6 +225,139 @@ "count": 8 } }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestPanel.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestPlayground.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailsPanel.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx": { + "no-nested-ternary": { + "count": 4 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + }, + "react/no-unescaped-entities": { + "count": 2 + } + }, + "src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx": { + "no-nested-ternary": { + "count": 3 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterDisplay.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.tsx": { + "max-params": { + "count": 2 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx": { + "no-nested-ternary": { + "count": 6 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/edit_guardrail_form.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/guardrail_info.tsx": { + "max-params": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 3 + } + }, + "src/app/(dashboard)/guardrails/_components/guardrail_optional_params.tsx": { + "no-nested-ternary": { + "count": 5 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/guardrail_provider_fields.tsx": { + "no-nested-ternary": { + "count": 5 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/guardrail_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/purity": { + "count": 1 + } + }, "src/app/(dashboard)/hooks/accessGroups/useAccessGroupDetails.ts": { "no-restricted-syntax": { "count": 1 @@ -536,6 +730,134 @@ "count": 1 } }, + "src/app/(dashboard)/policies/_components/add_attachment_form.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/add_policy_form.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 2 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx": { + "no-nested-ternary": { + "count": 10 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/attachment_table.test.tsx": { + "react/display-name": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/attachment_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/guardrail_selection_modal.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/impact_popover.test.tsx": { + "react/display-name": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/impact_popover.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/index.test.tsx": { + "react/display-name": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/index.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/pipeline_flow_builder.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 2 + } + }, + "src/app/(dashboard)/policies/_components/policy_info.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/policy_table.test.tsx": { + "react/display-name": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/policy_table.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/policy_test_panel.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/policies/_components/template_parameter_modal.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, "src/app/(dashboard)/projects/_components/ProjectDetailsPage.tsx": { "no-nested-ternary": { "count": 3 @@ -697,6 +1019,50 @@ "count": 1 } }, + "src/app/(dashboard)/skills/_components/ClaudeCodePluginsPanel.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/skills/_components/add_plugin_form.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/skills/_components/plugin_table.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/tag-management/_components/TagTable.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/tag-management/_components/components/CreateTagModal.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/tag-management/_components/index.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/tag-management/_components/tag_info.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, "src/app/(dashboard)/transform-request/TransformRequestPanel.tsx": { "no-restricted-imports": { "count": 1 @@ -774,6 +1140,43 @@ "count": 1 } }, + "src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "no-restricted-imports": { + "count": 1 + }, + "react/no-unescaped-entities": { + "count": 1 + } + }, + "src/app/(dashboard)/vector-stores/_components/VectorStoreTable.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/vector-stores/_components/index.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, "src/app/(dashboard)/workflows/WorkflowRuns.tsx": { "no-nested-ternary": { "count": 1 @@ -1261,67 +1664,6 @@ "count": 1 } }, - "src/app/(dashboard)/agents/_components/AgentsPanel.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/add_agent_form.tsx": { - "no-nested-ternary": { - "count": 3 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 2 - }, - "unused-imports/no-unused-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/agent_card_discovery.tsx": { - "react-hooks/refs": { - "count": 3 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/agent_cost_view.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/agent_form_fields.tsx": { - "no-nested-ternary": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/agent_info.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx": { - "no-nested-ternary": { - "count": 1 - } - }, - "src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx": { - "no-nested-ternary": { - "count": 2 - } - }, "src/components/alerting/dynamic_form.tsx": { "no-nested-ternary": { "count": 4 @@ -1363,14 +1705,6 @@ "count": 2 } }, - "src/app/(dashboard)/skills/_components/ClaudeCodePluginsPanel.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/components/claude_code_plugins/MakeSkillPublicForm.tsx": { "no-restricted-imports": { "count": 1 @@ -1379,19 +1713,6 @@ "count": 1 } }, - "src/app/(dashboard)/skills/_components/add_plugin_form.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/skills/_components/plugin_table.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, "src/components/cloudzero_export_modal.tsx": { "no-restricted-imports": { "count": 1 @@ -1534,139 +1855,6 @@ "count": 1 } }, - "src/app/(dashboard)/guardrails/_components/GuardrailsPanel.tsx": { - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/GuardrailTestPanel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/GuardrailTestPlayground.tsx": { - "no-nested-ternary": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx": { - "no-nested-ternary": { - "count": 2 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx": { - "no-nested-ternary": { - "count": 4 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - }, - "react/no-unescaped-entities": { - "count": 2 - } - }, - "src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx": { - "no-nested-ternary": { - "count": 3 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterDisplay.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.tsx": { - "max-params": { - "count": 2 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx": { - "no-nested-ternary": { - "count": 6 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/edit_guardrail_form.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "no-restricted-syntax": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/guardrail_info.tsx": { - "max-params": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 3 - } - }, - "src/app/(dashboard)/guardrails/_components/guardrail_optional_params.tsx": { - "no-nested-ternary": { - "count": 5 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/guardrail_provider_fields.tsx": { - "no-nested-ternary": { - "count": 5 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/guardrail_table.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/purity": { - "count": 1 - } - }, "src/components/key_team_helpers/key_list.tsx": { "react-hooks/set-state-in-effect": { "count": 1 @@ -2080,134 +2268,6 @@ "count": 1 } }, - "src/app/(dashboard)/policies/_components/add_attachment_form.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/add_policy_form.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 2 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx": { - "no-nested-ternary": { - "count": 10 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/attachment_table.test.tsx": { - "react/display-name": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/attachment_table.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/guardrail_selection_modal.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/impact_popover.test.tsx": { - "react/display-name": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/impact_popover.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/index.test.tsx": { - "react/display-name": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/pipeline_flow_builder.tsx": { - "no-nested-ternary": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 2 - } - }, - "src/app/(dashboard)/policies/_components/policy_info.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/policy_table.test.tsx": { - "react/display-name": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/policy_table.tsx": { - "no-nested-ternary": { - "count": 2 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/policy_test_panel.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 1 - } - }, - "src/app/(dashboard)/policies/_components/template_parameter_modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/immutability": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/components/price_data_reload.tsx": { "react-hooks/immutability": { "count": 2 @@ -2272,32 +2332,6 @@ "count": 1 } }, - "src/app/(dashboard)/tag-management/_components/TagTable.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/tag-management/_components/components/CreateTagModal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/tag-management/_components/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/tag-management/_components/tag_info.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/components/team/EditMembership.tsx": { "no-nested-ternary": { "count": 1 @@ -2388,43 +2422,6 @@ "count": 2 } }, - "src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx": { - "no-nested-ternary": { - "count": 2 - }, - "no-restricted-imports": { - "count": 1 - }, - "react/no-unescaped-entities": { - "count": 1 - } - }, - "src/app/(dashboard)/vector-stores/_components/VectorStoreTable.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/vector-stores/_components/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/components/view_logs/EvalViewer/EvalViewer.tsx": { "no-nested-ternary": { "count": 1 diff --git a/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/plugin_table.tsx b/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/plugin_table.tsx index 7f306541189..58aebd10932 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/plugin_table.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/skills/_components/plugin_table.tsx @@ -1,16 +1,10 @@ import { CopyOutlined } from "@ant-design/icons"; -import { ChevronDownIcon, ChevronUpIcon, SwitchVerticalIcon, TrashIcon } from "@heroicons/react/outline"; -import { - ColumnDef, - flexRender, - getCoreRowModel, - getSortedRowModel, - SortingState, - useReactTable, -} from "@tanstack/react-table"; -import { Badge, Button, Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "@tremor/react"; +import { TrashIcon } from "@heroicons/react/outline"; +import { ColumnDef, PaginationState, SortingState } from "@tanstack/react-table"; +import { Badge, Button } from "@tremor/react"; import { Tooltip } from "antd"; import React, { useState } from "react"; +import { DataTable, DataTableSortHeader } from "@/components/shared/DataTable"; import { DateCell, IdCell, StatusBadge } from "@/components/shared/table_cells"; import NotificationsManager from "@/components/molecules/notifications_manager"; import { getCategoryBadgeColor } from "@/components/claude_code_plugins/helpers"; @@ -25,15 +19,9 @@ interface PluginTableProps { onPluginClick: (pluginId: string) => void; } -const PluginTable: React.FC = ({ - pluginsList, - isLoading, - onDeleteClick, - accessToken, - isAdmin, - onPluginClick, -}) => { +const PluginTable: React.FC = ({ pluginsList, isLoading, onDeleteClick, isAdmin, onPluginClick }) => { const [sorting, setSorting] = useState([{ id: "created_at", desc: true }]); + const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 25 }); const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); @@ -42,7 +30,8 @@ const PluginTable: React.FC = ({ const columns: ColumnDef[] = [ { - header: "Skill Name", + id: "name", + header: ({ column }) => , accessorKey: "name", cell: ({ row }) => { const plugin = row.original; @@ -63,16 +52,20 @@ const PluginTable: React.FC = ({ }, }, { + id: "version", header: "Version", accessorKey: "version", + enableSorting: false, cell: ({ row }) => { const version = row.original.version || "N/A"; return {version}; }, }, { + id: "description", header: "Description", accessorKey: "description", + enableSorting: false, cell: ({ row }) => { const description = row.original.description || "No description"; return ( @@ -83,7 +76,8 @@ const PluginTable: React.FC = ({ }, }, { - header: "Category", + id: "category", + header: ({ column }) => , accessorKey: "category", cell: ({ row }) => { const category = row.original.category; @@ -103,7 +97,8 @@ const PluginTable: React.FC = ({ }, }, { - header: "Public", + id: "enabled", + header: ({ column }) => , accessorKey: "enabled", cell: ({ row }) => { const plugin = row.original; @@ -117,17 +112,19 @@ const PluginTable: React.FC = ({ }, }, { - header: "Created At", + id: "created_at", + header: ({ column }) => , accessorKey: "created_at", cell: ({ row }) => , }, ...(isAdmin ? [ { - header: "Actions", id: "actions", + header: "Actions", enableSorting: false, - cell: ({ row }: any) => { + meta: { pinned: "right" as const }, + cell: ({ row }: { row: { original: Plugin } }) => { const plugin = row.original; return ( @@ -153,98 +150,22 @@ const PluginTable: React.FC = ({ : []), ]; - const table = useReactTable({ - data: pluginsList, - columns, - state: { - sorting, - }, - onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - enableSorting: true, - }); - return ( -
-
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - -
-
- {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} -
- {header.column.getCanSort() && ( -
- {header.column.getIsSorted() ? ( - { - asc: , - desc: , - }[header.column.getIsSorted() as string] - ) : ( - - )} -
- )} -
-
- ))} -
- ))} -
- - {isLoading ? ( - - -
-

Loading...

-
-
-
- ) : pluginsList && pluginsList.length > 0 ? ( - table.getRowModel().rows.map((row) => ( - onPluginClick(row.original.id)} - > - {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} - - )) - ) : ( - - -
-

No skills found. Add one to get started.

-
-
-
- )} -
-
-
-
+ onPluginClick(plugin.id)} + isLoading={isLoading} + loadingMessage="Loading skills..." + noDataMessage="No skills found. Add one to get started." + size="compact" + /> ); };