mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 22:55:59 +00:00
SYNC: Merge pull request #3 from dbgate/feature/zip
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" context="module">
|
||||
function openArchive(fileName, folderName) {
|
||||
async function openArchive(fileName, folderName) {
|
||||
openNewTab({
|
||||
title: fileName,
|
||||
icon: 'img archive',
|
||||
@@ -10,17 +10,21 @@
|
||||
archiveFolder: folderName,
|
||||
},
|
||||
});
|
||||
// }
|
||||
}
|
||||
|
||||
async function openTextFile(fileName, fileType, folderName, tabComponent, icon) {
|
||||
const connProps: any = {};
|
||||
let tooltip = undefined;
|
||||
const isZipped = folderName.endsWith('.zip');
|
||||
|
||||
const resp = await apiCall('files/load', {
|
||||
folder: 'archive:' + folderName,
|
||||
file: fileName + '.' + fileType,
|
||||
format: 'text',
|
||||
});
|
||||
const resp = isZipped
|
||||
? await apiCall('files/download-text', { uri: `zip://archive:${folderName}//${fileName}.jsonl` })
|
||||
: await apiCall('files/load', {
|
||||
folder: 'archive:' + folderName,
|
||||
file: fileName + '.' + fileType,
|
||||
format: 'text',
|
||||
});
|
||||
|
||||
openNewTab(
|
||||
{
|
||||
@@ -58,7 +62,7 @@
|
||||
if (data.fileType == 'jsonl') {
|
||||
return 'img archive';
|
||||
}
|
||||
return ARCHIVE_ICONS[data.fileType];
|
||||
return ARCHIVE_ICONS[data.fileType] ?? 'img anyfile';
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -79,6 +83,7 @@
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
|
||||
export let data;
|
||||
$: isZipped = data.folderName?.endsWith('.zip');
|
||||
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
@@ -112,6 +117,9 @@
|
||||
openArchive(data.fileName, data.folderName);
|
||||
};
|
||||
const handleClick = () => {
|
||||
if (!data.fileType) {
|
||||
return;
|
||||
}
|
||||
if (data.fileType == 'jsonl') {
|
||||
handleOpenArchive();
|
||||
}
|
||||
@@ -133,11 +141,15 @@
|
||||
};
|
||||
|
||||
function createMenu() {
|
||||
if (!data.fileType) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
data.fileType == 'jsonl' && { text: 'Open', onClick: handleOpenArchive },
|
||||
data.fileType == 'jsonl' && { text: 'Open in text editor', onClick: handleOpenJsonLinesText },
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
!isZipped && { text: 'Delete', onClick: handleDelete },
|
||||
!isZipped && { text: 'Rename', onClick: handleRename },
|
||||
data.fileType == 'jsonl' &&
|
||||
createQuickExportMenu(
|
||||
fmt => async () => {
|
||||
@@ -174,29 +186,30 @@
|
||||
),
|
||||
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
|
||||
data.fileType == 'jsonl' && {
|
||||
text: 'Open in profiler',
|
||||
submenu: getExtensions()
|
||||
.drivers.filter(eng => eng.profilerFormatterFunction)
|
||||
.map(eng => ({
|
||||
text: eng.title,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Profiler',
|
||||
icon: 'img profiler',
|
||||
tabComponent: 'ProfilerTab',
|
||||
props: {
|
||||
jslidLoad: `archive://${data.folderName}/${data.fileName}`,
|
||||
engine: eng.engine,
|
||||
// profilerFormatterFunction: eng.profilerFormatterFunction,
|
||||
// profilerTimestampFunction: eng.profilerTimestampFunction,
|
||||
// profilerChartAggregateFunction: eng.profilerChartAggregateFunction,
|
||||
// profilerChartMeasures: eng.profilerChartMeasures,
|
||||
},
|
||||
});
|
||||
},
|
||||
})),
|
||||
},
|
||||
!isZipped &&
|
||||
data.fileType == 'jsonl' && {
|
||||
text: 'Open in profiler',
|
||||
submenu: getExtensions()
|
||||
.drivers.filter(eng => eng.profilerFormatterFunction)
|
||||
.map(eng => ({
|
||||
text: eng.title,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Profiler',
|
||||
icon: 'img profiler',
|
||||
tabComponent: 'ProfilerTab',
|
||||
props: {
|
||||
jslidLoad: `archive://${data.folderName}/${data.fileName}`,
|
||||
engine: eng.engine,
|
||||
// profilerFormatterFunction: eng.profilerFormatterFunction,
|
||||
// profilerTimestampFunction: eng.profilerTimestampFunction,
|
||||
// profilerChartAggregateFunction: eng.profilerChartAggregateFunction,
|
||||
// profilerChartMeasures: eng.profilerChartMeasures,
|
||||
},
|
||||
});
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||
import { saveFileToDisk } from '../utility/exportFileTools';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -100,7 +101,7 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
props: {
|
||||
conid: $currentDatabase?.connection?._id,
|
||||
database: $currentDatabase?.name,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
editor: {
|
||||
@@ -113,12 +114,12 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
);
|
||||
};
|
||||
|
||||
const handleOpenDuplicatorTab = () => {
|
||||
const handleOpenDataDeployTab = () => {
|
||||
openNewTab(
|
||||
{
|
||||
title: data.name,
|
||||
icon: 'img duplicator',
|
||||
tabComponent: 'DataDuplicatorTab',
|
||||
icon: 'img data-deploy',
|
||||
tabComponent: 'DataDeployTab',
|
||||
props: {
|
||||
conid: $currentDatabase?.connection?._id,
|
||||
database: $currentDatabase?.name,
|
||||
@@ -127,21 +128,56 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
{
|
||||
editor: {
|
||||
archiveFolder: data.name,
|
||||
conid: $currentDatabase?.connection?._id,
|
||||
database: $currentDatabase?.name,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const handleZipUnzip = async method => {
|
||||
await apiCall(method, {
|
||||
folder: data.name,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDownloadZip = async () => {
|
||||
saveFileToDisk(
|
||||
async filePath => {
|
||||
const zipped = await apiCall('archive/get-zipped-path', {
|
||||
folder: data.name,
|
||||
});
|
||||
await apiCall('files/simple-copy', {
|
||||
sourceFilePath: zipped.filePath,
|
||||
targetFilePath: filePath,
|
||||
});
|
||||
},
|
||||
{
|
||||
formatLabel: 'ZIP files',
|
||||
formatExtension: 'zip',
|
||||
defaultFileName: data.name?.endsWith('.zip') ? data.name : data.name + '.zip',
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
data.name != 'default' && { text: 'Delete', onClick: handleDelete },
|
||||
data.name != 'default' && { text: 'Rename', onClick: handleRename },
|
||||
data.name != 'default' &&
|
||||
$currentDatabase && [
|
||||
{ text: 'Data duplicator', onClick: handleOpenDuplicatorTab },
|
||||
isProApp() && { text: 'Data deployer', onClick: handleOpenDataDeployTab },
|
||||
{ text: 'Generate deploy DB SQL', onClick: handleGenerateDeploySql },
|
||||
{ text: 'Shell: Deploy DB', onClick: handleGenerateDeployScript },
|
||||
],
|
||||
data.name != 'default' &&
|
||||
isProApp() &&
|
||||
data.name.endsWith('.zip') && { text: 'Unpack ZIP', onClick: () => handleZipUnzip('archive/unzip') },
|
||||
data.name != 'default' &&
|
||||
isProApp() &&
|
||||
!data.name.endsWith('.zip') && { text: 'Pack (create ZIP)', onClick: () => handleZipUnzip('archive/zip') },
|
||||
|
||||
isProApp() && { text: 'Download ZIP', onClick: handleDownloadZip },
|
||||
|
||||
data.name != 'default' &&
|
||||
hasPermission('dbops/model/compare') &&
|
||||
@@ -158,7 +194,7 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
{...$$restProps}
|
||||
{data}
|
||||
title={data.name.endsWith('.link') ? data.name.slice(0, -5) : data.name}
|
||||
icon={data.name.endsWith('.link') ? 'img link' : 'img archive-folder'}
|
||||
icon={data.name.endsWith('.link') ? 'img link' : data.name.endsWith('.zip') ? 'img zipfile' : 'img archive-folder'}
|
||||
isBold={data.name == $currentArchive}
|
||||
on:click={() => ($currentArchive = data.name)}
|
||||
menu={createMenu}
|
||||
|
||||
@@ -330,15 +330,15 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
|
||||
});
|
||||
};
|
||||
|
||||
const handleImportWithDbDuplicator = () => {
|
||||
const handleShowDataDeployer = () => {
|
||||
showModal(ChooseArchiveFolderModal, {
|
||||
message: 'Choose archive folder for import from',
|
||||
message: 'Choose archive folder for data deployer',
|
||||
onConfirm: archiveFolder => {
|
||||
openNewTab(
|
||||
{
|
||||
title: archiveFolder,
|
||||
icon: 'img duplicator',
|
||||
tabComponent: 'DataDuplicatorTab',
|
||||
icon: 'img replicator',
|
||||
tabComponent: 'DataDeployerTab',
|
||||
props: {
|
||||
conid: connection?._id,
|
||||
database: name,
|
||||
@@ -439,8 +439,8 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
|
||||
|
||||
driver?.databaseEngineTypes?.includes('sql') &&
|
||||
hasPermission(`dbops/import`) && {
|
||||
onClick: handleImportWithDbDuplicator,
|
||||
text: 'Import with DB duplicator',
|
||||
onClick: handleShowDataDeployer,
|
||||
text: 'Data deployer',
|
||||
},
|
||||
|
||||
{ divider: true },
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
tabComponent: string;
|
||||
folder: string;
|
||||
currentConnection: boolean;
|
||||
extension: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const sql: FileTypeHandler = {
|
||||
@@ -15,6 +17,8 @@
|
||||
tabComponent: 'QueryTab',
|
||||
folder: 'sql',
|
||||
currentConnection: true,
|
||||
extension: 'sql',
|
||||
label: 'SQL file',
|
||||
};
|
||||
|
||||
const shell: FileTypeHandler = {
|
||||
@@ -23,6 +27,8 @@
|
||||
tabComponent: 'ShellTab',
|
||||
folder: 'shell',
|
||||
currentConnection: false,
|
||||
extension: 'js',
|
||||
label: 'JavaScript Shell script',
|
||||
};
|
||||
|
||||
const markdown: FileTypeHandler = {
|
||||
@@ -31,6 +37,8 @@
|
||||
tabComponent: 'MarkdownEditorTab',
|
||||
folder: 'markdown',
|
||||
currentConnection: false,
|
||||
extension: 'md',
|
||||
label: 'Markdown file',
|
||||
};
|
||||
|
||||
const charts: FileTypeHandler = {
|
||||
@@ -39,6 +47,8 @@
|
||||
tabComponent: 'ChartTab',
|
||||
folder: 'charts',
|
||||
currentConnection: true,
|
||||
extension: 'json',
|
||||
label: 'Chart file',
|
||||
};
|
||||
|
||||
const query: FileTypeHandler = {
|
||||
@@ -47,6 +57,8 @@
|
||||
tabComponent: 'QueryDesignTab',
|
||||
folder: 'query',
|
||||
currentConnection: true,
|
||||
extension: 'json',
|
||||
label: 'Query design file',
|
||||
};
|
||||
|
||||
const sqlite: FileTypeHandler = {
|
||||
@@ -55,6 +67,8 @@
|
||||
tabComponent: null,
|
||||
folder: 'sqlite',
|
||||
currentConnection: true,
|
||||
extension: 'sqlite',
|
||||
label: 'SQLite database',
|
||||
};
|
||||
|
||||
const diagrams: FileTypeHandler = {
|
||||
@@ -63,22 +77,52 @@
|
||||
tabComponent: 'DiagramTab',
|
||||
folder: 'diagrams',
|
||||
currentConnection: true,
|
||||
extension: 'json',
|
||||
label: 'Diagram file',
|
||||
};
|
||||
|
||||
const jobs: FileTypeHandler = {
|
||||
const impexp: FileTypeHandler = {
|
||||
icon: 'img export',
|
||||
format: 'json',
|
||||
tabComponent: 'ImportExportTab',
|
||||
folder: 'jobs',
|
||||
folder: 'impexp',
|
||||
currentConnection: false,
|
||||
extension: 'json',
|
||||
label: 'Import/Export file',
|
||||
};
|
||||
|
||||
const datadeploy: FileTypeHandler = isProApp()
|
||||
? {
|
||||
icon: 'img data-deploy',
|
||||
format: 'json',
|
||||
tabComponent: 'DataDeployTab',
|
||||
folder: 'datadeploy',
|
||||
currentConnection: false,
|
||||
extension: 'json',
|
||||
label: 'Data deploy file',
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const dbcompare: FileTypeHandler = isProApp()
|
||||
? {
|
||||
icon: 'img compare',
|
||||
format: 'json',
|
||||
tabComponent: 'CompareModelTab',
|
||||
folder: 'dbcompare',
|
||||
currentConnection: false,
|
||||
extension: 'json',
|
||||
label: 'Database compare file',
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const perspectives: FileTypeHandler = {
|
||||
icon: 'img perspective',
|
||||
format: 'json',
|
||||
tabComponent: 'PerspectiveTab',
|
||||
folder: 'pesrpectives',
|
||||
currentConnection: true,
|
||||
extension: 'json',
|
||||
label: 'Perspective file',
|
||||
};
|
||||
|
||||
const modtrans: FileTypeHandler = {
|
||||
@@ -87,6 +131,8 @@
|
||||
tabComponent: 'ModelTransformTab',
|
||||
folder: 'modtrans',
|
||||
currentConnection: false,
|
||||
extension: 'json',
|
||||
label: 'Model transform file',
|
||||
};
|
||||
|
||||
export const SAVED_FILE_HANDLERS = {
|
||||
@@ -98,8 +144,10 @@
|
||||
sqlite,
|
||||
diagrams,
|
||||
perspectives,
|
||||
jobs,
|
||||
impexp,
|
||||
modtrans,
|
||||
datadeploy,
|
||||
dbcompare,
|
||||
};
|
||||
|
||||
export const extractKey = data => data.file;
|
||||
@@ -122,6 +170,8 @@
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
|
||||
import AppObjectCore from './AppObjectCore.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { saveFileToDisk } from '../utility/exportFileTools';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -148,6 +198,7 @@
|
||||
hasPermission(`files/${data.folder}/write`) && { text: 'Create copy', onClick: handleCopy },
|
||||
hasPermission(`files/${data.folder}/write`) && { text: 'Delete', onClick: handleDelete },
|
||||
folder == 'markdown' && { text: 'Show page', onClick: showMarkdownPage },
|
||||
{ text: 'Download', onClick: handleDownload },
|
||||
];
|
||||
}
|
||||
|
||||
@@ -182,6 +233,19 @@
|
||||
});
|
||||
};
|
||||
|
||||
const handleDownload = () => {
|
||||
saveFileToDisk(
|
||||
async filePath => {
|
||||
await apiCall('files/export-file', {
|
||||
folder,
|
||||
file: data.file,
|
||||
filePath,
|
||||
});
|
||||
},
|
||||
{ formatLabel: handler.label, formatExtension: handler.format, defaultFileName: data.file }
|
||||
);
|
||||
};
|
||||
|
||||
async function openTab() {
|
||||
const resp = await apiCall('files/load', { folder, file: data.file, format: handler.format });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user