From 8bd1869768b845bbce7b11f95ef9aa548f7b111c Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 27 Mar 2025 13:00:09 +0530 Subject: [PATCH] feat: Import documents from a CSV. --- package.json | 4 +- pnpm-lock.yaml | 28 +-- src/lib/components/csvImportBox.svelte | 162 ++++++++++++++++++ src/lib/helpers/files.ts | 18 ++ .../project-[project]/+layout.svelte | 2 + .../collection-[collection]/+page.svelte | 125 +++++++++++++- .../attributes/+page.svelte | 77 +++++---- .../attributes/createAttributeDropdown.svelte | 45 +++-- .../csvDisabled.svelte | 12 ++ .../collection-[collection]/store.ts | 3 + 10 files changed, 406 insertions(+), 70 deletions(-) create mode 100644 src/lib/components/csvImportBox.svelte create mode 100644 src/routes/(console)/project-[project]/databases/database-[database]/collection-[collection]/csvDisabled.svelte diff --git a/package.json b/package.json index f74a73efc..44254c1e8 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,9 @@ "dependencies": { "@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c", "@appwrite.io/pink-icons": "0.25.0", - "@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5", + "@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310", "@appwrite.io/pink-legacy": "^1.0.3", - "@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84", + "@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310", "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.38.0", "@stripe/stripe-js": "^3.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f6bc6d6a..d5db0176e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,14 +15,14 @@ importers: specifier: 0.25.0 version: 0.25.0 '@appwrite.io/pink-icons-svelte': - specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5 - version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5(svelte@4.2.19) + specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310 + version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310(svelte@4.2.19) '@appwrite.io/pink-legacy': specifier: ^1.0.3 version: 1.0.3 '@appwrite.io/pink-svelte': - specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84 - version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19) + specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310 + version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19) '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -215,14 +215,14 @@ packages: resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c} version: 1.2.1 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@203ff849e6d6a66529bf690af2e97cade99ef488': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@203ff849e6d6a66529bf690af2e97cade99ef488} + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@2db2d48b7ac3f0f2a0a8b90c9d81310183586c2a': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@2db2d48b7ac3f0f2a0a8b90c9d81310183586c2a} version: 1.0.0-next.7 peerDependencies: svelte: ^4.0.0 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5} + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310} version: 1.0.0-next.7 peerDependencies: svelte: ^4.0.0 @@ -236,8 +236,8 @@ packages: '@appwrite.io/pink-legacy@1.0.3': resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==} - '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84} + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310} version: 1.0.0-next.85 peerDependencies: react-dom: ^18.0.0 @@ -4243,11 +4243,11 @@ snapshots: '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c': {} - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@203ff849e6d6a66529bf690af2e97cade99ef488(svelte@4.2.19)': + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@2db2d48b7ac3f0f2a0a8b90c9d81310183586c2a(svelte@4.2.19)': dependencies: svelte: 4.2.19 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5(svelte@4.2.19)': + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@310(svelte@4.2.19)': dependencies: svelte: 4.2.19 @@ -4260,9 +4260,9 @@ snapshots: '@appwrite.io/pink-icons': 1.0.0 the-new-css-reset: 1.11.3 - '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@203ff84(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)': + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@310(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)': dependencies: - '@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@203ff849e6d6a66529bf690af2e97cade99ef488(svelte@4.2.19) + '@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@2db2d48b7ac3f0f2a0a8b90c9d81310183586c2a(svelte@4.2.19) '@floating-ui/dom': 1.6.13 '@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.3(svelte@4.2.19))(svelte@4.2.19) '@melt-ui/svelte': 0.86.3(svelte@4.2.19) diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte new file mode 100644 index 000000000..9b444447a --- /dev/null +++ b/src/lib/components/csvImportBox.svelte @@ -0,0 +1,162 @@ + + +{#if showCsvImportBox} +
+
+
+

+ + Importing documents ({importItems.size}) + +

+ + +
+ + {#each [...importItems.entries()] as [key, value]} +
+
    +
  • +
    +
    + + {text(key)} + + + + Collection name + +
    +
    +
    +
  • +
+
+ {/each} +
+
+{/if} + + diff --git a/src/lib/helpers/files.ts b/src/lib/helpers/files.ts index f85f4e7bd..89e92d654 100644 --- a/src/lib/helpers/files.ts +++ b/src/lib/helpers/files.ts @@ -97,6 +97,24 @@ export function removeFile(file: File, files: FileList) { return dataTransfer.files; } +export function readColumnsFromCSV(file: File): Promise { + // more than enough! + const CHUNK_SIZE = 4096; + + return new Promise((resolve, reject) => { + const reader = new FileReader(); + + reader.onload = () => { + const text = reader.result as string; + const [firstLine] = text.split('\n'); + resolve(firstLine.split(',')); + }; + + reader.onerror = reject; + reader.readAsText(file.slice(0, CHUNK_SIZE)); + }); +} + export const defaultIgnore = ` ### Node ### # Logs diff --git a/src/routes/(console)/project-[project]/+layout.svelte b/src/routes/(console)/project-[project]/+layout.svelte index 9faa9c742..5c9bac20e 100644 --- a/src/routes/(console)/project-[project]/+layout.svelte +++ b/src/routes/(console)/project-[project]/+layout.svelte @@ -24,6 +24,7 @@ canWriteProjects, canWriteSites } from '$lib/stores/roles'; + import CsvImportBox from '$lib/components/csvImportBox.svelte'; onMount(() => { return sdk.forConsole.client.subscribe(['project', 'console'], (response) => { @@ -117,6 +118,7 @@ +