diff --git a/web/features/deployments/detail/settings-tab/access/channels-section.tsx b/web/features/deployments/detail/settings-tab/access/channels-section.tsx index 4dc086d202..a66619c49d 100644 --- a/web/features/deployments/detail/settings-tab/access/channels-section.tsx +++ b/web/features/deployments/detail/settings-tab/access/channels-section.tsx @@ -1,6 +1,6 @@ 'use client' -import type { Environment } from '@dify/contracts/enterprise/types.gen' +import type { AccessChannels, Environment } from '@dify/contracts/enterprise/types.gen' import type { ReactNode } from 'react' import { Switch, SwitchSkeleton } from '@langgenius/dify-ui/switch' import { useMutation, useQuery } from '@tanstack/react-query' @@ -18,9 +18,10 @@ const ACCESS_CHANNEL_SKELETON_SECTIONS = [ { key: 'cli' }, ] -function AccessChannelsSwitch({ appInstanceId, checked, disabled }: { +function AccessChannelsSwitch({ appInstanceId, checked, accessChannels, disabled }: { appInstanceId: string checked: boolean + accessChannels?: AccessChannels disabled?: boolean }) { const toggleAccessChannel = useMutation(consoleQuery.enterprise.accessService.updateAccessChannels.mutationOptions()) @@ -33,7 +34,11 @@ function AccessChannelsSwitch({ appInstanceId, checked, disabled }: { onCheckedChange={(enabled) => { toggleAccessChannel.mutate({ params: { appInstanceId }, - body: { appInstanceId, webAppEnabled: enabled }, + body: { + appInstanceId, + webAppEnabled: enabled, + developerApiEnabled: accessChannels?.developerApiEnabled ?? false, + }, }) }} /> @@ -150,6 +155,7 @@ export function AccessChannelsSection({ diff --git a/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx b/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx index 9989eb8593..f5d7b2011d 100644 --- a/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx +++ b/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx @@ -1,6 +1,7 @@ 'use client' import type { + AccessChannels, ApiKey, Environment, } from '@dify/contracts/enterprise/types.gen' @@ -60,10 +61,12 @@ function useDeveloperApiStatus(appInstanceId: string) { params: { appInstanceId }, }, })) - const apiEnabled = accessChannelsQuery.data?.accessChannels?.developerApiEnabled ?? false + const accessChannels = accessChannelsQuery.data?.accessChannels + const apiEnabled = accessChannels?.developerApiEnabled ?? false return { apiEnabled, + accessChannels, isLoading: accessChannelsQuery.isLoading, isError: accessChannelsQuery.isError, } @@ -109,9 +112,10 @@ function useDeveloperApiResources(appInstanceId: string) { } } -function DeveloperApiSwitch({ appInstanceId, checked, disabled }: { +function DeveloperApiSwitch({ appInstanceId, checked, accessChannels, disabled }: { appInstanceId: string checked: boolean + accessChannels?: AccessChannels disabled?: boolean }) { const toggleDeveloperAPI = useMutation(consoleQuery.enterprise.accessService.updateAccessChannels.mutationOptions()) @@ -124,7 +128,11 @@ function DeveloperApiSwitch({ appInstanceId, checked, disabled }: { onCheckedChange={(enabled) => { toggleDeveloperAPI.mutate({ params: { appInstanceId }, - body: { appInstanceId, developerApiEnabled: enabled }, + body: { + appInstanceId, + webAppEnabled: accessChannels?.webAppEnabled ?? false, + developerApiEnabled: enabled, + }, }) }} /> @@ -137,6 +145,7 @@ export function DeveloperApiHeaderSwitch({ appInstanceId }: { const { t } = useTranslation('deployments') const { apiEnabled, + accessChannels, isLoading, isError, } = useDeveloperApiStatus(appInstanceId) @@ -152,6 +161,7 @@ export function DeveloperApiHeaderSwitch({ appInstanceId }: { diff --git a/web/features/deployments/list/create-deployment-button.tsx b/web/features/deployments/list/create-deployment-button.tsx index 2633acc756..75918bfe44 100644 --- a/web/features/deployments/list/create-deployment-button.tsx +++ b/web/features/deployments/list/create-deployment-button.tsx @@ -13,7 +13,7 @@ export function CreateDeploymentButton({ className }: { diff --git a/web/features/deployments/list/environment-filter.tsx b/web/features/deployments/list/environment-filter.tsx index 743d5a23b8..e94faa34ca 100644 --- a/web/features/deployments/list/environment-filter.tsx +++ b/web/features/deployments/list/environment-filter.tsx @@ -35,7 +35,9 @@ function EnvironmentOptionIcon() { return } -export function EnvironmentFilter() { +export function EnvironmentFilter({ className }: { + className?: string +}) { const { t } = useTranslation('deployments') const [open, setOpen] = useState(false) const [envFilter, setEnvFilter] = useQueryState('env', envFilterQueryState) @@ -74,8 +76,9 @@ export function EnvironmentFilter() {
diff --git a/web/features/deployments/list/index.tsx b/web/features/deployments/list/index.tsx index 39e6222f8c..93e0e380cb 100644 --- a/web/features/deployments/list/index.tsx +++ b/web/features/deployments/list/index.tsx @@ -143,12 +143,13 @@ function DeploymentsSearchInput({ className }: { function DeploymentsListControls() { return (
-
-
- - +
+
+ +
- + +
) @@ -219,7 +220,7 @@ export function DeploymentsList() {
diff --git a/web/features/deployments/list/instance-card.tsx b/web/features/deployments/list/instance-card.tsx index b9be4fdf50..e377124a8e 100644 --- a/web/features/deployments/list/instance-card.tsx +++ b/web/features/deployments/list/instance-card.tsx @@ -108,12 +108,15 @@ function EnvironmentChip({ row }: { const { t } = useTranslation('deployments') const name = environmentName(row.environment) const status = deploymentStatus(row) + const quietReadyStatusClassName = status === 'ready' + ? 'border-divider-subtle bg-background-section-burn text-text-secondary' + : undefined return ( + )} /> @@ -233,6 +236,7 @@ function DeploymentAccessLinks({ appInstanceId, access, isLoading }: { key: 'webapp', href: getInstanceTabHref(appInstanceId, 'access'), label: t('card.access.webApp'), + shortLabel: t('card.access.webAppShort'), icon: 'i-ri-global-line', } : undefined, @@ -241,6 +245,7 @@ function DeploymentAccessLinks({ appInstanceId, access, isLoading }: { key: 'cli', href: getInstanceTabHref(appInstanceId, 'access'), label: t('card.access.cli'), + shortLabel: t('card.access.cliShort'), icon: 'i-ri-terminal-box-line', } : undefined, @@ -249,10 +254,11 @@ function DeploymentAccessLinks({ appInstanceId, access, isLoading }: { key: 'api-tokens', href: getInstanceTabHref(appInstanceId, 'api-tokens'), label: t('card.access.api'), + shortLabel: t('card.access.apiShort'), icon: 'i-ri-code-s-slash-line', } : undefined, - ].filter((link): link is { key: string, href: string, label: string, icon: string } => Boolean(link)) + ].filter((link): link is { key: string, href: string, label: string, shortLabel: string, icon: string } => Boolean(link)) if (links.length === 0) { return ( @@ -272,9 +278,15 @@ function DeploymentAccessLinks({ appInstanceId, access, isLoading }: { + + {links.length > 1 ? link.shortLabel : link.label} + )} /> diff --git a/web/i18n/en-US/deployments.json b/web/i18n/en-US/deployments.json index 029af3ecfe..97f6d8f276 100644 --- a/web/i18n/en-US/deployments.json +++ b/web/i18n/en-US/deployments.json @@ -99,9 +99,12 @@ "appMode.completion": "Completion", "appMode.workflow": "Workflow", "card.access.api": "API Tokens", + "card.access.apiShort": "API", "card.access.cli": "CLI", + "card.access.cliShort": "CLI", "card.access.none": "No access", "card.access.webApp": "Web app", + "card.access.webAppShort": "Web", "card.createFirstRelease": "Create first Release", "card.deploy": "Deploy", "card.deploying": "{{count}} deploying", @@ -173,9 +176,9 @@ "createGuide.steps.release": "Create instance and release", "createGuide.steps.source": "Choose source", "createGuide.steps.target": "Deploy target", - "createGuide.target.bindingHint": "Pick the credentials that will be used when this release runs.", "createGuide.target.bindingCount_one": "{{count}} binding", "createGuide.target.bindingCount_other": "{{count}} bindings", + "createGuide.target.bindingHint": "Pick the credentials that will be used when this release runs.", "createGuide.target.bindings": "Runtime bindings", "createGuide.target.deferredBindingHint": "Runtime credentials will be resolved from the real deployment plan during the final deploy action.", "createGuide.target.deferredEnvironmentHint": "The name is matched against the real environments after the app instance and release are created.", @@ -214,6 +217,7 @@ "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.close": "Close deployment drawer", "deployDrawer.defaultSelect": "Select...", "deployDrawer.deploy": "Deploy", "deployDrawer.deployExistingRelease": "Deploy existing release", @@ -254,7 +258,6 @@ "deployDrawer.selectProviderCred": "Select {{provider}} credential", "deployDrawer.selectProviderKey": "Select {{provider}} key", "deployDrawer.selectRelease": "Select a release", - "deployDrawer.close": "Close deployment drawer", "deployDrawer.targetEnv": "Target environment", "deployDrawer.title": "Deploy to environment", "deployDrawer.valuePlaceholder": "value", @@ -442,6 +445,8 @@ "subtitle": "Deploy and manage your apps across environments.", "tabs.access.description": "Manage WebApp and CLI access channels and sharing permissions.", "tabs.access.name": "Access methods", + "tabs.api-tokens.description": "Manage API tokens and invoke runtime instances over HTTP.", + "tabs.api-tokens.name": "API Tokens", "tabs.instances.description": "View and manage runtime instances in deployed environments.", "tabs.instances.name": "Instances", "tabs.overview.description": "View overall status and runtime status across environments.", @@ -450,10 +455,9 @@ "tabs.releases.name": "Versions", "tabs.settings.description": "Manage name, description, and backend-managed settings.", "tabs.settings.name": "Settings", - "tabs.api-tokens.description": "Manage API tokens and invoke runtime instances over HTTP.", - "tabs.api-tokens.name": "API Tokens", "title": "App instances", "versions.cancelCreate": "Cancel", + "versions.cancelDelete": "Cancel", "versions.col.action": "Action", "versions.col.author": "Author", "versions.col.commit": "Commit", @@ -470,9 +474,6 @@ "versions.createSuccess": "Release \"{{name}}\" created.", "versions.creating": "Creating...", "versions.currentOn": "Current on {{name}}", - "versions.cancelDelete": "Cancel", - "versions.deploy": "Deploy", - "versions.deployTo": "Deploy to {{name}}", "versions.deleteConfirmDesc": "Release \"{{name}}\" will be permanently deleted. This can't be undone.", "versions.deleteConfirmTitle": "Delete release?", "versions.deleteFailed": "Failed to delete release.", @@ -482,6 +483,8 @@ "versions.deleteImpactTitle": "Delete impact", "versions.deleteRelease": "Delete release", "versions.deleteSuccess": "Release \"{{name}}\" deleted.", + "versions.deploy": "Deploy", + "versions.deployTo": "Deploy to {{name}}", "versions.deployedStatus.active": "Running", "versions.deployedStatus.deploying": "Deploying", "versions.deployedStatus.failed": "Failed", diff --git a/web/i18n/zh-Hans/deployments.json b/web/i18n/zh-Hans/deployments.json index 8e5e67e4c5..822496e59a 100644 --- a/web/i18n/zh-Hans/deployments.json +++ b/web/i18n/zh-Hans/deployments.json @@ -99,9 +99,12 @@ "appMode.completion": "文本生成", "appMode.workflow": "工作流", "card.access.api": "API 令牌", + "card.access.apiShort": "API", "card.access.cli": "CLI", + "card.access.cliShort": "CLI", "card.access.none": "未开启接入", "card.access.webApp": "WebApp", + "card.access.webAppShort": "Web", "card.createFirstRelease": "创建首个发布版本", "card.deploy": "部署", "card.deploying": "{{count}} 个部署中", @@ -173,9 +176,9 @@ "createGuide.steps.release": "创建实例和发布版本", "createGuide.steps.source": "选择来源", "createGuide.steps.target": "部署目标", - "createGuide.target.bindingHint": "选择该发布版本运行时使用的凭据。", "createGuide.target.bindingCount_one": "{{count}} 项", "createGuide.target.bindingCount_other": "{{count}} 项", + "createGuide.target.bindingHint": "选择该发布版本运行时使用的凭据。", "createGuide.target.bindings": "运行时绑定", "createGuide.target.deferredBindingHint": "运行时凭据会在最终部署时根据真实部署计划解析。", "createGuide.target.deferredEnvironmentHint": "创建应用实例和发布版本后,会根据真实环境进行匹配。", @@ -214,6 +217,7 @@ "deployDrawer.bindingSelectionHint": "选择本次部署要使用的运行时凭据。", "deployDrawer.bindingsDisabled": "来自发布版本预览的解析结果,暂不支持在这里编辑。", "deployDrawer.cancel": "取消", + "deployDrawer.close": "关闭部署抽屉", "deployDrawer.defaultSelect": "选择…", "deployDrawer.deploy": "部署", "deployDrawer.deployExistingRelease": "部署已有发布版本", @@ -254,7 +258,6 @@ "deployDrawer.selectProviderCred": "选择 {{provider}} 凭据", "deployDrawer.selectProviderKey": "选择 {{provider}} 密钥", "deployDrawer.selectRelease": "选择一个发布版本", - "deployDrawer.close": "关闭部署抽屉", "deployDrawer.targetEnv": "目标环境", "deployDrawer.title": "部署到环境", "deployDrawer.valuePlaceholder": "值", @@ -442,6 +445,8 @@ "subtitle": "在不同环境中部署和管理你的应用。", "tabs.access.description": "管理 WebApp、CLI 接入渠道和共享访问权限。", "tabs.access.name": "接入方式", + "tabs.api-tokens.description": "管理 API 令牌,通过 HTTP 调用各环境实例。", + "tabs.api-tokens.name": "API 令牌", "tabs.instances.description": "查看和管理各环境中的运行实例。", "tabs.instances.name": "实例", "tabs.overview.description": "查看整体状态、各环境运行概况。", @@ -450,10 +455,9 @@ "tabs.releases.name": "版本", "tabs.settings.description": "管理名称、描述和后端托管设置。", "tabs.settings.name": "设置", - "tabs.api-tokens.description": "管理 API 令牌,通过 HTTP 调用各环境实例。", - "tabs.api-tokens.name": "API 令牌", "title": "应用实例", "versions.cancelCreate": "取消", + "versions.cancelDelete": "取消", "versions.col.action": "操作", "versions.col.author": "作者", "versions.col.commit": "提交", @@ -470,9 +474,6 @@ "versions.createSuccess": "发布版本 \"{{name}}\" 已创建。", "versions.creating": "创建中…", "versions.currentOn": "{{name}} 当前发布版本", - "versions.cancelDelete": "取消", - "versions.deploy": "部署", - "versions.deployTo": "部署到 {{name}}", "versions.deleteConfirmDesc": "发布版本 \"{{name}}\" 将被永久删除,此操作无法撤销。", "versions.deleteConfirmTitle": "删除发布版本?", "versions.deleteFailed": "删除发布版本失败。", @@ -482,6 +483,8 @@ "versions.deleteImpactTitle": "删除影响", "versions.deleteRelease": "删除发布版本", "versions.deleteSuccess": "发布版本 \"{{name}}\" 已删除。", + "versions.deploy": "部署", + "versions.deployTo": "部署到 {{name}}", "versions.deployedStatus.active": "运行中", "versions.deployedStatus.deploying": "部署中", "versions.deployedStatus.failed": "失败", diff --git a/web/service/client.ts b/web/service/client.ts index 92822eb1f6..6399e6a55e 100644 --- a/web/service/client.ts +++ b/web/service/client.ts @@ -550,6 +550,9 @@ export const consoleQuery: RouterUtils = createTanstackQue onSuccess: (_data, variables, _result, context) => { const appInstanceId = variables.params.appInstanceId return Promise.all([ + context.client.invalidateQueries({ + queryKey: consoleQuery.enterprise.appInstanceService.listAppInstances.key(), + }), context.client.invalidateQueries({ queryKey: consoleQuery.enterprise.appInstanceService.getAppInstance.key({ type: 'query',