diff --git a/src/commands/dataSourceCommand.ts b/src/commands/dataSourceCommand.ts index 61619872..7c31e504 100644 --- a/src/commands/dataSourceCommand.ts +++ b/src/commands/dataSourceCommand.ts @@ -214,52 +214,61 @@ export async function populateScratchpad( export async function runDataSource( dataSourceForm: DataSourceFiles ): Promise { - Object.assign(ext.insightsMeta, await getMeta()); - if (!ext.insightsMeta.assembly) { - ext.outputChannel.appendLine( - `To run a datasource you need to be connected to an Insights server` - ); - window.showErrorMessage( - "To run a datasource you need to be connected to an Insights server" - ); + if (DataSourcesPanel.running) { return; } + DataSourcesPanel.running = true; - dataSourceForm.insightsNode = getConnectedInsightsNode(); - const fileContent = dataSourceForm; + try { + Object.assign(ext.insightsMeta, await getMeta()); + if (!ext.insightsMeta.assembly) { + ext.outputChannel.appendLine( + `To run a datasource you need to be connected to an Insights server` + ); + window.showErrorMessage( + "To run a datasource you need to be connected to an Insights server" + ); + return; + } - let res: any; - const selectedType = getSelectedType(fileContent); - ext.isDatasourceExecution = true; - switch (selectedType) { - case "API": - res = await runApiDataSource(fileContent); - break; - case "QSQL": - res = await runQsqlDataSource(fileContent); - break; - case "SQL": - default: - res = await runSqlDataSource(fileContent); - break; - } + dataSourceForm.insightsNode = getConnectedInsightsNode(); + const fileContent = dataSourceForm; + + let res: any; + const selectedType = getSelectedType(fileContent); + ext.isDatasourceExecution = true; + switch (selectedType) { + case "API": + res = await runApiDataSource(fileContent); + break; + case "QSQL": + res = await runQsqlDataSource(fileContent); + break; + case "SQL": + default: + res = await runSqlDataSource(fileContent); + break; + } - ext.isDatasourceExecution = false; - if (res.error) { - window.showErrorMessage(res.error); - } else if (ext.resultsViewProvider.isVisible()) { - writeQueryResultsToView( - res, - getQuery(fileContent, selectedType), - selectedType - ); - } else { - const resString = arrayToTable(res); - writeQueryResultsToConsole( - resString, - getQuery(fileContent, selectedType), - selectedType - ); + ext.isDatasourceExecution = false; + if (res.error) { + window.showErrorMessage(res.error); + } else if (ext.resultsViewProvider.isVisible()) { + writeQueryResultsToView( + res, + getQuery(fileContent, selectedType), + selectedType + ); + } else { + const resString = arrayToTable(res); + writeQueryResultsToConsole( + resString, + getQuery(fileContent, selectedType), + selectedType + ); + } + } finally { + DataSourcesPanel.running = false; } } diff --git a/src/models/messages.ts b/src/models/messages.ts index 69f8fc93..95c34afc 100644 --- a/src/models/messages.ts +++ b/src/models/messages.ts @@ -19,4 +19,5 @@ export type DataSourceMessage = { insightsMeta: MetaObjectPayload; dataSourceName: string; dataSourceFile: DataSourceFiles; + running?: boolean; }; diff --git a/src/panels/datasource.ts b/src/panels/datasource.ts index 166e1f5d..5b08eae9 100644 --- a/src/panels/datasource.ts +++ b/src/panels/datasource.ts @@ -19,6 +19,8 @@ import { InsightsNode } from "../services/kdbTreeProvider"; import { getNonce } from "../utils/getNonce"; import { getUri } from "../utils/getUri"; +let running = false; + export class DataSourcesPanel { public static currentPanel: DataSourcesPanel | undefined; private uri; @@ -96,6 +98,22 @@ export class DataSourcesPanel { } } + public static set running(flag: boolean) { + running = flag; + const panel = DataSourcesPanel.currentPanel; + if (panel) { + panel.status(); + } + } + + public static get running() { + return running; + } + + public status() { + this._panel.webview.postMessage({ running }); + } + public refresh() { DataSourcesPanel.render(this.uri, this.dataSourceFile); } diff --git a/src/webview/components/kdbDataSourceView.ts b/src/webview/components/kdbDataSourceView.ts index c659045d..a0a613b8 100644 --- a/src/webview/components/kdbDataSourceView.ts +++ b/src/webview/components/kdbDataSourceView.ts @@ -64,6 +64,7 @@ export class KdbDataSourceView extends LitElement { @state() declare qsqlTarget: string; @state() declare qsql: string; @state() declare sql: string; + @state() declare running: boolean; constructor() { super(); @@ -91,6 +92,7 @@ export class KdbDataSourceView extends LitElement { this.qsqlTarget = ""; this.qsql = ""; this.sql = ""; + this.running = false; } connectedCallback() { @@ -105,6 +107,10 @@ export class KdbDataSourceView extends LitElement { private message = (event: MessageEvent) => { const params = event.data; + if (params.running !== undefined) { + this.running = params.running; + return; + } const ds = params.dataSourceFile; this.isInsights = params.isInsights; this.isMetaLoaded = !!params.insightsMeta.dap; @@ -930,6 +936,7 @@ export class KdbDataSourceView extends LitElement { appearance="secondary" class="grow" @click="${this.run}" + ?disabled="${this.running}" >Run diff --git a/test/suite/webview.test.ts b/test/suite/webview.test.ts index aa9c463d..f0fd7e9f 100644 --- a/test/suite/webview.test.ts +++ b/test/suite/webview.test.ts @@ -98,6 +98,15 @@ describe("KdbDataSourceView", () => { }); }); + describe("message", () => { + it("should update status", () => { + view["message"](>{ + data: { running: true }, + }); + assert.strictEqual(view.running, true); + }); + }); + describe("selectTab", () => { it("should return the selected tab", () => { sinon.stub(view, "selectedType").value("DEFAULT");