import React from 'react'; import _ from 'lodash'; import FormStyledButton from '../widgets/FormStyledButton'; import { useFormikContext } from 'formik'; import styled from 'styled-components'; import { FormReactSelect, FormConnectionSelect, FormDatabaseSelect, FormTablesSelect, FormSchemaSelect, } from '../utility/forms'; import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders'; import TableControl, { TableColumn } from '../utility/TableControl'; import { TextField, SelectField } from '../utility/inputs'; import { getActionOptions, getTargetName, isFileStorage } from './createImpExpScript'; import getElectron from '../utility/getElectron'; import ErrorInfo from '../widgets/ErrorInfo'; import getAsArray from '../utility/getAsArray'; import axios from '../utility/axios'; import LoadingInfo from '../widgets/LoadingInfo'; import SqlEditor from '../sqleditor/SqlEditor'; const Container = styled.div` max-height: 50vh; overflow-y: scroll; `; const Wrapper = styled.div` display: flex; `; const Column = styled.div` margin: 10px; flex: 1; `; const Label = styled.div` margin: 5px; margin-top: 15px; color: #777; `; const SourceNameWrapper = styled.div` display: flex; justify-content: space-between; `; const TrashWrapper = styled.div` &:hover { background-color: #ccc; } cursor: pointer; color: blue; `; const SqlWrapper = styled.div` position: relative; height: 100px; width: 20vw; `; function getFileFilters(storageType) { const res = []; if (storageType == 'csv') res.push({ name: 'CSV files', extensions: ['csv'] }); if (storageType == 'jsonl') res.push({ name: 'JSON lines', extensions: ['jsonl'] }); if (storageType == 'excel') res.push({ name: 'MS Excel files', extensions: ['xlsx'] }); res.push({ name: 'All Files', extensions: ['*'] }); return res; } async function addFilesToSourceList(files, values, setFieldValue) { const newSources = []; const storage = 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, }); } } } setFieldValue('sourceList', [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources]); } function ElectronFilesInput() { const { values, setFieldValue } = useFormikContext(); const electron = getElectron(); const [isLoading, setIsLoading] = React.useState(false); const handleClick = async () => { const files = electron.remote.dialog.showOpenDialogSync(electron.remote.getCurrentWindow(), { properties: ['openFile', 'multiSelections'], filters: getFileFilters(values.sourceStorageType), }); if (files) { const path = window.require('path'); try { setIsLoading(true); await addFilesToSourceList( files.map((full) => ({ full, ...path.parse(full), })), values, setFieldValue ); } finally { setIsLoading(false); } } }; return ( <> {isLoading && } ); } function FilesInput() { const electron = getElectron(); if (electron) { return ; } return ; } function SourceTargetConfig({ direction, storageTypeField, connectionIdField, databaseNameField, schemaNameField, tablesField = undefined, engine = undefined, }) { const { values, setFieldValue } = useFormikContext(); const types = values[storageTypeField] == 'jsldata' ? [{ value: 'jsldata', label: 'Query result data', directions: ['source'] }] : [ { value: 'database', label: 'Database', directions: ['source', 'target'] }, { value: 'csv', label: 'CSV file(s)', directions: ['source', 'target'] }, { value: 'jsonl', label: 'JSON lines file(s)', directions: ['source', 'target'] }, { value: 'excel', label: 'MS Excel file(s)', directions: ['source'] }, { value: 'query', label: 'SQL Query', directions: ['source'] }, ]; const storageType = values[storageTypeField]; const dbinfo = useDatabaseInfo({ conid: values[connectionIdField], database: values[databaseNameField] }); return ( {direction == 'source' && } {direction == 'target' && } x.directions.includes(direction))} name={storageTypeField} /> {(storageType == 'database' || storageType == 'query') && ( <> )} {storageType == 'database' && ( <> {tablesField && ( <>
setFieldValue( 'sourceList', _.uniq([...(values.sourceList || []), ...(dbinfo && dbinfo.tables.map((x) => x.pureName))]) ) } /> setFieldValue( 'sourceList', _.uniq([...(values.sourceList || []), ...(dbinfo && dbinfo.views.map((x) => x.pureName))]) ) } /> setFieldValue('sourceList', [])} />
)} )} {storageType == 'query' && ( <> setFieldValue('sourceSql', value)} engine={engine} focusOnCreate /> )} {isFileStorage(storageType) && direction == 'source' && }
); } function SourceName({ name }) { const { values, setFieldValue } = useFormikContext(); const handleDelete = () => { setFieldValue( 'sourceList', values.sourceList.filter((x) => x != name) ); }; return (
{name}
); } export default function ImportExportConfigurator() { const { values, setFieldValue } = useFormikContext(); const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName }); const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId }); const { engine: sourceEngine } = sourceConnectionInfo || {}; const { sourceList } = values; return ( } /> ( setFieldValue(`actionType_${row}`, e.target.value)} /> )} /> ( setFieldValue(`targetName_${row}`, e.target.value)} /> )} /> ); }