This commit is contained in:
Stephen Zhou 2026-04-29 13:09:13 +08:00
parent 4437c001dd
commit 6fa77397a4
No known key found for this signature in database
5 changed files with 72 additions and 40 deletions

View File

@ -0,0 +1,15 @@
import type { QueryClient } from '@tanstack/react-query'
import { isServer } from '@/utils/client'
import { makeQueryClient } from './query-client-server'
let browserQueryClient: QueryClient | undefined
export function getQueryClient() {
if (isServer)
return makeQueryClient()
if (!browserQueryClient)
browserQueryClient = makeQueryClient()
return browserQueryClient
}

View File

@ -1,21 +1,8 @@
'use client'
import type { QueryClient } from '@tanstack/react-query'
import { QueryClientProvider } from '@tanstack/react-query'
import { TanStackDevtoolsLoader } from '@/app/components/devtools/tanstack/loader'
import { isServer } from '@/utils/client'
import { makeQueryClient } from './query-client-server'
let browserQueryClient: QueryClient | undefined
function getQueryClient() {
if (isServer) {
return makeQueryClient()
}
if (!browserQueryClient)
browserQueryClient = makeQueryClient()
return browserQueryClient
}
import { getQueryClient } from './get-query-client'
export const TanstackQueryInitializer = ({ children }: { children: React.ReactNode }) => {
const queryClient = getQueryClient()

View File

@ -7,10 +7,11 @@ import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogTitl
import { Select, SelectContent, SelectItem, SelectItemIndicator, SelectItemText, SelectTrigger } from '@langgenius/dify-ui/select'
import { skipToken, useQuery } from '@tanstack/react-query'
import * as React from 'react'
import { useMemo, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
import { consoleQuery } from '@/service/client'
import { deploymentAppDataQueryOptions } from '@/service/deployments'
import { useDeploymentsStore } from '../store'
import { environmentHealth, environmentMode, environmentName, releaseCommit, releaseLabel } from '../utils'
import { HealthBadge, ModeBadge } from './status-badge'
@ -432,11 +433,23 @@ const DeployForm: FC<DeployFormProps> = ({
const DeployDrawer: FC = () => {
const { t } = useTranslation('deployments')
const drawer = useDeploymentsStore(state => state.deployDrawer)
const appData = useDeploymentsStore(state => drawer.appId ? state.appData[drawer.appId] : undefined)
const drawerAppId = drawer.appId
const storedAppData = useDeploymentsStore(state => drawerAppId ? state.appData[drawerAppId] : undefined)
const applyAppData = useDeploymentsStore(state => state.applyAppData)
const closeDeployDrawer = useDeploymentsStore(state => state.closeDeployDrawer)
const startDeploy = useDeploymentsStore(state => state.startDeploy)
const open = drawer.open
const appDataQuery = useQuery({
...deploymentAppDataQueryOptions(drawerAppId ?? ''),
enabled: open && Boolean(drawerAppId) && !storedAppData,
})
useEffect(() => {
if (appDataQuery.data)
applyAppData(appDataQuery.data)
}, [appDataQuery.data, applyAppData])
const appData = storedAppData ?? (appDataQuery.data?.appId === drawerAppId ? appDataQuery.data : undefined)
const environments = appData?.candidates.environmentOptions ?? []
const releases = appData?.candidates.releases ?? []
const defaultReleaseId = appData?.candidates.defaultReleaseId
@ -449,28 +462,35 @@ const DeployDrawer: FC = () => {
>
<DialogContent className="w-[560px] max-w-[90vw]">
<DialogCloseButton />
{!drawer.appId
{!drawerAppId
? <div className="p-4 text-text-tertiary">{t('deployDrawer.notFound')}</div>
: (
<DeployForm
key={formKey}
appId={drawer.appId}
environments={environments}
releases={releases}
defaultReleaseId={defaultReleaseId}
lockedEnvId={drawer.environmentId}
presetReleaseId={drawer.releaseId}
onCancel={closeDeployDrawer}
onSubmit={({ environmentId, releaseId, releaseNote, bindings }) =>
startDeploy({
appId: drawer.appId!,
environmentId,
releaseId,
releaseNote,
bindings,
})}
/>
)}
: !appData
? (
<div className="flex items-center gap-2 p-4 system-sm-regular text-text-tertiary">
<span className="h-4 w-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" />
{t('createModal.loadingApps')}
</div>
)
: (
<DeployForm
key={formKey}
appId={drawerAppId}
environments={environments}
releases={releases}
defaultReleaseId={defaultReleaseId}
lockedEnvId={drawer.environmentId}
presetReleaseId={drawer.releaseId}
onCancel={closeDeployDrawer}
onSubmit={({ environmentId, releaseId, releaseNote, bindings }) =>
startDeploy({
appId: drawerAppId,
environmentId,
releaseId,
releaseNote,
bindings,
})}
/>
)}
</DialogContent>
</Dialog>
)

View File

@ -7,8 +7,8 @@ import {
createApiKey,
createDeployment,
deleteApiKey,
fetchDeploymentAppData,
patchAccessChannel,
refreshDeploymentAppData,
rollbackEnvironment,
undeployEnvironment,
updateEnvironmentAccessPolicy,
@ -146,7 +146,7 @@ export const useDeploymentsStore = create<DeploymentsState>((set, get) => ({
})),
refreshAppData: async (appId) => {
const data = await fetchDeploymentAppData(appId)
const data = await refreshDeploymentAppData(appId)
get().applyAppData(data)
},

View File

@ -8,6 +8,7 @@ import type {
ListReleaseHistoryReply,
} from '@/contract/console/deployments'
import { queryOptions } from '@tanstack/react-query'
import { getQueryClient } from '@/context/get-query-client'
import { consoleClient } from './client'
const DEPLOYMENT_PAGE_SIZE = 100
@ -32,6 +33,8 @@ export type CreateDeploymentParams = {
const idempotencyKey = (prefix: string) => `${prefix}-${globalThis.crypto?.randomUUID?.() ?? Date.now()}`
export const deploymentAppDataQueryKey = (appId: string) => ['console', 'deployments', 'app-data', appId] as const
export const fetchDeploymentAppData = async (appId: string): Promise<DeploymentAppData> => {
const input = { params: { appId } }
const [
@ -72,11 +75,18 @@ export const fetchDeploymentAppData = async (appId: string): Promise<DeploymentA
export const deploymentAppDataQueryOptions = (appId: string) =>
queryOptions<DeploymentAppData>({
queryKey: ['console', 'deployments', 'app-data', appId],
queryKey: deploymentAppDataQueryKey(appId),
queryFn: () => fetchDeploymentAppData(appId),
staleTime: DEPLOYMENT_APP_DATA_STALE_TIME,
})
export const refreshDeploymentAppData = async (appId: string): Promise<DeploymentAppData> => {
return getQueryClient().fetchQuery({
...deploymentAppDataQueryOptions(appId),
staleTime: 0,
})
}
export const createDeployment = async ({
appId,
environmentId,