'use client' import type { SnippetPublishStatus } from './components/snippet-publish-status-filter' import type { SnippetListItem } from '@/types/snippet' import { cn } from '@langgenius/dify-ui/cn' import { Input } from '@langgenius/dify-ui/input' import { useDebounce } from 'ahooks' import { useAtomValue } from 'jotai' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { workspacePermissionKeysAtom } from '@/context/permission-state' import { currentWorkspaceLoadingAtom } from '@/context/workspace-state' import { TagFilter } from '@/features/tag-management/components/tag-filter' import useDocumentTitle from '@/hooks/use-document-title' import dynamic from '@/next/dynamic' import Link from '@/next/link' import { useInfiniteSnippetList } from '@/service/use-snippets' import CreatorsFilter from '../apps/creators-filter' import Empty from '../apps/empty' import { StudioListHeader } from '../apps/studio-list-header' import { canAccessSnippets } from '../snippets/utils/permission' import SnippetCard from './components/snippet-card' import SnippetCreateButton from './components/snippet-create-button' import SnippetPublishStatusFilter from './components/snippet-publish-status-filter' import { SNIPPET_LIST_SEARCH_DEBOUNCE_MS } from './constants' import { useSnippetsQueryState } from './hooks/use-snippets-query-state' const TagManagementModal = dynamic( () => import('@/features/tag-management/components/tag-management-modal').then( (mod) => mod.TagManagementModal, ), { ssr: false, }, ) const SNIPPET_CARD_SKELETON_KEYS = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'] const toSnippetPublishedQuery = (publishStatus: SnippetPublishStatus) => { if (publishStatus === 'published') return true if (publishStatus === 'draft') return false return undefined } type SnippetCardSkeletonProps = { count: number } const SnippetCardSkeleton = ({ count }: SnippetCardSkeletonProps) => { return ( <> {SNIPPET_CARD_SKELETON_KEYS.slice(0, count).map((key) => (
))} > ) } const SnippetList = () => { const { t } = useTranslation() const isLoadingCurrentWorkspace = useAtomValue(currentWorkspaceLoadingAtom) const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom) // oxlint-disable-next-line eslint-react/use-state -- custom URL query hook, not React.useState const { query: { tagIDs, keywords, creatorIDs }, setKeywords, setTagIDs, setCreatorIDs, } = useSnippetsQueryState() const debouncedKeywords = useDebounce(keywords, { wait: SNIPPET_LIST_SEARCH_DEBOUNCE_MS }) const containerRef = useRef