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

Create a single-page application for Query Viewer #22621

Merged
merged 1 commit into from Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -93,6 +93,13 @@ To simplify iteration, you can also run in `watch` mode, which automatically re-

To iterate quickly, simply re-build the project in IntelliJ after packaging is complete. Project resources will be hot-reloaded and changes are reflected on browser refresh.

To build the query viewer page, a single-page application which shows the query details from a JSON file,
run the following command:

yarn --cwd presto-main/src/main/resources/webapp/src run spa

You can find a HTML file named `query_viewer.html` in the `presto-main/src/main/resources/webapp` directory.

## Presto native and Velox

[Presto native](https://github.com/prestodb/presto/tree/master/presto-native-execution) is a C++ rewrite of Presto worker. [Presto native](https://github.com/prestodb/presto/tree/master/presto-native-execution) uses [Velox](https://github.com/facebookincubator/velox) as its primary engine to run presto workloads.
Expand Down
5 changes: 4 additions & 1 deletion presto-main/src/main/resources/webapp/src/package.json
Expand Up @@ -14,6 +14,8 @@
"babel-loader": "9.1.3",
"css-loader": "^6.8.1",
"flow-bin": "^0.215.1",
"html-inline-script-webpack-plugin": "^3.2.1",
"html-webpack-plugin": "^5.6.0",
"style-loader": "^3.3.3",
"webpack": "5.88.2",
"webpack-cli": "^5.1.4",
Expand All @@ -37,6 +39,7 @@
"install": "webpack --env=production --config webpack.config.js",
"package": "webpack --env=production --config webpack.config.js",
"watch": "webpack --config webpack.config.js --watch",
"serve": "webpack serve --config webpack.config.js"
"serve": "webpack serve --config webpack.config.js",
"spa": "webpack --env=production --config webpack-single-page.config.js"
}
}
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="description" content="Plan Viewer - Presto">
<title>Plan Viewer - Presto</title>

<link rel="icon" href="http://prestodb.io/docs/current/_static/favicon.ico">

<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->

<!-- jQuery -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>

<!-- Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

<!-- Sparkline -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-timeline/7.7.2/vis-timeline-graph2d.min.css">
<!-- vis-timeline -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-timeline/7.7.2/vis-timeline-graph2d.min.js"></script>

<style type="text/css">
.vis-timeline .item {
padding: 0px;
}
.vis-timeline .labelset .vlabel .inner {
padding: 0px;
}
.vis-timeline .item.range {
height: 3px;
}
.vis-timeline .red {
background-color: #F2DEDE;
border-color: #F2AEAE;
}
.vis-timeline .green {
background-color: #DFF0DB;
border-color: #B8F0AA;
}
.vis-timeline .blue {
background-color: #E3E9FC;
border-color: #B0C3FC;
}
.vis-timeline .orange {
background-color: #FFA500;
border-color: #B0C3FC;
}
#legend {
padding: 10px 40px;
display: grid;
grid-template-columns: 1fr 200px 200px 200px 200px 1fr;
}
#legend .bar {
border-style: solid;
border-width: 1px;
width: 200px;
height: 4px;
}
#legend .text {
margin-left: -20px;
}
#legend .red {
background-color: #F2DEDE;
border-color: #F2AEAE;
}
#legend .green {
background-color: #DFF0DB;
border-color: #B8F0AA;
}
#legend .blue {
background-color: #E3E9FC;
border-color: #B0C3FC;
}
#legend .orange {
background-color: #FFA500;
border-color: #B0C3FC;
}
#legend .empty {
border-style: none;
}
</style>
</head>

<body>

<div class="container">
<div id="title"></div>

<div id="query-view-container" style="margin-top: -20px">
</div>
</div> <!-- /container -->

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700" rel="stylesheet">

</body>
</html>
@@ -0,0 +1,74 @@
/* global __dirname */
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlInlineScriptPlugin = require('html-inline-script-webpack-plugin');
const path = require('node:path');
const TerserPlugin = require("terser-webpack-plugin");

module.exports = (env) => {
const mode = env.production ? 'production' : 'development';
return {
entry: {
'query_viewer': { import: path.join(__dirname, 'query_viewer.jsx'), filename: path.join('dev', '[name].js')},
'bootstrap_css': path.join(__dirname, '..', 'vendor', 'bootstrap', 'css', 'bootstrap.min.external-fonts.css'),
'css_loader': path.join(__dirname, '..', 'vendor', 'css-loaders', 'loader.css'),
'css_loader': path.join(__dirname, '..', 'assets', 'presto.css'),
},
externals: {
// substitutes `require('vis-timeline/standalone')` to `global.vis`
'vis-timeline/standalone': 'vis',
},
mode,
module: {
rules: [
{
test: /\.(?:js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }],
['@babel/preset-react', {runtime: "automatic"}],
['@babel/preset-flow']
],
},
}
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
]
},
resolve: {
extensions: ['.*', '.js', '.jsx']
},
output: {
path: __dirname,
},
optimization: {
minimize: mode === 'production',
minimizer: [
new TerserPlugin({
// do not genreate *.LICENSE.txt files
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
, '...'],
},
plugins: [
new HtmlWebpackPlugin({
inject: 'body',
filename: 'query_viewer.html',
template: 'templates/query_viewer.html',
}),
new HtmlInlineScriptPlugin({
htmlMatchPattern: [/query_viewer.html$/],
}),
],
};
};