diff --git a/frontend/src/api/agent/index.ts b/frontend/src/api/agent/index.ts index c2cda726..9a783693 100644 --- a/frontend/src/api/agent/index.ts +++ b/frontend/src/api/agent/index.ts @@ -135,8 +135,17 @@ export const BUILTIN_AGENT_AGENT_ID = BUILTIN_SMART_REASONING_ID; // 获取智能体列表(包括内置智能体) // disabled_own_agent_ids: 当前租户在对话下拉中停用的「我的」智能体 ID,仅影响本租户 -export function listAgents() { - return get<{ data: CustomAgent[]; disabled_own_agent_ids?: string[] }>('/api/v1/agents'); +export function listAgents(params?: { + /** + * Optional creator filter; mirrors listKnowledgeBases. Built-in agents + * (is_builtin=true) are always returned regardless of this filter so + * the conversation dropdown never silently loses quick-answer / + * smart-reasoning when a user picks "Created by me". + */ + creator?: 'all' | 'mine' | 'others'; +}) { + const qs = params?.creator && params.creator !== 'all' ? `?creator=${params.creator}` : ''; + return get<{ data: CustomAgent[]; disabled_own_agent_ids?: string[] }>(`/api/v1/agents${qs}`); } // 获取智能体详情 diff --git a/frontend/src/api/knowledge-base/index.ts b/frontend/src/api/knowledge-base/index.ts index 61b6bb38..dfed0590 100644 --- a/frontend/src/api/knowledge-base/index.ts +++ b/frontend/src/api/knowledge-base/index.ts @@ -1,9 +1,21 @@ import { get, post, put, del, postUpload, getDown } from "../../utils/request"; // 知识库管理 API(列表、创建、获取、更新、删除、复制) -export function listKnowledgeBases(params?: { agent_id?: string }) { +export function listKnowledgeBases(params?: { + agent_id?: string; + /** + * Optional creator filter. Server-side semantics: + * - "mine" → only KBs whose creator_id matches the caller + * - "others" → only KBs created by someone else in this tenant + * - omitted/"all" → no filter + * KBs predating the RBAC backfill (creator_id="") never match + * mine/others — they fall out of both views by design. + */ + creator?: 'all' | 'mine' | 'others'; +}) { const query = new URLSearchParams(); if (params?.agent_id) query.set('agent_id', params.agent_id); + if (params?.creator && params.creator !== 'all') query.set('creator', params.creator); const qs = query.toString(); return get(qs ? `/api/v1/knowledge-bases?${qs}` : '/api/v1/knowledge-bases'); } diff --git a/frontend/src/api/user-favorites.ts b/frontend/src/api/user-favorites.ts new file mode 100644 index 00000000..8de318e4 --- /dev/null +++ b/frontend/src/api/user-favorites.ts @@ -0,0 +1,34 @@ +// API client for per-user starred resources (DB-backed; see migration +// 000047 and internal/handler/user_resource_favorite.go). +// +// The backend authoritatively scopes favorites to the active (user, tenant) +// pair from the auth context — these helpers therefore never pass user_id +// or tenant_id, and a tenant switch automatically points reads at the +// right namespace. + +import { get, post, del } from '@/utils/request' + +export type FavoriteResourceType = 'kb' | 'agent' + +export interface FavoriteEntry { + user_id: string + tenant_id: number + resource_type: FavoriteResourceType + resource_id: string + /** ISO timestamp from the server (created_at column). */ + created_at: string +} + +export function listFavorites(type: FavoriteResourceType) { + return get<{ success: boolean; data: FavoriteEntry[] }>( + `/api/v1/user/favorites?type=${encodeURIComponent(type)}` + ) +} + +export function addFavorite(type: FavoriteResourceType, id: string) { + return post('/api/v1/user/favorites', { type, id }) +} + +export function removeFavorite(type: FavoriteResourceType, id: string) { + return del(`/api/v1/user/favorites/${encodeURIComponent(type)}/${encodeURIComponent(id)}`) +} diff --git a/frontend/src/components/ListSpaceSidebar.vue b/frontend/src/components/ListSpaceSidebar.vue index 132c7481..bffa8b3d 100644 --- a/frontend/src/components/ListSpaceSidebar.vue +++ b/frontend/src/components/ListSpaceSidebar.vue @@ -11,19 +11,32 @@ {{ $t('listSpaceSidebar.all') }} - -
- - {{ $t('listSpaceSidebar.mine') }} -
-
- -
- - {{ $t('listSpaceSidebar.sharedToMe') }} +
+ + {{ $t('listSpaceSidebar.favorites') }}
+ +
+ + {{ $t('listSpaceSidebar.recents') }} +
+
+ +
+ + {{ workspaceLabel }} +
+
+