import { useQuery } from '@tanstack/react-query' import { useEffect, useRef, useState } from 'react' import { Button } from '@/components/ui/button' import { countsUseLatest } from '@/lib/counts' import { fetchCountsCandidates } from '@/lib/countsDefinitions' import { countsKeys } from '@/lib/queryKeys' import { useLocale } from '@/lib/useLocale' import { useUITranslation } from '@/lib/useUITranslation' import { inputClass } from '@/lib/utils' import type { DialogueFormControls } from '@/lib/dialogues/useDialogue' import type { CountsCandidate, CountsDefinition, CountsFieldMetadata } from '@/lib/countsDefinitions' const CountsCandidatePicker = ( { field, definition, params, initial, maximum, controls, save }: { field: CountsFieldMetadata; params: URLSearchParams definition: CountsDefinition initial: (string | number | boolean)[]; maximum: number controls: DialogueFormControls; save: (values: string[]) => void }, ) => { const { label, message } = useUITranslation ('counts') const locale = useLocale () const [selected, setSelected] = useState (() => new Set (initial.map (String))) const [columns, setColumns] = useState (['id', 'name', 'category', 'kind']) const [draft, setDraft] = useState ('') const [search, setSearch] = useState ('') const [category, setCategory] = useState ('') const [page, setPage] = useState (1) const point = useRef (params.get ('execution_at')) const request = new URLSearchParams ({ field: field.key, query: search, page: String (page) }) for (const key of ['timezone', 'at', 'execution_at']) if (params.has (key)) request.set (key, params.get (key)!) if (countsUseLatest (params)) request.delete ('at') if (category) request.set ('category', category) const dynamic = field.candidateSource === 'tags' const { data, isFetching: fetching, isError: errorFlg } = useQuery ({ queryKey: countsKeys.candidates (request.toString (), locale), enabled: dynamic, queryFn: ({ signal }) => { const pinned = new URLSearchParams (request) if (point.current != null) pinned.set ('execution_at', point.current) return fetchCountsCandidates (pinned, locale, signal) }, retry: false }) useEffect (() => { if (data != null) point.current = data.executionAt }, [data]) useEffect (() => { controls.setActions ([{ label: label ('counts:pattern.selection'), onSelect: () => save ([...selected]) }]) }, [controls, label, save, selected]) const fixed: CountsCandidate[] = (field.choices ?? []).map (choice => ({ value: choice.value, name: message (choice.label).text })) const rows = dynamic ? data?.rows ?? [] : fixed.filter (row => row.name?.includes (search)) const headings: Record = { id: 'columns.resourceId', name: 'columns.name', category: 'common:categoryLabel', kind: 'columns.kind' } const available = dynamic ? ['id', 'name', 'category', 'kind'] : ['name'] const visible = available.filter (column => columns.includes (column)) const categories = definition.filterFields?.find (field => field.candidateSource === 'categories')?.choices ?? [] const cell = (row: CountsCandidate, column: string) => { if (column === 'category') return row.category == null ? '' : message (`common:categories.${row.category}`).text if (column === 'kind') return row.kind == null ? '' : message (`kinds.${row.kind}`).text return column === 'id' ? row.id : row.name } return
setDraft (event.target.value)} onKeyDown={event => { if (event.key !== 'Enter') return event.preventDefault () setSearch (draft) setPage (1) }}/>
{dynamic && }
{label ('counts:pattern.columns')} {available.map (column => )}

{label ('counts:pattern.value')}{':'} {label (dynamic ? 'columns.resourceId' : 'common:categoryLabel')}

{errorFlg &&

{label ('common:fetchError')}

}
{visible.map (column => )} {rows.map (row => {visible.map (column => )} )}
{label ('counts:pattern.selection')} {label (headings[column])}
= maximum} onChange={event => setSelected (previous => { const next = new Set (previous) if (event.target.checked) next.add (row.value) else next.delete (row.value) return next })}/> {cell (row, column)}
{dynamic &&
{page}
}
} export default CountsCandidatePicker