From de7795aa8095fcb26540b6600f123ae392eaf65c Mon Sep 17 00:00:00 2001
From: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
Date: Thu, 7 May 2026 21:36:30 +0800
Subject: [PATCH] tweaks
---
.../components/create-instance-modal.tsx | 11 +-
.../deployments/detail/deploy-tab.tsx | 157 ++++++++++--------
.../deployments/list/instance-card.tsx | 117 +++++++------
3 files changed, 157 insertions(+), 128 deletions(-)
diff --git a/web/features/deployments/components/create-instance-modal.tsx b/web/features/deployments/components/create-instance-modal.tsx
index 592753cc29..8966f025ab 100644
--- a/web/features/deployments/components/create-instance-modal.tsx
+++ b/web/features/deployments/components/create-instance-modal.tsx
@@ -1,5 +1,5 @@
'use client'
-import type { App, AppModeEnum } from '@/types/app'
+import type { App } from '@/types/app'
import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogTitle } from '@langgenius/dify-ui/dialog'
@@ -13,6 +13,7 @@ import AppIcon from '@/app/components/base/app-icon'
import Input from '@/app/components/base/input'
import { useRouter } from '@/next/navigation'
import { consoleQuery } from '@/service/client'
+import { AppModeEnum } from '@/types/app'
import { useDeploymentsStore } from '../store'
const MAX_STUDIO_SOURCE_APPS = 100
@@ -20,7 +21,7 @@ const MAX_STUDIO_SOURCE_APPS = 100
type StudioSourceApp = {
id: string
name: string
- mode: string
+ mode: AppModeEnum
iconType?: App['icon_type']
icon?: string
iconBackground?: string
@@ -32,7 +33,7 @@ function toStudioSourceAppInfo(app: App): StudioSourceApp {
return {
id: app.id,
name: app.name,
- mode: app.mode || 'workflow',
+ mode: app.mode || AppModeEnum.WORKFLOW,
iconType: app.icon_type,
icon: app.icon,
iconBackground: app.icon_background ?? undefined,
@@ -118,7 +119,7 @@ function AppPicker({ apps, isLoading, value, onChange }: AppPickerProps) {
imageUrl={selected.iconUrl}
/>
@@ -187,7 +188,7 @@ function AppPicker({ apps, isLoading, value, onChange }: AppPickerProps) {
imageUrl={app.iconUrl}
/>
diff --git a/web/features/deployments/detail/deploy-tab.tsx b/web/features/deployments/detail/deploy-tab.tsx
index 8012f27028..0e599cdcb6 100644
--- a/web/features/deployments/detail/deploy-tab.tsx
+++ b/web/features/deployments/detail/deploy-tab.tsx
@@ -1,6 +1,6 @@
'use client'
import type { KeyboardEvent } from 'react'
-import type { EnvironmentOption } from '../types'
+import type { EnvironmentDeploymentRow, EnvironmentOption } from '../types'
import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import {
@@ -93,6 +93,90 @@ function NewDeploymentMenu({ appInstanceId, availableEnvs }: {
)
}
+function DeploymentRowActions({ appInstanceId, envId, row }: {
+ appInstanceId: string
+ envId: string
+ row: EnvironmentDeploymentRow
+}) {
+ const { t } = useTranslation('deployments')
+ const [menuOpen, setMenuOpen] = useState(false)
+ const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
+ const cancelDeployment = useMutation(consoleQuery.enterprise.appDeploy.cancelRuntimeDeployment.mutationOptions())
+ const undeployDeployment = useMutation(consoleQuery.enterprise.appDeploy.undeployRuntimeInstance.mutationOptions())
+ const isUndeployed = isUndeployedDeploymentRow(row)
+ const status = deploymentStatus(row)
+
+ function handleRuntimeAction() {
+ const runtimeInstanceId = deploymentId(row)
+ setMenuOpen(false)
+
+ if (status === 'deploying') {
+ cancelDeployment.mutate({
+ params: {
+ appInstanceId,
+ runtimeInstanceId,
+ },
+ body: {
+ appInstanceId,
+ runtimeInstanceId,
+ },
+ })
+ return
+ }
+
+ undeployDeployment.mutate({
+ params: {
+ appInstanceId,
+ runtimeInstanceId,
+ },
+ body: {
+ appInstanceId,
+ runtimeInstanceId,
+ },
+ })
+ }
+
+ return (
+
e.stopPropagation()}
+ onKeyDown={e => e.stopPropagation()}
+ >
+
+ {!isUndeployed && (
+
+
+
+
+ {menuOpen && (
+
+
+
+ {status === 'deploying' ? t('deployTab.cancelDeployment') : t('deployTab.undeploy')}
+
+
+
+ )}
+
+ )}
+
+ )
+}
+
export function DeployTab({ instanceId: appInstanceId }: {
instanceId: string
}) {
@@ -103,9 +187,6 @@ export function DeployTab({ instanceId: appInstanceId }: {
},
}))
const { data: environmentOptionsReply } = useQuery(consoleQuery.enterprise.appDeploy.listDeploymentEnvironmentOptions.queryOptions())
- const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
- const cancelDeployment = useMutation(consoleQuery.enterprise.appDeploy.cancelRuntimeDeployment.mutationOptions())
- const undeployDeployment = useMutation(consoleQuery.enterprise.appDeploy.undeployRuntimeInstance.mutationOptions())
const environmentOptions = environmentOptionsFromOptionsReply(environmentOptionsReply)
const rows = environmentDeployments?.data?.filter(row => row.environment?.id) ?? []
const deployedRuntimeRows = deployedRows(environmentDeployments?.data)
@@ -163,71 +244,7 @@ export function DeployTab({ instanceId: appInstanceId }: {
const envId = environmentId(row.environment)
const isUndeployed = isUndeployedDeploymentRow(row)
const isExpanded = !isUndeployed && activeExpanded === envId
- const status = deploymentStatus(row)
const release = activeRelease(row)
- const actions = (
- e.stopPropagation()}
- onKeyDown={e => e.stopPropagation()}
- >
-
- {!isUndeployed && (
-
-
-
-
-
- {
- const runtimeInstanceId = deploymentId(row)
- if (status === 'deploying') {
- cancelDeployment.mutate({
- params: {
- appInstanceId,
- runtimeInstanceId,
- },
- body: {
- appInstanceId,
- runtimeInstanceId,
- },
- })
- return
- }
-
- undeployDeployment.mutate({
- params: {
- appInstanceId,
- runtimeInstanceId,
- },
- body: {
- appInstanceId,
- runtimeInstanceId,
- },
- })
- }}
- >
-
- {status === 'deploying' ? t('deployTab.cancelDeployment') : t('deployTab.undeploy')}
-
-
-
-
- )}
-
- )
const chevron = !isUndeployed && (
- {actions}
+
{chevron}
@@ -287,7 +304,7 @@ export function DeployTab({ instanceId: appInstanceId }: {
- {actions}
+
{chevron}
diff --git a/web/features/deployments/list/instance-card.tsx b/web/features/deployments/list/instance-card.tsx
index 8a8d8e143c..044a230c65 100644
--- a/web/features/deployments/list/instance-card.tsx
+++ b/web/features/deployments/list/instance-card.tsx
@@ -25,8 +25,6 @@ export function InstanceCard({ app }: {
}) {
const { t } = useTranslation('deployments')
const { formatTimeFromNow } = useFormatTimeFromNow()
- const [menuOpen, setMenuOpen] = useState(false)
- const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
if (!app.id)
return null
@@ -185,58 +183,71 @@ export function InstanceCard({ app }: {
-
-
-
-
-
-
- {menuOpen && (
-
- {
- setMenuOpen(false)
- openDeployDrawer({ appInstanceId: appId })
- }}
- >
- {t('card.menu.deploy')}
-
- }
- >
- {t('card.menu.viewDetail')}
-
-
- {
- e.stopPropagation()
- e.preventDefault()
- }}
- >
- {t('card.menu.delete')}
-
-
+
+
+ )
+}
+
+function InstanceCardActions({ appId, detailHref }: {
+ appId: string
+ detailHref: string
+}) {
+ const { t } = useTranslation('deployments')
+ const [menuOpen, setMenuOpen] = useState(false)
+ const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
+
+ return (
+
+
+
+
-
+ >
+
+
+ {menuOpen && (
+
+ {
+ setMenuOpen(false)
+ openDeployDrawer({ appInstanceId: appId })
+ }}
+ >
+ {t('card.menu.deploy')}
+
+ }
+ >
+ {t('card.menu.viewDetail')}
+
+
+ {
+ e.stopPropagation()
+ e.preventDefault()
+ }}
+ >
+ {t('card.menu.delete')}
+
+
+ )}
+
)