02a5d10538
* refactor(ui): migrate remaining inline pages to the concept design language Catch-up pass for surfaces the 2026-07 UI migration missed: - Bankavstämning: de-boxed toolbar, dry-table sections (preview, omatchade verifikationer, ignorerade, matchade), instructional copy moved behind the page "?" (HelpPopover via FocusedReport, sv+en), AttnLine for the dirty- dates hint, EmptyState for the blank page, space-y-8 rhythm. - Report detail views (trial balance, income statement, balance sheet, resultat-/balansrapport, reskontror, huvudbok, grundbok, dimension-P&L): shared Skeleton/Error/EmptyState shells, border-2 totals bands flattened to hairline cards with font-display tabular-nums headline numbers, ReportSectionTable rebuilt on the group-band idiom, font-mono money -> tabular-nums, house tablist for Förenklad/Detaljerad, GL filter de-boxed onto Input primitives, verdicts follow chips-mark-exceptions. - Extensions browse: PageHeader, locked section headers, rounded-lg secondary icon tiles, flat hover shift on cards, p-6 content. - Återkommande fakturor: page-level list moved off ui/table onto dry-table with hover-revealed quiet row actions; Skeleton loading. - Help: EmptyState for no search hits, flat hover shift on resource links. - Chart of accounts: spinner loading blocks -> Skeleton rows. - Kunskap graph + salary calendar popovers: rounded-lg, Input/Textarea primitives instead of hand-rolled shadow-sm controls. No logic, endpoint, or data changes. Verified via sandbox screenshots; lint 0 errors, 13214 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): review triage: skip empty industry sectors, keyboard path to schedule edit Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import { useTranslations } from 'next-intl'
|
|
import { Skeleton } from '@/components/ui/skeleton'
|
|
import { EmptyState } from '@/components/ui/empty-state'
|
|
import { Brain } from 'lucide-react'
|
|
import type { LedgerContext } from '@/lib/agent-context/ledger-context'
|
|
import type { DeepLedgerContext } from '@/lib/agent-context/ledger-deep'
|
|
import type { AgentCompetence } from '@/lib/agent-context/agent-competence'
|
|
import { AgentKnowledgeView } from './AgentKnowledgeView'
|
|
|
|
interface KnowledgePayload {
|
|
context: LedgerContext
|
|
deep: DeepLedgerContext
|
|
competence: AgentCompetence
|
|
companyName: string
|
|
}
|
|
|
|
/**
|
|
* Client wrapper for the "Vad din agent vet" view inside the assistant
|
|
* settings hub. Fetches the ledger context from /api/agent/knowledge on mount
|
|
* (lazy: this panel only renders when the Kunskap tab is opened, since Radix
|
|
* unmounts inactive tabs). Fetching client-side rather than via a server prop
|
|
* is deliberate: the settings sections mount as propless components in BOTH
|
|
* the full-page rail and the routed settings modal, so a server fetch wouldn't
|
|
* reach the modal.
|
|
*/
|
|
export function AgentKnowledgePanel() {
|
|
const t = useTranslations('agentKnowledge')
|
|
const [payload, setPayload] = useState<KnowledgePayload | null>(null)
|
|
const [error, setError] = useState(false)
|
|
|
|
useEffect(() => {
|
|
let cancelled = false
|
|
fetch('/api/agent/knowledge')
|
|
.then((res) => {
|
|
if (!res.ok) throw new Error(`knowledge fetch failed: ${res.status}`)
|
|
return res.json()
|
|
})
|
|
.then((json) => {
|
|
if (!cancelled) setPayload(json.data as KnowledgePayload)
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) setError(true)
|
|
})
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [])
|
|
|
|
if (error) {
|
|
return (
|
|
<EmptyState
|
|
icon={Brain}
|
|
title={t('load_error_title')}
|
|
description={t('load_error_description')}
|
|
/>
|
|
)
|
|
}
|
|
|
|
if (!payload) {
|
|
// Mirrors the loaded layout: graph hero, section header, two profile cards.
|
|
return (
|
|
<div className="space-y-8">
|
|
<Skeleton className="h-96 w-full rounded-lg" />
|
|
<div className="space-y-4">
|
|
<Skeleton className="h-4 w-40" />
|
|
<div className="grid gap-4 md:grid-cols-2">
|
|
<Skeleton className="h-48 w-full rounded-lg" />
|
|
<Skeleton className="h-48 w-full rounded-lg" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<AgentKnowledgeView
|
|
context={payload.context}
|
|
deep={payload.deep}
|
|
competence={payload.competence}
|
|
companyName={payload.companyName}
|
|
/>
|
|
)
|
|
}
|