Handle showing errors inside grids

This commit is contained in:
Andrew Kingston 2023-06-27 11:58:10 +01:00
parent cfdd6bafb7
commit 0d8d3a4851
3 changed files with 47 additions and 2 deletions

View File

@ -68,6 +68,7 @@
rowHeight, rowHeight,
contentLines, contentLines,
gridFocused, gridFocused,
error,
} = context } = context
// Keep config store up to date with props // Keep config store up to date with props
@ -149,8 +150,15 @@
</div> </div>
</div> </div>
</div> </div>
{:else if $error}
<div class="grid-error">
<div class="grid-error-title">There was a problem loading your grid</div>
<div class="grid-error-subtitle">
{$error}
</div>
</div>
{/if} {/if}
{#if $loading} {#if $loading && !$error}
<div in:fade|local={{ duration: 130 }} class="grid-loading"> <div in:fade|local={{ duration: 130 }} class="grid-loading">
<ProgressCircle /> <ProgressCircle />
</div> </div>
@ -273,6 +281,25 @@
opacity: 0.6; opacity: 0.6;
} }
/* Error */
.grid-error {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 8px;
}
.grid-error-title {
font-size: 18px;
font-weight: 600;
}
.grid-error-subtitle {
font-size: 16px;
}
/* Disable checkbox animation anywhere in the grid data */ /* Disable checkbox animation anywhere in the grid data */
.grid-data-outer :global(.spectrum-Checkbox-box:before), .grid-data-outer :global(.spectrum-Checkbox-box:before),
.grid-data-outer :global(.spectrum-Checkbox-box:after), .grid-data-outer :global(.spectrum-Checkbox-box:after),

View File

@ -14,6 +14,7 @@ export const createStores = () => {
const rowChangeCache = writable({}) const rowChangeCache = writable({})
const inProgressChanges = writable({}) const inProgressChanges = writable({})
const hasNextPage = writable(false) const hasNextPage = writable(false)
const error = writable(null)
// Generate a lookup map to quick find a row by ID // Generate a lookup map to quick find a row by ID
const rowLookupMap = derived( const rowLookupMap = derived(
@ -47,6 +48,7 @@ export const createStores = () => {
rowChangeCache, rowChangeCache,
inProgressChanges, inProgressChanges,
hasNextPage, hasNextPage,
error,
} }
} }
@ -68,6 +70,7 @@ export const deriveStores = context => {
inProgressChanges, inProgressChanges,
previousFocusedRowId, previousFocusedRowId,
hasNextPage, hasNextPage,
error,
} = context } = context
const instanceLoaded = writable(false) const instanceLoaded = writable(false)
const fetch = writable(null) const fetch = writable(null)
@ -122,7 +125,17 @@ export const deriveStores = context => {
// Subscribe to changes of this fetch model // Subscribe to changes of this fetch model
unsubscribe = newFetch.subscribe(async $fetch => { unsubscribe = newFetch.subscribe(async $fetch => {
if ($fetch.loaded && !$fetch.loading) { if ($fetch.error) {
// Present a helpful error to the user
let message = "An unknown error occurred"
if ($fetch.error.status === 403) {
message = "You don't have access to this data"
} else if ($fetch.error.message) {
message = $fetch.error.message
}
error.set(message)
} else if ($fetch.loaded && !$fetch.loading) {
error.set(null)
hasNextPage.set($fetch.hasNextPage) hasNextPage.set($fetch.hasNextPage)
const $instanceLoaded = get(instanceLoaded) const $instanceLoaded = get(instanceLoaded)
const resetRows = $fetch.resetKey !== lastResetKey const resetRows = $fetch.resetKey !== lastResetKey

View File

@ -57,6 +57,7 @@ export default class DataFetch {
cursor: null, cursor: null,
cursors: [], cursors: [],
resetKey: Math.random(), resetKey: Math.random(),
error: null,
}) })
// Merge options with their default values // Merge options with their default values
@ -252,6 +253,10 @@ export default class DataFetch {
try { try {
return await this.API.fetchTableDefinition(datasource.tableId) return await this.API.fetchTableDefinition(datasource.tableId)
} catch (error) { } catch (error) {
this.store.update(state => ({
...state,
error,
}))
return null return null
} }
} }