create release as dialog

This commit is contained in:
Stephen Zhou 2026-05-06 12:57:48 +08:00
parent 8604e72216
commit 24635dd0c1
No known key found for this signature in database
3 changed files with 127 additions and 57 deletions

View File

@ -2,12 +2,14 @@
import type { FC } from 'react'
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'
import { toast } from '@langgenius/dify-ui/toast'
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
import { useQuery } from '@tanstack/react-query'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea'
import { useCreateDeploymentRelease } from '../hooks/use-deployment-mutations'
import {
deploymentEnvironmentDeploymentsQueryOptions,
@ -86,7 +88,7 @@ const VersionsTab: FC<VersionsTabProps> = ({ instanceId: appId }) => {
size="small"
variant="primary"
disabled={!canCreateRelease}
onClick={() => setIsCreating(prev => !prev)}
onClick={() => setIsCreating(true)}
>
<span className="i-ri-add-line h-3.5 w-3.5" />
{t('versions.createRelease')}
@ -99,33 +101,91 @@ const VersionsTab: FC<VersionsTabProps> = ({ instanceId: appId }) => {
</div>
)}
{isCreating && (
<div className="rounded-xl border border-components-panel-border bg-components-panel-bg p-4">
<div className="mb-3 system-sm-semibold text-text-primary">{t('versions.createRelease')}</div>
<div className="flex flex-col gap-3">
<Input
value={releaseName}
onChange={e => setReleaseName(e.target.value)}
placeholder={t('versions.releaseNamePlaceholder')}
maxLength={128}
/>
<Input
value={releaseDescription}
onChange={e => setReleaseDescription(e.target.value)}
placeholder={t('versions.releaseDescriptionPlaceholder')}
maxLength={512}
/>
<div className="flex justify-end gap-2">
<Button size="small" variant="secondary" onClick={() => setIsCreating(false)}>
{t('versions.cancelCreate')}
</Button>
<Button size="small" variant="primary" disabled={!canSubmitRelease} onClick={() => void handleCreateRelease()}>
{createRelease.isPending ? t('versions.creating') : t('versions.create')}
</Button>
<Dialog open={isCreating} onOpenChange={setIsCreating}>
<DialogContent className="w-[560px] overflow-hidden p-0">
<DialogCloseButton />
<form
onSubmit={(event) => {
event.preventDefault()
void handleCreateRelease()
}}
>
<div className="flex items-start gap-3 border-b border-divider-subtle px-6 py-5 pr-14">
<div className="flex size-10 shrink-0 items-center justify-center rounded-lg bg-state-accent-hover text-text-accent">
<span className="i-ri-rocket-2-line size-5" />
</div>
<div className="min-w-0">
<DialogTitle className="title-xl-semi-bold text-text-primary">
{t('versions.createRelease')}
</DialogTitle>
<DialogDescription className="mt-1 system-sm-regular text-text-tertiary">
{t('versions.createReleaseDescription')}
</DialogDescription>
</div>
</div>
</div>
</div>
)}
<div className="flex flex-col gap-5 px-6 py-5">
<div className="flex flex-col gap-2">
<label className="system-xs-medium-uppercase text-text-tertiary" htmlFor="release-name">
{t('versions.releaseNameLabel')}
</label>
<Input
id="release-name"
value={releaseName}
onChange={e => setReleaseName(e.target.value)}
placeholder={t('versions.releaseNamePlaceholder')}
maxLength={128}
autoFocus
className="h-9"
/>
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between gap-3">
<label className="system-xs-medium-uppercase text-text-tertiary" htmlFor="release-description">
{t('versions.releaseDescriptionLabel')}
</label>
<span className="system-xs-regular text-text-quaternary">
{t('versions.optional')}
</span>
</div>
<Textarea
id="release-description"
value={releaseDescription}
onChange={e => setReleaseDescription(e.target.value)}
placeholder={t('versions.releaseDescriptionPlaceholder')}
maxLength={512}
className="min-h-[96px] resize-none"
/>
</div>
</div>
<div className="flex items-center justify-between gap-4 border-t border-divider-subtle bg-background-default-subtle px-6 py-4">
<div className="system-xs-regular text-text-tertiary">
{t('versions.createReleaseHint')}
</div>
<div className="flex shrink-0 justify-end gap-2">
<Button
type="button"
variant="secondary"
disabled={createRelease.isPending}
onClick={() => setIsCreating(false)}
>
{t('versions.cancelCreate')}
</Button>
<Button
type="submit"
variant="primary"
className="min-w-[88px]"
disabled={!canSubmitRelease}
>
{createRelease.isPending ? t('versions.creating') : t('versions.create')}
</Button>
</div>
</div>
</form>
</DialogContent>
</Dialog>
{releaseRows.length === 0
? (

View File

@ -107,9 +107,9 @@
"createModal.selected": "Selected",
"createModal.sourceApp": "Source app (required)",
"createModal.title": "Create app instance",
"deployDrawer.bindingsDisabled": "Resolved from the release preview. Editing is not available yet.",
"deployDrawer.bindingOptionsFailed": "Failed to load credential options.",
"deployDrawer.bindingSelectionHint": "Choose the credentials used by this deployment.",
"deployDrawer.bindingsDisabled": "Resolved from the release preview. Editing is not available yet.",
"deployDrawer.cancel": "Cancel",
"deployDrawer.defaultSelect": "Select...",
"deployDrawer.deploy": "Deploy",
@ -139,8 +139,8 @@
"deployDrawer.requiredBinding": "Required",
"deployDrawer.runtimeCredentials": "Runtime credentials",
"deployDrawer.secretPlaceholder": "secret",
"deployDrawer.selectEnv": "Select an environment",
"deployDrawer.selectCredential": "Select a credential",
"deployDrawer.selectEnv": "Select an environment",
"deployDrawer.selectProviderCred": "Select {{provider}} credential",
"deployDrawer.selectProviderKey": "Select {{provider}} key",
"deployDrawer.selectRelease": "Select a release",
@ -221,6 +221,7 @@
"overview.basicInfo": "Basic info",
"overview.cli": "CLI",
"overview.configureAccess": "Configure access",
"overview.createRelease": "Create release",
"overview.created": "Created",
"overview.deploy": "Deploy",
"overview.deploymentStatus": "Deployment status",
@ -234,11 +235,10 @@
"overview.manageDeployments": "Manage deployments",
"overview.name": "Name",
"overview.noAccessConfig": "No access configuration.",
"overview.noReleaseSourceUnavailable": "The source app was deleted. Existing releases can still be deployed, but there is no release yet.",
"overview.noReleaseYet": "Create a release before deploying this app instance.",
"overview.notConfigured": "Not configured",
"overview.notDeployedYet": "Not deployed yet.",
"overview.noReleaseYet": "Create a release before deploying this app instance.",
"overview.noReleaseSourceUnavailable": "The source app was deleted. Existing releases can still be deployed, but there is no release yet.",
"overview.createRelease": "Create release",
"overview.sourceApp": "Source app",
"overview.sourceAppDeletedDescription": "Historical releases are still deployable, but new releases cannot be generated from the deleted source app. Switch to another source app to continue.",
"overview.sourceAppDeletedTitle": "Source app was deleted",
@ -249,16 +249,6 @@
"overview.switchSourceAppHint": "After switching, only newly created releases use the new source app. Historical releases and existing deployments are not changed.",
"overview.viewDeployments": "View deployments",
"overview.webapp": "WebApp",
"versions.cancelCreate": "Cancel",
"versions.create": "Create",
"versions.createFailed": "Failed to create release.",
"versions.createRelease": "Create release",
"versions.creating": "Creating...",
"versions.emptySourceUnavailable": "No releases yet. The source app was deleted, so new releases cannot be created.",
"versions.emptyWithCreate": "No releases yet. Create the first release before deploying.",
"versions.releaseDescriptionPlaceholder": "Describe this release",
"versions.releaseNamePlaceholder": "Release name",
"versions.sourceAppUnavailable": "The source app was deleted. Existing releases are still deployable, but new releases cannot be created.",
"rollback.cancel": "Cancel",
"rollback.confirm": "Deploy release",
"rollback.currentRelease": "Current release",
@ -303,6 +293,7 @@
"tabs.versions.description": "All releases for this app. Deploy any release to an environment.",
"tabs.versions.name": "Versions",
"title": "App instances",
"versions.cancelCreate": "Cancel",
"versions.col.action": "Action",
"versions.col.author": "Author",
"versions.col.commit": "Commit",
@ -310,6 +301,12 @@
"versions.col.deployedTo": "Deployed to",
"versions.col.release": "Release",
"versions.commitTooltip": "Commit {{commit}}",
"versions.create": "Create",
"versions.createFailed": "Failed to create release.",
"versions.createRelease": "Create release",
"versions.createReleaseDescription": "Capture the current workflow as a deployable version.",
"versions.createReleaseHint": "New releases can be deployed to any environment.",
"versions.creating": "Creating...",
"versions.currentOn": "Current on {{name}}",
"versions.deploy": "Deploy",
"versions.deployTo": "Deploy to {{name}}",
@ -318,10 +315,18 @@
"versions.deployedStatus.failed": "Failed",
"versions.deployingTo": "{{name}} is deploying",
"versions.empty": "No releases available yet.",
"versions.emptySourceUnavailable": "No releases yet. The source app was deleted, so new releases cannot be created.",
"versions.emptyWithCreate": "No releases yet. Create the first release before deploying.",
"versions.hideYaml": "Hide YAML",
"versions.moreActions": "More actions",
"versions.optional": "Optional",
"versions.promote": "Promote",
"versions.promoteTo": "Promote to {{name}}",
"versions.releaseDescriptionLabel": "Description",
"versions.releaseDescriptionPlaceholder": "Describe this release",
"versions.releaseHistory": "Release history",
"versions.releaseNameLabel": "Release name",
"versions.releaseNamePlaceholder": "Release name",
"versions.sourceAppUnavailable": "The source app was deleted. Existing releases are still deployable, but new releases cannot be created.",
"versions.viewYaml": "View YAML"
}

View File

@ -107,9 +107,9 @@
"createModal.selected": "已选择",
"createModal.sourceApp": "源应用(必选)",
"createModal.title": "创建应用实例",
"deployDrawer.bindingsDisabled": "来自发布预览的解析结果,暂不支持在这里编辑。",
"deployDrawer.bindingOptionsFailed": "加载凭据选项失败。",
"deployDrawer.bindingSelectionHint": "选择本次部署要使用的运行时凭据。",
"deployDrawer.bindingsDisabled": "来自发布预览的解析结果,暂不支持在这里编辑。",
"deployDrawer.cancel": "取消",
"deployDrawer.defaultSelect": "选择...",
"deployDrawer.deploy": "部署",
@ -139,8 +139,8 @@
"deployDrawer.requiredBinding": "必填",
"deployDrawer.runtimeCredentials": "运行时凭据",
"deployDrawer.secretPlaceholder": "机密值",
"deployDrawer.selectEnv": "选择一个环境",
"deployDrawer.selectCredential": "选择凭据",
"deployDrawer.selectEnv": "选择一个环境",
"deployDrawer.selectProviderCred": "选择 {{provider}} 凭据",
"deployDrawer.selectProviderKey": "选择 {{provider}} 密钥",
"deployDrawer.selectRelease": "选择一个发布版本",
@ -221,6 +221,7 @@
"overview.basicInfo": "基本信息",
"overview.cli": "CLI",
"overview.configureAccess": "配置接入",
"overview.createRelease": "创建版本",
"overview.created": "创建时间",
"overview.deploy": "部署",
"overview.deploymentStatus": "部署状态",
@ -234,11 +235,10 @@
"overview.manageDeployments": "管理部署",
"overview.name": "名称",
"overview.noAccessConfig": "未配置接入方式。",
"overview.noReleaseSourceUnavailable": "源应用已删除。已有发布版本仍可部署,但当前还没有可部署版本。",
"overview.noReleaseYet": "请先创建发布版本,再部署该应用实例。",
"overview.notConfigured": "未配置",
"overview.notDeployedYet": "尚未部署。",
"overview.noReleaseYet": "请先创建发布版本,再部署该应用实例。",
"overview.noReleaseSourceUnavailable": "源应用已删除。已有发布版本仍可部署,但当前还没有可部署版本。",
"overview.createRelease": "创建版本",
"overview.sourceApp": "源应用",
"overview.sourceAppDeletedDescription": "历史 Release 仍可继续部署,但无法再基于已删除的源应用生成新 Release。请切换到其他源应用后继续使用。",
"overview.sourceAppDeletedTitle": "源应用已被删除",
@ -249,16 +249,6 @@
"overview.switchSourceAppHint": "切换后,仅新建 Release 会使用新的源应用;历史 Release 和现有部署不受影响。",
"overview.viewDeployments": "查看部署",
"overview.webapp": "WebApp",
"versions.cancelCreate": "取消",
"versions.create": "创建",
"versions.createFailed": "创建发布版本失败。",
"versions.createRelease": "创建版本",
"versions.creating": "创建中...",
"versions.emptySourceUnavailable": "暂无发布版本。源应用已删除,无法创建新版本。",
"versions.emptyWithCreate": "暂无发布版本,请先创建第一个可部署版本。",
"versions.releaseDescriptionPlaceholder": "描述这个版本",
"versions.releaseNamePlaceholder": "版本名称",
"versions.sourceAppUnavailable": "源应用已删除。已有发布版本仍可部署,但无法创建新版本。",
"rollback.cancel": "取消",
"rollback.confirm": "确认部署",
"rollback.currentRelease": "当前发布",
@ -303,6 +293,7 @@
"tabs.versions.description": "此应用的所有发布版本,可将任一版本发布到环境。",
"tabs.versions.name": "版本",
"title": "应用实例",
"versions.cancelCreate": "取消",
"versions.col.action": "操作",
"versions.col.author": "作者",
"versions.col.commit": "提交",
@ -310,6 +301,12 @@
"versions.col.deployedTo": "已部署到",
"versions.col.release": "发布",
"versions.commitTooltip": "Commit {{commit}}",
"versions.create": "创建",
"versions.createFailed": "创建发布版本失败。",
"versions.createRelease": "创建版本",
"versions.createReleaseDescription": "将当前工作流保存为可部署版本。",
"versions.createReleaseHint": "新版本可部署到任意环境。",
"versions.creating": "创建中...",
"versions.currentOn": "{{name}} 当前版本",
"versions.deploy": "部署",
"versions.deployTo": "部署到 {{name}}",
@ -318,10 +315,18 @@
"versions.deployedStatus.failed": "失败",
"versions.deployingTo": "{{name}} 正在部署",
"versions.empty": "暂无可用的发布版本。",
"versions.emptySourceUnavailable": "暂无发布版本。源应用已删除,无法创建新版本。",
"versions.emptyWithCreate": "暂无发布版本,请先创建第一个可部署版本。",
"versions.hideYaml": "隐藏 YAML",
"versions.moreActions": "更多操作",
"versions.optional": "可选",
"versions.promote": "发布",
"versions.promoteTo": "发布到 {{name}}",
"versions.releaseDescriptionLabel": "描述",
"versions.releaseDescriptionPlaceholder": "描述这个版本",
"versions.releaseHistory": "发布历史",
"versions.releaseNameLabel": "版本名称",
"versions.releaseNamePlaceholder": "版本名称",
"versions.sourceAppUnavailable": "源应用已删除。已有发布版本仍可部署,但无法创建新版本。",
"versions.viewYaml": "查看 YAML"
}