mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 04:16:00 +00:00
export working
This commit is contained in:
@@ -1,7 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
import TableControl from '../elements/TableControl.svelte';
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import PreviewCheckBox from './PreviewCheckBox.svelte';
|
||||
import SourceAction from './SourceAction.svelte';
|
||||
import SourceName from './SourceName.svelte';
|
||||
|
||||
import SourceTargetConfig from './SourceTargetConfig.svelte';
|
||||
import TargetName from './TargetName.svelte';
|
||||
|
||||
const { values } = getFormContext();
|
||||
|
||||
$: targetDbinfo = useDatabaseInfo({ conid: $values.targetConnectionId, database: $values.targetDatabaseName });
|
||||
$: sourceConnectionInfo = useConnectionInfo({ conid: $values.sourceConnectionId });
|
||||
|
||||
const previewSource = writable(null);
|
||||
|
||||
// engine={sourceEngine}
|
||||
// {setPreviewSource}
|
||||
@@ -30,6 +47,40 @@
|
||||
schemaNameField="targetSchemaName"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="m-2">
|
||||
<div class="title"><FontIcon icon="icon tables" /> Map source tables/files</div>
|
||||
|
||||
<TableControl
|
||||
rows={$values.sourceList || []}
|
||||
columns={[
|
||||
{
|
||||
fieldName: 'source',
|
||||
header: 'Source',
|
||||
component: SourceName,
|
||||
getProps: row => ({ name: row }),
|
||||
},
|
||||
{
|
||||
fieldName: 'action',
|
||||
header: 'Action',
|
||||
component: SourceAction,
|
||||
getProps: row => ({ name: row, targetDbinfo }),
|
||||
},
|
||||
{
|
||||
fieldName: 'target',
|
||||
header: 'Target',
|
||||
component: TargetName,
|
||||
getProps: row => ({ name: row }),
|
||||
},
|
||||
{
|
||||
fieldName: 'preview',
|
||||
header: 'Preview',
|
||||
component: PreviewCheckBox,
|
||||
getProps: row => ({ name: row, previewSource }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -38,4 +89,10 @@
|
||||
color: var(--theme-icon-blue);
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
margin: 10px 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
26
packages/web/src/impexp/PreviewCheckBox.svelte
Normal file
26
packages/web/src/impexp/PreviewCheckBox.svelte
Normal file
@@ -0,0 +1,26 @@
|
||||
<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}
|
||||
20
packages/web/src/impexp/SourceAction.svelte
Normal file
20
packages/web/src/impexp/SourceAction.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import SelectField from '../forms/SelectField.svelte';
|
||||
import { extensions } from '../stores';
|
||||
import { getActionOptions } from './createImpExpScript';
|
||||
|
||||
export let name;
|
||||
export let targetDbinfo;
|
||||
|
||||
const { values, setFieldValue } = getFormContext();
|
||||
|
||||
$: options = getActionOptions($extensions, name, $values, targetDbinfo);
|
||||
</script>
|
||||
|
||||
<SelectField
|
||||
{options}
|
||||
isNative
|
||||
value={values[`actionType_${name}`] || options[0].value}
|
||||
on:change={e => setFieldValue(`actionType_${name}`, e.detail)}
|
||||
/>
|
||||
49
packages/web/src/impexp/SourceName.svelte
Normal file
49
packages/web/src/impexp/SourceName.svelte
Normal file
@@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import ChangeDownloadUrlModal from '../modals/ChangeDownloadUrlModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
|
||||
export let name;
|
||||
const { values, setFieldValue } = getFormContext();
|
||||
|
||||
const handleDelete = () => {
|
||||
setFieldValue(
|
||||
'sourceList',
|
||||
$values.sourceList.filter(x => x != name)
|
||||
);
|
||||
};
|
||||
const doChangeUrl = url => {
|
||||
setFieldValue(`sourceFile_${name}`, { fileName: url, isDownload: true });
|
||||
};
|
||||
const handleChangeUrl = () => {
|
||||
showModal(ChangeDownloadUrlModal, { url: obj.fileName, onConfirm: doChangeUrl });
|
||||
};
|
||||
|
||||
$: obj = $values[`sourceFile_${name}`];
|
||||
</script>
|
||||
|
||||
<div class="flex space-between">
|
||||
<div>{name}</div>
|
||||
<div class="flex">
|
||||
{#if obj && !!obj.isDownload}
|
||||
<div class="icon" on:click={handleChangeUrl} title={obj && obj.fileName}>
|
||||
<FontIcon icon="icon web" />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="icon" on:click={handleDelete}>
|
||||
<FontIcon icon="icon delete" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
color: var(--theme-font-link);
|
||||
margin-left: 5px;
|
||||
}
|
||||
.icon:hover {
|
||||
background-color: var(--theme-bg-2);
|
||||
}
|
||||
</style>
|
||||
16
packages/web/src/impexp/TargetName.svelte
Normal file
16
packages/web/src/impexp/TargetName.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<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)}
|
||||
/>
|
||||
29
packages/web/src/modals/ChangeDownloadUrlModal.svelte
Normal file
29
packages/web/src/modals/ChangeDownloadUrlModal.svelte
Normal file
@@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import FormStyledButton from '../elements/FormStyledButton.svelte';
|
||||
|
||||
import FormProvider from '../forms/FormProvider.svelte';
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
|
||||
export let onConfirm;
|
||||
|
||||
const handleSubmit = async values => {
|
||||
onConfirm(values.url);
|
||||
closeCurrentModal();
|
||||
};
|
||||
</script>
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Download imported file from web</svelte:fragment>
|
||||
|
||||
<FormTextField label="URL" name="url" style={{ width: '30vw' }} focused />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="OK" on:click={handleSubmit} />
|
||||
<FormStyledButton value="Cancel" on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
@@ -8,11 +8,16 @@
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import LargeFormButton from '../forms/LargeFormButton.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import createImpExpScript from '../impexp/createImpExpScript';
|
||||
import ImportExportConfigurator from '../impexp/ImportExportConfigurator.svelte';
|
||||
import { getDefaultFileFormat } from '../plugins/fileformats';
|
||||
import RunnerOutputFiles from '../query/RunnerOutputFiles';
|
||||
import SocketMessageView from '../query/SocketMessageView.svelte';
|
||||
import { currentArchive, extensions } from '../stores';
|
||||
import { currentArchive, extensions, selectedWidget } from '../stores';
|
||||
import axiosInstance from '../utility/axiosInstance';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import socket from '../utility/socket';
|
||||
import useEffect from '../utility/useEffect';
|
||||
import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
@@ -28,41 +33,70 @@
|
||||
export let openedFile = undefined;
|
||||
export let importToArchive = false;
|
||||
|
||||
const refreshArchiveFolderRef = { current: null };
|
||||
|
||||
$: targetArchiveFolder = importToArchive ? `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}` : $currentArchive;
|
||||
|
||||
const handleGenerateScript = async () => {
|
||||
// const code = await createImpExpScript(extensions, values);
|
||||
// openNewTab(
|
||||
// {
|
||||
// title: 'Shell #',
|
||||
// icon: 'img shell',
|
||||
// tabComponent: 'ShellTab',
|
||||
// },
|
||||
// { editor: code }
|
||||
// );
|
||||
// modalState.close();
|
||||
$: effect = useEffect(() => registerRunnerDone(runnerId));
|
||||
|
||||
function registerRunnerDone(rid) {
|
||||
if (rid) {
|
||||
socket.on(`runner-done-${rid}`, handleRunnerDone);
|
||||
return () => {
|
||||
socket.off(`runner-done-${rid}`, handleRunnerDone);
|
||||
};
|
||||
} else {
|
||||
return () => {};
|
||||
}
|
||||
}
|
||||
|
||||
$: $effect;
|
||||
|
||||
const handleRunnerDone = () => {
|
||||
busy = false;
|
||||
if (refreshArchiveFolderRef.current) {
|
||||
axiosInstance.post('archive/refresh-folders', {});
|
||||
axiosInstance.post('archive/refresh-files', { folder: refreshArchiveFolderRef.current });
|
||||
$currentArchive = refreshArchiveFolderRef.current;
|
||||
$selectedWidget = 'archive';
|
||||
}
|
||||
};
|
||||
|
||||
const handleExecute = async values => {
|
||||
// if (busy) return;
|
||||
// setBusy(true);
|
||||
// const script = await createImpExpScript(extensions, values);
|
||||
// setExecuteNumber(num => num + 1);
|
||||
// let runid = runnerId;
|
||||
// const resp = await axios.post('runners/start', { script });
|
||||
// runid = resp.data.runid;
|
||||
// setRunnerId(runid);
|
||||
// if (values.targetStorageType == 'archive') {
|
||||
// refreshArchiveFolderRef.current = values.targetArchiveFolder;
|
||||
// } else {
|
||||
// refreshArchiveFolderRef.current = null;
|
||||
// }
|
||||
const handleGenerateScript = async e => {
|
||||
closeCurrentModal();
|
||||
const code = await createImpExpScript($extensions, e.detail);
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Shell #',
|
||||
icon: 'img shell',
|
||||
tabComponent: 'ShellTab',
|
||||
},
|
||||
{ editor: code }
|
||||
);
|
||||
};
|
||||
|
||||
const handleExecute = async e => {
|
||||
if (busy) return;
|
||||
const values = e.detail;
|
||||
busy = true;
|
||||
const script = await createImpExpScript($extensions, values);
|
||||
executeNumber += 1;
|
||||
let runid = runnerId;
|
||||
const resp = await axiosInstance.post('runners/start', { script });
|
||||
runid = resp.data.runid;
|
||||
runnerId = runid;
|
||||
|
||||
if (values.targetStorageType == 'archive') {
|
||||
refreshArchiveFolderRef.current = values.targetArchiveFolder;
|
||||
} else {
|
||||
refreshArchiveFolderRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
// axios.post('runners/cancel', {
|
||||
// runid: runnerId,
|
||||
// });
|
||||
axiosInstance.post('runners/cancel', {
|
||||
runid: runnerId,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -85,9 +119,9 @@
|
||||
|
||||
<div class="wrapper">
|
||||
<HorizontalSplitter initialValue="70%">
|
||||
<svelte:fragment slot="1">
|
||||
<div class="content" slot="1">
|
||||
<ImportExportConfigurator />
|
||||
</svelte:fragment>
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="2">
|
||||
<WidgetColumnBar>
|
||||
@@ -145,4 +179,13 @@
|
||||
border-top: 1px solid var(--theme-border);
|
||||
background-color: var(--theme-bg-modalheader);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-top: 1px solid var(--theme-border);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
runnerId,
|
||||
}),
|
||||
},
|
||||
!electron && {
|
||||
electron && {
|
||||
fieldName: 'copy',
|
||||
header: 'Copy',
|
||||
component: CopyLink,
|
||||
@@ -67,7 +67,7 @@
|
||||
runnerId,
|
||||
}),
|
||||
},
|
||||
!electron && {
|
||||
electron && {
|
||||
fieldName: 'show',
|
||||
header: 'Show',
|
||||
component: ShowLink,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" context="module">
|
||||
const lastFocusedEditor = writable(null);
|
||||
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) =>
|
||||
editor?.getTabId() == tabid ? editor : null
|
||||
editor?.getTabId && editor?.getTabId() == tabid ? editor : null
|
||||
);
|
||||
|
||||
registerFileCommands({
|
||||
@@ -53,10 +53,8 @@
|
||||
|
||||
const instance = get_current_component();
|
||||
|
||||
|
||||
let domEditor;
|
||||
|
||||
|
||||
$: if ($tabVisible && domEditor) {
|
||||
domEditor?.getEditor()?.focus();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" context="module">
|
||||
const lastFocusedEditor = writable(null);
|
||||
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) =>
|
||||
editor?.getTabId() == tabid ? editor : null
|
||||
editor?.getTabId && editor?.getTabId() == tabid ? editor : null
|
||||
);
|
||||
const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
fileExtension: 'sql',
|
||||
|
||||
execute: true,
|
||||
toggleComment:true,
|
||||
findReplace:true
|
||||
toggleComment: true,
|
||||
findReplace: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" context="module">
|
||||
const lastFocusedEditor = writable(null);
|
||||
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) =>
|
||||
editor?.getTabId() == tabid ? editor : null
|
||||
editor?.getTabId && editor?.getTabId() == tabid ? editor : null
|
||||
);
|
||||
const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user