feat(web): командная палитра ⌘K — поиск агентов/списков/наборов и действия (ReUI c-command-7 + cmdk)

This commit is contained in:
Denozordec
2026-09-25 01:35:29 +07:00
parent 28f1f35f16
commit 3d4edbad8b
7 changed files with 448 additions and 125 deletions
+20 -6
View File
@@ -68,6 +68,8 @@ import type { Agent } from '@evofw/shared'
type AgentsSearch = {
agent?: string
view: 'cards' | 'table'
/** Открыть sheet добавления агента (из ⌘K-палитры). */
add?: boolean
}
function parseAgentsSearch(search: Record<string, unknown>): AgentsSearch {
@@ -76,7 +78,8 @@ function parseAgentsSearch(search: Record<string, unknown>): AgentsSearch {
typeof search.agent === 'string' && search.agent.length > 0
? search.agent
: undefined
return { view, agent }
const add = search.add === true
return { view, agent, add }
}
export const Route = createFileRoute('/_auth/agents/')({
@@ -101,13 +104,14 @@ function formatNames(names: string[]): string {
function AgentsPage() {
const navigate = useNavigate({ from: Route.fullPath })
const { agent: detailAgentId, view } = Route.useSearch()
const { agent: detailAgentId, view, add: addParam } = Route.useSearch()
const qc = useQueryClient()
const agentsQ = useQuery(agentsQueryOptions())
const settingsQ = useQuery(settingsQueryOptions())
const { copyToClipboard } = useCopyToClipboard()
const canWrite = useCan()('fw:agents:write')
const [createOpen, setCreateOpen] = useState(false)
const [createOpenState, setCreateOpenState] = useState(false)
const createOpen = createOpenState || addParam === true
const [deleteAgentId, setDeleteAgentId] = useState<string | null>(null)
const [approveAllOpen, setApproveAllOpen] = useState(false)
const [bulkDeleteIds, setBulkDeleteIds] = useState<string[] | null>(null)
@@ -130,6 +134,10 @@ function AgentsPage() {
next.agent !== undefined
? next.agent || undefined
: base.agent,
add:
next.add !== undefined
? next.add || undefined
: base.add,
} satisfies AgentsSearch
},
replace: true,
@@ -463,7 +471,7 @@ function AgentsPage() {
icon: <Plus aria-hidden />,
iconClassName: 'text-primary [&_svg]:text-current',
badgeLabel: 'Открыть',
onSelect: () => setCreateOpen(true),
onSelect: () => setCreateOpenState(true),
},
{
id: 'pending',
@@ -568,7 +576,7 @@ function AgentsPage() {
)
const addButton = canWrite ? (
<Button size="sm" onClick={() => setCreateOpen(true)}>
<Button size="sm" onClick={() => setCreateOpenState(true)}>
<Plus data-icon="inline-start" />
Добавить агента
</Button>
@@ -726,7 +734,13 @@ function AgentsPage() {
</QueryState>
)}
<AddAgentSheet open={createOpen} onOpenChange={setCreateOpen} />
<AddAgentSheet
open={createOpen}
onOpenChange={(open) => {
setCreateOpenState(open)
if (!open && addParam) setSearch({ add: false })
}}
/>
<AgentDetailSheet
agentId={detailAgentId ?? null}