Add a global search, and stop the sidebar logo squeezing
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Successful in 3m14s
Playwright Tests / test-playwright (2, 2) (push) Successful in 1m53s
pre-commit / pre-commit (push) Failing after 2m13s
Test Backend / test-backend (push) Successful in 2m38s
Compose Smoke Test / test-compose (push) Successful in 38s
Playwright Tests / merge-reports (push) Successful in 1m8s
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Successful in 3m14s
Playwright Tests / test-playwright (2, 2) (push) Successful in 1m53s
pre-commit / pre-commit (push) Failing after 2m13s
Test Backend / test-backend (push) Successful in 2m38s
Compose Smoke Test / test-compose (push) Successful in 38s
Playwright Tests / merge-reports (push) Successful in 1m8s
`GET /api/v1/search/` hands the client one flat index of everything worth jumping to — flows and the nodes inside them, dashboards and the widgets on them, panels, secrets, modules, workers and alert channels — and cmdk matches it in the browser, so results narrow while typing without a round trip per keystroke. A node hit is the one thing no list endpoint could answer: it opens its flow with that node in focus. The panel is reached from **Search** above Documentation in the sidebar, or ⌘K anywhere. The flow canvas palette moves to ⌘P, being the narrower of the two. The panels dialog gains an address (`/dashboards?panels`) so a panel hit has somewhere to land, and the sidebar logo gets `shrink-0`: the rail's width animates while the logo is already back, and a flex item short of room is squeezed rather than clipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vGH7jqcXxWKP9wZFPyVdU
This commit is contained in:
@@ -35,8 +35,15 @@ import {
|
||||
import useCustomToast from "@/hooks/useCustomToast"
|
||||
import { handleError } from "@/utils"
|
||||
|
||||
type Search = { panels?: boolean }
|
||||
|
||||
export const Route = createFileRoute("/_layout/dashboards/")({
|
||||
component: Dashboards,
|
||||
// The panels dialog has no route of its own, so the address is how anything
|
||||
// else — the global search among them — arrives at it.
|
||||
validateSearch: (search: Record<string, unknown>): Search => ({
|
||||
panels: search.panels === true || search.panels === "true" || undefined,
|
||||
}),
|
||||
})
|
||||
|
||||
function Dashboards() {
|
||||
@@ -47,8 +54,12 @@ function Dashboards() {
|
||||
const [name, setName] = useState("")
|
||||
const [search, setSearch] = useState("")
|
||||
const [dialogOpen, setDialogOpen] = useState(false)
|
||||
const [panelsOpen, setPanelsOpen] = useState(false)
|
||||
const [deleteOpen, setDeleteOpen] = useState(false)
|
||||
// Which screens exist is a question with an address, so anything can link to
|
||||
// it — the global search lands a panel here.
|
||||
const { panels: panelsOpen } = Route.useSearch()
|
||||
const setPanelsOpen = (open: boolean) =>
|
||||
navigate({ to: "/dashboards", search: open ? { panels: true } : {} })
|
||||
|
||||
const create = useMutation({
|
||||
mutationFn: (dashboard: string) =>
|
||||
@@ -110,7 +121,7 @@ function Dashboards() {
|
||||
|
||||
{/* Its own root rather than a nested one: which screens exist is a
|
||||
different question from which dashboards do. */}
|
||||
<Dialog open={panelsOpen} onOpenChange={setPanelsOpen}>
|
||||
<Dialog open={panelsOpen ?? false} onOpenChange={setPanelsOpen}>
|
||||
<PanelsDialog />
|
||||
</Dialog>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user