mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Very first baby-steps into the land of modern web development.
Use `esbuild` to build TypeScript, and bundle components together in a minified form for the `lts_node` website. This is very much a work in progress, committing as a checkpoint.
This commit is contained in:
parent
6e36ab7161
commit
a84f590393
3
.gitignore
vendored
3
.gitignore
vendored
@ -59,6 +59,9 @@ src/rust/lqos_anonymous_stats_server/anonymous.sqlite
|
||||
src/rust/long_term_stats/license_server/lqkeys.bin
|
||||
src/rust/long_term_stats/lts_node/lqkeys.bin
|
||||
src/rust/long_term_stats/pgdb/.env
|
||||
src/rust/long_term_stats/site_build/node_modules
|
||||
src/rust/long_term_stats/site_build/output
|
||||
src/rust/long_term_stats/site_build/package-lock.json
|
||||
|
||||
# Ignore Rust build artifacts
|
||||
src/rust/target
|
||||
|
@ -7,9 +7,21 @@ use axum::{
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
|
||||
const JS_BUNDLE: &str = include_str!("../../../site_build/output/app.js");
|
||||
const JS_MAP: &str = include_str!("../../../site_build/output/app.js.map");
|
||||
const CSS: &str = include_str!("../../../site_build/output/style.css");
|
||||
const CSS_MAP: &str = include_str!("../../../site_build/output/style.css.map");
|
||||
const HTML_MAIN: &str = include_str!("../../../site_build/src/main.html");
|
||||
|
||||
pub async fn webserver() {
|
||||
let app = Router::new()
|
||||
.route("/", get(index_page));
|
||||
.route("/", get(index_page))
|
||||
.route("/app.js", get(js_bundle))
|
||||
.route("/app.js.map", get(js_map))
|
||||
.route("/style.css", get(css))
|
||||
.route("/style.css.map", get(css_map))
|
||||
;
|
||||
|
||||
log::info!("Listening for web traffic on 0.0.0.0:9127");
|
||||
axum::Server::bind(&"0.0.0.0:9127".parse().unwrap())
|
||||
@ -19,5 +31,33 @@ pub async fn webserver() {
|
||||
}
|
||||
|
||||
async fn index_page() -> Html<String> {
|
||||
Html("Hello, World!".to_string())
|
||||
Html(HTML_MAIN.to_string())
|
||||
}
|
||||
|
||||
async fn js_bundle() -> axum::response::Response<String> {
|
||||
axum::response::Response::builder()
|
||||
.header("Content-Type", "text/javascript")
|
||||
.body(JS_BUNDLE.to_string())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn js_map() -> axum::response::Response<String> {
|
||||
axum::response::Response::builder()
|
||||
.header("Content-Type", "text/json")
|
||||
.body(JS_MAP.to_string())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn css() -> axum::response::Response<String> {
|
||||
axum::response::Response::builder()
|
||||
.header("Content-Type", "text/css")
|
||||
.body(CSS.to_string())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn css_map() -> axum::response::Response<String> {
|
||||
axum::response::Response::builder()
|
||||
.header("Content-Type", "text/json")
|
||||
.body(CSS_MAP.to_string())
|
||||
.unwrap()
|
||||
}
|
20
src/rust/long_term_stats/site_build/README.md
Normal file
20
src/rust/long_term_stats/site_build/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Site Build
|
||||
|
||||
This folder compiles and packages the website used by `lts_node`. It
|
||||
needs to be compiled and made available to the `lts_node` process.
|
||||
|
||||
Steps: TBA
|
||||
|
||||
## Requirements
|
||||
|
||||
To run the build (as opposed to shipping pre-built files), you need to
|
||||
install `esbuild` and `npm` (ugh). You can do this with:
|
||||
|
||||
```bash
|
||||
(change directory to site_build folder)
|
||||
sudo apt-get install npm
|
||||
npm install --save-exact esbuild
|
||||
````
|
||||
|
||||
You can run the build manually by running `./esbuild.sh` in this
|
||||
directory.
|
12
src/rust/long_term_stats/site_build/esbuild.mjs
Executable file
12
src/rust/long_term_stats/site_build/esbuild.mjs
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env node
|
||||
import * as esbuild from 'esbuild'
|
||||
|
||||
await esbuild.build({
|
||||
entryPoints: ['src/app.ts', 'src/style.css'],
|
||||
bundle: true,
|
||||
minify: true,
|
||||
sourcemap: true,
|
||||
// target: ['chrome58', 'firefox57', 'safari11', 'edge16'],
|
||||
outdir: 'output/',
|
||||
loader: { '.html': 'text'}
|
||||
})
|
7
src/rust/long_term_stats/site_build/package.json
Normal file
7
src/rust/long_term_stats/site_build/package.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/bootstrap": "^5.2.6",
|
||||
"bootstrap": "^5.2.3",
|
||||
"esbuild": "0.17.17"
|
||||
}
|
||||
}
|
4
src/rust/long_term_stats/site_build/src/app.ts
Normal file
4
src/rust/long_term_stats/site_build/src/app.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import { LoginPage } from './login/login';
|
||||
|
||||
let loginPanel = new LoginPage();
|
4
src/rust/long_term_stats/site_build/src/html.d.ts
vendored
Normal file
4
src/rust/long_term_stats/site_build/src/html.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
declare module '*.html' {
|
||||
const value: string;
|
||||
export default value
|
||||
}
|
10
src/rust/long_term_stats/site_build/src/login/login.ts
Normal file
10
src/rust/long_term_stats/site_build/src/login/login.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import html from './template.html';
|
||||
|
||||
export class LoginPage {
|
||||
constructor() {
|
||||
document.body.innerHTML = html;
|
||||
let button = document.getElementById('btnLogin');
|
||||
if (button)
|
||||
button.onclick = () => { alert('blah') };
|
||||
}
|
||||
}
|
30
src/rust/long_term_stats/site_build/src/login/template.html
Normal file
30
src/rust/long_term_stats/site_build/src/login/template.html
Normal file
@ -0,0 +1,30 @@
|
||||
<div id="container" class="pad4">
|
||||
<div class="row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-4">
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Login</h5>
|
||||
<p>Please enter a username and password to access LibreQoS.</p>
|
||||
<p>You can control access locally with <em>bin/lqusers</em> from the console.</p>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>License ID</td>
|
||||
<td><input type="text" id="license" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Username</td>
|
||||
<td><input type="text" id="username" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password</td>
|
||||
<td><input type="password" id="password" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<a class="btn btn-primary" id="btnLogin">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</div>
|
14
src/rust/long_term_stats/site_build/src/main.html
Normal file
14
src/rust/long_term_stats/site_build/src/main.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>LibreWoS Long-Term Statistics</title>
|
||||
<link rel="shortcut icon" href="#" />
|
||||
|
||||
<script type="module" src="/app.js"></script>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>Hello</body>
|
||||
</html>
|
1
src/rust/long_term_stats/site_build/src/style.css
Normal file
1
src/rust/long_term_stats/site_build/src/style.css
Normal file
@ -0,0 +1 @@
|
||||
@import 'bootstrap/dist/css/bootstrap.css';
|
Loading…
Reference in New Issue
Block a user