Fetch dashboard panels independently
Load dashboard widgets concurrently so one slow or failed request never blocks the rest.Description
Requirements
Export a DashboardPanels component from src/App.tsx.
Start every declared panel loader during the initial effect without serial waits.
Show loading state independently for each unresolved panel.
Render a fulfilled panel immediately while other panel requests remain pending.
Keep one rejected panel from hiding or replacing successful sibling panels.
Retry only the selected failed panel with a fresh request signal.
Keep rendered panels in the same order as the input definitions regardless of settlement order.
Abort every outstanding panel request when its definition is removed or the component unmounts.
Partial success
Revenue resolves while Activity is still pending
Revenue renders immediately and Activity keeps its loading state
Each widget owns its loading, success, and error state.
Isolated retry
Usage fails, then its Retry button is activated
Only Usage loads again; completed panels remain visible
Retries must not reset unrelated data.
Constraints
Do not combine the panel requests with Promise.allNever retry a panel that already succeededDo not mutate the panels array
Hints
Hint 1
Store request state by stable panel ID instead of by completion order.
Hint 2
Start loaders from one effect pass, but attach an independent settlement handler to each promise.
Hint 3
Keep an AbortController per active panel and replace only the controller used by a retry.