'use client' import type { ReactNode } from 'react' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { Input } from '@langgenius/dify-ui/input' import { useAtomValue } from 'jotai' import { debounce, useQueryState } from 'nuqs' import { useTranslation } from 'react-i18next' import { StudioListHeader } from '@/app/components/apps/studio-list-header' import { SkeletonRectangle } from '@/app/components/base/skeleton' import { DeploymentEmptyState, DeploymentStateMessage } from '../../components/empty-state' import { useInfiniteScroll } from '../../shared/hooks/use-infinite-scroll' import { deploymentsListHasFilterAtom, deploymentsListQueryAtom, deploymentsListRowsAtom, deploymentsListShowEmptyStateAtom, deploymentsListShowSkeletonAtom, envFilterQueryState, keywordsQueryState, } from '../state' import { CreateDeploymentButton } from './create-deployment-button' import { EnvironmentFilter } from './environment-filter' import { InstanceCard } from './instance-card' const INSTANCE_CARD_SKELETON_KEYS = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'] function DeploymentsListState({ children }: { children: ReactNode }) { return {children} } function DeploymentsListEmpty() { const { t } = useTranslation('deployments') const hasAtomFilter = useAtomValue(deploymentsListHasFilterAtom) const [keywords, setKeywords] = useQueryState('keywords', keywordsQueryState) const [envFilter, setEnvFilter] = useQueryState('env', envFilterQueryState) const hasFilter = hasAtomFilter || Boolean(keywords.trim()) || Boolean(envFilter) function clearFilters() { void setKeywords(null) void setEnvFilter(null) } return ( {t('list.clearFilters')} ) : } /> ) } function InstanceCardSkeleton() { return (
) } function DeploymentsListSkeleton() { return INSTANCE_CARD_SKELETON_KEYS.map(key => ( )) } function DeploymentsSearchInput({ className }: { className?: string }) { const { t } = useTranslation('deployments') const [keywords, setKeywords] = useQueryState('keywords', keywordsQueryState) function handleKeywordsChange(next: string) { void setKeywords(next.trim() ? next : null, { limitUrlUpdates: next.trim() ? debounce(300) : undefined, shallow: false, }) } return (
handleKeywordsChange(e.target.value)} /> {keywords && ( )}
) } function DeploymentsListControls() { const { t } = useTranslation() return (

{t('menus.deployments', { ns: 'common' })}

)} >
) } export function DeploymentsListShell() { const { t } = useTranslation('deployments') const deploymentsListQuery = useAtomValue(deploymentsListQueryAtom) const appInstanceSummaries = useAtomValue(deploymentsListRowsAtom) const showSkeleton = useAtomValue(deploymentsListShowSkeletonAtom) const showEmptyState = useAtomValue(deploymentsListShowEmptyStateAtom) const { isError, isFetchingNextPage, } = deploymentsListQuery const { rootRef, sentinelRef } = useInfiniteScroll(deploymentsListQuery) return (
{showSkeleton ? : isError ? {t('common.loadFailed')} : appInstanceSummaries.length === 0 ? : appInstanceSummaries.map(summary => ( ))} {isFetchingNextPage && }
) }