mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 02:36:01 +00:00
preview data grid, fix multiple D & D to electron
This commit is contained in:
@@ -43,31 +43,49 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import TableControl from '../elements/TableControl.svelte';
|
||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { findFileFormat } from '../plugins/fileformats';
|
||||
import { extensions } from '../stores';
|
||||
import getAsArray from '../utility/getAsArray';
|
||||
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import { setUploadListener } from '../utility/uploadFiles';
|
||||
import PreviewCheckBox from './PreviewCheckBox.svelte';
|
||||
import { createPreviewReader, getTargetName } from './createImpExpScript';
|
||||
import SourceAction from './SourceAction.svelte';
|
||||
import SourceName from './SourceName.svelte';
|
||||
|
||||
import SourceTargetConfig from './SourceTargetConfig.svelte';
|
||||
import TargetName from './TargetName.svelte';
|
||||
|
||||
export let uploadedFile = undefined;
|
||||
export let openedFile = undefined;
|
||||
export let previewReaderStore;
|
||||
|
||||
const { values } = getFormContext();
|
||||
const { values, setFieldValue } = getFormContext();
|
||||
|
||||
$: targetDbinfo = useDatabaseInfo({ conid: $values.targetConnectionId, database: $values.targetDatabaseName });
|
||||
$: sourceConnectionInfo = useConnectionInfo({ conid: $values.sourceConnectionId });
|
||||
$: sourceEngine = $sourceConnectionInfo?.engine;
|
||||
$: sourceList = $values.sourceList;
|
||||
|
||||
const previewSource = writable(null);
|
||||
|
||||
$: supportsPreview =
|
||||
!!findFileFormat($extensions, $values.sourceStorageType) || $values.sourceStorageType == 'archive';
|
||||
|
||||
$: handleChangePreviewSource($previewSource);
|
||||
|
||||
const handleChangePreviewSource = async source => {
|
||||
console.log('SOURCE', source);
|
||||
if (source && supportsPreview) {
|
||||
const reader = await createPreviewReader($extensions, $values, source);
|
||||
if (previewReaderStore) previewReaderStore.set(reader);
|
||||
} else {
|
||||
if (previewReaderStore) previewReaderStore.set(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpload = file => {
|
||||
addFilesToSourceList(
|
||||
$extensions,
|
||||
@@ -125,6 +143,7 @@
|
||||
archiveFolderField="sourceArchiveFolder"
|
||||
schemaNameField="sourceSchemaName"
|
||||
tablesField="sourceList"
|
||||
engine={sourceEngine}
|
||||
setPreviewSource={previewSource.set}
|
||||
/>
|
||||
<div class="arrow">
|
||||
@@ -161,17 +180,39 @@
|
||||
{
|
||||
fieldName: 'target',
|
||||
header: 'Target',
|
||||
component: TargetName,
|
||||
getProps: row => ({ name: row }),
|
||||
slot: 1,
|
||||
},
|
||||
{
|
||||
fieldName: 'preview',
|
||||
header: 'Preview',
|
||||
component: PreviewCheckBox,
|
||||
getProps: row => ({ name: row, previewSource }),
|
||||
slot: 0,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
>
|
||||
<svelte:fragment slot="0" let:row>
|
||||
{#if supportsPreview}
|
||||
<CheckboxField
|
||||
checked={$previewSource == row}
|
||||
on:change={e => {
|
||||
// @ts-ignore
|
||||
if (e.target.checked) $previewSource = row;
|
||||
else $previewSource = null;
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="1" let:row>
|
||||
<TextField
|
||||
value={getTargetName($extensions, row, $values)}
|
||||
on:input={e =>
|
||||
setFieldValue(
|
||||
`targetName_${row}`,
|
||||
// @ts-ignore
|
||||
e.target.value
|
||||
)}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</TableControl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<script lang="ts">
|
||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
|
||||
import { findFileFormat } from '../plugins/fileformats';
|
||||
import { extensions } from '../stores';
|
||||
|
||||
const { values } = getFormContext();
|
||||
|
||||
export let name;
|
||||
export let previewSource;
|
||||
|
||||
$: supportsPreview =
|
||||
!!findFileFormat($extensions, $values.sourceStorageType) || $values.sourceStorageType == 'archive';
|
||||
</script>
|
||||
|
||||
{#if supportsPreview}
|
||||
<CheckboxField
|
||||
checked={$previewSource == name}
|
||||
onChange={e => {
|
||||
if (e.target.checked) $previewSource = name;
|
||||
else $previewSource = null;
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
53
packages/web/src/impexp/PreviewDataGrid.svelte
Normal file
53
packages/web/src/impexp/PreviewDataGrid.svelte
Normal file
@@ -0,0 +1,53 @@
|
||||
<script lang="ts">
|
||||
import { createGridCache, createGridConfig, FreeTableGridDisplay } from 'dbgate-datalib';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
import DataGridCore from '../datagrid/DataGridCore.svelte';
|
||||
import RowsArrayGrider from '../datagrid/RowsArrayGrider';
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||
import axiosInstance from '../utility/axiosInstance';
|
||||
|
||||
export let reader;
|
||||
|
||||
let isLoading = false;
|
||||
let model = null;
|
||||
let grider = null;
|
||||
let errorMessage = null;
|
||||
|
||||
const config = writable(createGridConfig());
|
||||
const cache = writable(createGridCache());
|
||||
|
||||
const handleLoadInitialData = async sourceReader => {
|
||||
try {
|
||||
if (!sourceReader) {
|
||||
model = null;
|
||||
grider = null;
|
||||
return;
|
||||
}
|
||||
errorMessage = null;
|
||||
isLoading = true;
|
||||
const resp = await axiosInstance.post('runners/load-reader', sourceReader);
|
||||
// @ts-ignore
|
||||
model = resp.data;
|
||||
grider = new RowsArrayGrider(resp.data.rows);
|
||||
isLoading = false;
|
||||
} catch (err) {
|
||||
isLoading = false;
|
||||
errorMessage = (err && err.response && err.response.data && err.response.data.error) || 'Loading failed';
|
||||
console.error(err.response);
|
||||
}
|
||||
};
|
||||
|
||||
$: handleLoadInitialData(reader);
|
||||
|
||||
$: display = new FreeTableGridDisplay(model, $config, config.update, $cache, cache.update);
|
||||
</script>
|
||||
|
||||
{#if isLoading}
|
||||
<LoadingInfo wrapper message="Loading data" />
|
||||
{:else if errorMessage}
|
||||
<ErrorInfo message={errorMessage} />
|
||||
{:else if grider}
|
||||
<DataGridCore {...$$props} {grider} {display} />
|
||||
{/if}
|
||||
@@ -1,16 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import { extensions } from '../stores';
|
||||
import { getTargetName } from './createImpExpScript';
|
||||
|
||||
const { values, setFieldValue } = getFormContext();
|
||||
|
||||
export let name;
|
||||
</script>
|
||||
|
||||
<TextField
|
||||
value={getTargetName($extensions, name, $values)}
|
||||
onChange={e => setFieldValue(`targetName_${name}`, e.target.value)}
|
||||
/>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import moment from 'moment';
|
||||
import { writable } from 'svelte/store';
|
||||
import HorizontalSplitter from '../elements/HorizontalSplitter.svelte';
|
||||
import LargeButton from '../elements/LargeButton.svelte';
|
||||
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
|
||||
@@ -10,6 +11,7 @@
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import createImpExpScript from '../impexp/createImpExpScript';
|
||||
import ImportExportConfigurator from '../impexp/ImportExportConfigurator.svelte';
|
||||
import PreviewDataGrid from '../impexp/PreviewDataGrid.svelte';
|
||||
import { getDefaultFileFormat } from '../plugins/fileformats';
|
||||
import RunnerOutputFiles from '../query/RunnerOutputFiles.svelte';
|
||||
import SocketMessageView from '../query/SocketMessageView.svelte';
|
||||
@@ -27,7 +29,8 @@
|
||||
let busy = false;
|
||||
let executeNumber = 0;
|
||||
let runnerId = null;
|
||||
let previewReader = null;
|
||||
|
||||
const previewReaderStore = writable(null);
|
||||
|
||||
export let initialValues;
|
||||
export let uploadedFile = undefined;
|
||||
@@ -121,7 +124,7 @@
|
||||
<div class="wrapper">
|
||||
<HorizontalSplitter initialValue="70%">
|
||||
<div class="content" slot="1">
|
||||
<ImportExportConfigurator {uploadedFile} {openedFile} />
|
||||
<ImportExportConfigurator {uploadedFile} {openedFile} {previewReaderStore} />
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="2">
|
||||
@@ -132,9 +135,9 @@
|
||||
<WidgetColumnBarItem title="Messages" name="messages">
|
||||
<SocketMessageView eventName={runnerId ? `runner-info-${runnerId}` : null} {executeNumber} />
|
||||
</WidgetColumnBarItem>
|
||||
{#if previewReader}
|
||||
{#if $previewReaderStore}
|
||||
<WidgetColumnBarItem title="Preview" name="preview">
|
||||
<!-- <PreviewDataGrid reader={previewReader} /> -->
|
||||
<PreviewDataGrid reader={$previewReaderStore} />
|
||||
</WidgetColumnBarItem>
|
||||
{/if}
|
||||
<WidgetColumnBarItem title="Advanced configuration" name="config" collapsed>
|
||||
|
||||
@@ -4,6 +4,7 @@ import newQuery from '../query/newQuery';
|
||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||
import getElectron from './getElectron';
|
||||
import { extensions } from '../stores';
|
||||
import { getUploadListener } from './uploadFiles';
|
||||
|
||||
export function canOpenByElectron(file, extensions) {
|
||||
if (!file) return false;
|
||||
@@ -20,6 +21,7 @@ export function openElectronFileCore(filePath, extensions) {
|
||||
const path = window.require('path');
|
||||
const fs = window.require('fs');
|
||||
const parsed = path.parse(filePath);
|
||||
const uploadListener = getUploadListener();
|
||||
|
||||
if (nameLower.endsWith('.sql')) {
|
||||
const data = fs.readFileSync(filePath, { encoding: 'utf-8' });
|
||||
@@ -34,17 +36,25 @@ export function openElectronFileCore(filePath, extensions) {
|
||||
}
|
||||
for (const format of extensions.fileFormats) {
|
||||
if (nameLower.endsWith(`.${format.extension}`)) {
|
||||
showModal(ImportExportModal, {
|
||||
openedFile: {
|
||||
if (uploadListener) {
|
||||
uploadListener({
|
||||
filePath,
|
||||
storageType: format.storageType,
|
||||
shortName: parsed.name,
|
||||
},
|
||||
importToArchive: true,
|
||||
initialValues: {
|
||||
sourceStorageType: format.storageType,
|
||||
},
|
||||
});
|
||||
});
|
||||
} else {
|
||||
showModal(ImportExportModal, {
|
||||
openedFile: {
|
||||
filePath,
|
||||
storageType: format.storageType,
|
||||
shortName: parsed.name,
|
||||
},
|
||||
importToArchive: true,
|
||||
initialValues: {
|
||||
sourceStorageType: format.storageType,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ export function setUploadListener(value) {
|
||||
uploadListener = value;
|
||||
}
|
||||
|
||||
export function getUploadListener() {
|
||||
return uploadListener;
|
||||
}
|
||||
|
||||
export default function uploadFiles(files) {
|
||||
const ext = get(extensions);
|
||||
const electron = getElectron();
|
||||
|
||||
@@ -12,5 +12,17 @@
|
||||
<WidgetTitle on:click={() => (visible = !visible)}>{title}</WidgetTitle>
|
||||
|
||||
{#if visible}
|
||||
<slot />
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
div {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
min-height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user