refactor(agent): keep the assistant in the nav, FAB and underlag flow only (#1557)

The founder wants the scattered per-page assistant buttons gone: the
assistant is reachable from the nav and the floating tab everywhere, so
in-page duplicates were noise. Removed the AgentSparkleButton call sites
(year-end, verifikat detail, supplier invoice detail, invoice editor)
and the now-orphaned component, the soft hand-off link in the Ny
verifikat modal (plus its i18n keys), and the transaction-row overflow
item. Kept: nav entry, floating tab, the Dokumentinkorg flow, and the
sanctioned "Skapa med assistent" split-button mode on /bookkeeping
(design.md convention 14).

The command palette's hand-off entries hardcoded the agent name "Anna";
they now use the identity from AgentSheetProvider like every other
affordance, and hide until agent onboarding is done (same gate as the
FAB).

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-13 11:19:45 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5
parent 5453f11330
commit 1e9f245f7c
10 changed files with 27 additions and 165 deletions
+25 -19
View File
@@ -26,6 +26,7 @@ import {
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { useCompany } from '@/contexts/CompanyContext'
import { useAgentSheet } from '@/components/agent/AgentSheetProvider'
import { requiredCapabilityForExtension } from '@/lib/entitlements/keys'
type Entry = {
@@ -93,6 +94,7 @@ export default function CommandPalette({ initialOpen = false }: { initialOpen?:
const [activeIndex, setActiveIndex] = useState(0)
const inputRef = useRef<HTMLInputElement>(null)
const { capabilities } = useCompany()
const { identity } = useAgentSheet()
// Drop entries that jump to a paywalled extension workspace the active
// company can't reach (e.g. the AI-only Dokumentinkorg). The page itself is
@@ -143,27 +145,31 @@ export default function CommandPalette({ initialOpen = false }: { initialOpen?:
return q ? visible.filter(e => matches(e, q)) : visible.slice(0, 6)
}, [q, allowedByCapability])
const annaFallback: Entry | null = q && filteredActions.length === 0 && filteredPages.length === 0
? {
id: 'anna-fallback',
label: `Fråga Anna: "${query.trim()}"`,
icon: Wand2,
href: `/chat/new?prompt=${encodeURIComponent(query.trim())}`,
}
: q
// The hand-off-to-assistant entries use the agent name the user chose in
// /onboarding/agent, and hide entirely until that onboarding is done: the
// same gate as the nav entry and the FAB.
const assistantName = identity.displayName?.trim() || 'assistenten'
const assistantFallback: Entry | null = !identity.isVerified || !q
? null
: filteredActions.length === 0 && filteredPages.length === 0
? {
id: 'anna-followup',
label: `Fråga Anna istället: "${query.trim()}"`,
id: 'assistant-fallback',
label: `Fråga ${assistantName}: "${query.trim()}"`,
icon: Wand2,
href: `/chat/new?prompt=${encodeURIComponent(query.trim())}`,
}
: {
id: 'assistant-followup',
label: `Fråga ${assistantName} istället: "${query.trim()}"`,
icon: Wand2,
href: `/chat/new?prompt=${encodeURIComponent(query.trim())}`,
}
: null
const flatEntries: Entry[] = [
...(annaFallback && filteredActions.length === 0 && filteredPages.length === 0 ? [annaFallback] : []),
...(assistantFallback && filteredActions.length === 0 && filteredPages.length === 0 ? [assistantFallback] : []),
...filteredActions,
...filteredPages,
...(annaFallback && (filteredActions.length > 0 || filteredPages.length > 0) ? [annaFallback] : []),
...(assistantFallback && (filteredActions.length > 0 || filteredPages.length > 0) ? [assistantFallback] : []),
]
function commit(entry: Entry) {
@@ -244,13 +250,13 @@ export default function CommandPalette({ initialOpen = false }: { initialOpen?:
})}
</Section>
)}
{annaFallback && (
<Section title="Anna">
{assistantFallback && (
<Section title={assistantName}>
<Row
entry={annaFallback}
active={flatEntries.indexOf(annaFallback) === activeIndex}
onSelect={() => commit(annaFallback)}
onHover={() => setActiveIndex(flatEntries.indexOf(annaFallback))}
entry={assistantFallback}
active={flatEntries.indexOf(assistantFallback) === activeIndex}
onSelect={() => commit(assistantFallback)}
onHover={() => setActiveIndex(flatEntries.indexOf(assistantFallback))}
/>
</Section>
)}