dify/web/features/deployments/detail/releases/release-actions/deploy-release-menu-utils.ts
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

158 lines
3.9 KiB
TypeScript

import type {
Environment,
EnvironmentDeployment,
Release,
} from '@dify/contracts/enterprise/types.gen'
import type { SelectorParam } from 'i18next'
import { releaseDeploymentAction } from '../../../shared/domain/release-action'
import {
isRuntimeDeploymentInProgress,
isUndeployedDeploymentRow,
} from '../../../shared/domain/runtime-status'
export type DeployMenuRowState = 'deploy' | 'rollback' | 'current' | 'deploying'
export type DeployMenuRow = {
env?: Environment
environmentId: string
state: DeployMenuRowState
label: string
disabledReason?: string
}
export type DeployMenuGroup = 'deploy' | 'rollback' | 'unavailable'
export type DeployMenuSection = {
group: DeployMenuGroup
rows: DeployMenuRow[]
}
type DeploymentTranslator = (
selector: SelectorParam<'deployments'>,
options?: Record<string, unknown>,
) => string
const GROUP_ORDER: DeployMenuGroup[] = ['deploy', 'rollback', 'unavailable']
function stateToGroup(state: DeployMenuRowState): DeployMenuGroup {
if (state === 'rollback') return 'rollback'
if (state === 'deploy') return 'deploy'
return 'unavailable'
}
export function releaseUsageCount(releaseId: string, deploymentRows: EnvironmentDeployment[]) {
const environmentIds = new Set<string>()
deploymentRows.forEach((row) => {
const usesRelease = row.currentRelease?.id === releaseId || row.desiredRelease?.id === releaseId
if (usesRelease) environmentIds.add(row.environment.id)
})
return environmentIds.size
}
function buildDeployMenuRow({
env,
deploymentRows,
releaseRows,
releaseId,
targetRelease,
t,
}: {
env: Environment
deploymentRows: EnvironmentDeployment[]
releaseRows: Release[]
releaseId: string
targetRelease: Release
t: DeploymentTranslator
}): DeployMenuRow {
const envId = env.id
const envName = env.displayName
const row = deploymentRows.find((item) => item.environment.id === envId)
const currentRelease = row?.currentRelease
const isCurrent = currentRelease?.id === releaseId
const isEnvironmentInProgress = isRuntimeDeploymentInProgress(row?.status)
if (isEnvironmentInProgress) {
return {
env,
environmentId: envId,
state: 'deploying',
label: t(($) => $['versions.deployingTo'], { name: envName }),
disabledReason: t(($) => $['versions.disabledReason.deploying']),
}
}
if (isCurrent) {
return {
env,
environmentId: envId,
state: 'current',
label: t(($) => $['versions.currentOn'], { name: envName }),
disabledReason: t(($) => $['versions.disabledReason.current'], { name: envName }),
}
}
const action = releaseDeploymentAction({
targetRelease,
currentRelease,
releaseRows,
isExistingRelease: true,
})
if (!row) {
return {
env,
environmentId: envId,
state: 'deploy',
label: t(($) => $['versions.deployTo'], { name: envName }),
}
}
if (action === 'rollback') {
return {
env,
environmentId: envId,
state: 'rollback',
label: t(($) => $['versions.rollbackTo'], { name: envName }),
}
}
return {
env,
environmentId: envId,
state: 'deploy',
label: t(($) => $['versions.deployTo'], { name: envName }),
}
}
export function buildDeployMenuSections({
environments,
environmentDeployments,
releaseRows,
releaseId,
targetRelease,
t,
}: {
environments: Environment[]
environmentDeployments: EnvironmentDeployment[]
releaseRows: Release[]
releaseId: string
targetRelease: Release
t: DeploymentTranslator
}) {
const deploymentRows = environmentDeployments.filter((row) => !isUndeployedDeploymentRow(row))
const menuRows = environments.map((env) =>
buildDeployMenuRow({
env,
deploymentRows,
releaseRows,
releaseId,
targetRelease,
t,
}),
)
return GROUP_ORDER.map((group) => ({
group,
rows: menuRows.filter((row) => stateToGroup(row.state) === group),
})).filter((section): section is DeployMenuSection => section.rows.length > 0)
}