Add WS debug console

This commit is contained in:
Pierre HUBERT 2025-02-11 21:57:34 +01:00
parent 558d5cda3f
commit b8a8e14f3c
6 changed files with 318 additions and 173 deletions

68
assets/ws_debug.js Normal file
View File

@ -0,0 +1,68 @@
let ws;
const JS_MESSAGE = "JS code";
const IN_MESSAGE = "Incoming";
/**
* Log message
*/
function log(src, txt) {
const target = document.getElementById("ws_log");
const msg = document.createElement("div");
msg.className = "message";
msg.innerHTML = `<div class='type'>${src}</div><div>${txt}</div>`
target.insertBefore(msg, target.firstChild);
}
/**
* Set the state of the WebSocket
*/
function setState(state) {
document.getElementById("state").innerText = state;
}
/**
* Initialize WebSocket connection
*/
function connect() {
disconnect();
log(JS_MESSAGE, "Initialize connection...");
ws = new WebSocket("/api/ws");
setState("Connecting...");
ws.onopen = function () {
log(JS_MESSAGE, "Connected to WebSocket !");
setState("Connected");
}
ws.onmessage = function (event) {
log(IN_MESSAGE, event.data);
}
ws.onclose = function () {
log(JS_MESSAGE, "Disconnected from WebSocket !");
setState("Disconnected");
}
ws.onerror = function (event) {
console.error("WS Error!", event);
log(JS_MESSAGE, `Error with websocket! ${event}`);
setState("Error");
}
}
/**
* Close WebSocket connection
*/
function disconnect() {
if (ws && ws.readyState === WebSocket.OPEN) {
log(JS_MESSAGE, "Close connection...");
ws.close();
}
setState("Disconnected");
ws = undefined;
}
/**
* Clear WS logs
*/
function clearLogs() {
document.getElementById("ws_log").innerHTML = "";
}

View File

@ -48,6 +48,7 @@ async fn main() -> std::io::Result<()> {
.route("/", web::post().to(web_ui::home))
.route("/oidc_cb", web::get().to(web_ui::oidc_cb))
.route("/sign_out", web::get().to(web_ui::sign_out))
.route("/ws_debug", web::get().to(web_ui::ws_debug))
// API routes
.route("/api", web::get().to(api::api_home))
.route("/api", web::post().to(api::api_home))

View File

@ -223,3 +223,22 @@ pub async fn sign_out(session: Session) -> HttpResult {
.insert_header(("location", "/"))
.finish())
}
#[derive(askama::Template)]
#[template(path = "ws_debug.html")]
struct WsDebugTemplate {
name: String,
}
/// WebSocket debug
pub async fn ws_debug(session: Session) -> HttpResult {
let Some(user): Option<User> = session.get(USER_SESSION_KEY)? else {
return Ok(HttpResponse::Found()
.insert_header(("location", "/"))
.finish());
};
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(WsDebugTemplate { name: user.name }.render().unwrap()))
}

46
templates/base_page.html Normal file
View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Matrix GW</title>
<link rel="icon" type="image/png" href="/assets/favicon.png"/>
<link rel="stylesheet" href="/assets/bootstrap.css"/>
<link rel="stylesheet" href="/assets/style.css"/>
</head>
<body>
<!-- Header -->
<header data-bs-theme="dark">
<div class="navbar navbar-dark bg-dark shadow-sm">
<div class="container">
<a href="/" class="navbar-brand d-flex align-items-center">
<svg xxmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="1" aria-hidden="true" class="me-2"
viewBox="0 0 24 24">
<path d="M10 11.5H17V13H10V11.5M10 8.5H19V10H10V8.5M20 5H9C7.9 5 7 5.9 7 7V21L11 17H20C21.1 17 22 16.1 22 15V7C22 5.9 21.1 5 20 5M20 15H10.2L9 16.2V7H20V15M3 7C2.4 7 2 7.4 2 8S2.4 9 3 9H5V7H3M2 11C1.4 11 1 11.4 1 12S1.4 13 2 13H5V11H2M1 15C.4 15 0 15.4 0 16C0 16.6 .4 17 1 17H5V15H1Z"/>
</svg>
<strong>Matrix GW</strong>
</a>
<ul class="navbar-nav mr-auto" style="flex: 1">
<li class="nav-item"><a href="/ws_debug" class="nav-link">WS Debug</a></li>
</ul>
<div class="navbar" >
<span>Hi <span style="font-style: italic;">{{ name }}</span>&nbsp;&nbsp;</span>
<a href="/sign_out">Sign out</a>
</div>
</div>
</div>
</header>
<div class="body-content">
{% block content %}
TO_REPLACE
{% endblock content %}
</div>
</body>
</html>

View File

@ -1,57 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Matrix GW</title>
<link rel="icon" type="image/png" href="/assets/favicon.png"/>
<link rel="stylesheet" href="/assets/bootstrap.css"/>
<link rel="stylesheet" href="/assets/style.css"/>
<script src="/assets/script.js"></script>
</head>
<body>
<!-- Header -->
<header data-bs-theme="dark">
<div class="navbar navbar-dark bg-dark shadow-sm">
<div class="container">
<a href="/" class="navbar-brand d-flex align-items-center">
<svg xxmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="1" aria-hidden="true" class="me-2"
viewBox="0 0 24 24">
<path d="M10 11.5H17V13H10V11.5M10 8.5H19V10H10V8.5M20 5H9C7.9 5 7 5.9 7 7V21L11 17H20C21.1 17 22 16.1 22 15V7C22 5.9 21.1 5 20 5M20 15H10.2L9 16.2V7H20V15M3 7C2.4 7 2 7.4 2 8S2.4 9 3 9H5V7H3M2 11C1.4 11 1 11.4 1 12S1.4 13 2 13H5V11H2M1 15C.4 15 0 15.4 0 16C0 16.6 .4 17 1 17H5V15H1Z"/>
</svg>
<strong>Matrix GW</strong>
</a>
<div class="navbar">
<span>Hi <span style="font-style: italic;">{{ name }}</span>&nbsp;&nbsp;</span>
<a href="/sign_out">Sign out</a>
</div>
</div>
</div>
</header>
<div class="body-content">
<!-- Success message -->
{% if let Some(msg) = success_message %}
<div class="alert alert-success">
{% extends "base_page.html" %}
{% block content %}
<!-- Success message -->
{% if let Some(msg) = success_message %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endif %}
</div>
{% endif %}
<!-- Error message -->
{% if let Some(msg) = error_message %}
<div class="alert alert-danger">
<!-- Error message -->
{% if let Some(msg) = error_message %}
<div class="alert alert-danger">
{{ msg }}
</div>
{% endif %}
</div>
{% endif %}
<!-- User ID -->
<div id="user_id_container"><strong>Current user ID</strong>: {{ user_id.0 }}</div>
<!-- User ID -->
<div id="user_id_container"><strong>Current user ID</strong>: {{ user_id.0 }}</div>
<!-- Display clients list -->
<div class="card border-light mb-3">
<!-- Display clients list -->
<div class="card border-light mb-3">
<div class="card-header">Registered clients</div>
<div class="card-body">
{% if clients.len() > 0 %}
@ -103,10 +70,10 @@
<p>No client registered yet!</p>
{% endif %}
</div>
</div>
</div>
<!-- New client -->
<div class="card border-light mb-3">
<!-- New client -->
<div class="card border-light mb-3">
<div class="card-header">New client</div>
<div class="card-body">
<form action="/" method="post">
@ -140,10 +107,10 @@
<input type="submit" class="btn btn-primary" value="Create client"/>
</form>
</div>
</div>
</div>
<!-- Matrix authentication token -->
<div class="card border-light mb-3">
<!-- Matrix authentication token -->
<div class="card border-light mb-3">
<div class="card-header">Matrix authentication token</div>
<div class="card-body">
<p>To obtain a new Matrix authentication token:</p>
@ -173,9 +140,7 @@
<input type="submit" class="btn btn-primary" value="Update"/>
</form>
</div>
</div>
</div>
</body>
</html>
<script src="/assets/script.js"></script>
{% endblock content %}

46
templates/ws_debug.html Normal file
View File

@ -0,0 +1,46 @@
{% extends "base_page.html" %}
{% block content %}
<style>
#ws_actions {
margin: 30px;
border: 1px white solid;
padding: 10px;
}
#ws_log {
margin: 30px;
border: 1px white solid;
padding: 10px;
}
#ws_log .message {
display: flex;
margin-bottom: 10px;
}
#ws_log .message .type {
font-style: italic;
margin-right: 10px;
}
</style>
<h2>WS Debug</h2>
<div id="ws_actions">
<button onclick="connect()">Reconnect</button>
<button onclick="disconnect()">Disconnect</button>
<button onclick="clearLogs()">Clear logs</button>
<span>State: <span id="state">DISCONNECTED</span></span>
</div>
<div id="ws_log">
<div class="message">
<div class="type">INFO</div>
<div>Welcome!</div>
</div>
</div>
<script src="/assets/ws_debug.js"></script>
{% endblock content %}