Skip to content

Commit 002a388

Browse files
committed
feat: enhance LocalTable and TeamLocalTable components with stats tracking
- Added optional onStatsChange prop to LocalTable and TeamLocalTable components to track and update server statistics. - Updated McpManage component to utilize the new stats tracking feature, passing state setters for personal and team stats. - Introduced Dashboard component to display the updated stats for better user insights.
1 parent 3886620 commit 002a388

File tree

4 files changed

+127
-7
lines changed

4 files changed

+127
-7
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Card, CardContent } from "@/components/ui/card";
2+
import { Server, Cloud, Users, Activity } from "lucide-react";
3+
4+
interface DashboardProps {
5+
personalStats: {
6+
total: number;
7+
active: number;
8+
disabled: number;
9+
};
10+
teamStats: {
11+
total: number;
12+
};
13+
}
14+
15+
export const Dashboard = ({ personalStats, teamStats }: DashboardProps) => {
16+
return (
17+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
18+
{/* Personal Total Servers */}
19+
<Card className="border-blue-200 bg-blue-50/50">
20+
<CardContent className="p-4">
21+
<div className="flex items-center justify-between">
22+
<div>
23+
<p className="text-sm font-medium text-blue-600">Personal Total</p>
24+
<p className="text-2xl font-bold text-blue-900">{personalStats.total}</p>
25+
</div>
26+
<div className="h-8 w-8 bg-blue-100 rounded-full flex items-center justify-center">
27+
<Server className="h-4 w-4 text-blue-600" />
28+
</div>
29+
</div>
30+
</CardContent>
31+
</Card>
32+
33+
{/* Personal Active Servers */}
34+
<Card className="border-green-200 bg-green-50/50">
35+
<CardContent className="p-4">
36+
<div className="flex items-center justify-between">
37+
<div>
38+
<p className="text-sm font-medium text-green-600">Personal Active</p>
39+
<p className="text-2xl font-bold text-green-900">{personalStats.active}</p>
40+
</div>
41+
<div className="h-8 w-8 bg-green-100 rounded-full flex items-center justify-center">
42+
<Activity className="h-4 w-4 text-green-600" />
43+
</div>
44+
</div>
45+
</CardContent>
46+
</Card>
47+
48+
{/* Personal Disabled Servers */}
49+
<Card className="border-orange-200 bg-orange-50/50">
50+
<CardContent className="p-4">
51+
<div className="flex items-center justify-between">
52+
<div>
53+
<p className="text-sm font-medium text-orange-600">Personal Disabled</p>
54+
<p className="text-2xl font-bold text-orange-900">{personalStats.disabled}</p>
55+
</div>
56+
<div className="h-8 w-8 bg-orange-100 rounded-full flex items-center justify-center">
57+
<Cloud className="h-4 w-4 text-orange-600" />
58+
</div>
59+
</div>
60+
</CardContent>
61+
</Card>
62+
63+
{/* Team Servers */}
64+
<Card className="border-purple-200 bg-purple-50/50">
65+
<CardContent className="p-4">
66+
<div className="flex items-center justify-between">
67+
<div>
68+
<p className="text-sm font-medium text-purple-600">Team Total</p>
69+
<p className="text-2xl font-bold text-purple-900">{teamStats.total}</p>
70+
</div>
71+
<div className="h-8 w-8 bg-purple-100 rounded-full flex items-center justify-center">
72+
<Users className="h-4 w-4 text-purple-600" />
73+
</div>
74+
</div>
75+
</CardContent>
76+
</Card>
77+
</div>
78+
);
79+
};

src/components/manage/LocalTable.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import { useCallback, useMemo, useState } from "react";
1616
import { useNavigate } from "react-router-dom";
1717
import { useServerTableColumns } from "./ServerTableColumns";
1818

19-
export const LocalTable = () => {
19+
interface LocalTableProps {
20+
onStatsChange?: (stats: { total: number; active: number; disabled: number }) => void;
21+
}
22+
23+
export const LocalTable = ({ onStatsChange }: LocalTableProps) => {
2024
const navigate = useNavigate();
2125
const { selectedClient, selectedPath } = useClientPathStore();
2226
const [localSyncDialogOpen, setLocalSyncDialogOpen] = useState(false);
@@ -59,8 +63,20 @@ export const LocalTable = () => {
5963
...serverConfig,
6064
}) as ServerTableData,
6165
);
62-
return [...activeServers, ...disabledServersData];
63-
}, [config?.mcpServers, disabledServers]);
66+
67+
const allServers = [...activeServers, ...disabledServersData];
68+
69+
// Update stats when data changes
70+
if (onStatsChange) {
71+
onStatsChange({
72+
total: allServers.length,
73+
active: activeServers.length,
74+
disabled: disabledServersData.length,
75+
});
76+
}
77+
78+
return allServers;
79+
}, [config?.mcpServers, disabledServers, onStatsChange]);
6480

6581
const handleSync = useCallback(
6682
(fromClient: string, toClient: string, overrideAll: boolean) => {

src/components/manage/team/TeamLocalTable.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import { useCallback, useMemo, useState } from "react";
1515
import { useNavigate } from "react-router-dom";
1616
import { useServerTableColumns } from "./TeamServerTableColumns";
1717

18-
export const TeamLocalTable = () => {
18+
interface TeamLocalTableProps {
19+
onStatsChange?: (stats: { total: number }) => void;
20+
}
21+
22+
export const TeamLocalTable = ({ onStatsChange }: TeamLocalTableProps) => {
1923
const navigate = useNavigate();
2024
const { getTeamConfigPath } = useConfigFileStore();
2125
const { selectedTeamId } = useTeamStore();
@@ -44,8 +48,16 @@ export const TeamLocalTable = () => {
4448
...serverConfig,
4549
}) as ServerTableData,
4650
);
51+
52+
// Update stats when data changes
53+
if (onStatsChange) {
54+
onStatsChange({
55+
total: activeServers.length,
56+
});
57+
}
58+
4759
return [...activeServers];
48-
}, [config?.mcpServers]);
60+
}, [config?.mcpServers, onStatsChange]);
4961

5062
const { isSyncing, handleCloudUpload: originalHandleCloudUpload } =
5163
useTeamCloudSync(serversData);

src/pages/manage.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { TeamCloudTable } from "@/components/manage/team/TeamCloudTable";
44
import { TeamLocalTable } from "@/components/manage/team/TeamLocalTable";
55
import { TeamSelector } from "@/components/manage/team/TeamSelector";
66
import { ConfigFileSelector } from "@/components/settings/ConfigFileSelector";
7+
import { Dashboard } from "@/components/manage/Dashboard";
78
import { Button } from "@/components/ui/button";
89
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
910
import { useAuth } from "@/hooks/useAuth";
@@ -26,6 +27,14 @@ export default function McpManage() {
2627
const { isAuthenticated } = useAuth();
2728
const { selectedTeamId } = useTeamStore();
2829
const [encryptionKey, setEncryptionKey] = useState<string | null>(null);
30+
const [personalStats, setPersonalStats] = useState({
31+
total: 0,
32+
active: 0,
33+
disabled: 0,
34+
});
35+
const [teamStats, setTeamStats] = useState({
36+
total: 0,
37+
});
2938
const navigate = useNavigate();
3039

3140
useEffect(() => {
@@ -50,6 +59,10 @@ export default function McpManage() {
5059
<TabsTrigger value="team">Team</TabsTrigger>
5160
</TabsList>
5261
</div>
62+
63+
{/* Dashboard */}
64+
<Dashboard personalStats={personalStats} teamStats={teamStats} />
65+
5366
<div className="flex-1 min-h-0">
5467
{/* personal */}
5568
<TabsContent value="personal" className="flex-1 min-h-0">
@@ -66,7 +79,7 @@ export default function McpManage() {
6679
</TabsTrigger>
6780
</TabsList>
6881
<TabsContent value="personalLocal" className="flex-1 min-h-0">
69-
<LocalTable />
82+
<LocalTable onStatsChange={setPersonalStats} />
7083
</TabsContent>
7184
<TabsContent value="personalCloud" className="flex-1 min-h-0">
7285
{isAuthenticated ? (
@@ -109,7 +122,7 @@ export default function McpManage() {
109122
<ConfigFileSelector />
110123
</div>
111124
<TabsContent value="teamLocal" className="flex-1 min-h-0">
112-
<TeamLocalTable />
125+
<TeamLocalTable onStatsChange={setTeamStats} />
113126
</TabsContent>
114127
<TabsContent value="teamCloud" className="flex-1 min-h-0">
115128
{!isAuthenticated ? (

0 commit comments

Comments
 (0)