mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-26 04:05:59 +00:00
preview in import dialog
This commit is contained in:
@@ -14,8 +14,8 @@ import {
|
||||
} from '../utility/forms';
|
||||
import { useArchiveFiles, useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import TableControl, { TableColumn } from '../utility/TableControl';
|
||||
import { TextField, SelectField } from '../utility/inputs';
|
||||
import { getActionOptions, getTargetName, isFileStorage } from './createImpExpScript';
|
||||
import { TextField, SelectField, CheckboxField } from '../utility/inputs';
|
||||
import { createPreviewReader, getActionOptions, getTargetName, isFileStorage } from './createImpExpScript';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import ErrorInfo from '../widgets/ErrorInfo';
|
||||
import getAsArray from '../utility/getAsArray';
|
||||
@@ -86,7 +86,7 @@ function getFileFilters(storageType) {
|
||||
return res;
|
||||
}
|
||||
|
||||
async function addFilesToSourceList(files, values, setFieldValue, preferedStorageType) {
|
||||
async function addFilesToSourceList(files, values, setFieldValue, preferedStorageType, setPreviewSource) {
|
||||
const newSources = [];
|
||||
const storage = preferedStorageType || values.sourceStorageType;
|
||||
for (const file of getAsArray(files)) {
|
||||
@@ -116,6 +116,9 @@ async function addFilesToSourceList(files, values, setFieldValue, preferedStorag
|
||||
if (preferedStorageType && preferedStorageType != values.sourceStorageType) {
|
||||
setFieldValue('sourceStorageType', preferedStorageType);
|
||||
}
|
||||
if (setPreviewSource && newSources.length == 1) {
|
||||
setPreviewSource(newSources[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function ElectronFilesInput() {
|
||||
@@ -308,7 +311,7 @@ function SourceName({ name }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function ImportExportConfigurator({ uploadedFile = undefined }) {
|
||||
export default function ImportExportConfigurator({ uploadedFile = undefined, onChangePreview = undefined }) {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName });
|
||||
const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId });
|
||||
@@ -316,6 +319,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
|
||||
const { sourceList } = values;
|
||||
const { setUploadListener } = useUploadsProvider();
|
||||
const theme = useTheme();
|
||||
const [previewSource, setPreviewSource] = React.useState(null);
|
||||
|
||||
const handleUpload = React.useCallback(
|
||||
(file) => {
|
||||
@@ -328,7 +332,8 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
|
||||
],
|
||||
values,
|
||||
setFieldValue,
|
||||
!sourceList || sourceList.length == 0 ? file.storageType : null
|
||||
!sourceList || sourceList.length == 0 ? file.storageType : null,
|
||||
setPreviewSource
|
||||
);
|
||||
// setFieldValue('sourceList', [...(sourceList || []), file.originalName]);
|
||||
},
|
||||
@@ -348,6 +353,21 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const supportsPreview = ['csv', 'jsonl', 'excel'].includes(values.sourceStorageType);
|
||||
|
||||
const handleChangePreviewSource = async () => {
|
||||
if (previewSource && supportsPreview) {
|
||||
const reader = await createPreviewReader(values, previewSource);
|
||||
if (onChangePreview) onChangePreview(reader);
|
||||
} else {
|
||||
onChangePreview(null);
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
handleChangePreviewSource();
|
||||
}, [previewSource, supportsPreview]);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Wrapper>
|
||||
@@ -396,6 +416,21 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<TableColumn
|
||||
fieldName="preview"
|
||||
header="Preview"
|
||||
formatter={(row) =>
|
||||
supportsPreview ? (
|
||||
<CheckboxField
|
||||
checked={previewSource == row}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) setPreviewSource(row);
|
||||
else setPreviewSource(null);
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</TableControl>
|
||||
</Container>
|
||||
);
|
||||
|
||||
59
packages/web/src/impexp/PreviewDataGrid.js
Normal file
59
packages/web/src/impexp/PreviewDataGrid.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import { createGridCache, createGridConfig, FreeTableGridDisplay } from '@dbgate/datalib';
|
||||
import React from 'react';
|
||||
import DataGridCore from '../datagrid/DataGridCore';
|
||||
import RowsArrayGrider from '../datagrid/RowsArrayGrider';
|
||||
import axios from '../utility/axios';
|
||||
import ErrorInfo from '../widgets/ErrorInfo';
|
||||
import LoadingInfo from '../widgets/LoadingInfo';
|
||||
|
||||
export default function PreviewDataGrid({ reader, ...other }) {
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const [errorMessage, setErrorMessage] = React.useState(null);
|
||||
const [model, setModel] = React.useState(null);
|
||||
const [config, setConfig] = React.useState(createGridConfig());
|
||||
const [cache, setCache] = React.useState(createGridCache());
|
||||
const [grider, setGrider] = React.useState(null);
|
||||
|
||||
const handleLoadInitialData = async () => {
|
||||
try {
|
||||
if (!reader) {
|
||||
setModel(null);
|
||||
setGrider(null);
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
const resp = await axios.post('runners/load-reader', reader);
|
||||
// @ts-ignore
|
||||
setModel(resp.data);
|
||||
setGrider(new RowsArrayGrider(resp.data.rows));
|
||||
setIsLoading(false);
|
||||
} catch (err) {
|
||||
setIsLoading(false);
|
||||
const errorMessage = (err && err.response && err.response.data && err.response.data.error) || 'Loading failed';
|
||||
setErrorMessage(errorMessage);
|
||||
console.error(err.response);
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
handleLoadInitialData();
|
||||
}, [reader]);
|
||||
|
||||
const display = React.useMemo(() => new FreeTableGridDisplay(model, config, setConfig, cache, setCache), [
|
||||
model,
|
||||
config,
|
||||
cache,
|
||||
grider,
|
||||
]);
|
||||
|
||||
if (isLoading) {
|
||||
return <LoadingInfo wrapper message="Loading data" />;
|
||||
}
|
||||
if (errorMessage) {
|
||||
return <ErrorInfo message={errorMessage} />;
|
||||
}
|
||||
|
||||
if (!grider) return null;
|
||||
|
||||
return <DataGridCore {...other} grider={grider} display={display} />;
|
||||
}
|
||||
@@ -211,3 +211,19 @@ export function getActionOptions(source, values, targetDbinfo) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function createPreviewReader(values, sourceName) {
|
||||
const [sourceConnection, sourceDriver] = await getConnection(
|
||||
values.sourceStorageType,
|
||||
values.sourceConnectionId,
|
||||
values.sourceDatabaseName
|
||||
);
|
||||
const [functionName, props] = getSourceExpr(sourceName, values, sourceConnection, sourceDriver);
|
||||
return {
|
||||
functionName,
|
||||
props: {
|
||||
...props,
|
||||
limitRows: 100,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user