'use client' import type { Environment, EnvironmentDeployment, Release, } from '@dify/contracts/enterprise/types.gen' import { Button } from '@langgenius/dify-ui/button' import { useAtomValue, useSetAtom } from 'jotai' import { ScopeProvider } from 'jotai-scope' import { useTranslation } from 'react-i18next' import { EnvVarBindingsPanel } from '../../shared/components/env-var-bindings' import { isAvailableDeploymentTarget } from '../../shared/domain/runtime-status' import { canAttemptDeployAtom, canSubmitDeployAtom, closeDeployDrawerAtom, deployBindingSlotsAtom, deployEnvVarSlotsAtom, deployEnvVarValuesAtom, deployFormAppInstanceIdAtom, deployHasBindingOptionsErrorAtom, deployHasSelectedEnvironmentAtom, deployIsBindingOptionsLoadingAtom, deployReadyFormConfigAtom, deployReadyFormLocalAtoms, deployReleaseSubmissionAtom, deploySelectedBindingsAtom, deployShowValidationErrorsAtom, deployTargetReleaseIdAtom, isDeployReleaseSubmittingAtom, releaseDeploymentViewAtom, releaseDeploymentViewIsErrorAtom, releaseDeploymentViewIsLoadingAtom, selectDeployBindingAtom, setDeployEnvVarAtom, showDeployValidationErrorsAtom, } from '../state' import { currentReleaseIdForEnvironment, selectableDeployReleases } from '../state/release-options' import { BindingOptionsPanel, DEPLOY_DRAWER_BINDING_LIST_CLASS_NAME, DeployFormHeader, EnvironmentField, ReleaseField, } from './form-sections' import { DeployFormSkeleton } from './form-skeleton' type DeployFormProps = { appInstanceId: string lockedEnvId?: string presetReleaseId?: string } type DeployReadyFormProps = DeployFormProps & { environments: Environment[] releases: Release[] runtimeRows: EnvironmentDeployment[] defaultReleaseId?: string releaseEmptyLabel?: string } function DeployRuntimeCredentialBindingsSection() { const { t } = useTranslation('deployments') const bindingSlots = useAtomValue(deployBindingSlotsAtom) const selectedBindings = useAtomValue(deploySelectedBindingsAtom) const isBindingOptionsLoading = useAtomValue(deployIsBindingOptionsLoadingAtom) const hasBindingOptionsError = useAtomValue(deployHasBindingOptionsErrorAtom) const showValidationErrors = useAtomValue(deployShowValidationErrorsAtom) const selectBinding = useSetAtom(selectDeployBindingAtom) return ( $['deployDrawer.bindingCount'], { count: bindingSlots.length })} showMissingRequired={showValidationErrors} onChange={selectBinding} /> ) } function DeployEnvVarBindingsSection() { const { t } = useTranslation('deployments') const envVarSlots = useAtomValue(deployEnvVarSlotsAtom) const envVarValues = useAtomValue(deployEnvVarValuesAtom) const isBindingOptionsLoading = useAtomValue(deployIsBindingOptionsLoadingAtom) const hasBindingOptionsError = useAtomValue(deployHasBindingOptionsErrorAtom) const showValidationErrors = useAtomValue(deployShowValidationErrorsAtom) const setDeployEnvVar = useSetAtom(setDeployEnvVarAtom) if (isBindingOptionsLoading || hasBindingOptionsError) return null return ( $['deployDrawer.envVars'])} hint={t(($) => $['deployDrawer.envVarHint'])} envVarPlaceholder={t(($) => $['deployDrawer.envVarPlaceholder'])} literalSourceLabel={t(($) => $['deployDrawer.envVarSource.literal'])} defaultSourceLabel={t(($) => $['deployDrawer.envVarSource.default'])} lastDeploymentSourceLabel={t(($) => $['deployDrawer.envVarSource.lastDeployment'])} valueTypeLabels={{ string: t(($) => $['deployDrawer.envVarType.string']), number: t(($) => $['deployDrawer.envVarType.number']), secret: t(($) => $['deployDrawer.envVarType.secret']), }} sourceAriaLabel={(key) => t(($) => $['deployDrawer.envVarSource.ariaLabel'], { key })} defaultSourcePriority="lastDeployment" envVarCountLabel={t(($) => $['deployDrawer.envVarCount'], { count: envVarSlots.length })} missingRequiredLabel={t(($) => $['deployDrawer.missingRequiredEnvVar'])} listClassName={DEPLOY_DRAWER_BINDING_LIST_CLASS_NAME} showMissingRequired={showValidationErrors} onChange={setDeployEnvVar} /> ) } function DeployBindingsSection() { const targetReleaseId = useAtomValue(deployTargetReleaseIdAtom) const hasSelectedEnvironment = useAtomValue(deployHasSelectedEnvironmentAtom) if (!targetReleaseId || !hasSelectedEnvironment) return null return ( <> ) } function DeployFormBody() { return (
) } function DeployFooter() { const { t } = useTranslation('deployments') const closeDeployDrawer = useSetAtom(closeDeployDrawerAtom) const showValidationErrors = useSetAtom(showDeployValidationErrorsAtom) const submitDeployRelease = useSetAtom(deployReleaseSubmissionAtom) const canAttemptDeploy = useAtomValue(canAttemptDeployAtom) const canDeploy = useAtomValue(canSubmitDeployAtom) const isSubmitting = useAtomValue(isDeployReleaseSubmittingAtom) const submitLabel = isSubmitting ? t(($) => $['deployDrawer.deploying']) : t(($) => $['deployDrawer.deploy']) function handleDeploy() { showValidationErrors() if (!canDeploy) return submitDeployRelease({ deployFailedMessage: t(($) => $['deployDrawer.deployFailed']), }) } return (
) } function deployReadyFormStoreKey({ appInstanceId, environments, releases, runtimeRows, defaultReleaseId, lockedEnvId, presetReleaseId, }: DeployReadyFormProps) { return [ appInstanceId, lockedEnvId ?? 'any', presetReleaseId ?? 'new', defaultReleaseId ?? 'none', environments.map((env) => env.id).join(','), releases.map((release) => release.id).join(','), runtimeRows.map((row) => `${row.environment.id}:${row.currentRelease?.id ?? 'none'}`).join(','), ].join('|') } function DeployReadyForm(config: DeployReadyFormProps) { return (
) } function DeployFormContent({ appInstanceId, lockedEnvId, presetReleaseId }: DeployFormProps) { const { t } = useTranslation('deployments') const deploymentView = useAtomValue(releaseDeploymentViewAtom) const isLoading = useAtomValue(releaseDeploymentViewIsLoadingAtom) const isError = useAtomValue(releaseDeploymentViewIsErrorAtom) if (isLoading) { return } if (isError) { return (
{t(($) => $['common.loadFailed'])}
) } if (!deploymentView) { return (
{t(($) => $['common.loadFailed'])}
) } const runtimeRows = deploymentView.environmentDeployments const environments = runtimeRows .filter((row) => lockedEnvId || isAvailableDeploymentTarget(row)) .map((row) => row.environment) const releaseRows = deploymentView.releases const currentReleaseId = currentReleaseIdForEnvironment(runtimeRows, lockedEnvId) const releases = selectableDeployReleases({ releases: releaseRows, lockedEnvId, currentReleaseId, presetReleaseId, }) const defaultReleaseId = releases[0]?.id const releaseEmptyLabel = lockedEnvId && !presetReleaseId && currentReleaseId ? t(($) => $['deployDrawer.noOtherReleaseAvailable']) : undefined const readyFormConfig = { appInstanceId, environments, releases, runtimeRows, defaultReleaseId, releaseEmptyLabel, lockedEnvId, presetReleaseId, } const formKey = deployReadyFormStoreKey(readyFormConfig) return } export function DeployForm(props: DeployFormProps) { return ( ) }