feat(app): ⌘K command palette — app-wide launcher
The keyboard twin of the map's inspect panel: ⌘K (or the "Launch…" nav button) from any page. Empty query = the "Start Menu" (browsable launchable apps, local + remote, grouped by machine badge); typing searches every deployment. Enter launches the app in a new tab; per-result actions jump to it on the map (/map?focus=<id>, which the map now honors by selecting + centering) or open its Castle details. Navigation/launch only — no mutation — for v1.
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
||||
type ReactFlowInstance,
|
||||
} from "@xyflow/react"
|
||||
import "@xyflow/react/dist/style.css"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { useNavigate, useSearchParams } from "react-router-dom"
|
||||
import {
|
||||
BoxSelect,
|
||||
ExternalLink,
|
||||
@@ -429,6 +429,7 @@ export function SystemMapPage() {
|
||||
const [addExt, setAddExt] = useState(false)
|
||||
|
||||
const openProgram = useCallback((program: string) => navigate(`/programs/${program}`), [navigate])
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
// Kind lookup for handlers (which config section to write). Kept in a ref so the
|
||||
// stable callbacks below don't need it in their dep arrays.
|
||||
@@ -955,6 +956,17 @@ export function SystemMapPage() {
|
||||
setFocus(picks.length === 1 ? picks[0].id : null)
|
||||
}, [])
|
||||
|
||||
// "Go to on map" from the command palette (/map?focus=<id>): select + center it.
|
||||
useEffect(() => {
|
||||
const f = searchParams.get("focus")
|
||||
if (!f) return
|
||||
const t = setTimeout(() => {
|
||||
setFocus(f)
|
||||
rfRef.current?.fitView({ nodes: [{ id: f }], padding: 0.6, duration: 400 })
|
||||
}, 200)
|
||||
return () => clearTimeout(t)
|
||||
}, [searchParams])
|
||||
|
||||
// Remember where the user dropped a node (persist across refetches + reloads).
|
||||
const onNodeDragStop = useCallback((_e: MouseEvent | TouchEvent, _n: Node, dragged: Node[]) => {
|
||||
for (const nd of dragged) posRef.current![nd.id] = nd.position
|
||||
|
||||
Reference in New Issue
Block a user