import { Icon } from '#/components/icon' import { Badge } from '#/components/ui/badge' import { Button } from '#/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '#/components/ui/dropdown-menu' import { flattenResearchPages, useResearchFeed, } from '#/features/platforms/use-research-feed' import { PostLoadError } from '#/features/posts/use-post-feed' import { citationUrlKey } from '#/features/research/citation-url' import type { CitationTarget } from '#/features/research/use-citation-navigation' import { PlatformIcon } from '../platforms/platform-icon' import { type ColumnRegistry, useRegisterColumn } from './column-tools' import type { DeckColumn } from './model' import { ResearchPostCard } from './research-post-card' import { describeSource } from './source-description' export function ResearchColumn({ column, connectionLabel, onEdit, onRemove, onMove, first, last, registry, citation, }: { column: DeckColumn connectionLabel?: string onEdit: () => void onRemove: () => void onMove: (direction: -1 | 1) => void first: boolean last: boolean registry: ColumnRegistry citation?: CitationTarget }) { const query = useResearchFeed(column) useRegisterColumn(registry, column, query) const posts = flattenResearchPages(query.data?.pages ?? []) const citedKey = citation ? citationUrlKey(citation.post.url) : null const visiblePosts = citation && !posts.some((post) => citationUrlKey(post.url) === citedKey) ? [citation.post, ...posts] : posts const error = query.error instanceof PostLoadError ? query.error.detail : { message: '投稿を取得できませんでした。', retryable: true } const headingId = `column-${column.id}` const sourceDescription = describeSource(column.source) return (

{column.title}

} > 編集 onMove(-1)} disabled={first} aria-label={`${column.title}を左へ`} > ← 左へ移動 onMove(1)} disabled={last} aria-label={`${column.title}を右へ`} > 右へ移動 → カラムを削除
{connectionLabel ?? '接続が見つかりません'} {sourceDescription.label}

{sourceDescription.query}

{query.isFetching ? '投稿を取得しています…' : `${posts.length}件を読み込み済み`}

{visiblePosts.map((post) => ( ))} {query.isError ? (

{error.message}

{error.retryable ? ( ) : null}
) : null} {!query.isPending && !query.isError && visiblePosts.length === 0 ? (

条件に一致する投稿はありません。

) : null} {query.hasNextPage && !query.isFetchNextPageError ? (
) : null} {!query.isPending && !query.isError && posts.length > 0 && !query.hasNextPage ? (

これ以上の投稿はありません。

) : null}
) }