Skip to content

Commit

Permalink
Merge pull request #426 from KxSystems/KXI-53885
Browse files Browse the repository at this point in the history
Fix issues with large results
  • Loading branch information
Philip-Carneiro-KX authored Oct 1, 2024
2 parents 1465b4b + cd9ad5c commit da84b42
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 124 deletions.
2 changes: 1 addition & 1 deletion src/commands/serverCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ export function writeQueryResultsToView(
duration?: string,
isFromConnTree?: boolean,
): void {
commands.executeCommand("kdb.resultsPanel.update", result, isInsights, type);
commands.executeCommand("kdb.resultsPanel.update", result, isInsights);
if (!checkIfIsDatasource(type)) {
addQueryHistory(
query,
Expand Down
8 changes: 2 additions & 6 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,8 @@ export async function activate(context: ExtensionContext) {
),
commands.registerCommand(
"kdb.resultsPanel.update",
(results: string, isInsights: boolean, dataSourceType?: string) => {
ext.resultsViewProvider.updateResults(
results,
isInsights,
dataSourceType,
);
(results: string, isInsights: boolean) => {
ext.resultsViewProvider.updateResults(results, isInsights);
},
),
commands.registerCommand("kdb.resultsPanel.clear", () => {
Expand Down
201 changes: 117 additions & 84 deletions src/services/resultsPanelProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import { ext } from "../extensionVariables";
import * as utils from "../utils/execution";
import { getNonce } from "../utils/getNonce";
import { getUri } from "../utils/getUri";
import { kdbOutputLog } from "../utils/core";

export class KdbResultsViewProvider implements WebviewViewProvider {
public static readonly viewType = "kdb-results";
private _view?: WebviewView;
public isInsights = false;
public _colorTheme: any;
private _view?: WebviewView;
private _results: string | string[] = "";

constructor(private readonly _extensionUri: Uri) {
Expand All @@ -48,10 +50,11 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
localResourceRoots: [Uri.joinPath(this._extensionUri, "out")],
};

webviewView.webview.html = this._getWebviewContent("");
webviewView.webview.html = this._getWebviewContent();
this.updateWebView("");

webviewView.webview.onDidReceiveMessage((data) => {
webviewView.webview.html = this._getWebviewContent(data);
this.updateWebView(data);
});
webviewView.onDidChangeVisibility(() => {
ext.isResultsTabVisible = webviewView.visible;
Expand All @@ -62,19 +65,11 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
});
}

public updateResults(
queryResults: any,
isInsights?: boolean,
dataSourceType?: string,
) {
public updateResults(queryResults: any, isInsights?: boolean) {
if (this._view) {
this._view.show?.(true);
this._view.webview.postMessage(queryResults);
this._view.webview.html = this._getWebviewContent(
queryResults,
isInsights,
dataSourceType,
);
this.isInsights = !!isInsights;
this.updateWebView(queryResults);
}
}

Expand Down Expand Up @@ -176,7 +171,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
}
}

convertToGrid(results: any, isInsights: boolean): string {
convertToGrid(results: any, isInsights: boolean): any {
const queryResult = isInsights ? results.rows : results;

const columnDefs = this.generateCoumnDefs(results, isInsights);
Expand All @@ -199,7 +194,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
if (rowData.length > 0) {
ext.resultPanelCSV = this.convertToCsv(rowData).join("\n");
}
return JSON.stringify({
return {
defaultColDef: {
sortable: true,
resizable: true,
Expand All @@ -217,7 +212,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
suppressContextMenu: true,
suppressDragLeaveHidesColumns: true,
tooltipShowDelay: 200,
});
};
}

isVisible(): boolean {
Expand Down Expand Up @@ -251,84 +246,122 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
: "";
}

private _getWebviewContent(
queryResult: any,
isInsights?: boolean,
_dataSourceType?: string,
) {
public updateWebView(queryResult: any) {
ext.resultPanelCSV = "";
this._results = queryResult;
let result = "";
let gridOptions = undefined;
if (!this._view) {
kdbOutputLog("[Results Tab] No view to update", "ERROR");
return;
}
if (typeof queryResult === "string" || typeof queryResult === "number") {
result =
queryResult !== ""
? `<p class="results-txt">${queryResult
.toString()
.replace(/\n/g, "<br/>")}</p>`
: "<p>No results to show</p>";
} else if (queryResult) {
gridOptions = this.convertToGrid(queryResult, this.isInsights);
}
if (gridOptions) {
this._view.webview.postMessage({
command: "setGridOptions",
gridOptions: gridOptions,
});
} else {
this._view.webview.postMessage({
command: "setResultsContent",
results: result,
});
}
}

private _getWebviewContent() {
const agGridTheme = this.defineAgGridTheme();
if (this._view) {
const webviewUri = getUri(this._view.webview, this._extensionUri, [
"out",
"webview.js",
]);
const nonce = getNonce();
let result = "";
let gridOptionsString = "";
return /*html*/ `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="stylesheet" href="${this._getLibUri("reset.css")}" />
<link rel="stylesheet" href="${this._getLibUri("vscode.css")}" />
<link rel="stylesheet" href="${this._getLibUri("resultsPanel.css")}" />
<link rel="stylesheet" href="${this._getLibUri("ag-grid.min.css")}" />
<link rel="stylesheet" href="${this._getLibUri(
"ag-theme-alpine.min.css",
)}" />
<title>Q Results</title>
<script nonce="${nonce}" src="${this._getLibUri(
"ag-grid-community.min.js",
)}"></script>
</head>
<body>
<div id="results" class="results-view-container">
<div class="content-wrapper"></div>
</div>
<script type="module" nonce="${nonce}" src="${webviewUri}"></script>
<div id="grid" style="height: 100%; width:100%;" class="${agGridTheme}"></div>
<script nonce="${nonce}" >
const vscode = acquireVsCodeApi();
let gridApi;
let isGrid = false;
if (typeof queryResult === "string" || typeof queryResult === "number") {
result =
queryResult !== ""
? `<p class="results-txt">${queryResult
.toString()
.replace(/\n/g, "<br/>")}</p>`
: "<p>No results to show</p>";
} else if (queryResult) {
isGrid = true;
gridOptionsString = this.convertToGrid(queryResult, !!isInsights);
}
function saveColumnWidths() {
if (!gridApi) {return null};
return gridApi.getAllColumns().map(col => ({
colId: col.getColId(),
width: col.getActualWidth()
}));
}
result =
gridOptionsString === ""
? result !== ""
? result
: "<p>No results to show</p>"
: "";
return /*html*/ `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="stylesheet" href="${this._getLibUri("reset.css")}" />
<link rel="stylesheet" href="${this._getLibUri("vscode.css")}" />
<link rel="stylesheet" href="${this._getLibUri("resultsPanel.css")}" />
<link rel="stylesheet" href="${this._getLibUri("ag-grid.min.css")}" />
<link rel="stylesheet" href="${this._getLibUri(
"ag-theme-alpine.min.css",
)}" />
<title>Q Results</title>
<script nonce="${nonce}" src="${this._getLibUri(
"ag-grid-community.min.js",
)}"></script>
</head>
<body>
<div id="results" class="results-view-container">
<div class="content-wrapper">
${result}
</div>
</div>
<script type="module" nonce="${nonce}" src="${webviewUri}"></script>
<div id="grid" style="height: 100%; width:100%;" class="${agGridTheme}"></div>
<script nonce="${nonce}" >
document.addEventListener('DOMContentLoaded', () => {
if(${isGrid}){
const gridDiv = document.getElementById('grid');
const obj = JSON.parse('${gridOptionsString}');
const gridApi = agGrid.createGrid(gridDiv, obj);
document.getElementById("results").scrollIntoView();
}
});
document.addEventListener('contextmenu', (e) => {
e.stopImmediatePropagation()
}, true);
</script>
</body>
</html>
`;
function restoreColumnWidths(columnWidths) {
if (!gridApi || !columnWidths) return;
columnWidths.forEach(colWidth => {
gridApi.getColumnState().forEach(colState => {
if (colState.colId === colWidth.colId) {
colState.width = colWidth.width;
}
});
});
gridApi.setColumnState(gridApi.getColumnState());
}
window.addEventListener('message', event => {
const message = event.data;
if (message.command === 'setGridOptions') {
const columnWidths = saveColumnWidths();
const gridOptions = message.gridOptions;
const gridDiv = document.getElementById('grid');
const resultsDiv = document.querySelector('#results .content-wrapper');
resultsDiv.innerHTML = '';
gridDiv.innerHTML = '';
gridApi = agGrid.createGrid(gridDiv, gridOptions);
restoreColumnWidths(columnWidths);
document.getElementById("results").scrollIntoView();
} else if (message.command === 'setResultsContent') {
const resultsContent = message.results;
const resultsDiv = document.querySelector('#results .content-wrapper');
const gridDiv = document.getElementById('grid');
gridDiv.innerHTML = '';
resultsDiv.innerHTML = '';
resultsDiv.innerHTML = resultsContent;
}
});
document.addEventListener('contextmenu', (e) => {
e.stopImmediatePropagation();
}, true);
</script>
</body>
</html>
`;
} else {
return "";
}
Expand Down
3 changes: 2 additions & 1 deletion src/webview/styles/resultsPanel.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
html,
body {
height: 86vh;
width: 100%;
width: 99%;
padding: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
Expand Down
2 changes: 0 additions & 2 deletions test/suite/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import assert from "assert";
import mock from "mock-fs";
import * as sinon from "sinon";
import * as vscode from "vscode";
import * as fs from "fs";
import * as dataSourceCommand from "../../src/commands/dataSourceCommand";
import * as installTools from "../../src/commands/installTools";
import * as serverCommand from "../../src/commands/serverCommand";
Expand Down Expand Up @@ -1307,7 +1306,6 @@ describe("serverCommand", () => {
"kdb.resultsPanel.update",
result,
false,
"WORKBOOK",
);

executeCommandStub.restore();
Expand Down
Loading

0 comments on commit da84b42

Please sign in to comment.