diff --git a/client/src/common/SqlEditor.tsx b/client/src/common/SqlEditor.tsx index 202c75674..a973408ca 100644 --- a/client/src/common/SqlEditor.tsx +++ b/client/src/common/SqlEditor.tsx @@ -10,13 +10,20 @@ import 'ace-builds/src-noconflict/theme-sqlserver'; const noop = () => {}; export interface Props { + autoHeight: boolean; onChange?: (value: string) => void; readOnly: boolean; value: string; onSelectionChange: (value: string) => void; } -function SqlEditor({ onChange, readOnly, value, onSelectionChange }: Props) { +function SqlEditor({ + autoHeight, + onChange, + readOnly, + value, + onSelectionChange, +}: Props) { const { config } = useAppContext(); const [dimensions, setDimensions] = useState({ width: -1, height: -1 }); const [editor, setEditor] = useState(null); @@ -57,39 +64,64 @@ function SqlEditor({ onChange, readOnly, value, onSelectionChange }: Props) { tabSize: 2, }; + if (autoHeight) { + return ( + setDimensions(contentRect.bounds)} + > + {({ measureRef }) => ( +
+ setEditor(editor)} + onSelectionChange={handleSelection} + readOnly={readOnly} + setOptions={setOptions} + showGutter={true} + showPrintMargin={false} + theme="sqlserver" + value={value} + width={width + 'px'} + /> +
+ )} +
+ ); + } + return ( - setDimensions(contentRect.bounds)} - > - {({ measureRef }) => ( -
- setEditor(editor)} - onSelectionChange={handleSelection} - readOnly={readOnly} - setOptions={setOptions} - showGutter={true} - showPrintMargin={false} - theme="sqlserver" - value={value} - width={width + 'px'} - /> -
- )} -
+ setEditor(editor)} + onSelectionChange={handleSelection} + readOnly={readOnly} + setOptions={setOptions} + showGutter={true} + showPrintMargin={false} + theme="sqlserver" + value={value} + maxLines={12} + width={'100%'} + /> ); } SqlEditor.propTypes = { + autoHeight: PropTypes.bool, onChange: PropTypes.func, onSelectionChange: PropTypes.func, readOnly: PropTypes.bool, @@ -97,6 +129,7 @@ SqlEditor.propTypes = { }; SqlEditor.defaultProps = { + autoHeight: true, onSelectionChange: () => {}, readOnly: false, value: '', diff --git a/client/src/common/SqlpadTauChart.tsx b/client/src/common/SqlpadTauChart.tsx index 32f8151d7..3a669841e 100644 --- a/client/src/common/SqlpadTauChart.tsx +++ b/client/src/common/SqlpadTauChart.tsx @@ -45,11 +45,12 @@ function SqlpadTauChart({ let chart: any; if (!isRunning && !queryError && chartConfiguration && columns && rows) { - const queryResult = { + const dataRows = getObjectRows(columns, rows); + const chartConfig = getTauChartConfig( + chartConfiguration, columns, - rows: getObjectRows(columns, rows), - }; - const chartConfig = getTauChartConfig(chartConfiguration, queryResult); + dataRows + ); if (chartConfig) { chart = new Chart(chartConfig); chart.renderTo('#chart'); @@ -86,7 +87,6 @@ SqlpadTauChart.propTypes = { isRunning: PropTypes.bool, chartConfiguration: PropTypes.object, queryError: PropTypes.string, - queryResult: PropTypes.object, }; export default SqlpadTauChart; diff --git a/client/src/common/getTauChartConfig.tsx b/client/src/common/getTauChartConfig.tsx index 5c1fc96a3..8f145c56d 100644 --- a/client/src/common/getTauChartConfig.tsx +++ b/client/src/common/getTauChartConfig.tsx @@ -5,6 +5,7 @@ import quickFilter from 'taucharts/dist/plugins/quick-filter'; import tooltip from 'taucharts/dist/plugins/tooltip'; import tcTrendline from 'taucharts/dist/plugins/trendline'; import baseUrl from '../utilities/baseUrl'; +import { StatementColumn } from '../types'; /** * Caution this uses any type for a few things @@ -25,11 +26,6 @@ interface Field { inputType: string; } -interface Column { - name: string; - datatype: string; -} - interface ChartConfiguration { chartType: string; fields: StringMap; @@ -62,13 +58,14 @@ const getUnmetFields = (chartType: string, selectedFieldMap: StringMap) => { export default function getTauChartConfig( chartConfiguration: ChartConfiguration, - queryResult: any + columns: StatementColumn[] = [], + rows: any[] = [] ) { if (!chartConfiguration) { return null; } - const columns = queryResult ? queryResult.columns : []; - let dataRows = queryResult ? queryResult.rows : []; + + let dataRows = rows || []; const chartType = chartConfiguration.chartType; const selectedFields = chartConfiguration.fields; @@ -109,7 +106,7 @@ export default function getTauChartConfig( // loop through data rows and convert types as needed dataRows = dataRows.map((row: DataRow) => { const newRow: DataRow = {}; - columns.forEach((col: Column) => { + columns.forEach((col: StatementColumn) => { const { datatype, name } = col; if (datatype === 'date' || datatype === 'datetime') { newRow[name] = new Date(row[name]); @@ -131,7 +128,7 @@ export default function getTauChartConfig( forceDimensionFields.forEach((fieldDefinition) => { const columnName = selectedFields[fieldDefinition.fieldId]; const column = columns.find( - (column: Column) => column.name === columnName + (column: StatementColumn) => column.name === columnName ); const colDatatype = column ? column.datatype : null; if (columnName && colDatatype === 'number' && newRow[columnName]) { @@ -154,7 +151,7 @@ export default function getTauChartConfig( if (fieldDefinition && fieldDefinition.inputType !== 'field-dropdown') { fieldsMap[fieldColName] = columnName; - } else if (columns.find((c: Column) => c.name === columnName)) { + } else if (columns.find((c: StatementColumn) => c.name === columnName)) { fieldsMap[fieldColName] = columnName; } return fieldsMap; diff --git a/client/src/queryEditor/QueryEditorChartToolbar.tsx b/client/src/queryEditor/QueryEditorChartToolbar.tsx index 8752b78c8..c51221665 100644 --- a/client/src/queryEditor/QueryEditorChartToolbar.tsx +++ b/client/src/queryEditor/QueryEditorChartToolbar.tsx @@ -4,18 +4,22 @@ import React from 'react'; import IconButton from '../common/IconButton'; import { exportPng } from '../common/tauChartRef'; import { + useLastStatementId, useSessionQueryId, useSessionQueryName, - useSessionQueryResult, + useStatementStatus, } from '../stores/editor-store'; +import { api } from '../utilities/api'; function QueryEditorChartToolbar({ children }: any) { const queryId = useSessionQueryId() || 'new'; const queryName = useSessionQueryName() || 'New query'; - const queryResult = useSessionQueryResult(); - const downloadEnabled = - queryResult && queryResult.rows && queryResult.rows.length; + const statementId = useLastStatementId(); + const status = useStatementStatus(statementId); + const { data } = api.useStatementResults(statementId, status); + + const downloadEnabled = data && data.length; return (
- {isRunning && runQueryStartTime ? ( - - Query time: - - ) : null} -
- ); - } - - const serverSec = queryResult ? queryResult.durationMs / 1000 : ''; - const rowCount = - queryResult && queryResult.rows ? queryResult.rows.length : ''; - - const incomplete = queryResult ? queryResult.incomplete : false; - - return ( -
-
{serverSec} seconds
-
{rowCount} rows
- {incomplete && } -
- ); -} - -QueryHistoryResultHeader.defaultProps = { - isRunning: false, -}; - -export default QueryHistoryResultHeader; diff --git a/client/src/stores/editor-actions.ts b/client/src/stores/editor-actions.ts index 5d5b84c76..bd742bef8 100644 --- a/client/src/stores/editor-actions.ts +++ b/client/src/stores/editor-actions.ts @@ -368,7 +368,6 @@ export const loadQuery = async (queryId: string) => { selectedStatementId: '', isRunning: false, queryError: undefined, - queryResult: undefined, unsavedChanges: false, }); diff --git a/client/src/stores/editor-store.ts b/client/src/stores/editor-store.ts index 978ea493d..08a5bca3a 100644 --- a/client/src/stores/editor-store.ts +++ b/client/src/stores/editor-store.ts @@ -43,7 +43,6 @@ export interface EditorSession { selectedText: string; selectedStatementId: string; queryError?: any; - queryResult?: any; runQueryStartTime?: any; showValidation: boolean; unsavedChanges: boolean; @@ -86,7 +85,6 @@ export const INITIAL_SESSION: EditorSession = { canWrite: true, canDelete: true, queryError: undefined, - queryResult: undefined, runQueryStartTime: undefined, selectedText: '', selectedStatementId: '', @@ -214,10 +212,6 @@ export function useSessionChartFields() { return useEditorStore((s) => s.getFocusedSession().chartFields); } -export function useSessionQueryResult() { - return useEditorStore((s) => s.getFocusedSession().queryResult); -} - export function useSessionQueryError() { return useEditorStore((s) => { const { queryError, selectedStatementId } = s.getFocusedSession(); diff --git a/client/vite.config.ts b/client/vite.config.ts index b8160702f..c19cbf218 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -31,6 +31,7 @@ proxy['^/.*/api/app'] = PROXY_URL; // https://vitejs.dev/config/ export default defineConfig({ + base: '/sqlpad/', plugins: [reactRefresh()], server: { proxy,