diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.js b/packages/web/src/appobj/DatabaseObjectAppObject.js index e48039912..3cb4d56d3 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.js +++ b/packages/web/src/appobj/DatabaseObjectAppObject.js @@ -11,6 +11,7 @@ import useShowModal from '../modals/showModal'; import { findEngineDriver } from 'dbgate-tools'; import useExtensions from '../utility/useExtensions'; import useOpenNewTab from '../utility/useOpenNewTab'; +import uuidv1 from 'uuid/v1'; const icons = { tables: 'img table', @@ -45,6 +46,10 @@ const menus = { label: 'Open active chart', isActiveChart: true, }, + { + label: 'Query designer', + isQueryDesigner: true, + }, ], views: [ { @@ -75,6 +80,10 @@ const menus = { label: 'Open active chart', isActiveChart: true, }, + { + label: 'Query designer', + isQueryDesigner: true, + }, ], procedures: [ { @@ -199,6 +208,30 @@ function Menu({ data }) { }, } ); + } else if (menu.isQueryDesigner) { + openNewTab( + { + title: data.pureName, + icon: 'img query-design', + tabComponent: 'QueryDesignTab', + props: { + conid: data.conid, + database: data.database, + }, + }, + { + editor: { + tables: [ + { + ...data, + designerId: uuidv1(), + left: 50, + top: 50, + }, + ], + }, + } + ); } else { openDatabaseObjectDetail(openNewTab, menu.tab, menu.sqlTemplate, data); } diff --git a/packages/web/src/designer/Designer.js b/packages/web/src/designer/Designer.js index 328920874..b019e7b2a 100644 --- a/packages/web/src/designer/Designer.js +++ b/packages/web/src/designer/Designer.js @@ -37,13 +37,15 @@ export default function Designer({ value, onChange, conid, database }) { if (!data) return; const rect = e.target.getBoundingClientRect(); var json = JSON.parse(data); + const { objectTypeField } = json; + if (objectTypeField != 'tables' && objectTypeField != 'views') return; json.designerId = uuidv1(); json.left = e.clientX - rect.left; json.top = e.clientY - rect.top; onChange((current) => { const foreignKeys = _.compact([ - ...json.foreignKeys.map((fk) => { + ...(json.foreignKeys || []).map((fk) => { const tables = (current.tables || []).filter( (tbl) => fk.refTableName == tbl.pureName && fk.refSchemaName == tbl.schemaName ); diff --git a/packages/web/src/designer/QueryDesignColumns.js b/packages/web/src/designer/QueryDesignColumns.js index f4162bff1..b58d1f08c 100644 --- a/packages/web/src/designer/QueryDesignColumns.js +++ b/packages/web/src/designer/QueryDesignColumns.js @@ -2,6 +2,7 @@ import React from 'react'; import DataFilterControl from '../datagrid/DataFilterControl'; import { CheckboxField, SelectField, TextField } from '../utility/inputs'; import TableControl, { TableColumn } from '../utility/TableControl'; +import InlineButton from '../widgets/InlineButton'; import { findDesignerFilterType } from './designerTools'; function getTableDisplayName(column, tables) { @@ -15,15 +16,26 @@ export default function QueryDesignColumns({ value, onChange }) { const changeColumn = React.useCallback( (col) => { - const newValue = { - ...value, - columns: (value.columns || []).map((x) => + onChange((current) => ({ + ...current, + columns: (current.columns || []).map((x) => x.designerId == col.designerId && x.columnName == col.columnName ? col : x ), - }; - onChange(newValue); + })); }, - [onChange, value] + [onChange] + ); + + const removeColumn = React.useCallback( + (col) => { + onChange((current) => ({ + ...current, + columns: (current.columns || []).filter( + (x) => x.designerId != col.designerId || x.columnName != col.columnName + ), + })); + }, + [onChange] ); return ( @@ -124,6 +136,15 @@ export default function QueryDesignColumns({ value, onChange }) { /> )} /> + ( + <> + removeColumn(row)}>Remove + + )} + /> ); } diff --git a/packages/web/src/tabs/QueryDesignTab.js b/packages/web/src/tabs/QueryDesignTab.js index 170811d32..4effaacac 100644 --- a/packages/web/src/tabs/QueryDesignTab.js +++ b/packages/web/src/tabs/QueryDesignTab.js @@ -18,7 +18,6 @@ import SaveTabModal from '../modals/SaveTabModal'; import useModalState from '../modals/useModalState'; import sqlFormatter from 'sql-formatter'; import useEditorData from '../utility/useEditorData'; -import applySqlTemplate from '../utility/applySqlTemplate'; import LoadingInfo from '../widgets/LoadingInfo'; import useExtensions from '../utility/useExtensions'; import QueryDesigner from '../designer/QueryDesigner'; @@ -26,15 +25,7 @@ import QueryDesignColumns from '../designer/QueryDesignColumns'; import { findEngineDriver } from 'dbgate-tools'; import { generateDesignedQuery } from '../designer/designerTools'; -export default function QueryDesignTab({ - tabid, - conid, - database, - initialArgs, - tabVisible, - toolbarPortalRef, - ...other -}) { +export default function QueryDesignTab({ tabid, conid, database, tabVisible, toolbarPortalRef, ...other }) { const [sessionId, setSessionId] = React.useState(null); const [executeNumber, setExecuteNumber] = React.useState(0); const setOpenedTabs = useSetOpenedTabs(); @@ -47,10 +38,6 @@ export default function QueryDesignTab({ const [sqlPreview, setSqlPreview] = React.useState(''); const { editorData, setEditorData, isLoading } = useEditorData({ tabid, - loadFromArgs: - initialArgs && initialArgs.sqlTemplate - ? () => applySqlTemplate(initialArgs.sqlTemplate, extensions, { conid, database, ...other }) - : null, }); const editorRef = React.useRef(null);