mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 09:28:04 +08:00
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:
@ -9,7 +9,7 @@ import DifyLogo from '@/app/components/base/logo/dify-logo'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
|
||||
type IAccountSettingProps = {
|
||||
langGeniusVersionInfo: LangGeniusVersionResponse
|
||||
@ -22,7 +22,7 @@ export default function AccountAbout({
|
||||
}: IAccountSettingProps) {
|
||||
const { t } = useTranslation()
|
||||
const isLatest = langGeniusVersionInfo.current_version === langGeniusVersionInfo.latest_version
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const systemFeatures = useSystemFeatures()
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
||||
@ -24,10 +24,10 @@ import ThemeSwitcher from '@/app/components/base/theme-switcher'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { IS_CLOUD_EDITION } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { useLogout } from '@/service/use-common'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import AccountAbout from '../account-about'
|
||||
@ -43,7 +43,7 @@ export default function AppSelector() {
|
||||
`
|
||||
const router = useRouter()
|
||||
const [aboutVisible, setAboutVisible] = useState(false)
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
const systemFeatures = useSystemFeatures()
|
||||
|
||||
const { t } = useTranslation()
|
||||
const docLink = useDocLink()
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { memo } from 'react'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { useGetDataSourceListAuth } from '@/service/use-datasource'
|
||||
import Card from './card'
|
||||
import InstallFromMarketplace from './install-from-marketplace'
|
||||
|
||||
const DataSourcePage = () => {
|
||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { enable_marketplace } = useSystemFeatures()
|
||||
const { data } = useGetDataSourceListAuth()
|
||||
|
||||
return (
|
||||
|
||||
@ -9,10 +9,10 @@ import { NUM_INFINITE } from '@/app/components/billing/config'
|
||||
import { Plan } from '@/app/components/billing/type'
|
||||
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useLocale } from '@/context/i18n'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { LanguagesSupported } from '@/i18n-config/language'
|
||||
import { useMembers } from '@/service/use-common'
|
||||
import EditWorkspaceModal from './edit-workspace-modal'
|
||||
@ -36,7 +36,7 @@ const MembersPage = () => {
|
||||
|
||||
const { userProfile, currentWorkspace, isCurrentWorkspaceOwner, isCurrentWorkspaceManager } = useAppContext()
|
||||
const { data, refetch } = useMembers()
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const systemFeatures = useSystemFeatures()
|
||||
const { formatTimeFromNow } = useFormatTimeFromNow()
|
||||
const [inviteModalVisible, setInviteModalVisible] = useState(false)
|
||||
const [invitationResults, setInvitationResults] = useState<InvitationResult[]>([])
|
||||
|
||||
@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { useWorkspacePermissions } from '@/service/use-workspace'
|
||||
|
||||
type InviteButtonProps = {
|
||||
@ -14,7 +14,7 @@ type InviteButtonProps = {
|
||||
const InviteButton = (props: InviteButtonProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { currentWorkspace } = useAppContext()
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const systemFeatures = useSystemFeatures()
|
||||
const { data: workspacePermissions, isFetching: isFetchingWorkspacePermissions } = useWorkspacePermissions(currentWorkspace!.id, systemFeatures.branding.enabled)
|
||||
if (systemFeatures.branding.enabled) {
|
||||
if (isFetchingWorkspacePermissions) {
|
||||
|
||||
@ -7,7 +7,7 @@ import { Fragment } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { useWorkspacePermissions } from '@/service/use-workspace'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
@ -18,7 +18,7 @@ type Props = {
|
||||
const TransferOwnership = ({ onOperate }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
const { currentWorkspace } = useAppContext()
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const systemFeatures = useSystemFeatures()
|
||||
const { data: workspacePermissions, isFetching: isFetchingWorkspacePermissions } = useWorkspacePermissions(currentWorkspace!.id, systemFeatures.branding.enabled)
|
||||
if (systemFeatures.branding.enabled) {
|
||||
if (isFetchingWorkspacePermissions) {
|
||||
|
||||
@ -10,8 +10,8 @@ import { useEffect, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { IS_CLOUD_EDITION } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import {
|
||||
CustomConfigurationStatusEnum,
|
||||
@ -41,7 +41,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
const { data: speech2textDefaultModel, isLoading: isSpeech2textDefaultModelLoading } = useDefaultModel(ModelTypeEnum.speech2text)
|
||||
const { data: ttsDefaultModel, isLoading: isTTSDefaultModelLoading } = useDefaultModel(ModelTypeEnum.tts)
|
||||
const { modelProviders: providers } = useProviderContext()
|
||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { enable_marketplace } = useSystemFeatures()
|
||||
const isDefaultModelLoading = isTextGenerationDefaultModelLoading
|
||||
|| isEmbeddingsDefaultModelLoading
|
||||
|| isRerankDefaultModelLoading
|
||||
|
||||
@ -10,7 +10,7 @@ import Loading from '@/app/components/base/loading'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import useTimestamp from '@/hooks/use-timestamp'
|
||||
import { ModelProviderQuotaGetPaid } from '@/types/model-provider'
|
||||
import { cn } from '@/utils/classnames'
|
||||
@ -56,7 +56,7 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { currentWorkspace } = useAppContext()
|
||||
const { trial_models } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { trial_models } = useSystemFeatures()
|
||||
const credits = Math.max((currentWorkspace.trial_credits - currentWorkspace.trial_credits_used) || 0, 0)
|
||||
const providerMap = useMemo(() => new Map(
|
||||
providers.map(p => [p.provider, p.preferred_provider_type]),
|
||||
|
||||
@ -5,11 +5,11 @@ import DifyLogo from '@/app/components/base/logo/dify-logo'
|
||||
import WorkplaceSelector from '@/app/components/header/account-dropdown/workplace-selector'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { WorkspaceProvider } from '@/context/workspace-context'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { Plan } from '../billing/type'
|
||||
import AccountDropdown from './account-dropdown'
|
||||
import AppNav from './app-nav'
|
||||
@ -33,7 +33,7 @@ const Header = () => {
|
||||
const isMobile = media === MediaType.mobile
|
||||
const { enableBilling, plan } = useProviderContext()
|
||||
const { setShowPricingModal, setShowAccountSettingModal } = useModalContext()
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const systemFeatures = useSystemFeatures()
|
||||
const isFreePlan = plan.type === Plan.sandbox
|
||||
const isBrandingEnabled = systemFeatures.branding.enabled
|
||||
const handlePlanClick = useCallback(() => {
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
import { RiHourglass2Fill } from '@remixicon/react'
|
||||
import dayjs from 'dayjs'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useSystemFeatures } from '@/hooks/use-global-public'
|
||||
import { LicenseStatus } from '@/types/feature'
|
||||
import PremiumBadge from '../../base/premium-badge'
|
||||
|
||||
const LicenseNav = () => {
|
||||
const { t } = useTranslation()
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
const systemFeatures = useSystemFeatures()
|
||||
|
||||
if (systemFeatures.license?.status === LicenseStatus.EXPIRING) {
|
||||
const expiredAt = systemFeatures.license?.expired_at
|
||||
|
||||
Reference in New Issue
Block a user