import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useNavigate } from 'react-router-dom' import { listInitiatives } from '../api/initiatives.js' import { listWorkspaceOpenActions } from '../api/workspace.js' import { useProgramScope } from '../context/ProgramScopeContext.jsx' import { loadRecentObjects } from '../utils/recentObjects.js' import { actionPath, gatePath, initiativeCatalogPath, projectPath, scopedPath, } from '../utils/routes.js' const TYPE_LABELS = { action: 'Arbeitspaket', project: 'Projekt', gate: 'Gate', initiative: 'Vorhaben', } function matchQuery(text, query) { return (text || '').toLowerCase().includes(query.toLowerCase()) } export function QuickJump() { const navigate = useNavigate() const { applyFromInitiative } = useProgramScope() const [open, setOpen] = useState(false) const [query, setQuery] = useState('') const [initiatives, setInitiatives] = useState([]) const [actions, setActions] = useState([]) const [recent, setRecent] = useState([]) const rootRef = useRef(null) useEffect(() => { let cancelled = false Promise.all([ listInitiatives().catch(() => []), listWorkspaceOpenActions().catch(() => []), ]).then(([initData, actionData]) => { if (cancelled) return setInitiatives(initData) setActions(actionData) }) return () => { cancelled = true } }, []) useEffect(() => { setRecent(loadRecentObjects()) }, [open]) useEffect(() => { function onDocClick(e) { if (rootRef.current && !rootRef.current.contains(e.target)) { setOpen(false) } } document.addEventListener('mousedown', onDocClick) return () => document.removeEventListener('mousedown', onDocClick) }, []) const results = useMemo(() => { const q = query.trim() if (!q) return [] const hits = [] for (const item of initiatives) { if (matchQuery(item.title, q)) { hits.push({ key: `initiative-${item.id}`, label: item.title, meta: 'Vorhaben', href: scopedPath('/control/status', { initiativeId: item.id }), onSelect: () => applyFromInitiative(item.id), }) } } for (const action of actions) { if (matchQuery(action.title, q)) { hits.push({ key: `action-${action.id}`, label: action.title, meta: 'Arbeitspaket', href: actionPath(action.id), }) } } return hits.slice(0, 8) }, [query, initiatives, actions, applyFromInitiative]) const go = useCallback( (href, onSelect) => { if (onSelect) onSelect() navigate(href) setOpen(false) setQuery('') }, [navigate], ) return (