'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 ( ) } 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 ( 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 ( ) }