diff --git a/package.json b/package.json index 40b9d83c..ab8da818 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "axios": "^0.18.1", "core-js": "^2.6.5", "material-design-icons-iconfont": "^5.0.1", - "multinet": "0.10.0", + "multinet": "0.12.0", "vue": "^2.6.10", "vue-gtag": "^1.2.1", "vue-router": "^3.0.2", diff --git a/src/components/TableDialog.vue b/src/components/TableDialog.vue index a1372dd0..4b91b399 100644 --- a/src/components/TableDialog.vue +++ b/src/components/TableDialog.vue @@ -21,11 +21,66 @@ > Create Table - + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + + + @@ -35,18 +90,15 @@ import Vue from 'vue'; import api from '@/api'; import { FileType } from '@/types'; -import FileUploadForm from '@/components/FileUploadForm.vue'; - +import { validFileType, fileName as getFileName } from '@/utils/files'; +const defaultKeyField = '_key'; export default Vue.extend({ name: 'TableDialog', props: { workspace: String, }, - components: { - FileUploadForm, - }, data() { return { tableDialog: false, @@ -58,12 +110,66 @@ export default Vue.extend({ displayName: 'CSV', }, ] as FileType[], + file: null as File | null, + fileName: null as string | null, + fileUploadError: null as string | null, + tableCreationError: null as string | null, + key: defaultKeyField, + overwrite: false, }; }, + computed: { + createDisabled(): boolean { + return ( + !this.file || + !this.fileName || + !!this.fileUploadError + ); + }, + }, methods: { - uploadSuccess() { - this.tableDialog = false; - this.$emit('success'); + restoreKeyField() { + this.key = defaultKeyField; + }, + handleFileInput(file: File) { + this.file = file; + + if (!file) { + this.fileUploadError = null; + } else if (!validFileType(file, this.types)) { + this.fileUploadError = 'Invalid file type'; + } else { + this.fileName = this.fileName || getFileName(file); + this.fileUploadError = null; + } + }, + async createTable() { + const { + file, + workspace, + fileName, + key, + overwrite, + } = this; + + if (file === null || fileName === null) { + return; + } + + try { + await api.uploadTable(workspace, fileName, { + type: 'csv', + data: file, + key, + overwrite, + }); + + this.tableCreationError = null; + this.tableDialog = false; + this.$emit('success'); + } catch (err) { + this.tableCreationError = err.statusText; + } }, }, }); diff --git a/src/utils/files.ts b/src/utils/files.ts new file mode 100644 index 00000000..6864cc8b --- /dev/null +++ b/src/utils/files.ts @@ -0,0 +1,16 @@ +import { validUploadType } from 'multinet'; +import { FileType } from '@/types'; + + +const fileExtension = (file: File) => file.name.split('.').slice(-1)[0]; +const fileName = (file: File) => file.name.split('.')[0]; + +function validFileType(file: File, allowedTypes: FileType[]) { + const extension = fileExtension(file); + return allowedTypes.some((type) => type.extension.includes(extension) && validUploadType(type.queryCall)); +} + +export { + fileName, + validFileType, +}; diff --git a/yarn.lock b/yarn.lock index 0ab794af..68621254 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5502,10 +5502,10 @@ multimatch@^2.1.0: arrify "^1.0.0" minimatch "^3.0.0" -multinet@0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.10.0.tgz#92470b0b1020632ec4effe538f9e7c584a719f29" - integrity sha512-GAPUCVqHoG9RBqbx5F2vI3Mp15gLeYuOrkGvZC/Rl1DUe7vuNxiVEKXzoa9N59F0vYVR/eoDAtp+UPjTOtnsLw== +multinet@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.12.0.tgz#44c4c47272a609373edabf384c637f1d5641ae39" + integrity sha512-dkufPqpnRX6KNYPdxtE3cOKXtmyIQiZS1kCH6NjeALrP/a5+/eptEunN45cGL7huCIV8PLeLxkmkpLS6nr1M+A== dependencies: axios "^0.19.0"