Skip to content

Commit 00fc23d

Browse files
committed
Cancel button in webview
Signed-off-by: worksofliam <[email protected]>
1 parent f8f8368 commit 00fc23d

File tree

4 files changed

+90
-55
lines changed

4 files changed

+90
-55
lines changed

src/views/html.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ export function getHeader(options: {withCollapsed?: boolean} = {}): string {
6767
min-height: 100vh;
6868
}
6969
70+
.primaryButton {
71+
background-color: var(--vscode-button-background);
72+
color: var(--vscode-button-foreground);
73+
border: none;
74+
border-radius: 5px;
75+
padding: 5px 10px;
76+
cursor: pointer;
77+
}
78+
7079
/* https://cssloaders.github.io */
7180
.loader {
7281
width: 32px;

src/views/results/html.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function getLoadingHTML(): string {
3838
`;
3939
}
4040

41-
export function generateScroller(basicSelect: string, isCL: boolean): string {
41+
export function generateScroller(basicSelect: string, isCL: boolean, withCancel?: boolean): string {
4242
const withCollapsed = Configuration.get<boolean>('collapsedResultSet');
4343

4444
return /*html*/`
@@ -121,6 +121,17 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
121121
break;
122122
}
123123
});
124+
125+
const cancelButton = document.getElementById('cancelButton');
126+
127+
if (cancelButton) {
128+
cancelButton.addEventListener('click', () => {
129+
vscode.postMessage({
130+
command: 'cancel',
131+
queryId: myQueryId
132+
});
133+
});
134+
}
124135
}
125136
126137
function fetchNextPage() {
@@ -206,6 +217,7 @@ export function generateScroller(basicSelect: string, isCL: boolean): string {
206217
<div id="spinnerContent" class="center-screen">
207218
<p id="loadingText">Running statement</p>
208219
<span class="loader"></span>
220+
${withCancel ? `<button id="cancelButton" class="primaryButton">Cancel</button>` : ``}
209221
</div>
210222
</body>
211223
</html>

src/views/results/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,20 @@ async function runHandler(options?: StatementInfo) {
207207

208208
if (statementDetail.content.trim().length > 0) {
209209
try {
210+
const inWindow = Boolean(options && options.viewColumn);
211+
210212
if (statementDetail.qualifier === `cl`) {
211-
if (options && options.viewColumn) {
213+
if (inWindow) {
212214
useWindow(`CL results`, options.viewColumn);
213215
}
214216
chosenView.setScrolling(statementDetail.content, true); // Never errors
217+
215218
} else if (statementDetail.qualifier === `statement`) {
216219
// If it's a basic statement, we can let it scroll!
217-
if (options && options.viewColumn) {
220+
if (inWindow) {
218221
useWindow(possibleTitle, options.viewColumn);
219222
}
220-
chosenView.setScrolling(statementDetail.content); // Never errors
223+
chosenView.setScrolling(statementDetail.content, false, undefined, inWindow); // Never errors
221224

222225
} else if ([`explain`, `onlyexplain`].includes(statementDetail.qualifier)) {
223226
// If it's an explain, we need to

src/views/results/resultSetPanelProvider.ts

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ import Configuration from "../../configuration";
88
import * as html from "./html";
99

1010
export class ResultSetPanelProvider implements WebviewViewProvider {
11-
_view: WebviewView|WebviewPanel;
11+
_view: WebviewView | WebviewPanel;
1212
loadingState: boolean;
1313
currentQuery: Query<any>;
1414
constructor() {
1515
this._view = undefined;
1616
this.loadingState = false;
1717
}
1818

19-
resolveWebviewView(webviewView: WebviewView|WebviewPanel, context?: WebviewViewResolveContext, _token?: CancellationToken) {
19+
resolveWebviewView(webviewView: WebviewView | WebviewPanel, context?: WebviewViewResolveContext, _token?: CancellationToken) {
2020
this._view = webviewView;
2121

2222
this._view.onDidDispose(() => {
@@ -33,54 +33,65 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
3333

3434
webviewView.webview.html = html.getLoadingHTML();
3535
this._view.webview.onDidReceiveMessage(async (message) => {
36-
if (message.query) {
37-
38-
if (this.currentQuery) {
39-
// If we get a request for a new query, then we need to close the old one
40-
if (this.currentQuery.getId() !== message.queryId) {
41-
// This is a new query, so we need to clean up the old one
36+
switch (message.command) {
37+
case `cancel`:
38+
commands.executeCommand(`vscode-db2i.statement.cancel`);
39+
if (this.currentQuery) {
4240
await this.currentQuery.close();
43-
this.currentQuery = undefined;
4441
}
45-
}
46-
47-
try {
48-
setCancelButtonVisibility(true);
49-
if (this.currentQuery === undefined) {
50-
// We will need to revisit this if we ever allow multiple result tabs like ACS does
51-
// Query.cleanup();
52-
53-
let query = await JobManager.getPagingStatement(message.query, { isClCommand: message.isCL, autoClose: true, isTerseResults: true });
54-
this.currentQuery = query;
42+
break;
43+
44+
default:
45+
if (message.query) {
46+
47+
if (this.currentQuery) {
48+
// If we get a request for a new query, then we need to close the old one
49+
if (this.currentQuery.getId() !== message.queryId) {
50+
// This is a new query, so we need to clean up the old one
51+
await this.currentQuery.close();
52+
this.currentQuery = undefined;
53+
}
54+
}
55+
56+
try {
57+
setCancelButtonVisibility(true);
58+
if (this.currentQuery === undefined) {
59+
// We will need to revisit this if we ever allow multiple result tabs like ACS does
60+
// Query.cleanup();
61+
62+
let query = await JobManager.getPagingStatement(message.query, { isClCommand: message.isCL, autoClose: true, isTerseResults: true });
63+
this.currentQuery = query;
64+
}
65+
66+
let queryResults = this.currentQuery.getState() == QueryState.RUN_MORE_DATA_AVAILABLE ? await this.currentQuery.fetchMore() : await this.currentQuery.run();
67+
68+
const jobId = this.currentQuery.getHostJob().id;
69+
70+
this._view.webview.postMessage({
71+
command: `rows`,
72+
jobId,
73+
rows: queryResults.data,
74+
columnMetaData: queryResults.metadata ? queryResults.metadata.columns : undefined, // Query.fetchMore() doesn't return the metadata
75+
columnHeadings: Configuration.get(`resultsets.columnHeadings`) || 'Name',
76+
queryId: this.currentQuery.getId(),
77+
update_count: queryResults.update_count,
78+
isDone: queryResults.is_done
79+
});
80+
81+
} catch (e) {
82+
this.setError(e.message);
83+
this._view.webview.postMessage({
84+
command: `rows`,
85+
rows: [],
86+
queryId: ``,
87+
isDone: true
88+
});
89+
}
90+
91+
setCancelButtonVisibility(false);
92+
updateStatusBar();
5593
}
56-
57-
let queryResults = this.currentQuery.getState() == QueryState.RUN_MORE_DATA_AVAILABLE ? await this.currentQuery.fetchMore() : await this.currentQuery.run();
58-
59-
const jobId = this.currentQuery.getHostJob().id;
60-
61-
this._view.webview.postMessage({
62-
command: `rows`,
63-
jobId,
64-
rows: queryResults.data,
65-
columnMetaData: queryResults.metadata ? queryResults.metadata.columns : undefined, // Query.fetchMore() doesn't return the metadata
66-
columnHeadings: Configuration.get(`resultsets.columnHeadings`) || 'Name',
67-
queryId: this.currentQuery.getId(),
68-
update_count: queryResults.update_count,
69-
isDone: queryResults.is_done
70-
});
71-
72-
} catch (e) {
73-
this.setError(e.message);
74-
this._view.webview.postMessage({
75-
command: `rows`,
76-
rows: [],
77-
queryId: ``,
78-
isDone: true
79-
});
80-
}
81-
82-
setCancelButtonVisibility(false);
83-
updateStatusBar();
94+
break;
8495
}
8596
});
8697
}
@@ -92,11 +103,11 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
92103
await delay(100);
93104
currentLoop += 1;
94105
}
95-
106+
96107
if (this._view && 'show' in this._view) {
97108
this._view.show(true);
98109
}
99-
110+
100111
}
101112

102113
async focus() {
@@ -132,11 +143,11 @@ export class ResultSetPanelProvider implements WebviewViewProvider {
132143
}
133144
}
134145

135-
async setScrolling(basicSelect, isCL = false, queryId: string = ``) {
146+
async setScrolling(basicSelect, isCL = false, queryId: string = ``, withCancel = false) {
136147
this.loadingState = false;
137148
await this.focus();
138149

139-
this._view.webview.html = html.generateScroller(basicSelect, isCL);
150+
this._view.webview.html = html.generateScroller(basicSelect, isCL, withCancel);
140151

141152
this._view.webview.postMessage({
142153
command: `fetch`,

0 commit comments

Comments
 (0)