refactor!: replace Zustand global store with TanStack Query for systemFeatures

Follow-up to SSR prefetch migration (2833965). Eliminates the Zustand
middleman that was syncing TanStack Query data into a separate store.

- Remove useGlobalPublicStore Zustand store entirely
- Create hooks/use-global-public.ts with useSystemFeatures,
  useSystemFeaturesQuery, useIsSystemFeaturesPending, useSetupStatusQuery
- Migrate all 93 consumers to import from @/hooks/use-global-public
- Simplify global-public-context.tsx to a thin provider component
- Update 18 test files to mock the new hook interface
- Fix SetupStatusResponse.setup_at type from Date to string (JSON)
- Fix setup-status.spec.ts mock target to match consoleClient

BREAKING CHANGE: useGlobalPublicStore is removed. Use useSystemFeatures()
from @/hooks/use-global-public instead.
This commit is contained in:
yyh
2026-02-01 19:06:08 +08:00
parent 2833965815
commit 806ece9a67
102 changed files with 296 additions and 411 deletions

View File

@ -51,11 +51,9 @@ vi.mock('@/context/provider-context', () => ({
// Mock global public store - allow dynamic configuration
let mockWebappAuthEnabled = false
vi.mock('@/context/global-public-context', () => ({
useGlobalPublicStore: (selector: (s: any) => any) => selector({
systemFeatures: {
webapp_auth: { enabled: mockWebappAuthEnabled },
branding: { enabled: false },
},
useSystemFeatures: () => ({
webapp_auth: { enabled: mockWebappAuthEnabled },
branding: { enabled: false },
}),
}))

View File

@ -24,9 +24,9 @@ import Tooltip from '@/app/components/base/tooltip'
import { UserAvatarList } from '@/app/components/base/user-avatar-list'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { useAppContext } from '@/context/app-context'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useProviderContext } from '@/context/provider-context'
import { useAsyncWindowOpen } from '@/hooks/use-async-window-open'
import { useSystemFeatures } from '@/hooks/use-global-public'
import { AccessMode } from '@/models/access-control'
import { useGetUserCanAccessApp } from '@/service/access-control'
import { copyApp, deleteApp, exportAppBundle, exportAppConfig, updateAppInfo } from '@/service/apps'
@ -67,7 +67,7 @@ export type AppCardProps = {
const AppCard = ({ app, onRefresh, onlineUsers = [] }: AppCardProps) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
const systemFeatures = useSystemFeatures()
const { isCurrentWorkspaceEditor } = useAppContext()
const { onPlanInfoChanged } = useProviderContext()
const { push } = useRouter()

View File

@ -27,10 +27,8 @@ vi.mock('@/context/app-context', () => ({
// Mock global public store
vi.mock('@/context/global-public-context', () => ({
useGlobalPublicStore: () => ({
systemFeatures: {
branding: { enabled: false },
},
useSystemFeatures: () => ({
branding: { enabled: false },
}),
}))

View File

@ -27,7 +27,7 @@ import { ToastContext } from '@/app/components/base/toast'
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { useAppContext } from '@/context/app-context'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useSystemFeatures } from '@/hooks/use-global-public'
import { CheckModal } from '@/hooks/use-pay'
import { DSLImportStatus } from '@/models/app'
import { fetchWorkflowOnlineUsers, importAppBundle } from '@/service/apps'
@ -68,7 +68,7 @@ const List: FC<Props> = ({
}) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const { systemFeatures } = useGlobalPublicStore()
const systemFeatures = useSystemFeatures()
const router = useRouter()
const { push } = useRouter()
const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator, isLoadingCurrentWorkspace } = useAppContext()