diff --git a/packages/web/src/DragAndDropFileTarget.js b/packages/web/src/DragAndDropFileTarget.js
index fae06f3f8..41e0211f0 100644
--- a/packages/web/src/DragAndDropFileTarget.js
+++ b/packages/web/src/DragAndDropFileTarget.js
@@ -1,5 +1,6 @@
import React from 'react';
import styled from 'styled-components';
+import { fileformats } from './fileformats';
import { FontIcon } from './icons';
import useTheme from './theme/useTheme';
@@ -47,7 +48,13 @@ export default function DragAndDropFileTarget({ isDragActive, inputProps }) {
Drop the files to upload to DbGate
- Supported file types: csv, MS Excel, json-lines
+
+ Supported file types:{' '}
+ {fileformats
+ .filter((x) => x.readerFunc)
+ .map((x) => x.name)
+ .join(', ')}
+
diff --git a/packages/web/src/fileformats/csv.ts b/packages/web/src/fileformats/csv.ts
index 5e6ec2b90..410a70d38 100644
--- a/packages/web/src/fileformats/csv.ts
+++ b/packages/web/src/fileformats/csv.ts
@@ -1,7 +1,13 @@
-export default {
+import fileFormatBase from './fileFormatBase';
+import { FileFormatDefinition } from './types';
+
+const csvFormat: FileFormatDefinition = {
+ ...fileFormatBase,
storageType: 'csv',
extension: 'csv',
- name: 'CSV files',
+ name: 'CSV',
readerFunc: 'csvReader',
writerFunc: 'csvWriter',
};
+
+export default csvFormat;
diff --git a/packages/web/src/fileformats/excel.ts b/packages/web/src/fileformats/excel.ts
index d73eab3bd..1ae48e0f9 100644
--- a/packages/web/src/fileformats/excel.ts
+++ b/packages/web/src/fileformats/excel.ts
@@ -1,6 +1,27 @@
-export default {
+import { DatabaseInfo } from 'dbgate-types';
+import axios from '../utility/axios';
+import fileFormatBase from './fileFormatBase';
+import { FileFormatDefinition } from './types';
+
+const excelFormat: FileFormatDefinition = {
+ ...fileFormatBase,
storageType: 'excel',
extension: 'xlsx',
- name: 'MS Excel files',
+ name: 'MS Excel',
readerFunc: 'excelSheetReader',
+
+ addFilesToSourceList: async (file, newSources, newValues) => {
+ const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`);
+ const structure: DatabaseInfo = resp.data;
+ for (const table of structure.tables) {
+ const sourceName = table.pureName;
+ newSources.push(sourceName);
+ newValues[`sourceFile_${sourceName}`] = {
+ fileName: file.full,
+ sheetName: table.pureName,
+ };
+ }
+ },
};
+
+export default excelFormat;
diff --git a/packages/web/src/fileformats/fileFormatBase.ts b/packages/web/src/fileformats/fileFormatBase.ts
new file mode 100644
index 000000000..cb7bc1265
--- /dev/null
+++ b/packages/web/src/fileformats/fileFormatBase.ts
@@ -0,0 +1,11 @@
+const fileFormatBase = {
+ addFilesToSourceList: async (file, newSources, newValues) => {
+ const sourceName = file.name;
+ newSources.push(sourceName);
+ newValues[`sourceFile_${sourceName}`] = {
+ fileName: file.full,
+ };
+ },
+};
+
+export default fileFormatBase;
diff --git a/packages/web/src/fileformats/jsonl.ts b/packages/web/src/fileformats/jsonl.ts
index b58b00e23..02882140c 100644
--- a/packages/web/src/fileformats/jsonl.ts
+++ b/packages/web/src/fileformats/jsonl.ts
@@ -1,7 +1,13 @@
-export default {
+import fileFormatBase from './fileFormatBase';
+import { FileFormatDefinition } from './types';
+
+const jsonlFormat: FileFormatDefinition = {
+ ...fileFormatBase,
storageType: 'jsonl',
extension: 'jsonl',
name: 'JSON lines',
readerFunc: 'jsonLinesReader',
writerFunc: 'jsonLinesWriter',
};
+
+export default jsonlFormat;
diff --git a/packages/web/src/fileformats/types.ts b/packages/web/src/fileformats/types.ts
index f6ba39495..b44e65f19 100644
--- a/packages/web/src/fileformats/types.ts
+++ b/packages/web/src/fileformats/types.ts
@@ -4,4 +4,13 @@ export interface FileFormatDefinition {
name: string;
readerFunc?: string;
writerFunc?: string;
+ addFilesToSourceList: (
+ file: {
+ full: string;
+ },
+ newSources: string[],
+ newValues: {
+ [key: string]: any;
+ }
+ ) => void;
}
diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js
index d03fc40f0..f90172c4b 100644
--- a/packages/web/src/impexp/ImportExportConfigurator.js
+++ b/packages/web/src/impexp/ImportExportConfigurator.js
@@ -96,43 +96,31 @@ function getFileFilters(storageType) {
return res;
}
-async function addFilesToSourceList(files, values, setFieldValue, preferedStorageType, setPreviewSource) {
+async function addFilesToSourceList(files, values, setValues, preferedStorageType, setPreviewSource) {
const newSources = [];
+ const newValues = {};
const storage = preferedStorageType || values.sourceStorageType;
for (const file of getAsArray(files)) {
- if (isFileStorage(storage)) {
- if (storage == 'excel') {
- const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`);
- /** @type {import('dbgate-types').DatabaseInfo} */
- const structure = resp.data;
- for (const table of structure.tables) {
- const sourceName = table.pureName;
- newSources.push(sourceName);
- setFieldValue(`sourceFile_${sourceName}`, {
- fileName: file.full,
- sheetName: table.pureName,
- });
- }
- } else {
- const sourceName = file.name;
- newSources.push(sourceName);
- setFieldValue(`sourceFile_${sourceName}`, {
- fileName: file.full,
- });
- }
+ const format = findFileFormat(storage);
+ if (format && format.addFilesToSourceList) {
+ await format.addFilesToSourceList(file, newSources, newValues);
}
}
- setFieldValue('sourceList', [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources]);
+ newValues['sourceList'] = [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources];
if (preferedStorageType && preferedStorageType != values.sourceStorageType) {
- setFieldValue('sourceStorageType', preferedStorageType);
+ newValues['sourceStorageType'] = preferedStorageType;
}
+ setValues({
+ ...values,
+ ...newValues,
+ });
if (setPreviewSource && newSources.length == 1) {
setPreviewSource(newSources[0]);
}
}
function ElectronFilesInput() {
- const { values, setFieldValue } = useFormikContext();
+ const { values, setValues } = useFormikContext();
const electron = getElectron();
const [isLoading, setIsLoading] = React.useState(false);
@@ -151,7 +139,7 @@ function ElectronFilesInput() {
...path.parse(full),
})),
values,
- setFieldValue
+ setValues
);
} finally {
setIsLoading(false);
@@ -195,7 +183,7 @@ function SourceTargetConfig({
{ value: 'database', label: 'Database', directions: ['source', 'target'] },
...fileformats.map((format) => ({
value: format.storageType,
- label: format.name,
+ label: `${format.name} files(s)`,
directions: getFileFormatDirections(format),
})),
{ value: 'query', label: 'SQL Query', directions: ['source'] },
@@ -335,7 +323,7 @@ function SourceName({ name }) {
}
export default function ImportExportConfigurator({ uploadedFile = undefined, onChangePreview = undefined }) {
- const { values, setFieldValue } = useFormikContext();
+ const { values, setFieldValue, setValues } = useFormikContext();
const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName });
const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId });
const { engine: sourceEngine } = sourceConnectionInfo || {};
@@ -354,7 +342,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC
},
],
values,
- setFieldValue,
+ setValues,
!sourceList || sourceList.length == 0 ? file.storageType : null,
setPreviewSource
);