perf(reference-data): sweep the remaining raw reads onto the session cache, ratchet to 0 (#1941)
Final consumer migration of the responsiveness plan: the 35 files still fetching fiscal periods, settings, accounts, cash accounts, dimensions or templates on their own now read lib/reference-data, and every client write site invalidates the shared cache instead of refetching locally. Settings and registries: FiscalYearsManager, FiscalPeriodEditor (period snapshotted once per company so a revalidation cannot reset dates being edited), BookingTemplatesPanel, ChartOfAccounts, ChartOfAccountsManager, EditAccountDialog, CorrectionEntryDialog, StrikeLinesDialog, InvoicePaymentAccountsSettings; the dimensions registry (DimensionsManager, DimensionCombobox, LineDimensionFields, DimensionFilter, bookkeeping/[id]) reads useDimensions and the ad-hoc fetchDimensions/fetchDimensionsCached helpers are deleted. Pages and pickers: CashAccountSelector (FyPicker-shaped restore, once per company load), use-account-names, FiscalYearGapNotice, OpeningBalancePeriodStep, BankFileConfirmStep, ImportReviewStep, the import page (invalidates accounts + periods after a SIE execute), customers list, invoices list + detail, pending, salary employee, asset dispose, year-end and periodisering pages (invalidate periods after closing), reports DimensionPnlView (its pivot picker read the wrong payload key and was always empty; it now populates), SkatteverketPanel, TemplatePicker, ArticleForm (vat_registered). Invoice dialogs and extensions: SendInvoiceDialog, PaymentBookingDialog (init reduced to the credit-note lookup + catalogue, proposal and voucher preview fire on open when cached; a local getSession replaces the network getUser for the fallback CC), InvoiceInboxWorkspace, TicWorkspace, ArcimMigrationWorkspace (invalidates after each SIE import step), enable-banking AccountPickerDialog. raw-reference-fetch ratchet: 35 -> 0 files. 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:
co-authored by
Jakob Wennberg
Claude Fable 5
parent
4560ccbfc9
commit
3ee3565d6d
@@ -23,6 +23,8 @@ import {
|
||||
} from '@/components/bookkeeping/correction-entry-description'
|
||||
import { nextLineDescriptionForAccountChange } from '@/components/bookkeeping/correction-line-description'
|
||||
import { useToast } from '@/components/ui/use-toast'
|
||||
import { useAccounts } from '@/lib/reference-data/hooks'
|
||||
import { invalidateReferenceData } from '@/lib/reference-data/invalidate'
|
||||
import { getErrorMessage } from '@/lib/errors/get-error-message'
|
||||
import { Loader2, Plus, Trash2 } from 'lucide-react'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
@@ -33,7 +35,7 @@ import {
|
||||
} from '@/lib/bookkeeping/correction-line-account'
|
||||
import { splitCreateAccountPrefill } from '@/lib/bookkeeping/create-account-prefill'
|
||||
import { loadBasCatalog, type CatalogAccount } from '@/lib/bookkeeping/bas-catalog-client'
|
||||
import type { JournalEntry, JournalEntryLine, BASAccount } from '@/types'
|
||||
import type { JournalEntry, JournalEntryLine } from '@/types'
|
||||
|
||||
interface CorrectionLine {
|
||||
account_number: string
|
||||
@@ -53,9 +55,18 @@ export default function CorrectionEntryDialog({ entry, open, onOpenChange, onCor
|
||||
const { toast } = useToast()
|
||||
const router = useRouter()
|
||||
const t = useTranslations('journal_detail')
|
||||
const [accounts, setAccounts] = useState<BASAccount[]>([])
|
||||
// The full chart (deactivated rows included) comes from the session cache
|
||||
// (lib/reference-data); only the static BAS catalogue is loaded per open,
|
||||
// and it is module-cached after the first time.
|
||||
const { accounts, isLoading: accountsLoading, error: accountsError, refresh: refreshAccounts } = useAccounts(false)
|
||||
const [catalog, setCatalog] = useState<CatalogAccount[]>([])
|
||||
const [accountsStatus, setAccountsStatus] = useState<'loading' | 'ready' | 'error'>('loading')
|
||||
const [catalogStatus, setCatalogStatus] = useState<'loading' | 'ready' | 'error'>('loading')
|
||||
const accountsStatus: 'loading' | 'ready' | 'error' =
|
||||
accountsLoading || catalogStatus === 'loading'
|
||||
? 'loading'
|
||||
: accountsError || catalogStatus === 'error'
|
||||
? 'error'
|
||||
: 'ready'
|
||||
const [lines, setLines] = useState<CorrectionLine[]>([])
|
||||
const [description, setDescription] = useState('')
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
@@ -98,26 +109,18 @@ export default function CorrectionEntryDialog({ entry, open, onOpenChange, onCor
|
||||
// Pre-fill the verifikationstext with the same auto text the server
|
||||
// would generate; only a user edit is sent along (see handleSubmit).
|
||||
setDescription(autoCorrectionDescription(entry.description))
|
||||
void fetchAccounts()
|
||||
void loadCatalog()
|
||||
}
|
||||
}, [open, entry.id]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
async function fetchAccounts() {
|
||||
setAccountsStatus('loading')
|
||||
async function loadCatalog() {
|
||||
setCatalogStatus('loading')
|
||||
try {
|
||||
const [res, basCatalog] = await Promise.all([
|
||||
fetch('/api/bookkeeping/accounts?active=false'),
|
||||
loadBasCatalog(),
|
||||
])
|
||||
if (!res.ok) throw new Error(`accounts ${res.status}`)
|
||||
const { data } = await res.json()
|
||||
setAccounts(data || [])
|
||||
setCatalog(basCatalog)
|
||||
setAccountsStatus('ready')
|
||||
setCatalog(await loadBasCatalog())
|
||||
setCatalogStatus('ready')
|
||||
} catch {
|
||||
setAccounts([])
|
||||
setCatalog([])
|
||||
setAccountsStatus('error')
|
||||
setCatalogStatus('error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,9 +172,9 @@ export default function CorrectionEntryDialog({ entry, open, onOpenChange, onCor
|
||||
// a dead end here: the rättelse can only post to accounts that exist in the
|
||||
// chart. Creating it inline keeps the half-finished rättelse intact.
|
||||
const handleAccountCreated = async (account: { account_number: string; account_name?: string }) => {
|
||||
await fetchAccounts()
|
||||
await invalidateReferenceData('ref:accounts')
|
||||
if (creatingAccountForLine != null) {
|
||||
// fetchAccounts' state update is not visible in this closure, so the
|
||||
// The refreshed cache is not visible in this closure, so the
|
||||
// fresh account's own name is passed alongside the stale sources. The
|
||||
// reactivate path reports no name, but that account is already in
|
||||
// `accounts` (the fetch includes deactivated rows).
|
||||
@@ -339,7 +342,7 @@ export default function CorrectionEntryDialog({ entry, open, onOpenChange, onCor
|
||||
{accountsStatus === 'loading' ? t('accounts_loading') : t('accounts_load_failed')}
|
||||
</span>
|
||||
{accountsStatus === 'error' && (
|
||||
<Button variant="outline" size="sm" onClick={() => void fetchAccounts()}>
|
||||
<Button variant="outline" size="sm" onClick={() => void refreshAccounts()}>
|
||||
{t('accounts_retry')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user