Skip to content

Commit 18cd29d

Browse files
Merge pull request #741 from bruin-data/feature/add-preview-query-in-side-panel
Add Preview selection for SQL editor
2 parents 26a75fe + 4d4adbb commit 18cd29d

5 files changed

Lines changed: 118 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Changelog
2+
## [0.79.3] - [2026-03-18]
3+
- Added ability to select text in the SQL editor and run the selection directly in Query Preview for debugging.
4+
25
## [0.79.2] - [2026-03-18]
36
- Added cancel button for export query operations, allowing users to stop long-running exports.
47

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "bruin",
33
"displayName": "Bruin",
44
"description": "Manage your Bruin data assets from within VS Code.",
5-
"version": "0.79.2",
5+
"version": "0.79.3",
66
"engines": {
77
"vscode": "^1.87.0"
88
},

src/panels/BruinPanel.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,47 @@ export class BruinPanel {
628628
}
629629
break;
630630

631+
case "bruin.runSelectedInPreview":
632+
trackEvent("Command Executed", { command: "runSelectedInPreview", source: "extension" });
633+
try {
634+
const selectedQuery = message.payload?.query;
635+
if (!selectedQuery) {
636+
vscode.window.showWarningMessage("No text selected to run");
637+
break;
638+
}
639+
640+
const activeTabId = QueryPreviewPanel.getActiveTabId();
641+
642+
// Clear previous state for this tab
643+
QueryPreviewPanel.clearTabState(activeTabId);
644+
645+
// Set the query for this tab
646+
QueryPreviewPanel.setLastExecutedQuery(selectedQuery);
647+
QueryPreviewPanel.setTabQuery(activeTabId, selectedQuery);
648+
649+
// Show loading state
650+
QueryPreviewPanel.postMessage("query-output-message", {
651+
status: "loading",
652+
message: true,
653+
tabId: activeTabId,
654+
});
655+
656+
// Focus the Query Preview panel
657+
await QueryPreviewPanel.focusSafely();
658+
659+
// Execute the query
660+
QueryPreviewPanel.postMessage("bruin.executePreviewQuery", {
661+
status: "success",
662+
message: "",
663+
tabId: activeTabId,
664+
extractedQuery: selectedQuery
665+
});
666+
} catch (error) {
667+
const errorMessage = error instanceof Error ? error.message : String(error);
668+
vscode.window.showErrorMessage(`Error running selection in preview: ${errorMessage}`);
669+
}
670+
break;
671+
631672
case "bruin.validate":
632673
trackEvent("Command Executed", { command: "validate", source: "extension" });
633674
if (!this._lastRenderedDocumentUri) {

webview-ui/src/components/asset/SqlEditor.vue

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
>
1818
DDL
1919
</button>
20+
<span v-if="selectedText" class="separator">|</span>
21+
<button
22+
v-if="selectedText"
23+
@click="runSelectedText"
24+
class="preview-selection-btn"
25+
>
26+
Preview selection
27+
</button>
2028
</div>
2129
<div class="flex items-center">
2230
<!-- BigQuery Cost Estimate (success and error) -->
@@ -100,7 +108,7 @@
100108
</div>
101109
</div>
102110
<!-- Code Editor -->
103-
<div id="sql-editor" class="code-container pb-0">
111+
<div id="sql-editor" class="code-container pb-0" @mouseup="handleTextSelection">
104112
<div class="copy-button-wrapper">
105113
<vscode-button
106114
@click="copyToClipboard"
@@ -176,6 +184,7 @@ const clickOpened = ref(false);
176184
const showCostError = ref(false);
177185
const isErrorSticky = ref(false);
178186
const errorIcon = ref(null);
187+
const selectedText = ref('');
179188
180189
const vClickOutside = {
181190
mounted(el, binding) {
@@ -199,6 +208,36 @@ function copyToClipboard() {
199208
}, 2000);
200209
}
201210
211+
// Handle text selection in the code editor
212+
function handleTextSelection() {
213+
const selection = window.getSelection();
214+
let text = selection?.toString().trim() || '';
215+
216+
// Remove line numbers that get included in selection
217+
// Line numbers appear as standalone numbers on their own line when selected
218+
if (text) {
219+
text = text
220+
.split('\n')
221+
.filter(line => !/^\d+$/.test(line.trim())) // Remove lines that are just numbers (line numbers)
222+
.join('\n')
223+
.trim();
224+
}
225+
226+
selectedText.value = text;
227+
}
228+
229+
// Run selected text in Query Preview panel
230+
function runSelectedText() {
231+
if (!selectedText.value) return;
232+
233+
vscode.postMessage({
234+
command: 'bruin.runSelectedInPreview',
235+
payload: {
236+
query: selectedText.value
237+
}
238+
});
239+
}
240+
202241
const lineHeight = 18;
203242
const editorPadding = 12;
204243
const minEditorHeight = `${lineHeight * 2}px`;
@@ -402,14 +441,25 @@ const handleMessage = (event) => {
402441
}
403442
};
404443
444+
// Handle selection change to clear when deselected
445+
function handleSelectionChange() {
446+
const selection = window.getSelection();
447+
const text = selection?.toString().trim() || '';
448+
if (!text) {
449+
selectedText.value = '';
450+
}
451+
}
452+
405453
// Setup message listeners
406454
onMounted(() => {
407455
window.addEventListener('message', handleMessage);
456+
document.addEventListener('selectionchange', handleSelectionChange);
408457
console.log('SqlEditor: Message listener added');
409458
});
410459
411460
onBeforeUnmount(() => {
412461
window.removeEventListener('message', handleMessage);
462+
document.removeEventListener('selectionchange', handleSelectionChange);
413463
console.log('SqlEditor: Message listener removed');
414464
});
415465
@@ -459,6 +509,26 @@ watch(
459509
background-color: var(--vscode-list-hoverBackground);
460510
}
461511
512+
.separator {
513+
color: var(--vscode-disabledForeground);
514+
font-size: 12px;
515+
margin: 0 4px;
516+
}
517+
518+
.preview-selection-btn {
519+
background: transparent;
520+
border: none;
521+
color: var(--vscode-textLink-foreground);
522+
font-size: 12px;
523+
font-family: var(--vscode-font-family);
524+
cursor: pointer;
525+
padding: 4px 0;
526+
}
527+
528+
.preview-selection-btn:hover {
529+
color: var(--vscode-textLink-activeForeground);
530+
}
531+
462532
#sql-editor,
463533
.python-content {
464534
background-color: var(--vscode-sideBar-background);

0 commit comments

Comments
 (0)