mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-24 17:36:00 +00:00
db sync UX
This commit is contained in:
@@ -322,10 +322,10 @@ module.exports = {
|
|||||||
for (const row of diffRows) {
|
for (const row of diffRows) {
|
||||||
// console.log('PAIR', row.source && row.source.pureName, row.target && row.target.pureName);
|
// console.log('PAIR', row.source && row.source.pureName, row.target && row.target.pureName);
|
||||||
const unifiedDiff = createTwoFilesPatch(
|
const unifiedDiff = createTwoFilesPatch(
|
||||||
(row.source && row.source.pureName) || '',
|
|
||||||
(row.target && row.target.pureName) || '',
|
(row.target && row.target.pureName) || '',
|
||||||
getCreateObjectScript(row.source, driver),
|
(row.source && row.source.pureName) || '',
|
||||||
getCreateObjectScript(row.target, driver),
|
getCreateObjectScript(row.target, driver),
|
||||||
|
getCreateObjectScript(row.source, driver),
|
||||||
'',
|
'',
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
@@ -340,7 +340,7 @@ module.exports = {
|
|||||||
|
|
||||||
const diffJson = parse(unifiedDiff);
|
const diffJson = parse(unifiedDiff);
|
||||||
// $: diffHtml = html(diffJson, { outputFormat: 'side-by-side', drawFileList: false });
|
// $: diffHtml = html(diffJson, { outputFormat: 'side-by-side', drawFileList: false });
|
||||||
const diffHtml = html(diffJson, {});
|
const diffHtml = html(diffJson, { outputFormat: 'side-by-side' });
|
||||||
|
|
||||||
const fileName = `${uuidv1()}.html`;
|
const fileName = `${uuidv1()}.html`;
|
||||||
await fs.writeFile(path.join(uploadsdir(), fileName), diff2htmlPage(diffHtml));
|
await fs.writeFile(path.join(uploadsdir(), fileName), diff2htmlPage(diffHtml));
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
'icon add-key': 'mdi mdi-key-plus',
|
'icon add-key': 'mdi mdi-key-plus',
|
||||||
'icon report': 'mdi mdi-file-chart',
|
'icon report': 'mdi mdi-file-chart',
|
||||||
'icon swap': 'mdi mdi-swap-horizontal-bold',
|
'icon swap': 'mdi mdi-swap-horizontal-bold',
|
||||||
'icon save-sync': 'mdi mdi-content-save-move',
|
'icon deploy': 'mdi mdi-content-save-move',
|
||||||
|
|
||||||
'img ok': 'mdi mdi-check-circle color-icon-green',
|
'img ok': 'mdi mdi-check-circle color-icon-green',
|
||||||
'img ok-inv': 'mdi mdi-check-circle color-icon-inv-green',
|
'img ok-inv': 'mdi mdi-check-circle color-icon-inv-green',
|
||||||
|
|||||||
@@ -28,15 +28,27 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
registerCommand({
|
registerCommand({
|
||||||
id: 'compareModels.saveSync',
|
id: 'compareModels.deploy',
|
||||||
category: 'Compare models',
|
category: 'Compare models',
|
||||||
toolbarName: 'Save/Sync',
|
toolbarName: 'Deploy',
|
||||||
name: 'Save/Sync',
|
name: 'Deploy',
|
||||||
icon: 'icon save-sync',
|
icon: 'icon deploy',
|
||||||
group: 'save',
|
group: 'save',
|
||||||
toolbar: true,
|
toolbar: true,
|
||||||
isRelatedToTab: true,
|
isRelatedToTab: true,
|
||||||
onClick: () => getCurrentEditor().saveSync(),
|
onClick: () => getCurrentEditor().deploy(),
|
||||||
|
testEnabled: () => getCurrentEditor() != null,
|
||||||
|
});
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'compareModels.refresh',
|
||||||
|
category: 'Compare models',
|
||||||
|
toolbarName: 'Refresh',
|
||||||
|
name: 'Refresh models',
|
||||||
|
icon: 'icon reload',
|
||||||
|
toolbar: true,
|
||||||
|
isRelatedToTab: true,
|
||||||
|
onClick: () => getCurrentEditor().refreshModels(),
|
||||||
testEnabled: () => getCurrentEditor() != null,
|
testEnabled: () => getCurrentEditor() != null,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -73,6 +85,8 @@
|
|||||||
import useEditorData from '../query/useEditorData';
|
import useEditorData from '../query/useEditorData';
|
||||||
import { extensions } from '../stores';
|
import { extensions } from '../stores';
|
||||||
import axiosInstance from '../utility/axiosInstance';
|
import axiosInstance from '../utility/axiosInstance';
|
||||||
|
import { changeTab } from '../utility/common';
|
||||||
|
import contextMenu, { getContextMenu, registerMenu } from '../utility/contextMenu';
|
||||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||||
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||||
import resolveApi from '../utility/resolveApi';
|
import resolveApi from '../utility/resolveApi';
|
||||||
@@ -114,13 +128,23 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
$: sqlPreview = getAlterTableScript(
|
$: sqlPreview = getAlterTableScript(
|
||||||
diffRows[pairIndex]?.source,
|
|
||||||
diffRows[pairIndex]?.target,
|
diffRows[pairIndex]?.target,
|
||||||
|
diffRows[pairIndex]?.source,
|
||||||
dbDiffOptions,
|
dbDiffOptions,
|
||||||
targetDb,
|
targetDb,
|
||||||
driver
|
driver
|
||||||
).sql;
|
).sql;
|
||||||
|
|
||||||
|
$: changeTab(tabid, tab => ({
|
||||||
|
...tab,
|
||||||
|
title: $values?.targetDatabase,
|
||||||
|
props: {
|
||||||
|
...tab.props,
|
||||||
|
conid: $values?.targetConid,
|
||||||
|
database: $values?.targetDatabase,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export async function showReport() {
|
export async function showReport() {
|
||||||
const resp = await axiosInstance.post('database-connections/generate-db-diff-report', {
|
const resp = await axiosInstance.post('database-connections/generate-db-diff-report', {
|
||||||
sourceConid: $values?.sourceConid,
|
sourceConid: $values?.sourceConid,
|
||||||
@@ -154,6 +178,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function refreshModels() {
|
||||||
|
axiosInstance.post('database-connections/sync-model', {
|
||||||
|
conid: $values?.targetConid,
|
||||||
|
database: $values?.targetDatabase,
|
||||||
|
});
|
||||||
|
axiosInstance.post('database-connections/sync-model', {
|
||||||
|
conid: $values?.sourceConid,
|
||||||
|
database: $values?.sourceDatabase,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function handleConfirmSql(sql) {
|
async function handleConfirmSql(sql) {
|
||||||
const conid = $values?.targetConid;
|
const conid = $values?.targetConid;
|
||||||
const database = $values?.targetDatabase;
|
const database = $values?.targetDatabase;
|
||||||
@@ -168,20 +203,21 @@
|
|||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
||||||
} else {
|
} else {
|
||||||
|
$values = _.omitBy($values, (v, k) => k.startsWith('isChecked_'));
|
||||||
await axiosInstance.post('database-connections/sync-model', { conid, database });
|
await axiosInstance.post('database-connections/sync-model', { conid, database });
|
||||||
showSnackbarSuccess('Saved to database');
|
showSnackbarSuccess('Saved to database');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSyncSql() {
|
function getDeploySql() {
|
||||||
return diffRows
|
return diffRows
|
||||||
.filter(row => $values[`isChecked_${row.identifier}`])
|
.filter(row => $values[`isChecked_${row.identifier}`])
|
||||||
.map(row => getAlterTableScript(row?.source, row.target, dbDiffOptions, targetDb, driver).sql)
|
.map(row => getAlterTableScript(row?.target, row?.source, dbDiffOptions, targetDb, driver).sql)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveSync() {
|
export function deploy() {
|
||||||
const sql = getSyncSql();
|
const sql = getDeploySql();
|
||||||
showModal(ConfirmSqlModal, {
|
showModal(ConfirmSqlModal, {
|
||||||
sql,
|
sql,
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
@@ -200,9 +236,20 @@
|
|||||||
update: setEditorData,
|
update: setEditorData,
|
||||||
set: setEditorData,
|
set: setEditorData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
registerMenu(
|
||||||
|
{ command: 'compareModels.deploy' },
|
||||||
|
{ divider: true },
|
||||||
|
{ command: 'compareModels.refresh' },
|
||||||
|
{ command: 'compareModels.swap' },
|
||||||
|
{ divider: true },
|
||||||
|
{ command: 'compareModels.reportDiff' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const menu = getContextMenu();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper" use:contextMenu={menu}>
|
||||||
<VerticalSplitter>
|
<VerticalSplitter>
|
||||||
<div slot="1" class="flexcol">
|
<div slot="1" class="flexcol">
|
||||||
<FormProviderCore {values}>
|
<FormProviderCore {values}>
|
||||||
@@ -302,10 +349,10 @@
|
|||||||
>
|
>
|
||||||
<svelte:fragment slot="1">
|
<svelte:fragment slot="1">
|
||||||
<DiffView
|
<DiffView
|
||||||
leftTitle={diffRows[pairIndex]?.source?.pureName}
|
leftTitle={diffRows[pairIndex]?.target?.pureName}
|
||||||
rightTitle={diffRows[pairIndex]?.source?.pureName}
|
rightTitle={diffRows[pairIndex]?.source?.pureName}
|
||||||
leftText={getCreateObjectScript(diffRows[pairIndex]?.source, driver)}
|
leftText={getCreateObjectScript(diffRows[pairIndex]?.target, driver)}
|
||||||
rightText={getCreateObjectScript(diffRows[pairIndex]?.target, driver)}
|
rightText={getCreateObjectScript(diffRows[pairIndex]?.source, driver)}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user