Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Sql Preview webview implementation with multi-doc PRQL Sql Preview support #110

Merged
merged 32 commits into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f42ffda
add new ViewContext string enum for the prql view context keys
RandomFractals Feb 17, 2023
54ebeb4
set active prql document uri context key on active prql editor docume…
RandomFractals Feb 17, 2023
46bf190
rename active prql document uri context key
RandomFractals Feb 17, 2023
7007359
move sql preview impl. and utils to new src/views folder
RandomFractals Feb 17, 2023
897baae
reformat all ts code to rollback prior prettier formatting changes
RandomFractals Feb 17, 2023
b28b9c5
first draft of new sql preview webview setup
RandomFractals Feb 17, 2023
45bc01c
minor docs updates for the new SqlPreview class and methods
RandomFractals Feb 17, 2023
a2f5a75
activat prql extension when prql.sqlPreviewPanel is loaded or deseria…
RandomFractals Feb 17, 2023
c27d7b3
register sql preview serializer to reopen sql preview after vscode re…
RandomFractals Feb 17, 2023
dc8d1b1
move all the old sql preview functions to new SqlPreview class
RandomFractals Feb 17, 2023
ae3b5e3
clarify docs in sql preview serializer
RandomFractals Feb 18, 2023
5779ff7
delete utils.ts with one one liner method
RandomFractals Feb 18, 2023
180a70f
move CompilationResult interface to separate ts file
RandomFractals Feb 18, 2023
c27fbf3
refactor webview resource uri and html template construction
RandomFractals Feb 18, 2023
91a02dd
move debounce to sqlPreview.ts and delete utils.ts
RandomFractals Feb 18, 2023
f4c574d
finish webview refactor for multi-instance sql preview
RandomFractals Feb 18, 2023
562496b
sql preview changes to load prql from file after vscode reload
RandomFractals Feb 18, 2023
bae92ff
finalize webview reload and rework compilation results display
RandomFractals Feb 18, 2023
ecce07e
move sql html update to a separate function in sqlPreview.js
RandomFractals Feb 18, 2023
b16b306
remove unused vars and args from new sql preview class and methods
RandomFractals Feb 18, 2023
63ccab6
user prql-logo.png for the sql preview webview panel
RandomFractals Feb 18, 2023
ead788d
remove Sql Preview: prefix from preview panel title
RandomFractals Feb 19, 2023
2a3cbe3
reveal open sql preview on active prql editor change
RandomFractals Feb 19, 2023
fa26e7f
save last prql compilation result instead of just sql html
RandomFractals Feb 19, 2023
2e78022
refactor active sql preview context values update
RandomFractals Feb 19, 2023
f832aad
clear sql preview context values and workspace state on no reveal
RandomFractals Feb 19, 2023
6884886
get clipboard sql content and filename from current sql preview
RandomFractals Feb 19, 2023
3f086c5
clear active sql preview context when new active text editor is not prql
RandomFractals Feb 19, 2023
17e5481
refine sql preview errors display in webview html and js script
RandomFractals Feb 19, 2023
7aacb89
remove theme change template
RandomFractals Feb 19, 2023
86d6034
tidy up margins and spacing in sql-preview.css
RandomFractals Feb 19, 2023
34a55ac
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"main": "out/extension.js",
"activationEvents": [
"onLanguage:prql",
"onWebviewPanel:prql.sqlPreviewPanel",
"onCommand:prql.openSqlPreview",
"onCommand:prql.generateSqlFile",
"onCommand:prql.copySqlToClipboard",
Expand Down
24 changes: 20 additions & 4 deletions resources/sql_output.css → resources/sql-preview.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,31 @@ code {
font-weight: var(--vscode-editor-font-weight) !important;
}

body {
margin: 0px;
padding: 10px;
}

h3 {
margin: 10px 0 0 10px;
color: var(--vscode-editorError-foreground);
}

.error {
padding: 0px;
margin: 0px;
}

#result {
margin: 0px;
padding: 0px;
}

#last-html {
overflow-y: scroll;
max-height: 80vh;
margin-top: 0px;
margin: 0px;
padding: 0px;
}

#error-container {
Expand All @@ -50,13 +66,13 @@ h3 {
}

.error-container-fixed {
left: 20px;
right: 20px;
left: 10px;
right: 10px;
bottom: 0;
position: fixed;
border-top: 2px solid var(--vscode-editorError-foreground);
}

#error-message {
padding-left: 10px;
padding: 0px;
}
25 changes: 25 additions & 0 deletions resources/sql-preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'none';
style-src ##CSP_SOURCE##;
style-src-attr 'unsafe-inline';
script-src ##CSP_SOURCE##;"
/>
<link href="##CSS_URI##" rel="stylesheet" />
<script src="##JS_URI##" type="application/javascript"></script>
<title>PRQL SQL Preview</title>
</head>
<body>
<div id="result">Waiting for a PRQL file...</div>
<div class="error">
<pre id="last-html"></pre>
<div id="error-container">
<pre id="error-message"></pre>
</div>
</div>
</body>
</html>
90 changes: 90 additions & 0 deletions resources/sqlPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// initialize vscode api
const vscode = acquireVsCodeApi();

// prql document vars and view state
let documentUrl = '';
let viewState = {documentUrl: documentUrl};

// add page load handler
window.addEventListener('load', initializeView);

/**
* Initializes sql preview webview.
*/
function initializeView() {
// restore previous view state
viewState = vscode.getState();
if (viewState && viewState.documentUrl) {
// get last previewed prql document url
documentUrl = viewState.documentUrl;
}
else {
// create new empty view config
viewState = {};
viewState.documentUrl = documentUrl;
vscode.setState(viewState);
}

// request initial sql preview load
vscode.postMessage({command: 'refresh'});
}

// add view update handler
window.addEventListener('message', (event) => {
switch (event.data.command) {
case 'update':
// show updated sql preview content
update(event.data.result)
break;
case 'changeTheme':
// do nothing: this webview html is UI theme neutral,
// and will update sql html content on the next edit
break;
case 'refresh':
updateViewState(event.data);
break;
default:
throw new Error('unknown message');
}
});

/**
* Updates Sql Preview view state on initial view load and refresh.
*
* @param {*} prqlInfo Prql document info from webview.
*/
function updateViewState(prqlInfo) {
// get and save prql document url in view state
documentUrl = prqlInfo.documentUrl;
viewState.documentUrl = documentUrl;
vscode.setState(viewState);
}


/**
* Displays updated sql html from compiled PRQL result.
*
* @param {*} compilationResult PRQL compilation result.
*/
function update(compilationResult) {
// show updated sql preview content
const result = compilationResult;
const errorContainer = document.getElementById('error-container');
if (result.status === 'ok') {
document.getElementById('result').innerHTML = result.sqlHtml;
}
else if (result.lastSqlHtml) {
document.getElementById('last-html').innerHTML = result.lastSqlHtml;
document.getElementById('error-container').classList.add('error-container-fixed');
}

if (result.status === 'error' && result.error.message.length > 0) {
// show errors
document.getElementById('error-message').innerHTML = result.error.message;
errorContainer.style.display = 'block';
}
else {
// hide error container
errorContainer.style.display = 'none';
}
}
36 changes: 0 additions & 36 deletions resources/sql_output.html

This file was deleted.

37 changes: 0 additions & 37 deletions resources/sql_output.js

This file was deleted.

61 changes: 36 additions & 25 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as constants from './constants';

import { compile } from './compiler';
import { TextEncoder } from 'util';
import { SqlPreview } from './views/sqlPreview';

/**
* Registers PRQL extension commands.
Expand All @@ -23,12 +24,32 @@ export function registerCommands(context: ExtensionContext) {
registerCommand(context, constants.GenerateSqlFile, generateSqlFile);
registerCommand(context, constants.ViewSettings, viewPrqlSettings);

registerCommand(context, constants.OpenSqlPreview, (documentUri: Uri) => {
if (!documentUri && window.activeTextEditor) {
// use active text editor document Uri
documentUri = window.activeTextEditor.document.uri;
}

// render Sql Preview for the requested PRQL document
SqlPreview.render(context, documentUri);
});

registerCommand(context, constants.CopySqlToClipboard, () => {
const sql: string | undefined = context.workspaceState.get('prql.sql');
if (sql) {
// write the last generated sql code to vscode clipboard

// get last generated prql sql content from workspace state
let sql: string | undefined = context.workspaceState.get('prql.sql');

let sqlFileName = 'SQL';
if (SqlPreview.currentView) {
// get sql filename and content fromn sql preview
sqlFileName = `prql://${path.basename(SqlPreview.currentView.documentUri.path, '.prql')}.sql`;
sql = SqlPreview.currentView.lastCompilationResult?.sql;
}

if (sql !== undefined) {
// write the last active sql preview sql code to vscode clipboard
env.clipboard.writeText(sql);
window.showInformationMessage('PRQL: SQL copied to Clipboard.');
window.showInformationMessage(`Copied ${sqlFileName} to Clipboard.`);
}
});
}
Expand All @@ -45,32 +66,29 @@ function registerCommand(
context: ExtensionContext,
commandId: string,
callback: (...args: any[]) => any,
thisArg?: any
): void {
thisArg?: any): void {

const command: Disposable = commands.registerCommand(
commandId,
async (...args) => {
try {
await callback(...args);
} catch (e: unknown) {
}
catch (e: unknown) {
window.showErrorMessage(String(e));
console.error(e);
}
},
thisArg
);

context.subscriptions.push(command);
}

/**
* Opens vscode Settings panel with PRQL settings.
*/
async function viewPrqlSettings() {
await commands.executeCommand(
constants.WorkbenchActionOpenSettings,
constants.ExtensionId
);
await commands.executeCommand(constants.WorkbenchActionOpenSettings, constants.ExtensionId);
}

/**
Expand All @@ -93,29 +111,22 @@ async function generateSqlFile() {
if (Array.isArray(result)) {
window.showErrorMessage(`PRQL Compile \
${result[0].display ?? result[0].reason}`);
} else {
}
else {
const prqlDocumentUri: Uri = editor.document.uri;
const prqlFilePath = path.parse(prqlDocumentUri.fsPath);
const prqlSettings = workspace.getConfiguration('prql');
const target = <string>prqlSettings.get('target');
const addTargetDialectToSqlFilenames = <boolean>(
prqlSettings.get(constants.AddTargetDialectToSqlFilenames)
);
const addTargetDialectToSqlFilenames =
<boolean>prqlSettings.get(constants.AddTargetDialectToSqlFilenames);

let sqlFilenameSuffix = '';
if (
addTargetDialectToSqlFilenames &&
target !== 'Generic' &&
target !== 'None'
) {
if (addTargetDialectToSqlFilenames && target !== 'Generic' && target !== 'None') {
sqlFilenameSuffix = `.${target.toLowerCase()}`;
}

// create sql filename based on prql file path, name, and current settings
const sqlFilePath = path.join(
prqlFilePath.dir,
`${prqlFilePath.name}${sqlFilenameSuffix}.sql`
);
const sqlFilePath = path.join(prqlFilePath.dir, `${prqlFilePath.name}${sqlFilenameSuffix}.sql`);

// create sql file
const sqlFileUri: Uri = Uri.file(sqlFilePath);
Expand Down
Loading