'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 '../../shared/components/empty-state' import { useInfiniteScroll } from '../../shared/hooks/use-infinite-scroll' import { deploymentsListHasFilterAtom, deploymentsListQueryAtom, deploymentsListRowsAtom, deploymentsListShowEmptyStateAtom, deploymentsListShowErrorStateAtom, 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 hasFilter = useAtomValue(deploymentsListHasFilterAtom) const [_keywords, setKeywords] = useQueryState('keywords', keywordsQueryState) const [_envFilter, setEnvFilter] = useQueryState('env', envFilterQueryState) 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 showErrorState = useAtomValue(deploymentsListShowErrorStateAtom) const showEmptyState = useAtomValue(deploymentsListShowEmptyStateAtom) const { rootRef, sentinelRef } = useInfiniteScroll(deploymentsListQuery) return (
{showSkeleton ? : showErrorState ? {t('common.loadFailed')} : showEmptyState ? : appInstanceSummaries.map(summary => ( ))} {deploymentsListQuery.isFetchingNextPage && }
) }