fix(banking): harden PSD2 loading, error, and refresh states (#934)
Fixes loading/error/refresh-state gaps across the Enable Banking (PSD2) surfaces: - Delete the dead post-OAuth bank_connected sync flow + 9 orphaned i18n keys. - Surface fetch failures instead of empty/false-healthy states (settings panel error card, BankSelector non-OK guard, chip hidden on error). - Stop the full-panel spinner flash on refetch; clear the spinner in finally. - Client-side sync/backfill timeouts + live elapsed counter with a grace-period unlock so a slow bank can't trap the modal. - Broadcast a bank-sync signal so the transactions chip refetches after a manual sync. - Consolidate the import page onto the shared banking panel (also removes the core -> @/extensions import-rule violation) and standardize spinners. - Surface previously silent chart/fiscal-year fetch failures in the account picker. - Review fixes: cancellation guard on the deferred bank_error microtask; key the sync-progress dialog per attempt to reset its elapsed timer.
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { createClient } from '@/lib/supabase/client'
|
||||
import { notifyBankSyncUpdated } from '@/lib/transactions/bank-sync-signal'
|
||||
import { useCompany, useCapability } from '@/contexts/CompanyContext'
|
||||
import { CAPABILITY } from '@/lib/entitlements/keys'
|
||||
|
||||
@@ -129,6 +130,9 @@ export default function BankSyncNowButton() {
|
||||
? t('bank_sync_new_since_last_visit_one')
|
||||
: t('bank_sync_new_since_last_visit_many', { count: data.imported ?? 0 }),
|
||||
})
|
||||
// Tell the neighbouring status chip to refetch so it doesn't keep showing
|
||||
// the pre-sync "synced Nd ago" until a hard reload.
|
||||
notifyBankSyncUpdated()
|
||||
router.refresh()
|
||||
} catch (error) {
|
||||
toast({
|
||||
|
||||
@@ -5,6 +5,7 @@ import Link from 'next/link'
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { AlertTriangle, RefreshCw } from 'lucide-react'
|
||||
import { createClient } from '@/lib/supabase/client'
|
||||
import { onBankSyncUpdated } from '@/lib/transactions/bank-sync-signal'
|
||||
import { useCompany } from '@/contexts/CompanyContext'
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -72,17 +73,31 @@ export default function BankSyncStatusChip() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!company?.id) return
|
||||
const companyId = company.id
|
||||
let cancelled = false
|
||||
const supabase = createClient()
|
||||
supabase
|
||||
.from('bank_connections')
|
||||
.select('id, status, last_synced_at')
|
||||
.eq('company_id', company.id)
|
||||
.then(({ data }) => {
|
||||
if (!cancelled) setRows(data ?? [])
|
||||
})
|
||||
|
||||
const load = () => {
|
||||
supabase
|
||||
.from('bank_connections')
|
||||
.select('id, status, last_synced_at')
|
||||
.eq('company_id', companyId)
|
||||
.then(({ data, error }) => {
|
||||
if (cancelled) return
|
||||
// On error keep the chip hidden (empty rows) rather than rendering a
|
||||
// false "healthy" state from stale data.
|
||||
setRows(error ? [] : (data ?? []))
|
||||
})
|
||||
}
|
||||
|
||||
load()
|
||||
// Refetch when a manual "Sync now" / reconnect elsewhere on the page
|
||||
// changes the connections, so the chip doesn't keep showing "synced 2d ago".
|
||||
const unsubscribe = onBankSyncUpdated(load)
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
unsubscribe()
|
||||
}
|
||||
}, [company?.id])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user