'use client' import type { GuideMethod, WorkflowSourceApp } from '@/features/deployments/create-guide/state/types' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { Input } from '@langgenius/dify-ui/input' import { RadioGroup, RadioItem } from '@langgenius/dify-ui/radio' import { useAtomValue, useSetAtom } from 'jotai' import { useTranslation } from 'react-i18next' import Uploader from '@/app/components/app/create-from-dsl-modal/uploader' import AppIcon from '@/app/components/base/app-icon' import { SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton' import { dslFileAtom, effectiveMethodAtom, sourceSearchTextAtom, } from '@/features/deployments/create-guide/state/primitives' import { unsupportedDslNodesAtom } from '@/features/deployments/create-guide/state/queries' import { dslReadErrorAtom, dslUnsupportedModeAtom, effectiveSelectedAppAtom, isReadingDslAtom, sourceAppsQueryAtom, } from '@/features/deployments/create-guide/state/source' import { continueFromSourceAtom, selectDslFileAtom, selectMethodAtom, selectSourceAppAtom, setSourceSearchTextAtom, sourceCanGoNextAtom, } from '@/features/deployments/create-guide/state/workflow' import { DeploymentStateMessage } from '@/features/deployments/shared/components/empty-state' import { TitleTooltip } from '@/features/deployments/shared/components/title-tooltip' import { UnsupportedDslNodesAlert } from '@/features/deployments/shared/components/unsupported-dsl-nodes-alert' import { isDeploymentDslImportEnabled } from '@/features/deployments/shared/domain/feature-flags' import { useInfiniteScroll } from '@/features/deployments/shared/hooks/use-infinite-scroll' import { StepShell } from './layout' const sourceAppSkeletonKeys = ['first-source-app', 'second-source-app', 'third-source-app'] export function SourceStepContent() { const method = useAtomValue(effectiveMethodAtom) const unsupportedDslNodes = useAtomValue(unsupportedDslNodesAtom) return (
{method === 'bindApp' && ( )} {method === 'importDsl' && ( )}
) } function SourceMethodSection() { const { t } = useTranslation('deployments') const method = useAtomValue(effectiveMethodAtom) const selectMethod = useSetAtom(selectMethodAtom) return ( value={method} onValueChange={selectMethod} className="flex flex-col items-stretch gap-2 sm:flex-row" > {isDeploymentDslImportEnabled && ( )} ) } function SourceMethodCard({ value, icon, title, description, badge }: { value: GuideMethod icon: string title: string description: string badge?: string }) { return ( value={value} nativeButton render={ )} ) } function SourceAppList() { const { t } = useTranslation('deployments') const selectSourceApp = useSetAtom(selectSourceAppAtom) const effectiveSelectedApp = useAtomValue(effectiveSelectedAppAtom) const sourceAppsQuery = useAtomValue(sourceAppsQueryAtom) const sourceApps = (sourceAppsQuery.data?.pages.flatMap(page => page.data) ?? []) as WorkflowSourceApp[] const sourceAppsLoading = sourceAppsQuery.isLoading || sourceAppsQuery.isPlaceholderData || (sourceAppsQuery.isFetching && sourceApps.length === 0) const { rootRef, sentinelRef } = useInfiniteScroll(sourceAppsQuery, { enabled: !sourceAppsLoading, rootMargin: '0px 0px 160px 0px', threshold: 0.1, }) return (
{sourceAppsLoading ? : sourceApps.length === 0 ? ( {t('createGuide.source.empty')} ) : (
{sourceApps.map(app => ( selectSourceApp(app)} /> ))} {sourceAppsQuery.isFetchingNextPage && (
{t('createModal.loadingApps')}
)} {sourceAppsQuery.hasNextPage && )}
) } function SourceAppSkeleton() { return (
{sourceAppSkeletonKeys.map(key => (
))}
) } function SourceAppOption({ app, onSelect, selected }: { app: WorkflowSourceApp onSelect: () => void selected: boolean }) { return ( ) } function DslUploadSection() { const { t } = useTranslation('deployments') const dslFile = useAtomValue(dslFileAtom) const selectDslFile = useSetAtom(selectDslFileAtom) return (
) } function DslReadStatus() { const { t } = useTranslation('deployments') const isReadingDsl = useAtomValue(isReadingDslAtom) const dslReadError = useAtomValue(dslReadErrorAtom) const dslUnsupportedMode = useAtomValue(dslUnsupportedModeAtom) return ( <> {isReadingDsl && (
{t('createGuide.dsl.reading')}
)} {dslReadError && (
{t('createGuide.dsl.readFailed')}
)} {dslUnsupportedMode && (
{t('createGuide.dsl.unsupportedMode')}
)} ) } export function SourceActionButtons() { const { t } = useTranslation('deployments') const canGoNext = useAtomValue(sourceCanGoNextAtom) const continueFromSource = useSetAtom(continueFromSourceAtom) return ( ) }