export working

This commit is contained in:
Jan Prochazka
2021-03-13 12:04:33 +01:00
parent 423f876d68
commit 8770034bf5
12 changed files with 281 additions and 40 deletions

View File

@@ -31,6 +31,9 @@ body {
.icon-invisible { .icon-invisible {
visibility: hidden; visibility: hidden;
} }
.space-between {
justify-content: space-between;
}
.flex { .flex {
display: flex; display: flex;
} }

View File

@@ -1,7 +1,24 @@
<script lang="ts"> <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 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 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} // engine={sourceEngine}
// {setPreviewSource} // {setPreviewSource}
@@ -30,6 +47,40 @@
schemaNameField="targetSchemaName" schemaNameField="targetSchemaName"
/> />
</div> </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> </div>
<style> <style>
@@ -38,4 +89,10 @@
color: var(--theme-icon-blue); color: var(--theme-icon-blue);
align-self: center; align-self: center;
} }
.title {
font-size: 20px;
text-align: center;
margin: 10px 0px;
}
</style> </style>

View 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}

View 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)}
/>

View 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>

View 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)}
/>

View 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>

View File

@@ -8,11 +8,16 @@
import FormTextField from '../forms/FormTextField.svelte'; import FormTextField from '../forms/FormTextField.svelte';
import LargeFormButton from '../forms/LargeFormButton.svelte'; import LargeFormButton from '../forms/LargeFormButton.svelte';
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
import createImpExpScript from '../impexp/createImpExpScript';
import ImportExportConfigurator from '../impexp/ImportExportConfigurator.svelte'; import ImportExportConfigurator from '../impexp/ImportExportConfigurator.svelte';
import { getDefaultFileFormat } from '../plugins/fileformats'; import { getDefaultFileFormat } from '../plugins/fileformats';
import RunnerOutputFiles from '../query/RunnerOutputFiles'; import RunnerOutputFiles from '../query/RunnerOutputFiles';
import SocketMessageView from '../query/SocketMessageView.svelte'; 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 WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte'; import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
@@ -28,41 +33,70 @@
export let openedFile = undefined; export let openedFile = undefined;
export let importToArchive = false; export let importToArchive = false;
const refreshArchiveFolderRef = { current: null };
$: targetArchiveFolder = importToArchive ? `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}` : $currentArchive; $: targetArchiveFolder = importToArchive ? `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}` : $currentArchive;
const handleGenerateScript = async () => { $: effect = useEffect(() => registerRunnerDone(runnerId));
// const code = await createImpExpScript(extensions, values);
// openNewTab( function registerRunnerDone(rid) {
// { if (rid) {
// title: 'Shell #', socket.on(`runner-done-${rid}`, handleRunnerDone);
// icon: 'img shell', return () => {
// tabComponent: 'ShellTab', socket.off(`runner-done-${rid}`, handleRunnerDone);
// }, };
// { editor: code } } else {
// ); return () => {};
// modalState.close(); }
}
$: $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 => { const handleGenerateScript = async e => {
// if (busy) return; closeCurrentModal();
// setBusy(true); const code = await createImpExpScript($extensions, e.detail);
// const script = await createImpExpScript(extensions, values); openNewTab(
// setExecuteNumber(num => num + 1); {
// let runid = runnerId; title: 'Shell #',
// const resp = await axios.post('runners/start', { script }); icon: 'img shell',
// runid = resp.data.runid; tabComponent: 'ShellTab',
// setRunnerId(runid); },
// if (values.targetStorageType == 'archive') { { editor: code }
// refreshArchiveFolderRef.current = values.targetArchiveFolder; );
// } else { };
// refreshArchiveFolderRef.current = null;
// } 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 = () => { const handleCancel = () => {
// axios.post('runners/cancel', { axiosInstance.post('runners/cancel', {
// runid: runnerId, runid: runnerId,
// }); });
}; };
</script> </script>
@@ -85,9 +119,9 @@
<div class="wrapper"> <div class="wrapper">
<HorizontalSplitter initialValue="70%"> <HorizontalSplitter initialValue="70%">
<svelte:fragment slot="1"> <div class="content" slot="1">
<ImportExportConfigurator /> <ImportExportConfigurator />
</svelte:fragment> </div>
<svelte:fragment slot="2"> <svelte:fragment slot="2">
<WidgetColumnBar> <WidgetColumnBar>
@@ -145,4 +179,13 @@
border-top: 1px solid var(--theme-border); border-top: 1px solid var(--theme-border);
background-color: var(--theme-bg-modalheader); 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> </style>

View File

@@ -58,7 +58,7 @@
runnerId, runnerId,
}), }),
}, },
!electron && { electron && {
fieldName: 'copy', fieldName: 'copy',
header: 'Copy', header: 'Copy',
component: CopyLink, component: CopyLink,
@@ -67,7 +67,7 @@
runnerId, runnerId,
}), }),
}, },
!electron && { electron && {
fieldName: 'show', fieldName: 'show',
header: 'Show', header: 'Show',
component: ShowLink, component: ShowLink,

View File

@@ -1,7 +1,7 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); const lastFocusedEditor = writable(null);
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) =>
editor?.getTabId() == tabid ? editor : null editor?.getTabId && editor?.getTabId() == tabid ? editor : null
); );
registerFileCommands({ registerFileCommands({
@@ -53,10 +53,8 @@
const instance = get_current_component(); const instance = get_current_component();
let domEditor; let domEditor;
$: if ($tabVisible && domEditor) { $: if ($tabVisible && domEditor) {
domEditor?.getEditor()?.focus(); domEditor?.getEditor()?.focus();
} }

View File

@@ -1,7 +1,7 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); const lastFocusedEditor = writable(null);
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => 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); const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);
@@ -22,8 +22,8 @@
fileExtension: 'sql', fileExtension: 'sql',
execute: true, execute: true,
toggleComment:true, toggleComment: true,
findReplace:true findReplace: true,
}); });
</script> </script>

View File

@@ -1,7 +1,7 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); const lastFocusedEditor = writable(null);
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => 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); const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);