Skip to content

Commit

Permalink
show self code error table when new errors are detected
Browse files Browse the repository at this point in the history
  • Loading branch information
ajshedivy committed Jan 3, 2024
1 parent 8140afb commit 0ba27a8
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 48 deletions.
148 changes: 108 additions & 40 deletions src/views/results/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,45 +198,113 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
`;
}

export function generateTable(data: any[]): string {
// Function to check if a string is a valid JSON
function isJsonString(str: string): boolean {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}

// Function to generate table rows
function generateRows(data: any[]): string {
let rows = '';
for (const row of data) {
let newRow = '<tr>';
for (const key of row) {
let cellVal = row[key] === undefined ? 'null' : row[key];
if (isJsonString(cellVal)) {
var formattedJson = JSON.stringify(JSON.parse(cellVal), null, 2);
newRow += `<td><pre style="max-height: 100px; overflow-y: auto; margin: 0;">${formattedJson}</pre></td>`;
} else {
newRow += `<td>${cellVal}</td>`;
}
}
newRow += '</tr>';
rows += newRow;
}
return rows;
}

// Generate the table
let table = /*html*/`
<table>
<tbody>
${generateRows(data)}
</tbody>
</table>
`;
export function generateDynamicTable(): string {
// const parsedData = JSON.parse(data);

return /*html*/`
<!DOCTYPE html>
<html lang="en">
<head>
<script>
/*
${new Date().getTime()}
*/
const vscode = acquireVsCodeApi();
let mustLoadHeaders = true;
let totalRows = 0;
window.addEventListener("load", main);
function main() {
window.addEventListener('message', event => {
const data = event.data;
switch (data.command) {
case 'setTableData':
if (mustLoadHeaders && event.data.columnList) {
setHeaders('resultset', event.data.columnList);
mustLoadHeaders = false;
}
if (data.rows && data.rows.length > 0) {
totalRows += data.rows.length;
appendRows('resultset', data.rows);
}
const nextButton = document.getElementById("nextButton");
if (data.rows === undefined && totalRows === 0) {
nextButton.innerText = 'Query executed with no result set returned. Rows affected: ' + data.update_count;
} else {
nextButton.innerText = ('Loaded ' + totalRows + '. End of data');
}
break;
}
});
}
function setHeaders(tableId, columns) {
var tHeadRef = document.getElementById(tableId).getElementsByTagName('thead')[0];
tHeadRef.innerHTML = '';
// Insert a row at the end of table
var newRow = tHeadRef.insertRow();
columns.forEach(colName => {
// Insert a cell at the end of the row
var newCell = newRow.insertCell();
// Append a text node to the cell
var newText = document.createTextNode(colName);
newCell.appendChild(newText);
});
}
function isJsonString(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
function appendRows(tableId, arrayOfObjects) {
var tBodyRef = document.getElementById(tableId).getElementsByTagName('tbody')[0];
for (const row of arrayOfObjects) {
// Insert a row at the end of table
var newRow = tBodyRef.insertRow()
for (const cell of row) {
// Insert a cell at the end of the row
var newCell = newRow.insertCell();
var cellVal = cell === undefined ? 'null' : cell;
// check if cell contains JSON
if (isJsonString(cellVal)) {
var formattedJson = JSON.stringify(JSON.parse(cellVal), null, 2);
// Create a pre tag and apply inline styles for scrolling
var pre = document.createElement('pre');
pre.style.maxHeight = '100px'; // Adjust the height as needed
pre.style.overflowY = 'auto';
pre.style.margin = '0'; // To remove default margin of pre
pre.textContent = formattedJson; // Using textContent to preserve text formatting
newCell.appendChild(pre);
} else {
// Append a text node to the cell
var newText = document.createTextNode(cellVal);
newCell.appendChild(newText);
}
}
}
return table;
}
</script>
</head>
<body>
<table id="resultset">
<thead></thead>
<tbody></tbody>
</table>
<p id="nextButton"></p>
</body>
</html>
`;
}
72 changes: 64 additions & 8 deletions src/views/results/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ResultSetPanelProvider {
}

let queryResults = queryObject.getState() == QueryState.RUN_MORE_DATA_AVAILABLE ? await queryObject.fetchMore() : await queryObject.run();
console.log( queryResults.metadata ? queryResults.metadata.columns.map(x=>x.name) : undefined);
data = queryResults.data;
this._view.webview.postMessage({
command: `rows`,
Expand Down Expand Up @@ -117,9 +118,65 @@ class ResultSetPanelProvider {
queryId: ``
});
}
setError(error) {
// TODO: pretty error
this._view.webview.html = `<p>${error}</p>`;
}
}

class SelfCodePanelProvider {
_view: vscode.WebviewView;
loadingState: boolean;
constructor() {
this._view = undefined;
this.loadingState = false;
}

resolveWebviewView(webviewView: vscode.WebviewView, context: vscode.WebviewViewResolveContext, _token: vscode.CancellationToken) {
this._view = webviewView;

webviewView.webview.options = {
// Allow scripts in the webview
enableScripts: true,
};
webviewView.webview.html = html.getLoadingHTML();
}

async ensureActivation() {
let currentLoop = 0;
while (!this._view && currentLoop < 15) {
await this.focus();
await delay(100);
currentLoop += 1;
}
}

async focus() {
if (!this._view) {
// Weird one. Kind of a hack. _view.show doesn't work yet because it's not initialized.
// But, we can call a VS Code API to focus on the tab, which then
// 1. calls resolveWebviewView
// 2. sets this._view
await vscode.commands.executeCommand(`vscode-db2i.resultset.focus`);
} else {
this._view.show(true);
}
}

async setTableData(data: any[]) {
this._view.webview.html = html.generateTable(data);
await this.focus();

const rows = Object.values(data).map(obj => Object.values(obj));
const cols = Object.keys(data[0]);

const rawhtml = html.generateDynamicTable();

this._view.webview.html = rawhtml;
this._view.webview.postMessage({
command: 'setTableData',
rows: rows,
columnList: cols
});
}

setError(error) {
Expand Down Expand Up @@ -148,7 +205,7 @@ export interface ParsedStatementInfo extends StatementInfo {

export function initialise(context: vscode.ExtensionContext) {
let resultSetProvider = new ResultSetPanelProvider();
let selfCodeErrorProvider = new ResultSetPanelProvider();
let selfCodeErrorProvider = new SelfCodePanelProvider();

context.subscriptions.push(
vscode.window.registerWebviewViewProvider(`vscode-db2i.selfCodeErrorPanel`, selfCodeErrorProvider, {
Expand Down Expand Up @@ -272,14 +329,13 @@ export function initialise(context: vscode.ExtensionContext) {
const data = await JobManager.runSQL(content, undefined);
const hasErrors = data.length > 0;
if(hasErrors) {
selfCodeCache = data.length;
vscode.commands.executeCommand(`setContext`, `vscode-db2i:selfCodeCountChanged`, true);
selfCodeErrorProvider.setTableData(data);
if(data.length !== selfCodeCache) {
if (data.length !== selfCodeCache) {
await vscode.commands.executeCommand(`setContext`, `vscode-db2i:selfCodeCountChanged`, true);
await selfCodeErrorProvider.setTableData(data);
selfCodeCache = data.length;
}

} else {
vscode.commands.executeCommand(`setContext`, `vscode-db2i:selfCodeCountChanged`, false);
await vscode.commands.executeCommand(`setContext`, `vscode-db2i:selfCodeCountChanged`, false);
}


Expand Down

0 comments on commit 0ba27a8

Please sign in to comment.