'use client' import type { AppInstanceCard } from '@dify/contracts/enterprise/types.gen' import type { InstanceDetailTabKey } from '../detail/tabs' import { cn } from '@langgenius/dify-ui/cn' import { DropdownMenu, DropdownMenuContent, DropdownMenuLinkItem, DropdownMenuTrigger, } from '@langgenius/dify-ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { useTranslation } from 'react-i18next' import { AppTypeIcon } from '@/app/components/app/type-selector' import AppIcon from '@/app/components/base/app-icon' import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import Link from '@/next/link' import { toAppMode } from '../app-mode' const INSTANCE_CARD_MENU_TAB_KEYS = ['deploy', 'versions', 'settings'] satisfies InstanceDetailTabKey[] function getInstanceTabHref(appInstanceId: string, tabKey: InstanceDetailTabKey) { return `/deployments/${appInstanceId}/${tabKey}` } export function InstanceCard({ app }: { app: AppInstanceCard }) { const { t } = useTranslation('deployments') const { formatTimeFromNow } = useFormatTimeFromNow() if (!app.id) return null const appInstanceId = app.id const appName = app.name ?? appInstanceId const appMode = toAppMode(app.mode) const detailHref = `/deployments/${appInstanceId}/overview` const statusCount = (status: string) => app.statuses?.find(item => item.status === status)?.count ?? 0 const failedCount = statusCount('failed') + statusCount('deploy_failed') const deployingCount = statusCount('deploying') const readyCount = statusCount('ready') const envCount = failedCount + deployingCount + readyCount const lastDeployedAt = app.lastDeployedAt ? Date.parse(app.lastDeployedAt) : null const primaryStatus: 'none' | 'failed' | 'deploying' | 'ready' = envCount === 0 ? 'none' : failedCount > 0 ? 'failed' : deployingCount > 0 ? 'deploying' : 'ready' const primaryText = primaryStatus === 'none' ? t('card.notDeployed') : primaryStatus === 'failed' ? t('card.failed', { count: failedCount }) : primaryStatus === 'deploying' ? t('card.deploying', { count: deployingCount }) : t('card.ready', { count: readyCount }) const secondaryParts: string[] = [] if (primaryStatus === 'failed' && deployingCount > 0) secondaryParts.push(t('card.deploying', { count: deployingCount })) if ((primaryStatus === 'failed' || primaryStatus === 'deploying') && readyCount > 0) secondaryParts.push(t('card.ready', { count: readyCount })) const statusSummaryLabel = (status?: string) => { if (status === 'failed' || status === 'deploy_failed') return t('status.deployFailed') if (status === 'deploying') return t('status.deploying') if (status === 'ready') return t('status.ready') return status || 'unknown' } const statusSummaryTooltip = app.statuses?.filter(item => item.count && item.status !== 'undeployed') ?? [] const statusTooltip = primaryStatus === 'none' ? t('card.tooltip.notDeployed') : (