diff --git a/packages/api/src/controllers/sessions.js b/packages/api/src/controllers/sessions.js index bebd09039..e543b7a0a 100644 --- a/packages/api/src/controllers/sessions.js +++ b/packages/api/src/controllers/sessions.js @@ -146,7 +146,7 @@ module.exports = { }, executeQuery_meta: true, - async executeQuery({ sesid, sql, autoCommit, limitRows, frontMatter }) { + async executeQuery({ sesid, sql, autoCommit, autoDetectCharts, limitRows, frontMatter }) { const session = this.opened.find(x => x.sesid == sesid); if (!session) { throw new Error('Invalid session'); @@ -154,7 +154,7 @@ module.exports = { logger.info({ sesid, sql }, 'Processing query'); this.dispatchMessage(sesid, 'Query execution started'); - session.subprocess.send({ msgtype: 'executeQuery', sql, autoCommit, limitRows, frontMatter }); + session.subprocess.send({ msgtype: 'executeQuery', sql, autoCommit, autoDetectCharts, limitRows, frontMatter }); return { state: 'ok' }; }, diff --git a/packages/api/src/proc/sessionProcess.js b/packages/api/src/proc/sessionProcess.js index 0c05d670c..485483f9d 100644 --- a/packages/api/src/proc/sessionProcess.js +++ b/packages/api/src/proc/sessionProcess.js @@ -117,7 +117,7 @@ async function handleExecuteControlCommand({ command }) { } } -async function handleExecuteQuery({ sql, autoCommit, limitRows, frontMatter }) { +async function handleExecuteQuery({ sql, autoCommit, autoDetectCharts, limitRows, frontMatter }) { lastActivity = new Date().getTime(); await waitConnected(); @@ -146,7 +146,16 @@ async function handleExecuteQuery({ sql, autoCommit, limitRows, frontMatter }) { ...driver.getQuerySplitterOptions('stream'), returnRichInfo: true, })) { - await handleQueryStream(dbhan, driver, queryStreamInfoHolder, sqlItem, undefined, limitRows, frontMatter); + await handleQueryStream( + dbhan, + driver, + queryStreamInfoHolder, + sqlItem, + undefined, + limitRows, + frontMatter, + autoDetectCharts + ); // const handler = new StreamHandler(resultIndex); // const stream = await driver.stream(systemConnection, sqlItem, handler); // handler.stream = stream; diff --git a/packages/api/src/utility/handleQueryStream.js b/packages/api/src/utility/handleQueryStream.js index 73affccb3..617991ea3 100644 --- a/packages/api/src/utility/handleQueryStream.js +++ b/packages/api/src/utility/handleQueryStream.js @@ -14,13 +14,9 @@ class QueryStreamTableWriter { this.currentChangeIndex = 1; this.initializedFile = false; this.sesid = sesid; - // if (isProApp()) { - // this.chartProcessor = new ChartProcessor(); - // } - this.chartProcessor = new ChartProcessor(); } - initializeFromQuery(structure, resultIndex, chartDefinition) { + initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false) { this.jslid = crypto.randomUUID(); this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`); fs.writeFileSync( @@ -34,8 +30,8 @@ class QueryStreamTableWriter { this.writeCurrentStats(false, false); this.resultIndex = resultIndex; this.initializedFile = true; - if (isProApp() && chartDefinition) { - this.chartProcessor = new ChartProcessor([chartDefinition]); + if (isProApp() && (chartDefinition || autoDetectCharts)) { + this.chartProcessor = chartDefinition ? new ChartProcessor([chartDefinition]) : new ChartProcessor(); } process.send({ msgtype: 'recordset', jslid: this.jslid, resultIndex, sesid: this.sesid }); } @@ -138,12 +134,14 @@ class StreamHandler { startLine, sesid = undefined, limitRows = undefined, - frontMatter = undefined + frontMatter = undefined, + autoDetectCharts = false ) { this.recordset = this.recordset.bind(this); this.startLine = startLine; this.sesid = sesid; this.frontMatter = frontMatter; + this.autoDetectCharts = autoDetectCharts; this.limitRows = limitRows; this.rowsLimitOverflow = false; this.row = this.row.bind(this); @@ -177,7 +175,8 @@ class StreamHandler { this.currentWriter.initializeFromQuery( Array.isArray(columns) ? { columns } : columns, this.queryStreamInfoHolder.resultIndex, - this.frontMatter?.[`chart-${this.queryStreamInfoHolder.resultIndex + 1}`] + this.frontMatter?.[`chart-${this.queryStreamInfoHolder.resultIndex + 1}`], + this.autoDetectCharts ); this.queryStreamInfoHolder.resultIndex += 1; this.rowCounter = 0; @@ -252,7 +251,8 @@ function handleQueryStream( sqlItem, sesid = undefined, limitRows = undefined, - frontMatter = undefined + frontMatter = undefined, + autoDetectCharts = false ) { return new Promise((resolve, reject) => { const start = sqlItem.trimStart || sqlItem.start; @@ -262,7 +262,8 @@ function handleQueryStream( start && start.line, sesid, limitRows, - frontMatter + frontMatter, + autoDetectCharts ); driver.stream(dbhan, sqlItem.text, handler); }); diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index e1689abf3..b210e61db 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -233,6 +233,8 @@ 'icon upload': 'mdi mdi-upload', 'icon limit': 'mdi mdi-car-speed-limiter', + 'icon chart': 'mdi mdi-chart-bar', + 'img ok': 'mdi mdi-check-circle color-icon-green', 'img ok-inv': 'mdi mdi-check-circle color-icon-inv-green', 'img alert': 'mdi mdi-alert-circle color-icon-blue', diff --git a/packages/web/src/query/ResultTabs.svelte b/packages/web/src/query/ResultTabs.svelte index 9611fd0c0..53fb2795e 100644 --- a/packages/web/src/query/ResultTabs.svelte +++ b/packages/web/src/query/ResultTabs.svelte @@ -80,6 +80,7 @@ label: `Result ${index + 1}`, isResult: true, component: JslDataGrid, + resultIndex: info.resultIndex, props: { jslid: info.jslid, driver, onOpenChart: () => handleOpenChart(info.resultIndex) }, }))), ...charts.map((info, index) => ({ @@ -144,6 +145,21 @@ } onSetFrontMatterField?.('selected-chart', resultIndex + 1); } + + export function openCurrentChart() { + const currentIndex = domTabs.getValue(); + console.log('Current index:', currentIndex); + const currentTab = allTabs[currentIndex]; + console.log('Current tab:', currentTab); + if (currentTab?.isChart) { + return; + } + const resultIndex = currentTab?.resultIndex; + console.log('Result index:', resultIndex); + if (resultIndex != null) { + handleOpenChart(resultIndex); + } + } + + {#if isProApp() && visibleResultTabs && !busy} + { + domResultTabs?.openCurrentChart(); + }} + > + Open chart + {/if} + {#if isProApp() && !visibleResultTabs} + { + autoDetectCharts = !autoDetectCharts; + }} + > + Detect chart + {/if}