'use client' import type { GuideMethod, WorkflowSourceApp } from '@/features/deployments/create-guide/state' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { Input } from '@langgenius/dify-ui/input' import { RadioRoot } from '@langgenius/dify-ui/radio' import { RadioGroup } from '@langgenius/dify-ui/radio-group' 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 { DeploymentStateMessage } from '@/features/deployments/components/empty-state' import { TitleTooltip } from '@/features/deployments/components/title-tooltip' import { UnsupportedDslNodesAlert } from '@/features/deployments/components/unsupported-dsl-nodes-alert' import { continueFromSourceAtom, dslFileAtom, dslReadErrorAtom, dslUnsupportedModeAtom, effectiveSelectedAppAtom, isReadingDslAtom, methodAtom, selectDslFileAtom, selectMethodAtom, selectSourceAppAtom, setSourceSearchTextAtom, sourceAppsQueryAtom, sourceCanGoNextAtom, sourceSearchTextAtom, unsupportedDslNodesAtom, } from '@/features/deployments/create-guide/state' import { StepShell } from './layout' const sourceAppSkeletonKeys = ['first-source-app', 'second-source-app', 'third-source-app'] export function SourceStepContent() { const method = useAtomValue(methodAtom) const unsupportedDslNodes = useAtomValue(unsupportedDslNodesAtom) return (
{method === 'bindApp' && ( )} {method === 'importDsl' && ( )}
) } function SourceMethodSection() { const { t } = useTranslation('deployments') const method = useAtomValue(methodAtom) const selectMethod = useSetAtom(selectMethodAtom) return ( value={method} onValueChange={selectMethod} className="flex flex-col items-stretch gap-2 sm:flex-row" > ) } function SourceMethodCard({ value, icon, title, description, badge }: { value: GuideMethod icon: string title: string description: string badge?: string }) { return ( value={value} variant="unstyled" className={cn( `relative box-content h-[84px] w-full cursor-pointer rounded-xl border-[0.5px] border-components-option-card-option-border bg-components-panel-on-panel-item-bg p-3 text-left shadow-xs outline-hidden hover:shadow-md focus-visible:ring-2 focus-visible:ring-state-accent-solid sm:w-[240px]`, 'data-checked:border-components-option-card-option-selected-border data-checked:bg-components-option-card-option-selected-bg data-checked:shadow-md data-checked:ring-[0.5px] data-checked:ring-components-option-card-option-selected-border data-checked:ring-inset', )} > {title} {badge && ( {badge} )} {description} ) } function SourceAppSelectionSection() { const { t } = useTranslation('deployments') return (
) } function SourceSearchInput() { const { t } = useTranslation('deployments') const sourceSearchText = useAtomValue(sourceSearchTextAtom) const setSourceSearchText = useSetAtom(setSourceSearchTextAtom) return (
) } 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) return (
{sourceAppsLoading ? : sourceApps.length === 0 ? ( {t('createGuide.source.empty')} ) : (
{sourceApps.map(app => ( selectSourceApp(app)} /> ))} {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 ( ) }