diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte index 8c0e48b8a..60f93abf6 100644 --- a/src/lib/components/csvImportBox.svelte +++ b/src/lib/components/csvImportBox.svelte @@ -27,37 +27,42 @@ const importItems: Writable = writable(new Map()); async function showCompletionNotification( - databaseId: string, - collectionId: string, - importData: Payload + database: string, + collection: string, + payload: Payload ) { - await invalidate(Dependencies.DOCUMENTS); - const url = `${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}/collection-${collectionId}`; + const isSuccess = payload.status === 'completed'; + const isError = !isSuccess && !!payload.errors; - // extract clean message from nested backend error. - const match = importData.errors.join('').match(/message: '(.*)' Message:/i); - const errorMessage = match?.[1]; + if (!isSuccess && !isError) return; - const type = importData.status === 'completed' ? 'success' : 'error'; - const message = - importData.status === 'completed' - ? 'CSV import finished successfully.' - : `${errorMessage}`; + let errorMessage = 'Import failed. Check your CSV for correct fields and required values.'; + if (isError && Array.isArray(payload.errors)) { + try { + // the `errors` is a list of json encoded string. + errorMessage = JSON.parse(payload.errors[0]).message; + } catch { + // do nothing, fallback to default message. + } + } + + const type = isSuccess ? 'success' : 'error'; + const message = isError ? errorMessage : 'CSV import finished successfully.'; + const url = `${base}/project-${page.params.region}-${page.params.project}/databases/database-${database}/collection-${collection}`; addNotification({ type, message, isHtml: true, buttons: - collectionId === page.params.collection || type === 'error' - ? undefined - : [ - { - name: 'View documents', - method: () => goto(url) - } - ] + isSuccess && collection !== page.params.collection + ? [{ name: 'View documents', method: () => goto(url) }] + : undefined }); + + if (isSuccess) { + await invalidate(Dependencies.DOCUMENTS); + } } async function updateOrAddItem(importData: Payload | Models.Migration) { diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index 0dd009cd7..8513fa9c2 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -107,7 +107,6 @@ function createPreferences() { } ); }, - getCustomCollectionColumns: (collectionId: string): Preferences['columns'] => { return preferences?.collections?.[collectionId] ?? []; }, diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/table.svelte index 42bccd017..b85fe889c 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/table.svelte @@ -33,6 +33,7 @@ import { toLocaleDateTime } from '$lib/helpers/date'; import DualTimeView from '$lib/components/dualTimeView.svelte'; import { flags } from '$lib/flags'; + export let data: PageData; const databaseId = page.params.database; @@ -255,12 +256,13 @@ {@const datetime = document[id]} {@const formatted = formatColumn(document[id])} {@const isDatetimeAttribute = attr.type === 'datetime'} + {@const isEncryptedAttribute = isString(attr) && attr.encrypt} {#if isDatetimeAttribute} Timestamp {toLocaleDateTime(datetime, true)} - {:else if isString(attr) && attr.encrypt && showEncrypt} + {:else if isEncryptedAttribute && showEncrypt}