diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte index ec7a2c9a3e..8c0cd9f6ba 100644 --- a/src/lib/components/csvImportBox.svelte +++ b/src/lib/components/csvImportBox.svelte @@ -8,16 +8,20 @@ import { getProjectId } from '$lib/helpers/project'; import { writable, type Writable } from 'svelte/store'; import { addNotification } from '$lib/stores/notifications'; - import { Layout, Typography } from '@appwrite.io/pink-svelte'; + import { Layout, Typography, Icon } from '@appwrite.io/pink-svelte'; + import { IconExclamationCircle } from '@appwrite.io/pink-icons-svelte'; + import { Modal, Code } from '$lib/components'; import { type Models, type Payload, Query } from '@appwrite.io/console'; // re-render the key for sheet UI. import { hash } from '$lib/helpers/string'; import { spreadsheetRenderKey } from '$routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store'; + import Link from '$lib/elements/link.svelte'; type ImportItem = { status: string; table?: string; + errors?: string[]; }; type ImportItemsMap = Map; @@ -112,7 +116,10 @@ if (shouldSkip) return items; const next = new Map(items); - next.set(importData.$id, { status, table: tableName ?? undefined }); + const errors = Array.isArray((importData as Payload).errors) + ? ((importData as Payload).errors as string[]) + : undefined; + next.set(importData.$id, { status, table: tableName ?? undefined, errors }); return next; }); @@ -138,7 +145,7 @@ return 60; case 'completed': case 'failed': - return 100; + return 60; default: return 30; } @@ -149,7 +156,7 @@ switch (status) { case 'completed': case 'failed': - return `Import to ${name} ${status}`; + return `Importing CSV file${name ? ` to ${name}` : ''}`; case 'processing': return `Importing CSV file${name ? ` to ${name}` : ''}`; default: @@ -179,6 +186,22 @@ $: isOpen = true; $: showCsvImportBox = $importItems.size > 0; + + let showDetails = false; + let selectedErrors: string[] = []; + let parsedErrors: string[] = []; + + function openDetails(errors: string[] | undefined) { + selectedErrors = errors ?? []; + parsedErrors = selectedErrors.map((err) => { + try { + return JSON.stringify(JSON.parse(err), null, 2); + } catch { + return err; + } + }); + showDetails = true; + } {#if showCsvImportBox} @@ -222,6 +245,25 @@ class:is-danger={value.status === 'failed'} style="--graph-size:{graphSize(value.status)}%"> + {#if value.status === 'failed'} + + + + There was an import issue. + openDetails(value.errors)} + >View details + + + {/if} @@ -232,6 +274,14 @@ {/if} + + + + + + + +