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')} + + + )} +
)