Skip to content

Commit 6678ba2

Browse files
authored
Merge pull request #217 from codefori/feature/result_table_footer
Add footer to results table so status is always visible
2 parents ad2f9d1 + f33b579 commit 6678ba2

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

src/views/html.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ export function getHeader(options: {withCollapsed?: boolean} = {}): string {
2020
top: 0; /* Don't forget this, required for the stickiness */
2121
}
2222
23+
tfoot tr {
24+
background-color: var(--vscode-multiDiffEditor-headerBackground);
25+
text-align: left;
26+
position: sticky; /* Lock the footer row to the bottom so it's always visible as rows are scrolled */
27+
bottom: 0; /* Don't forget this, required for the stickiness */
28+
}
29+
2330
#resultset th,
2431
#resultset td {
2532
padding: 5px 15px;

src/views/results/html.ts

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,27 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
5252
*/
5353
const vscode = acquireVsCodeApi();
5454
const basicSelect = ${JSON.stringify(basicSelect)};
55+
const htmlTableId = 'resultset';
56+
const statusId = 'status';
57+
const messageSpanId = 'messageSpan';
58+
5559
let myQueryId = '';
56-
57-
let mustLoadHeaders = true;
60+
let needToInitializeTable = true;
5861
let totalRows = 0;
5962
let noMoreRows = false;
6063
let isFetching = false;
6164
6265
window.addEventListener("load", main);
6366
function main() {
64-
let Observer = new IntersectionObserver(function(entries) {
67+
new IntersectionObserver(function(entries) {
6568
// isIntersecting is true when element and viewport are overlapping
6669
// isIntersecting is false when element and viewport don't overlap
6770
if(entries[0].isIntersecting === true) {
6871
if (isFetching === false && noMoreRows === false) {
6972
fetchNextPage();
7073
}
7174
}
72-
}, { threshold: [0] });
73-
74-
Observer.observe(document.getElementById("nextButton"));
75+
}, { threshold: [0] }).observe(document.getElementById(messageSpanId));
7576
7677
window.addEventListener('message', event => {
7778
const data = event.data;
@@ -85,21 +86,21 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
8586
isFetching = false;
8687
noMoreRows = data.isDone;
8788
88-
if (mustLoadHeaders && event.data.columnList) {
89-
setHeaders('resultset', event.data.columnList);
90-
mustLoadHeaders = false;
89+
if (needToInitializeTable && event.data.columnList) {
90+
initializeTable(event.data.columnList);
91+
needToInitializeTable = false;
9192
}
9293
9394
if (data.rows && data.rows.length > 0) {
9495
totalRows += data.rows.length;
95-
appendRows('resultset', data.rows);
96+
appendRows(data.rows);
9697
}
9798
98-
const nextButton = document.getElementById("nextButton");
9999
if (data.rows === undefined && totalRows === 0) {
100-
nextButton.innerText = 'Query executed with no result set returned. Rows affected: ' + data.update_count;
100+
document.getElementById(messageSpanId).innerText = 'Statement executed with no result set returned. Rows affected: ' + data.update_count;
101101
} else {
102-
nextButton.innerText = noMoreRows ? ('Loaded ' + totalRows + '. End of data') : ('Loaded ' + totalRows + '. Fetching more...');
102+
document.getElementById(statusId).innerText = noMoreRows ? ('Loaded ' + totalRows + '. End of data') : ('Loaded ' + totalRows + '. More available.');
103+
document.getElementById(messageSpanId).style.visibility = "hidden";
103104
}
104105
break;
105106
@@ -124,27 +125,26 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
124125
document.getElementById("spinnerContent").style.display = 'none';
125126
}
126127
127-
function setHeaders(tableId, columns) {
128-
var tHeadRef = document.getElementById(tableId).getElementsByTagName('thead')[0];
129-
tHeadRef.innerHTML = '';
130-
131-
// Insert a row at the end of table
132-
var newRow = tHeadRef.insertRow();
133-
134-
columns.forEach(colName => {
135-
// Insert a cell at the end of the row
136-
var newCell = newRow.insertCell();
137-
138-
// Append a text node to the cell
139-
var newText = document.createTextNode(colName);
140-
newCell.appendChild(newText);
141-
});
128+
function initializeTable(columns) {
129+
// Initialize the header
130+
var header = document.getElementById(htmlTableId).getElementsByTagName('thead')[0];
131+
header.innerHTML = '';
132+
var headerRow = header.insertRow();
133+
columns.forEach(colName => headerRow.insertCell().appendChild(document.createTextNode(colName)));
134+
135+
// Initialize the footer
136+
var footer = document.getElementById(htmlTableId).getElementsByTagName('tfoot')[0];
137+
footer.innerHTML = '';
138+
var newCell = footer.insertRow().insertCell();
139+
newCell.colSpan = columns.length;
140+
newCell.id = statusId;
141+
newCell.appendChild(document.createTextNode(' '));
142142
}
143143
144-
function appendRows(tableId, arrayOfObjects) {
145-
var tBodyRef = document.getElementById(tableId).getElementsByTagName('tbody')[0];
144+
function appendRows(rows) {
145+
var tBodyRef = document.getElementById(htmlTableId).getElementsByTagName('tbody')[0];
146146
147-
for (const row of arrayOfObjects) {
147+
for (const row of rows) {
148148
// Insert a row at the end of table
149149
var newRow = tBodyRef.insertRow()
150150
@@ -170,8 +170,9 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
170170
<table id="resultset">
171171
<thead></thead>
172172
<tbody></tbody>
173-
</table>
174-
<p id="nextButton"></p>
173+
<tfoot></tfoot>
174+
</table>
175+
<p id="messageSpan"></p>
175176
<div id="spinnerContent" class="center-screen">
176177
<p id="loadingText">Running statement</p>
177178
<span class="loader"></span>

0 commit comments

Comments
 (0)