feat(observabilidade): debounce search + row clickable inteira
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export interface Filters {
|
||||
days: number
|
||||
@@ -18,6 +18,18 @@ interface Props {
|
||||
|
||||
export function FilterBar({ initial, projects, tools, skills, onChange }: Props) {
|
||||
const [f, setF] = useState<Filters>(initial)
|
||||
const [qLocal, setQLocal] = useState<string>(initial.q)
|
||||
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => {
|
||||
if (qLocal !== f.q) {
|
||||
const next = { ...f, q: qLocal }
|
||||
setF(next)
|
||||
onChange(next)
|
||||
}
|
||||
}, 300)
|
||||
return () => clearTimeout(t)
|
||||
}, [qLocal])
|
||||
|
||||
function update(partial: Partial<Filters>) {
|
||||
const next = { ...f, ...partial }
|
||||
@@ -81,8 +93,8 @@ export function FilterBar({ initial, projects, tools, skills, onChange }: Props)
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Pesquisar no prompt inicial…"
|
||||
value={f.q}
|
||||
onChange={(e) => update({ q: e.target.value })}
|
||||
value={qLocal}
|
||||
onChange={(e) => setQLocal(e.target.value)}
|
||||
className="flex-1 min-w-[200px] bg-slate-900 border border-white/10 rounded px-3 py-2 text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import type { SessionMeta } from '../../../api/types/session'
|
||||
|
||||
function formatDuration(sec: number | null): string {
|
||||
@@ -26,16 +26,18 @@ interface Props {
|
||||
}
|
||||
|
||||
export function SessionRow({ session }: Props) {
|
||||
const navigate = useNavigate()
|
||||
const when = new Date(session.started_at).toLocaleString('pt-PT', { dateStyle: 'short', timeStyle: 'short' })
|
||||
return (
|
||||
<tr className="border-b border-white/5 hover:bg-white/5">
|
||||
<tr
|
||||
className="border-b border-white/5 hover:bg-white/5 cursor-pointer"
|
||||
onClick={() => navigate(`/sessions/${session.session_id}`)}
|
||||
>
|
||||
<td className="px-3 py-2 text-sm text-slate-300">{when}</td>
|
||||
<td className="px-3 py-2 text-sm text-slate-400">{session.project_slug}</td>
|
||||
<td className="px-3 py-2 text-sm text-slate-200">
|
||||
<Link to={`/sessions/${session.session_id}`} className="hover:underline">
|
||||
{session.first_prompt?.slice(0, 80) ?? '—'}
|
||||
{(session.first_prompt?.length ?? 0) > 80 ? '…' : ''}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-sm text-slate-400">{formatDuration(session.duration_sec)}</td>
|
||||
<td className="px-3 py-2 text-sm text-right text-slate-400">{session.event_count}</td>
|
||||
|
||||
Reference in New Issue
Block a user