import { useState, useEffect } from 'react' import { Listbox } from '@headlessui/react' import { getObjects, getObjectDefs, createObject } from '../api' import { formatRelativeTime } from '../utils' import { Spinner, EmptyState, Pagination } from './Common' export default function Objects() { const [data, setData] = useState>([]) const [types, setTypes] = useState([]) const [filter, setFilter] = useState('') const [error, setError] = useState('') const [loading, setLoading] = useState(true) const [total, setTotal] = useState(0) const [limit, setLimit] = useState(50) const [offset, setOffset] = useState(0) const [showCreate, setShowCreate] = useState(false) const [createType, setCreateType] = useState('') const [creating, setCreating] = useState(false) const [createMsg, setCreateMsg] = useState<{ ok: boolean; text: string } | null>(null) useEffect(() => { getObjectDefs() .then((res) => setTypes(res.object_defs.map((d) => d.name))) .catch(() => {}) }, []) useEffect(() => { setLoading(true) getObjects(filter || undefined, limit, offset) .then((res) => { setData(res.objects) setTotal(res.total) }) .catch((e) => setError(e.message)) .finally(() => setLoading(false)) }, [filter, limit, offset]) const handleFilterChange = (newFilter: string) => { setFilter(newFilter) setOffset(0) // reset to first page } const refresh = () => { setLoading(true) getObjects(filter || undefined, limit, offset) .then((res) => { setData(res.objects); setTotal(res.total) }) .catch((e) => setError(e.message)) .finally(() => setLoading(false)) } const handleCreate = async () => { if (!createType) return setCreating(true) setCreateMsg(null) try { const obj = await createObject(createType) setCreateMsg({ ok: true, text: `Created object #${obj.id} (${obj.type})` }) setShowCreate(false) setCreateType('') refresh() setTimeout(() => setCreateMsg(null), 3000) } catch (err: any) { setCreateMsg({ ok: false, text: err.message || 'Failed to create object' }) } finally { setCreating(false) } } if (loading) return if (error) return
Error: {error}
return (

Objects

{!showCreate ? ( ) : (
)} {createMsg && ( {createMsg.text} )}
{filter || 'All Types'} `cursor-pointer select-none px-4 py-2 transition-colors ${ active ? 'bg-blue-600 text-white' : 'text-gray-100' }` } > {({ selected }) => All Types} {types.map((t) => ( `cursor-pointer select-none px-4 py-2 transition-colors ${ active ? 'bg-blue-600 text-white' : 'text-gray-100' }` } > {({ selected }) => {t}} ))}
{data.length === 0 ? ( ) : ( {data.map((obj, i) => ( ))}
ID Type Created
{obj.id} {obj.type} {formatRelativeTime(obj.created_at)}
)}
) }