diff --git a/packages/web/src/designer/DesignerQueryDumper.ts b/packages/web/src/designer/DesignerQueryDumper.ts
index 21dfbf313..492c7e887 100644
--- a/packages/web/src/designer/DesignerQueryDumper.ts
+++ b/packages/web/src/designer/DesignerQueryDumper.ts
@@ -55,7 +55,7 @@ export class DesignerQueryDumper {
});
// cross join conditions in subcomponents
- for (const ref of this.designer.references) {
+ for (const ref of this.designer.references || []) {
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, component.tables, component.myAndParentTables)) {
select.where = mergeConditions(select.where, {
conditionType: 'and',
@@ -70,9 +70,9 @@ export class DesignerQueryDumper {
}
addConditions(select: Select, tables: DesignerTableInfo[]) {
- for (const column of this.designer.columns) {
+ for (const column of this.designer.columns || []) {
if (!column.filter) continue;
- const table = this.designer.tables.find((x) => x.designerId == column.designerId);
+ const table = (this.designer.tables || []).find((x) => x.designerId == column.designerId);
if (!tables.find((x) => x.designerId == table.designerId)) continue;
const condition = parseFilter(column.filter, findDesignerFilterType(column, this.designer));
@@ -102,7 +102,7 @@ export class DesignerQueryDumper {
// top level cross join conditions
const topLevelTables = this.topLevelTables;
- for (const ref of this.designer.references) {
+ for (const ref of this.designer.references || []) {
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, topLevelTables, topLevelTables)) {
res.where = mergeConditions(res.where, {
conditionType: 'and',
@@ -111,7 +111,7 @@ export class DesignerQueryDumper {
}
}
- const topLevelColumns = this.designer.columns.filter((col) =>
+ const topLevelColumns = (this.designer.columns || []).filter((col) =>
topLevelTables.find((tbl) => tbl.designerId == col.designerId)
);
const selectIsGrouped = !!topLevelColumns.find((x) => x.isGrouped || (x.aggregate && x.aggregate != '---'));
diff --git a/packages/web/src/designer/QueryDesignToolbar.js b/packages/web/src/designer/QueryDesignToolbar.js
new file mode 100644
index 000000000..58efb9f30
--- /dev/null
+++ b/packages/web/src/designer/QueryDesignToolbar.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import useHasPermission from '../utility/useHasPermission';
+import ToolbarButton from '../widgets/ToolbarButton';
+
+export default function QueryDesignToolbar({ execute, isDatabaseDefined, busy, save }) {
+ const hasPermission = useHasPermission();
+ return (
+ <>
+
+ Execute
+
+ {hasPermission('files/query/write') && (
+
+ Save
+
+ )}
+ >
+ );
+}
diff --git a/packages/web/src/designer/QueryDesigner.js b/packages/web/src/designer/QueryDesigner.js
index 53947a8f8..f5f1969ae 100644
--- a/packages/web/src/designer/QueryDesigner.js
+++ b/packages/web/src/designer/QueryDesigner.js
@@ -2,6 +2,6 @@ import React from 'react';
import styled from 'styled-components';
import Designer from './Designer';
-export default function QueryDesigner({ value, conid, database, engine, onChange, onKeyDown }) {
+export default function QueryDesigner({ value, conid, database, engine, onChange }) {
return ;
}
diff --git a/packages/web/src/sqleditor/ResultTabs.js b/packages/web/src/sqleditor/ResultTabs.js
index 6b81eadeb..8642051ad 100644
--- a/packages/web/src/sqleditor/ResultTabs.js
+++ b/packages/web/src/sqleditor/ResultTabs.js
@@ -27,7 +27,7 @@ export default function ResultTabs({ children, sessionId, executeNumber }) {
}, [sessionId, socket]);
return (
- 0 ? 1 : 0}>
+ 0 ? 'Result 1' : null}>
{children}
{_.sortBy(resultInfos, 'resultIndex').map((info) => (
diff --git a/packages/web/src/tabs/QueryDesignTab.js b/packages/web/src/tabs/QueryDesignTab.js
index 8359bf15d..50f56b0c2 100644
--- a/packages/web/src/tabs/QueryDesignTab.js
+++ b/packages/web/src/tabs/QueryDesignTab.js
@@ -6,7 +6,7 @@ import axios from '../utility/axios';
import { useConnectionInfo } from '../utility/metadataLoaders';
import SqlEditor from '../sqleditor/SqlEditor';
import { useUpdateDatabaseForTab, useSetOpenedTabs } from '../utility/globalState';
-import QueryToolbar from '../query/QueryToolbar';
+import QueryDesignToolbar from '../designer/QueryDesignToolbar';
import SocketMessagesView from '../query/SocketMessagesView';
import { TabPage } from '../widgets/TabControl';
import ResultTabs from '../sqleditor/ResultTabs';
@@ -62,7 +62,7 @@ export default function QueryDesignTab({
const generatePreview = (value, engine) => {
if (!engine || !value) return;
const sql = generateDesignedQuery(value, engine);
- setSqlPreview(sql);
+ setSqlPreview(sqlFormatter.format(sql));
};
React.useEffect(() => {
@@ -84,10 +84,9 @@ export default function QueryDesignTab({
useUpdateDatabaseForTab(tabVisible, conid, database);
- const handleExecute = async () => {
+ const handleExecute = React.useCallback(async () => {
if (busy) return;
setExecuteNumber((num) => num + 1);
- const selectedText = editorRef.current.editor.getSelectedText();
let sesid = sessionId;
if (!sesid) {
@@ -101,9 +100,9 @@ export default function QueryDesignTab({
setBusy(true);
await axios.post('sessions/execute-query', {
sesid,
- sql: selectedText || editorData,
+ sql: sqlPreview,
});
- };
+ }, [busy]);
const handleCancel = () => {
axios.post('sessions/cancel', {
@@ -119,12 +118,21 @@ export default function QueryDesignTab({
setBusy(false);
};
- const handleKeyDown = (data, hash, keyString, keyCode, event) => {
- if (keyCode == keycodes.f5) {
- event.preventDefault();
+ const handleKeyDown = React.useCallback((e) => {
+ if (e.keyCode == keycodes.f5) {
+ e.preventDefault();
handleExecute();
}
- };
+ }, []);
+
+ React.useEffect(() => {
+ if (tabVisible) {
+ document.addEventListener('keydown', handleKeyDown, false);
+ return () => {
+ document.removeEventListener('keydown', handleKeyDown);
+ };
+ }
+ }, [tabVisible, handleKeyDown]);
if (isLoading) {
return (
@@ -143,7 +151,6 @@ export default function QueryDesignTab({
database={database}
engine={connection && connection.engine}
onChange={setEditorData}
- onKeyDown={handleKeyDown}
>
@@ -162,22 +169,22 @@ export default function QueryDesignTab({
)}
- {/* {toolbarPortalRef &&
+ {toolbarPortalRef &&
toolbarPortalRef.current &&
tabVisible &&
ReactDOM.createPortal(
- ,
toolbarPortalRef.current
- )} */}
+ )}
{
+ if (activePageLabel != null) {
+ const pageIndex = _.findIndex(childrenArray, (x) => x.props.label == activePageLabel);
+ if (pageIndex >= 0) setValue(pageIndex);
+ }
+ }, [activePageLabel]);
+
const theme = useTheme();
// // cleanup closed tabs