Errors now show as toasts in the bottom right corner
This commit is contained in:
1 parent
115ee29a85
commit
49dd11be56
6 files changed
+125
-29
No files matched your search
+20
-18
@@ -1,24 +1,27 @@
|
||||
import type { JSX } from 'solid-js';
|
||||
import { createMemo, createSignal, Match, Show, Switch } from 'solid-js';
|
||||
import { createEffect, createMemo, createSignal, Match, Switch } from 'solid-js';
|
||||
|
||||
import { FilterPanel } from '@/components/FilterPanel';
|
||||
import { OpportunityTable } from '@/components/OpportunityTable';
|
||||
import { buttonPrimary, linkButton } from '@/components/styles';
|
||||
import { buttonPrimary } from '@/components/styles';
|
||||
import { ThemeToggle } from '@/components/ThemeToggle';
|
||||
import { ToastList } from '@/components/ToastList';
|
||||
import type { OpportunityFilters } from '@/lib/filterOpportunities';
|
||||
import { emptyFilters, filterOpportunities, statusOptions } from '@/lib/filterOpportunities';
|
||||
import { createLiveUpdates } from '@/primitives/createLiveUpdates';
|
||||
import { createClassifications, createOpportunities } from '@/primitives/createOpportunities';
|
||||
import { createOpportunityAnnotations } from '@/primitives/createOpportunityAnnotations';
|
||||
import { createTheme } from '@/primitives/createTheme';
|
||||
import { createToasts } from '@/primitives/createToasts';
|
||||
|
||||
const statePanel = 'rounded-[10px] border border-line bg-surface px-6 py-12 text-center';
|
||||
|
||||
/** The page: the filters, any save error, and the table of opportunities. */
|
||||
/** The page: the filters, the table of opportunities, and toasts for errors. */
|
||||
export function App(): JSX.Element {
|
||||
const toasts = createToasts();
|
||||
const opportunities = createOpportunities();
|
||||
const classifications = createClassifications();
|
||||
const annotations = createOpportunityAnnotations(opportunities.items);
|
||||
const annotations = createOpportunityAnnotations(opportunities.items, toasts.show);
|
||||
createLiveUpdates({ opportunities, classifications, annotations });
|
||||
const theme = createTheme();
|
||||
const [filters, setFilters] = createSignal<OpportunityFilters>(emptyFilters());
|
||||
@@ -32,6 +35,17 @@ export function App(): JSX.Element {
|
||||
setFilters(emptyFilters());
|
||||
};
|
||||
|
||||
// A failed load is shown where the list would be, with a retry, and as a
|
||||
// toast, so it's seen wherever the user is looking.
|
||||
createEffect(() => {
|
||||
const err = opportunities.error();
|
||||
if (err) toasts.show(`Opportunities didn't load: ${err.message}`);
|
||||
});
|
||||
createEffect(() => {
|
||||
const err = classifications.error();
|
||||
if (err) toasts.show(`Classifications didn't load: ${err.message}`);
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="mx-auto max-w-[1440px] px-3 pt-4 pb-12 sm:px-6 sm:pt-7 sm:pb-16">
|
||||
<header class="mb-5 flex items-center justify-between gap-4">
|
||||
@@ -52,20 +66,6 @@ export function App(): JSX.Element {
|
||||
total={opportunities.items().length}
|
||||
/>
|
||||
|
||||
<Show when={annotations.error()}>
|
||||
{(message) => (
|
||||
<div
|
||||
class="mb-4 flex items-center justify-between gap-4 rounded-md bg-danger-soft px-3.5 py-2.5 text-danger"
|
||||
role="alert"
|
||||
>
|
||||
<span>{message()}</span>
|
||||
<button type="button" class={linkButton} onClick={annotations.dismissError}>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
|
||||
<main>
|
||||
<Switch fallback={<OpportunityTable opportunities={rows()} annotations={annotations} />}>
|
||||
<Match when={opportunities.isLoading() && opportunities.items().length === 0}>
|
||||
@@ -94,6 +94,8 @@ export function App(): JSX.Element {
|
||||
</Match>
|
||||
</Switch>
|
||||
</main>
|
||||
|
||||
<ToastList toasts={toasts.items()} onDismiss={toasts.dismiss} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user