diff --git a/package.json b/package.json
index 2ff061c5f..f3f391254 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"private": true,
- "version": "4.7.2",
+ "version": "4.7.3-beta.1",
"name": "dbgate-all",
"workspaces": [
"packages/*",
diff --git a/packages/api/src/controllers/files.js b/packages/api/src/controllers/files.js
index 14ea526a5..6d82c2e29 100644
--- a/packages/api/src/controllers/files.js
+++ b/packages/api/src/controllers/files.js
@@ -141,8 +141,8 @@ module.exports = {
},
generateUploadsFile_meta: true,
- async generateUploadsFile() {
- const fileName = `${uuidv1()}.html`;
+ async generateUploadsFile({ extension }) {
+ const fileName = `${uuidv1()}.${extension || 'html'}`;
return {
fileName,
filePath: path.join(uploadsdir(), fileName),
diff --git a/packages/web/src/appobj/ArchiveFileAppObject.svelte b/packages/web/src/appobj/ArchiveFileAppObject.svelte
index 60eee5e9c..02c92fbdf 100644
--- a/packages/web/src/appobj/ArchiveFileAppObject.svelte
+++ b/packages/web/src/appobj/ArchiveFileAppObject.svelte
@@ -70,7 +70,7 @@
import { archiveFilesAsDataSheets, currentArchive, extensions, getCurrentDatabase } from '../stores';
import createQuickExportMenu from '../utility/createQuickExportMenu';
- import { exportElectronFile } from '../utility/exportElectronFile';
+ import { exportQuickExportFile } from '../utility/exportFileTools';
import openNewTab from '../utility/openNewTab';
import AppObjectCore from './AppObjectCore.svelte';
import getConnectionLabel from '../utility/getConnectionLabel';
@@ -169,31 +169,33 @@
{ text: 'Delete', onClick: handleDelete },
{ text: 'Rename', onClick: handleRename },
data.fileType == 'jsonl' &&
- createQuickExportMenu($extensions, fmt => async () => {
- exportElectronFile(
- data.fileName,
- {
- functionName: 'archiveReader',
- props: {
- fileName: data.fileName,
- folderName: data.folderName,
+ createQuickExportMenu(
+ fmt => async () => {
+ exportQuickExportFile(
+ data.fileName,
+ {
+ functionName: 'archiveReader',
+ props: {
+ fileName: data.fileName,
+ folderName: data.folderName,
+ },
},
+ fmt
+ );
+ },
+ {
+ text: 'Export',
+ onClick: () => {
+ showModal(ImportExportModal, {
+ initialValues: {
+ sourceStorageType: 'archive',
+ sourceArchiveFolder: data.folderName,
+ sourceList: [data.fileName],
+ },
+ });
},
- fmt
- );
- }),
- data.fileType == 'jsonl' && {
- text: 'Export',
- onClick: () => {
- showModal(ImportExportModal, {
- initialValues: {
- sourceStorageType: 'archive',
- sourceArchiveFolder: data.folderName,
- sourceList: [data.fileName],
- },
- });
- },
- },
+ }
+ ),
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
];
diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte
index 8e264d051..c7bb2c01f 100644
--- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte
+++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte
@@ -1,6 +1,6 @@
-{#if quickExportHandlerRef && electron}
-
+{#if quickExportHandlerRef}
+
{:else}
{/if}
diff --git a/packages/web/src/charts/ChartCore.svelte b/packages/web/src/charts/ChartCore.svelte
index 17efe256d..1fc893003 100644
--- a/packages/web/src/charts/ChartCore.svelte
+++ b/packages/web/src/charts/ChartCore.svelte
@@ -28,7 +28,7 @@
import contextMenu, { getContextMenu, registerMenu } from '../utility/contextMenu';
import createActivator, { getActiveComponent } from '../utility/createActivator';
- import { saveFileToDisk } from '../utility/exportElectronFile';
+ import { saveFileToDisk } from '../utility/exportFileTools';
export let data;
export let title;
diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts
index 143ea85d6..454a59704 100644
--- a/packages/web/src/commands/stdCommands.ts
+++ b/packages/web/src/commands/stdCommands.ts
@@ -26,7 +26,7 @@ import { removeLocalStorage } from '../utility/storageCache';
import { showSnackbarSuccess } from '../utility/snackbar';
import { apiCall } from '../utility/api';
import runCommand from './runCommand';
-import { openWebLink } from '../utility/exportElectronFile';
+import { openWebLink } from '../utility/exportFileTools';
import { getSettings } from '../utility/metadataLoaders';
// function themeCommand(theme: ThemeDefinition) {
diff --git a/packages/web/src/datagrid/CollectionDataGridCore.svelte b/packages/web/src/datagrid/CollectionDataGridCore.svelte
index dde0c38c3..a3f798ba2 100644
--- a/packages/web/src/datagrid/CollectionDataGridCore.svelte
+++ b/packages/web/src/datagrid/CollectionDataGridCore.svelte
@@ -109,6 +109,7 @@
import { parseFilter } from 'dbgate-filterparser';
import { scriptToSql } from 'dbgate-sqltree';
import _ from 'lodash';
+ import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
import registerCommand from '../commands/registerCommand';
import ErrorInfo from '../elements/ErrorInfo.svelte';
import ConfirmNoSqlModal from '../modals/ConfirmNoSqlModal.svelte';
@@ -121,7 +122,7 @@
import { registerMenu } from '../utility/contextMenu';
import createActivator, { getActiveComponent } from '../utility/createActivator';
import createQuickExportMenu from '../utility/createQuickExportMenu';
- import { exportElectronFile } from '../utility/exportElectronFile';
+ import { exportQuickExportFile } from '../utility/exportFileTools';
import { getConnectionInfo } from '../utility/metadataLoaders';
import openNewTab from '../utility/openNewTab';
import ChangeSetGrider from './ChangeSetGrider';
@@ -193,31 +194,30 @@
);
}
- registerMenu(
- { command: 'collectionDataGrid.openQuery', tag: 'export' },
- {
- ...createQuickExportMenu($extensions, fmt => async () => {
- const coninfo = await getConnectionInfo({ conid });
- exportElectronFile(
- pureName || 'Data',
- {
- functionName: 'queryReader',
- props: {
- connection: {
- ..._.omit(coninfo, ['_id', 'displayName']),
- database,
- },
- sql: getExportQuery(),
- },
+ const quickExportHandler = fmt => async () => {
+ const coninfo = await getConnectionInfo({ conid });
+ exportQuickExportFile(
+ pureName || 'Data',
+ {
+ functionName: 'queryReader',
+ props: {
+ connection: {
+ ..._.omit(coninfo, ['_id', 'displayName']),
+ database,
},
- fmt
- );
- }),
- tag: 'export',
- },
+ sql: getExportQuery(),
+ },
+ },
+ fmt
+ );
+ };
- { command: 'collectionDataGrid.export', tag: 'export' }
- );
+ registerQuickExportHandler(quickExportHandler);
+
+ registerMenu({ command: 'collectionDataGrid.openQuery', tag: 'export' }, () => ({
+ ...createQuickExportMenu(quickExportHandler, { command: 'collectionDataGrid.export' }),
+ tag: 'export',
+ }));
async () => {
const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
if (archiveMatch) {
- exportElectronFile(
+ exportQuickExportFile(
archiveMatch[2],
{
functionName: 'archiveReader',
@@ -116,7 +116,7 @@
fmt
);
} else {
- exportElectronFile(
+ exportQuickExportFile(
'Query',
{
functionName: 'jslDataReader',
@@ -130,13 +130,10 @@
};
registerQuickExportHandler(quickExportHandler);
- registerMenu(
- {
- ...createQuickExportMenu($extensions, quickExportHandler),
- tag: 'export',
- },
- { command: 'jslTableGrid.export', tag: 'export' }
- );
+ registerMenu(() => ({
+ ...createQuickExportMenu(quickExportHandler, { command: 'jslTableGrid.export' }),
+ tag: 'export',
+ }));
import _ from 'lodash';
import { getContext } from 'svelte';
-import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
+ import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
import registerCommand from '../commands/registerCommand';
import ImportExportModal from '../modals/ImportExportModal.svelte';
import { showModal } from '../modals/modalTools';
- import { extensions } from '../stores';
import { apiCall } from '../utility/api';
import { registerMenu } from '../utility/contextMenu';
import createActivator, { getActiveComponent } from '../utility/createActivator';
import createQuickExportMenu from '../utility/createQuickExportMenu';
- import { exportElectronFile } from '../utility/exportElectronFile';
+ import { exportQuickExportFile } from '../utility/exportFileTools';
import { getConnectionInfo } from '../utility/metadataLoaders';
import openNewTab from '../utility/openNewTab';
import ChangeSetGrider from './ChangeSetGrider';
@@ -182,7 +181,7 @@ import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.sve
const quickExportHandler = fmt => async () => {
const coninfo = await getConnectionInfo({ conid });
- exportElectronFile(
+ exportQuickExportFile(
pureName || 'Data',
{
functionName: 'queryReader',
@@ -202,11 +201,10 @@ import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.sve
registerMenu(
{ command: 'sqlDataGrid.openActiveChart', tag: 'chart' },
{ command: 'sqlDataGrid.openQuery', tag: 'export' },
- {
- ...createQuickExportMenu($extensions, quickExportHandler),
+ () => ({
+ ...createQuickExportMenu(quickExportHandler, { command: 'sqlDataGrid.export' }),
tag: 'export',
- },
- { command: 'sqlDataGrid.export', tag: 'export' }
+ })
);
diff --git a/packages/web/src/designer/Designer.svelte b/packages/web/src/designer/Designer.svelte
index f7f13ff44..815338cc4 100644
--- a/packages/web/src/designer/Designer.svelte
+++ b/packages/web/src/designer/Designer.svelte
@@ -39,7 +39,7 @@
import registerCommand from '../commands/registerCommand';
import createActivator, { getActiveComponent } from '../utility/createActivator';
import { GraphDefinition, GraphLayout } from './GraphLayout';
- import { saveFileToDisk } from '../utility/exportElectronFile';
+ import { saveFileToDisk } from '../utility/exportFileTools';
import { apiCall } from '../utility/api';
import moveDrag from '../utility/moveDrag';
import { rectanglesHaveIntersection } from './designerMath';
diff --git a/packages/web/src/elements/Link.svelte b/packages/web/src/elements/Link.svelte
index b3ce281cf..ed9d16d5d 100644
--- a/packages/web/src/elements/Link.svelte
+++ b/packages/web/src/elements/Link.svelte
@@ -1,5 +1,5 @@
@@ -64,15 +79,23 @@
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
isNative
notSelected
- options={tableList.map(tbl => ({
- label: fullNameToLabel(tbl),
- value: fullNameToString(tbl),
- }))}
+ options={tableOptions}
on:change={e => {
if (e.detail) {
const name = fullNameFromString(e.detail);
refTableName = name.pureName;
refSchemaName = name.schemaName;
+ if (columns?.length == 1) {
+ const table = $dbInfo?.tables?.find(x => x.pureName == refTableName && x.schemaName == refSchemaName);
+ if (table?.primaryKey?.columns?.length == 1) {
+ columns = [
+ {
+ ...columns[0],
+ refColumnName: table.primaryKey.columns[0].columnName,
+ },
+ ];
+ }
+ }
}
}}
/>
diff --git a/packages/web/src/tabs/CompareModelTab.svelte b/packages/web/src/tabs/CompareModelTab.svelte
index 6df13b66b..4bec9a75f 100644
--- a/packages/web/src/tabs/CompareModelTab.svelte
+++ b/packages/web/src/tabs/CompareModelTab.svelte
@@ -158,7 +158,7 @@
import { changeTab } from '../utility/common';
import contextMenu, { getContextMenu, registerMenu } from '../utility/contextMenu';
import createActivator, { getActiveComponent } from '../utility/createActivator';
- import { saveFileToDisk } from '../utility/exportElectronFile';
+ import { saveFileToDisk } from '../utility/exportFileTools';
import { useArchiveFolders, useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
import resolveApi from '../utility/resolveApi';
import { showSnackbarSuccess } from '../utility/snackbar';
diff --git a/packages/web/src/tabs/TableDataTab.svelte b/packages/web/src/tabs/TableDataTab.svelte
index 764c8a336..35ade672e 100644
--- a/packages/web/src/tabs/TableDataTab.svelte
+++ b/packages/web/src/tabs/TableDataTab.svelte
@@ -50,14 +50,11 @@
import { showSnackbarSuccess } from '../utility/snackbar';
import StatusBarTabItem from '../widgets/StatusBarTabItem.svelte';
import openNewTab from '../utility/openNewTab';
- import { getBoolSettingsValue } from '../settings/settingsTools';
import { setContext } from 'svelte';
import { apiCall } from '../utility/api';
import { getLocalStorage, setLocalStorage } from '../utility/storageCache';
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
- import ToolStripDropDownButton from '../buttons/ToolStripDropDownButton.svelte';
- import { createQuickExportMenuItems } from '../utility/createQuickExportMenu';
import ToolStripExportButton, { createQuickExportHandlerRef } from '../buttons/ToolStripExportButton.svelte';
export let tabid;
diff --git a/packages/web/src/utility/createQuickExportMenu.ts b/packages/web/src/utility/createQuickExportMenu.ts
index 5872ade54..b304881c9 100644
--- a/packages/web/src/utility/createQuickExportMenu.ts
+++ b/packages/web/src/utility/createQuickExportMenu.ts
@@ -1,30 +1,27 @@
-import { ExtensionsDirectory, QuickExportDefinition } from 'dbgate-types';
-import getElectron from './getElectron';
+import { QuickExportDefinition } from 'dbgate-types';
+import { getExtensions } from '../stores';
-export function createQuickExportMenuItems(
- extensions: ExtensionsDirectory,
- handler: (fmt: QuickExportDefinition) => Function
-) {
- const electron = getElectron();
- if (!electron) {
- return null;
- }
- return extensions.quickExports.map(fmt => ({
- text: fmt.label,
- onClick: handler(fmt),
- }));
+export function createQuickExportMenuItems(handler: (fmt: QuickExportDefinition) => Function, advancedExportMenuItem) {
+ const extensions = getExtensions();
+ return [
+ ...extensions.quickExports.map(fmt => ({
+ text: fmt.label,
+ onClick: handler(fmt),
+ })),
+ { divider: true },
+ {
+ text: 'More...',
+ ...advancedExportMenuItem,
+ },
+ ];
}
export default function createQuickExportMenu(
- extensions: ExtensionsDirectory,
- handler: (fmt: QuickExportDefinition) => Function
+ handler: (fmt: QuickExportDefinition) => Function,
+ advancedExportMenuItem
) {
- const electron = getElectron();
- if (!electron) {
- return { _skip: true };
- }
return {
- text: 'Quick export',
- submenu: createQuickExportMenuItems(extensions, handler),
+ text: 'Export',
+ submenu: createQuickExportMenuItems(handler, advancedExportMenuItem),
};
}
diff --git a/packages/web/src/utility/exportElectronFile.ts b/packages/web/src/utility/exportFileTools.ts
similarity index 78%
rename from packages/web/src/utility/exportElectronFile.ts
rename to packages/web/src/utility/exportFileTools.ts
index 2bb288d5c..91cf2c798 100644
--- a/packages/web/src/utility/exportElectronFile.ts
+++ b/packages/web/src/utility/exportFileTools.ts
@@ -4,16 +4,23 @@ import { showSnackbar, showSnackbarInfo, showSnackbarError, closeSnackbar } from
import resolveApi from './resolveApi';
import { apiCall, apiOff, apiOn } from './api';
-export async function exportElectronFile(dataName, reader, format) {
+export async function exportQuickExportFile(dataName, reader, format) {
const electron = getElectron();
- const filters = [{ name: format.label, extensions: [format.extension] }];
- const filePath = await electron.showSaveDialog({
- filters,
- defaultPath: `${dataName}.${format.extension}`,
- properties: ['showOverwriteConfirmation'],
- });
- if (!filePath) return;
+ let filePath;
+ let pureFileName;
+ if (electron) {
+ const filters = [{ name: format.label, extensions: [format.extension] }];
+ filePath = electron.showSaveDialog({
+ filters,
+ defaultPath: `${dataName}.${format.extension}`,
+ properties: ['showOverwriteConfirmation'],
+ });
+ } else {
+ const resp = await apiCall('files/generate-uploads-file', { extension: format.extension });
+ filePath = resp.filePath;
+ pureFileName = resp.fileName;
+ }
const script = new ScriptWriter();
@@ -50,6 +57,10 @@ export async function exportElectronFile(dataName, reader, format) {
apiOff(`runner-done-${runid}`, handleRunnerDone);
if (isCanceled) showSnackbarError(`Export ${dataName} canceled`);
else showSnackbarInfo(`Export ${dataName} finished`);
+
+ if (!electron) {
+ window.open(`${resolveApi()}/uploads/get?file=${pureFileName}`, '_blank');
+ }
}
apiOn(`runner-done-${runid}`, handleRunnerDone);
diff --git a/packages/web/src/widgets/TabsPanel.svelte b/packages/web/src/widgets/TabsPanel.svelte
index b82fedd82..17220e4bf 100644
--- a/packages/web/src/widgets/TabsPanel.svelte
+++ b/packages/web/src/widgets/TabsPanel.svelte
@@ -387,7 +387,7 @@
draggingDbGroupTarget = null;
}}
>
-
+
{tabGroup.tabDbName}