From bf8a587a1d92998ad94164d271e1b4080d5df2d4 Mon Sep 17 00:00:00 2001
From: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
Date: Mon, 11 May 2026 20:51:35 +0800
Subject: [PATCH] tweaks
---
.../deployments/detail/versions-tab.tsx | 77 ++++++----------
.../versions-tab/release-history-table.tsx | 91 ++++++++++++++++++-
2 files changed, 116 insertions(+), 52 deletions(-)
diff --git a/web/features/deployments/detail/versions-tab.tsx b/web/features/deployments/detail/versions-tab.tsx
index be50e19b5a..59e7e7b179 100644
--- a/web/features/deployments/detail/versions-tab.tsx
+++ b/web/features/deployments/detail/versions-tab.tsx
@@ -7,17 +7,20 @@ import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
import { consoleQuery } from '@/service/client'
-import { DEPLOYMENT_PAGE_SIZE } from '../data'
-import { deployedRows } from '../utils'
import { ReleaseHistoryTable } from './versions-tab/release-history-table'
-function CreateReleaseControl({ appInstanceId, canCreateRelease }: {
+function CreateReleaseControl({ appInstanceId }: {
appInstanceId: string
- canCreateRelease: boolean
}) {
const { t } = useTranslation('deployments')
const createRelease = useMutation(consoleQuery.enterprise.appDeploy.createRelease.mutationOptions())
const [isCreating, setIsCreating] = useState(false)
+ const { data: overview } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({
+ input: {
+ params: { appInstanceId },
+ },
+ }))
+ const canCreateRelease = overview ? overview.instance?.canCreateRelease ?? true : false
async function handleCreateRelease(form: HTMLFormElement) {
if (!canCreateRelease || createRelease.isPending)
@@ -149,64 +152,42 @@ function CreateReleaseControl({ appInstanceId, canCreateRelease }: {
)
}
+function SourceAppUnavailableNotice({ appInstanceId }: {
+ appInstanceId: string
+}) {
+ const { t } = useTranslation('deployments')
+ const { data: overview } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({
+ input: {
+ params: { appInstanceId },
+ },
+ }))
+ if (overview?.instance?.canCreateRelease !== false)
+ return null
+
+ return (
+
+ {t('versions.sourceAppUnavailable')}
+
+ )
+}
+
export function VersionsTab({ appInstanceId }: {
appInstanceId: string
}) {
const { t } = useTranslation('deployments')
- const input = { params: { appInstanceId } }
- const { data: overview } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({
- input,
- }))
- const { data: releaseHistory } = useQuery(consoleQuery.enterprise.appDeploy.listReleases.queryOptions({
- input: {
- ...input,
- query: {
- pageNumber: 1,
- resultsPerPage: DEPLOYMENT_PAGE_SIZE,
- },
- },
- }))
- const { data: environmentDeployments } = useQuery(consoleQuery.enterprise.appDeploy.listRuntimeInstances.queryOptions({
- input,
- }))
- const releaseRows = releaseHistory?.data?.filter(row => row.id) ?? []
- const deploymentRows = deployedRows(environmentDeployments?.data)
- const canCreateRelease = overview?.instance?.canCreateRelease ?? true
return (
{t('versions.releaseHistory')}
- {' '}
-
- (
- {releaseRows.length}
- )
-
-
+
- {!canCreateRelease && (
-
- {t('versions.sourceAppUnavailable')}
-
- )}
+
- {releaseRows.length === 0
- ? (
-
- {canCreateRelease ? t('versions.emptyWithCreate') : t('versions.emptySourceUnavailable')}
-
- )
- : (
-
- )}
+
)
}
diff --git a/web/features/deployments/detail/versions-tab/release-history-table.tsx b/web/features/deployments/detail/versions-tab/release-history-table.tsx
index 2e583831e7..3a3516f4ac 100644
--- a/web/features/deployments/detail/versions-tab/release-history-table.tsx
+++ b/web/features/deployments/detail/versions-tab/release-history-table.tsx
@@ -1,10 +1,15 @@
'use client'
import type { ReleaseRow, RuntimeInstanceRow } from '@dify/contracts/enterprise/types.gen'
+import type { ReactNode } from 'react'
import { cn } from '@langgenius/dify-ui/cn'
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
+import { useQuery } from '@tanstack/react-query'
import { useTranslation } from 'react-i18next'
+import { consoleQuery } from '@/service/client'
+import { DEPLOYMENT_PAGE_SIZE } from '../../data'
import {
+ deployedRows,
formatDate,
releaseCommit,
releaseLabel,
@@ -15,9 +20,27 @@ import { getReleaseDeployments } from './release-deployments'
const GRID_TEMPLATE = 'grid-cols-[minmax(0,0.9fr)_minmax(0,1fr)_minmax(0,0.8fr)_minmax(0,1.5fr)_96px]'
-export function ReleaseHistoryTable({ appInstanceId, releaseRows, deploymentRows }: {
+type ReleaseRowWithId = ReleaseRow & {
+ id: string
+}
+
+function hasReleaseId(row: ReleaseRow): row is ReleaseRowWithId {
+ return Boolean(row.id)
+}
+
+function ReleaseHistoryTableState({ children }: {
+ children: ReactNode
+}) {
+ return (
+
+ {children}
+
+ )
+}
+
+function ReleaseHistoryRows({ appInstanceId, releaseRows, deploymentRows }: {
appInstanceId: string
- releaseRows: ReleaseRow[]
+ releaseRows: ReleaseRowWithId[]
deploymentRows: RuntimeInstanceRow[]
}) {
const { t } = useTranslation('deployments')
@@ -63,7 +86,7 @@ export function ReleaseHistoryTable({ appInstanceId, releaseRows, deploymentRows
-
+
@@ -114,7 +137,7 @@ export function ReleaseHistoryTable({ appInstanceId, releaseRows, deploymentRows
))}
-
+
@@ -123,3 +146,63 @@ export function ReleaseHistoryTable({ appInstanceId, releaseRows, deploymentRows
)
}
+
+export function ReleaseHistoryTable({ appInstanceId }: {
+ appInstanceId: string
+}) {
+ const { t } = useTranslation('deployments')
+ const input = { params: { appInstanceId } }
+ const overviewQuery = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({
+ input,
+ }))
+ const releaseHistoryQuery = useQuery(consoleQuery.enterprise.appDeploy.listReleases.queryOptions({
+ input: {
+ ...input,
+ query: {
+ pageNumber: 1,
+ resultsPerPage: DEPLOYMENT_PAGE_SIZE,
+ },
+ },
+ }))
+ const releaseRows = releaseHistoryQuery.data?.data?.filter(hasReleaseId) ?? []
+ const shouldLoadRuntimeInstances = releaseRows.length > 0
+ const environmentDeploymentsQuery = useQuery(consoleQuery.enterprise.appDeploy.listRuntimeInstances.queryOptions({
+ input,
+ enabled: shouldLoadRuntimeInstances,
+ }))
+ const isLoading = releaseHistoryQuery.isLoading
+ || (releaseRows.length === 0 && overviewQuery.isLoading)
+ || (shouldLoadRuntimeInstances && environmentDeploymentsQuery.isLoading)
+ const sourceAppUnavailable = overviewQuery.data?.instance?.canCreateRelease === false
+ const deploymentRows = deployedRows(environmentDeploymentsQuery.data?.data)
+
+ if (isLoading) {
+ return (
+
+
+
+
+
+ )
+ }
+
+ if (releaseRows.length === 0) {
+ return (
+
+ {sourceAppUnavailable ? t('versions.emptySourceUnavailable') : t('versions.emptyWithCreate')}
+
+ )
+ }
+
+ return (
+
+ )
+}