"use client"; /** * Topbar domain API * * 涵盖:useNotificationBell、useCurrentUser、useGlobalSearch * * widget 通过 `import { useNotificationBell } from "@/lib/api/topbar"` 调用, * 不再各自内嵌 gql/接口/手写类型。 * * 注意:useNotificationBell 与 universal.useNotifications(分页通知列表)语义不同, * 前者是 topbar 铃铛 widget 专用(按 limit 取最近 N 条),后者是分页查询。 * * 关联:spec §2.2 */ import { GET_NOTIFICATIONS_DOC, GET_CURRENT_USER_DOC, SEARCH_DOC, } from "@/lib/api/operations/topbar.graphql"; import { useWidgetQuery } from "@/lib/useWidgetQuery"; import type { UseQueryResult } from "./types"; // ===== 领域模型类型 ===== export interface NotificationItem { id: string; title: string; } export interface CurrentUser { id: string; name: string; email: string; role: string; } export interface SearchResult { id: string; type: string; title: string; subtitle: string; } // ===== 内部 Query 类型 ===== interface NotificationsQueryData { notifications: NotificationItem[]; } type NotificationsQueryVars = { limit: number; }; interface CurrentUserQueryData { me: CurrentUser | null; } type CurrentUserQueryVars = Record; interface SearchQueryData { search: SearchResult[]; } type SearchQueryVars = { keyword: string; limit: number; }; // ===== Hooks ===== /** * 查询通知列表(topbar 铃铛 widget 专用,按 limit 取最近 N 条)。 * * 关联:portal-shell spec §5.6 统一 Hook */ export function useNotificationBell( limit: number, ): UseQueryResult { const result = useWidgetQuery( GET_NOTIFICATIONS_DOC, { limit }, ); return { data: result.data?.notifications, loading: result.loading, error: result.error, refetch: result.refetch, }; } /** * 查询当前登录用户(iam 子图 me 字段)。 * * 关联:portal-shell spec §5.6 统一 Hook */ export function useCurrentUser(): UseQueryResult { const result = useWidgetQuery( GET_CURRENT_USER_DOC, {}, ); return { data: result.data?.me, loading: result.loading, error: result.error, refetch: result.refetch, }; } /** * 全局搜索。 * * `keyword` 为空时不发起查询(enabled: false),避免无效请求。 * * 关联:portal-shell spec §5.6 统一 Hook */ export function useGlobalSearch( keyword: string, limit: number, ): UseQueryResult { const result = useWidgetQuery( SEARCH_DOC, { keyword, limit }, { enabled: keyword.length > 0 }, ); return { data: result.data?.search, loading: result.loading, error: result.error, refetch: result.refetch, }; }