From 3f36471ec01b403730cd6217e4dd32f959a42abb Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Thu, 7 May 2026 19:23:49 +0800 Subject: [PATCH] tweaks --- .../components/create-instance-modal.tsx | 20 +++++++++++---- .../deployments/components/rollback-modal.tsx | 9 ++++--- .../deployments/detail/deployment-sidebar.tsx | 7 +++--- web/features/deployments/detail/index.tsx | 15 +++++------ .../deployments/detail/overview-tab.tsx | 18 ++++++------- .../deployments/detail/settings-tab.tsx | 25 +++++++++---------- web/features/deployments/types.ts | 20 --------------- web/features/deployments/utils.ts | 22 ---------------- 8 files changed, 52 insertions(+), 84 deletions(-) diff --git a/web/features/deployments/components/create-instance-modal.tsx b/web/features/deployments/components/create-instance-modal.tsx index 8e003415c6..592753cc29 100644 --- a/web/features/deployments/components/create-instance-modal.tsx +++ b/web/features/deployments/components/create-instance-modal.tsx @@ -1,5 +1,4 @@ 'use client' -import type { AppInfo, AppMode } from '../types' import type { App, AppModeEnum } from '@/types/app' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' @@ -18,11 +17,22 @@ import { useDeploymentsStore } from '../store' const MAX_STUDIO_SOURCE_APPS = 100 -function toStudioSourceAppInfo(app: App): AppInfo { +type StudioSourceApp = { + id: string + name: string + mode: string + iconType?: App['icon_type'] + icon?: string + iconBackground?: string + iconUrl?: string | null + description?: string +} + +function toStudioSourceAppInfo(app: App): StudioSourceApp { return { id: app.id, name: app.name, - mode: (app.mode || 'workflow') as AppMode, + mode: app.mode || 'workflow', iconType: app.icon_type, icon: app.icon, iconBackground: app.icon_background ?? undefined, @@ -32,13 +42,13 @@ function toStudioSourceAppInfo(app: App): AppInfo { } type AppPickerProps = { - apps: AppInfo[] + apps: StudioSourceApp[] isLoading: boolean value: string onChange: (appId: string) => void } -export function AppPicker({ apps, isLoading, value, onChange }: AppPickerProps) { +function AppPicker({ apps, isLoading, value, onChange }: AppPickerProps) { const { t } = useTranslation('deployments') const [open, setOpen] = useState(false) const [keywords, setKeywords] = useState('') diff --git a/web/features/deployments/components/rollback-modal.tsx b/web/features/deployments/components/rollback-modal.tsx index d01aaa48bb..9e6b9d83c2 100644 --- a/web/features/deployments/components/rollback-modal.tsx +++ b/web/features/deployments/components/rollback-modal.tsx @@ -21,7 +21,6 @@ import { environmentOptionsFromOptionsReply, releaseCommit, releaseLabel, - toAppInfoFromOverview, } from '../utils' function InfoRow({ label, value }: { @@ -77,7 +76,9 @@ export function RollbackModal() { const currentRelease = activeRelease(currentRow) const environment = currentRow?.environment ?? environmentOptions.find(env => env.id === modal.environmentId) - const app = toAppInfoFromOverview(overview?.instance) + const app = overview?.instance + const appName = app?.name ?? '-' + const sourceAppName = app?.sourceAppName ?? appName const confirm = () => { if (!modal.appInstanceId || !modal.environmentId || !modal.targetReleaseId) @@ -110,8 +111,8 @@ export function RollbackModal() {
- - + + ) : ( diff --git a/web/features/deployments/detail/index.tsx b/web/features/deployments/detail/index.tsx index 016416f8ad..805d87124e 100644 --- a/web/features/deployments/detail/index.tsx +++ b/web/features/deployments/detail/index.tsx @@ -11,7 +11,6 @@ import { useRouter, useSelectedLayoutSegment } from '@/next/navigation' import { consoleQuery } from '@/service/client' import { DeployDrawer } from '../components/deploy-drawer' import { RollbackModal } from '../components/rollback-modal' -import { toAppInfoFromOverview } from '../utils' import { DeploymentSidebar } from './deployment-sidebar' import { isInstanceDetailTabKey } from './tabs' @@ -33,9 +32,10 @@ export function InstanceDetail({ instanceId, children }: { useDocumentTitle(t('documentTitle.detail')) - const app = toAppInfoFromOverview(overviewQuery.data?.instance) + const app = overviewQuery.data?.instance + const appId = app?.id - if (!app && overviewQuery.isLoading) { + if (!appId && overviewQuery.isLoading) { return (
@@ -43,7 +43,7 @@ export function InstanceDetail({ instanceId, children }: { ) } - if (!app) { + if (!appId || !app) { return (
{t('detail.notFound')}
@@ -54,14 +54,15 @@ export function InstanceDetail({ instanceId, children }: {
) } - const appModeLabel = app ? getAppModeLabel(app.mode, tCommon) : t('detail.sourceAppDeleted') + const appName = app.name ?? appId + const appModeLabel = getAppModeLabel(app.mode ?? 'workflow', tCommon) return ( <>
state.openDeployDrawer) - const app = toAppInfoFromOverview(overview?.instance) const overviewApp = overview?.instance const deployments = overview?.deployments?.filter(row => row.environment?.id && row.status?.toLowerCase() !== 'undeployed') ?? [] const releaseRows = releaseHistory?.data?.filter(row => row.id) ?? [] const canCreateRelease = overviewApp?.canCreateRelease ?? true - if (!app) + if (!overviewApp?.id) return null + const appId = overviewApp.id + const appName = overviewApp.name ?? appId const switchTab = (tab: SwitchableTab) => { - router.push(`/deployments/${instanceId}/${tab}`) + router.push(`/deployments/${appId}/${tab}`) } - const appModeLabel = getAppModeLabel(overviewApp?.mode ?? app.mode, tCommon) + const appModeLabel = getAppModeLabel(overviewApp.mode ?? 'workflow', tCommon) const webappAccessUrl = webappUrl(overview?.access?.webappUrl) const cliUrl = overview?.access?.cliUrl const apiUrl = overview?.access?.apiUrl ?? accessConfig?.developerApi?.apiUrl @@ -135,9 +135,9 @@ export function OverviewTab({ instanceId }: {
- - - + + +
@@ -169,7 +169,7 @@ export function OverviewTab({ instanceId }: { switchTab('versions') return } - openDeployDrawer({ appInstanceId: app.id }) + openDeployDrawer({ appInstanceId: appId }) }} > {releaseRows.length === 0 ? t('overview.createRelease') : t('overview.deploy')} diff --git a/web/features/deployments/detail/settings-tab.tsx b/web/features/deployments/detail/settings-tab.tsx index 82154c198e..1e8050a479 100644 --- a/web/features/deployments/detail/settings-tab.tsx +++ b/web/features/deployments/detail/settings-tab.tsx @@ -1,5 +1,5 @@ 'use client' -import type { AppInfo } from '../types' +import type { AppInstanceBasicInfo } from '@dify/contracts/enterprise/types.gen' import type { GetAppInstanceSettingsReply } from '@/features/deployments/types' import { AlertDialog, @@ -17,27 +17,25 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import { useRouter } from '@/next/navigation' import { consoleQuery } from '@/service/client' -import { - deployedRows, - toAppInfoFromOverview, -} from '../utils' +import { deployedRows } from '../utils' type SettingsFormProps = { - app: AppInfo + app: AppInstanceBasicInfo settings?: GetAppInstanceSettingsReply hasDeployments: boolean - onSave: (patch: Pick) => Promise + onSave: (patch: Pick) => Promise onDelete: () => Promise } function SettingsForm({ app, settings, hasDeployments, onSave, onDelete }: SettingsFormProps) { const { t } = useTranslation('deployments') - const [name, setName] = useState(settings?.name ?? app.name) + const appName = app.name ?? app.id ?? '' + const [name, setName] = useState(settings?.name ?? appName) const [description, setDescription] = useState(settings?.description ?? app.description ?? '') const [isSaving, setIsSaving] = useState(false) const [isDeleting, setIsDeleting] = useState(false) const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) - const initialName = settings?.name ?? app.name + const initialName = settings?.name ?? appName const initialDescription = settings?.description ?? app.description ?? '' const canSave = Boolean(name.trim() && (name !== initialName || description !== initialDescription) && !isSaving) const canDelete = !hasDeployments && Boolean(settings) && settings?.deleteGuard?.canDelete !== false @@ -153,7 +151,7 @@ function SettingsForm({ app, settings, hasDeployments, onSave, onDelete }: Setti {t('settings.deleteConfirmTitle')} - {t('settings.deleteConfirmDesc', { name: app.name })} + {t('settings.deleteConfirmDesc', { name: appName })}
@@ -183,16 +181,17 @@ export function SettingsTab({ instanceId }: { const { data: environmentDeployments } = useQuery(consoleQuery.enterprise.appDeploy.listRuntimeInstances.queryOptions({ input: appInput, })) - const app = toAppInfoFromOverview(overview?.instance) + const app = overview?.instance const settingsQuery = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceSettings.queryOptions({ input: appInput, })) - if (!app) + if (!app?.id) return null const hasDeployments = deployedRows(environmentDeployments?.data).length > 0 - const formKey = `${app.id}-${settingsQuery.data?.name ?? app.name}-${settingsQuery.data?.description ?? app.description ?? ''}` + const appName = app.name ?? app.id + const formKey = `${app.id}-${settingsQuery.data?.name ?? appName}-${settingsQuery.data?.description ?? app.description ?? ''}` return ( environment.id)