diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16d7dc17..e79a57f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,15 @@
All notable changes to the **kdb VS Code extension** are documented in this file.
+# v1.9.0
+
+### Enhancements
+
+### Fixes
+
+- Fix for results tab flickering , improving of UX
+- Fix for Issue [#382](https://github.com/KxSystems/kx-vscode/issues/382)
+
# v1.8.0
### Enhancements
diff --git a/package.json b/package.json
index 8b958450..d5e669de 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"displayName": "kdb",
"description": "IDE support for kdb product suite including the q programming language",
"publisher": "KX",
- "version": "1.8.0",
+ "version": "1.9.0",
"engines": {
"vscode": "^1.86.0"
},
diff --git a/src/services/resultsPanelProvider.ts b/src/services/resultsPanelProvider.ts
index 31dcf05a..145584c7 100644
--- a/src/services/resultsPanelProvider.ts
+++ b/src/services/resultsPanelProvider.ts
@@ -174,26 +174,52 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
convertToGrid(results: any, isInsights: boolean): any {
const queryResult = isInsights ? results.rows : results;
- const columnDefs = this.generateCoumnDefs(results, isInsights);
let rowData = [];
- if (!isInsights && typeof results[0] === "string") {
- rowData = [];
+ let columnDefs = [];
+
+ if (Array.isArray(queryResult[0])) {
+ if (typeof queryResult[0][0] === "object") {
+ rowData = queryResult[0].map((_, index) => {
+ const row: any = {};
+ queryResult.forEach((subArray: any[]) => {
+ Object.assign(row, subArray[index]);
+ });
+ return row;
+ });
+ } else {
+ rowData = queryResult.map((element: any) => ({ value: element }));
+ }
+ } else {
+ rowData = queryResult;
+ }
+
+ if (isInsights) {
+ results.rows = rowData;
+ columnDefs = this.generateCoumnDefs(results, isInsights);
} else {
- rowData = queryResult.map((row: any) => {
- for (const key in row) {
- if (Object.prototype.hasOwnProperty.call(row, key)) {
- row[key] =
- row[key] !== undefined && row[key] !== null
- ? this.sanitizeString(row[key])
- : "";
- }
- }
- return row;
+ columnDefs = this.generateCoumnDefs(rowData, isInsights);
+ }
+
+ if (
+ !columnDefs.some(
+ (col: any) => col.field.toString().toLowerCase() === "index",
+ )
+ ) {
+ rowData = rowData.map((row: any, index: any) => ({
+ index: index + 1,
+ ...row,
+ }));
+ columnDefs.unshift({
+ field: "index",
+ headerName: "Index",
+ cellDataType: "number",
});
}
+
if (rowData.length > 0) {
ext.resultPanelCSV = this.convertToCsv(rowData).join("\n");
}
+
return {
defaultColDef: {
sortable: true,
@@ -202,8 +228,8 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
flex: 1,
minWidth: 100,
},
- rowData,
- columnDefs,
+ rowData: rowData,
+ columnDefs: columnDefs,
domLayout: "autoHeight",
pagination: true,
paginationPageSize: 100,
@@ -212,6 +238,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
suppressContextMenu: true,
suppressDragLeaveHidesColumns: true,
tooltipShowDelay: 200,
+ loading: true,
};
}
@@ -304,7 +331,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
"ag-grid-community.min.js",
)}">
-
+
@@ -321,7 +348,7 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
function restoreColumnWidths(columnWidths) {
if (!gridApi || !columnWidths) return;
- gridApi.applyColumnState({state: columnWidths});
+ gridApi.applyColumnState({state: columnWidths, applyOrder: true,});
}
window.addEventListener('message', event => {
@@ -333,8 +360,14 @@ export class KdbResultsViewProvider implements WebviewViewProvider {
const resultsDiv = document.querySelector('#results .content-wrapper');
resultsDiv.innerHTML = '';
gridDiv.innerHTML = '';
+ const rowData = gridOptions.rowData;
+ gridOptions.rowData = [];
gridApi = agGrid.createGrid(gridDiv, gridOptions);
restoreColumnWidths(columnWidths);
+ setTimeout(() => {
+ gridApi.setGridOption("rowData", rowData);
+ gridApi.setGridOption("loading", false);
+ }, 500);
document.getElementById("results").scrollIntoView();
} else if (message.command === 'setResultsContent') {
const resultsContent = message.results;
diff --git a/test/suite/panels.test.ts b/test/suite/panels.test.ts
index fe9d4e20..20d6196f 100644
--- a/test/suite/panels.test.ts
+++ b/test/suite/panels.test.ts
@@ -178,7 +178,7 @@ describe("WebPanels", () => {
});
describe("convertToGrid()", () => {
- it("should convert results to grid format for inisights", () => {
+ it("should convert results to grid format for insights", () => {
const results = {
rows: [
{ prop1: "value1", prop2: "value2" },
@@ -196,10 +196,11 @@ describe("WebPanels", () => {
minWidth: 100,
},
rowData: [
- { prop1: "value1", prop2: "value2" },
- { prop1: "value3", prop2: "value4" },
+ { index: 1, prop1: "value1", prop2: "value2" },
+ { index: 2, prop1: "value3", prop2: "value4" },
],
columnDefs: [
+ { field: "index", headerName: "Index", cellDataType: "number" },
{
field: "prop1",
headerName: "prop1",
@@ -221,6 +222,7 @@ describe("WebPanels", () => {
suppressContextMenu: true,
suppressDragLeaveHidesColumns: true,
tooltipShowDelay: 200,
+ loading: true,
});
// Mock ext.connectionNode
@@ -234,7 +236,7 @@ describe("WebPanels", () => {
stub.restore();
});
- it("should convert results to grid format with empty rows ", () => {
+ it("should convert results to grid format with empty rows", () => {
const results = {
rows: [],
meta: { prop1: "type1", prop2: "type2" },
@@ -250,6 +252,7 @@ describe("WebPanels", () => {
},
rowData: [],
columnDefs: [
+ { field: "index", headerName: "Index", cellDataType: "number" },
{
field: "prop1",
headerName: "prop1",
@@ -271,6 +274,112 @@ describe("WebPanels", () => {
suppressContextMenu: true,
suppressDragLeaveHidesColumns: true,
tooltipShowDelay: 200,
+ loading: true,
+ });
+
+ // Mock ext.connectionNode
+ const stub = sinon.stub(ext, "activeConnection");
+ stub.get(() => insightsConn);
+
+ const output = resultsPanel.convertToGrid(results, true);
+ assert.equal(JSON.stringify(output), expectedOutput);
+
+ // Restore the stub
+ stub.restore();
+ });
+
+ it("should convert results to grid format when queryResult[0] is an array of objects", () => {
+ const results = {
+ rows: [
+ [{ sym: "a" }, { sym: "b" }, { sym: "c" }],
+ [{ val: 1 }, { val: 2 }, { val: 3 }],
+ ],
+ meta: { sym: "type1", val: "type2" },
+ };
+
+ const expectedOutput = JSON.stringify({
+ defaultColDef: {
+ sortable: true,
+ resizable: true,
+ filter: true,
+ flex: 1,
+ minWidth: 100,
+ },
+ rowData: [
+ { index: 1, sym: "a", val: 1 },
+ { index: 2, sym: "b", val: 2 },
+ { index: 3, sym: "c", val: 3 },
+ ],
+ columnDefs: [
+ { field: "index", headerName: "Index", cellDataType: "number" },
+ {
+ field: "sym",
+ headerName: "sym",
+ headerTooltip: "type1",
+ cellDataType: "text",
+ },
+ {
+ field: "val",
+ headerName: "val",
+ headerTooltip: "type2",
+ cellDataType: "text",
+ },
+ ],
+ domLayout: "autoHeight",
+ pagination: true,
+ paginationPageSize: 100,
+ enableCellTextSelection: true,
+ ensureDomOrder: true,
+ suppressContextMenu: true,
+ suppressDragLeaveHidesColumns: true,
+ tooltipShowDelay: 200,
+ loading: true,
+ });
+
+ // Mock ext.connectionNode
+ const stub = sinon.stub(ext, "activeConnection");
+ stub.get(() => insightsConn);
+
+ const output = resultsPanel.convertToGrid(results, true);
+ assert.equal(JSON.stringify(output), expectedOutput);
+
+ // Restore the stub
+ stub.restore();
+ });
+
+ it("should convert results to grid format when queryResult[0] is an array of non-objects", () => {
+ const results = {
+ rows: [[1, 2, 3]],
+ meta: { value: "type1" },
+ };
+
+ const expectedOutput = JSON.stringify({
+ defaultColDef: {
+ sortable: true,
+ resizable: true,
+ filter: true,
+ flex: 1,
+ minWidth: 100,
+ },
+ rowData: [{ index: 1, value: [1, 2, 3] }],
+ columnDefs: [
+ { field: "index", headerName: "Index", cellDataType: "number" },
+ {
+ field: "value",
+ headerName: "value",
+ headerTooltip: "type1",
+ cellDataType: "text",
+ },
+ ],
+ domLayout: "autoHeight",
+ pagination: true,
+ paginationPageSize: 100,
+ enableCellTextSelection: true,
+ ensureDomOrder: true,
+ suppressContextMenu: true,
+ suppressDragLeaveHidesColumns: true,
+ tooltipShowDelay: 200,
+ loading: true,
});
// Mock ext.connectionNode