feat(extensions): unify extensions endpoint and refresh extensions page UX

- Rename /home/plugins route to /home/extensions and update all sidebar links.
- Add unified GET /api/v1/extensions returning plugins, MCP servers and skills,
  sorted by name; replace the three separate frontend fetches with this single call.
- Migrate the extensions page to shadcn primitives (Tabs/Card/Alert/Badge/Skeleton/
  Switch/Label) and clean up hardcoded color tokens on the extension card.
- Add a localStorage-persisted "Group by type" switch that, when enabled in the
  All Types tab, renders extensions grouped by type with a compact section header.
- Show a spinner while loading and rename the empty-state copy from
  "No plugins installed" to "No extensions installed".
- Rename the "格式 / Formats" filter label to "类型 / Types" across all 8 locales.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Junyan Qin
2026-05-09 23:50:17 +08:00
parent 46a9ed3da6
commit 8ff60c5b98
18 changed files with 756 additions and 551 deletions

View File

@@ -15,6 +15,7 @@ import {
ApiRespPlugins,
ApiRespPlugin,
ApiRespPluginConfig,
ApiRespExtensions,
AsyncTaskCreatedResp,
ApiRespSystemInfo,
ApiRespAsyncTasks,
@@ -543,6 +544,11 @@ export class BackendClient extends BaseHttpClient {
return this.get(`/api/v1/knowledge/parsers${params}`);
}
// ============ Extensions API ============
public getExtensions(): Promise<ApiRespExtensions> {
return this.get('/api/v1/extensions');
}
// ============ Plugins API ============
public getPlugins(): Promise<ApiRespPlugins> {
return this.get('/api/v1/plugins');
@@ -815,7 +821,10 @@ export class BackendClient extends BaseHttpClient {
serverName: string,
server: Partial<MCPServer>,
): Promise<AsyncTaskCreatedResp> {
return this.put(`/api/v1/mcp/servers/${encodeURIComponent(serverName)}`, server);
return this.put(
`/api/v1/mcp/servers/${encodeURIComponent(serverName)}`,
server,
);
}
public deleteMCPServer(serverName: string): Promise<AsyncTaskCreatedResp> {
@@ -835,7 +844,10 @@ export class BackendClient extends BaseHttpClient {
serverName: string,
serverData: object,
): Promise<AsyncTaskCreatedResp> {
return this.post(`/api/v1/mcp/servers/${encodeURIComponent(serverName)}/test`, serverData);
return this.post(
`/api/v1/mcp/servers/${encodeURIComponent(serverName)}/test`,
serverData,
);
}
public installMCPServerFromGithub(