feat: add a DEBUG page to the UI with a database usage example

This commit is contained in:
Florian Briand 2024-09-16 22:58:41 +02:00
parent d43ee1c28f
commit 0d51e3aa68
Signed by: florian_briand
GPG Key ID: CC981B9E6B98E70B
5 changed files with 272 additions and 1 deletions

View File

@ -580,6 +580,10 @@ video {
margin-bottom: 1rem;
}
.mb-1 {
margin-bottom: 0.25rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
@ -604,6 +608,10 @@ video {
margin-top: 1rem;
}
.mb-5 {
margin-bottom: 1.25rem;
}
.block {
display: block;
}
@ -616,6 +624,10 @@ video {
display: inline-flex;
}
.table {
display: table;
}
.grid {
display: grid;
}
@ -696,6 +708,10 @@ video {
width: 100%;
}
.max-w-3xl {
max-width: 48rem;
}
.max-w-7xl {
max-width: 80rem;
}
@ -756,6 +772,12 @@ video {
margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.divide-y > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
@ -801,6 +823,10 @@ video {
border-width: 2px;
}
.border-b {
border-bottom-width: 1px;
}
.border-dashed {
border-style: dashed;
}
@ -850,6 +876,11 @@ video {
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.bg-blue-600 {
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
}
.p-2 {
padding: 0.5rem;
}
@ -858,6 +889,10 @@ video {
padding: 1rem;
}
.p-6 {
padding: 1.5rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
@ -868,26 +903,59 @@ video {
padding-right: 1rem;
}
.px-5 {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.py-12 {
padding-top: 3rem;
padding-bottom: 3rem;
}
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.py-2\.5 {
padding-top: 0.625rem;
padding-bottom: 0.625rem;
}
.py-3 {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.py-8 {
padding-top: 2rem;
padding-bottom: 2rem;
}
.text-left {
text-align: left;
}
.text-center {
text-align: center;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
@ -908,10 +976,24 @@ video {
line-height: 1.25rem;
}
.text-xl {
font-size: 1.25rem;
line-height: 1.75rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.font-bold {
font-weight: 700;
}
.font-light {
font-weight: 300;
}
.font-medium {
font-weight: 500;
}
@ -920,6 +1002,10 @@ video {
font-weight: 600;
}
.uppercase {
text-transform: uppercase;
}
.leading-tight {
line-height: 1.25;
}
@ -964,6 +1050,11 @@ video {
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}
.hover\:bg-blue-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
}
.focus\:outline-none:focus {
outline: 2px solid transparent;
outline-offset: 2px;
@ -991,11 +1082,24 @@ video {
--tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity));
}
.focus\:ring-blue-300:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(147 197 253 / var(--tw-ring-opacity));
}
@media (min-width: 640px) {
.sm\:max-w-md {
max-width: 28rem;
}
.sm\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.sm\:p-8 {
padding: 2rem;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
@ -1051,6 +1155,12 @@ video {
margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
}
.md\:space-y-5 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
.md\:border-0 {
border-width: 0px;
}
@ -1072,6 +1182,11 @@ video {
padding: 1.5rem;
}
.md\:text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.md\:text-blue-700 {
--tw-text-opacity: 1;
color: rgb(29 78 216 / var(--tw-text-opacity));
@ -1088,6 +1203,10 @@ video {
}
@media (min-width: 1024px) {
.lg\:mt-5 {
margin-top: 1.25rem;
}
.lg\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@ -1102,12 +1221,20 @@ video {
--tw-space-x-reverse: 1;
}
.rtl\:text-right:where([dir="rtl"], [dir="rtl"] *) {
text-align: right;
}
@media (prefers-color-scheme: dark) {
.dark\:divide-gray-600 > :not([hidden]) ~ :not([hidden]) {
--tw-divide-opacity: 1;
border-color: rgb(75 85 99 / var(--tw-divide-opacity));
}
.dark\:border {
border-width: 1px;
}
.dark\:border-gray-600 {
--tw-border-opacity: 1;
border-color: rgb(75 85 99 / var(--tw-border-opacity));
@ -1133,6 +1260,11 @@ video {
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
.dark\:bg-blue-600 {
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
}
.dark\:text-gray-200 {
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
@ -1168,6 +1300,11 @@ video {
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
}
.dark\:hover\:bg-blue-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
}
.dark\:hover\:text-white:hover {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
@ -1177,6 +1314,11 @@ video {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity));
}
.dark\:focus\:ring-blue-800:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(30 64 175 / var(--tw-ring-opacity));
}
}
@media (min-width: 768px) {

View File

@ -19,5 +19,10 @@ pub fn get_menu_items() -> Vec<MenuItem> {
label: "CPS".to_string(),
href: "/cps".to_string(),
},
MenuItem {
id: "debug".to_string(),
label: "DEBUG".to_string(),
href: "/debug".to_string(),
},
]
}

View File

@ -0,0 +1,72 @@
{% extends "base.html" %}
{% import "navbar/navbar.html" as navbar -%}
{% block title %}Pharma Libre - Debug{% endblock %}
{% block body %}
{% call navbar::navbar(current="debug") %}
<div class="py-10">
<header id="page-header">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<h1 id="page-title" class="text-3xl font-bold leading-tight tracking-tight text-gray-900">
DEBUG
</h1>
</div>
</header>
<main id="page-main">
<div class="mx-auto max-w-7xl py-12 sm:px-6 lg:px-8">
<div class="mx-auto max-w-3xl">
<div
class="w-full p-6 bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md dark:bg-gray-800 dark:border-gray-700 sm:p-8">
<h1
class="mb-1 text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Base de données
</h1>
<p class="font-light text-gray-500 dark:text-gray-400 mb-5">
Données extraites de la base de donnée à des fins de debug
</p>
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">
ID
</th>
<th scope="col" class="px-6 py-3">
Value
</th>
</tr>
</thead>
<tbody>
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row"
class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
db_ping_status
</th>
<td class="px-6 py-4">
{{ db_ping_status }}
</td>
</tr>
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row"
class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
debug_entries_count
</th>
<td class="px-6 py-4">
{{ debug_entries_count }}
</td>
</tr>
</tbody>
</table>
<div class="mt-4 space-y-4 lg:mt-5 md:space-y-5">
<button type="button"
class="w-full text-white bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
hx-trigger="click" hx-post="/debug/add_random" hx-swap="none">
Add random debug entry
</button>
</div>
</div>
</div>
</div>
</main>
</div>
{% endblock %}

View File

@ -0,0 +1,48 @@
use askama_axum::Template;
use axum::{extract::State, routing};
use ::entity::{debug, debug::Entity as DebugEntity};
use axum_htmx::HxRequest;
use sea_orm::*;
use crate::AppState;
async fn get_debug_entries(db: &DatabaseConnection) -> Result<Vec<debug::Model>, DbErr> {
DebugEntity::find().all(db).await
}
async fn add_random_debug_entry(State(AppState { db_connection }): State<AppState>) {
let random_entry = debug::ActiveModel {
title: Set("Random title".to_string()),
text: Set("Random text".to_string()),
..Default::default()
};
random_entry.insert(&db_connection).await.unwrap();
}
#[derive(Template)]
#[template(path = "debug.html")]
struct GetDebugTemplate {
hx_request: bool,
db_ping_status: bool,
debug_entries_count: usize,
}
async fn debug(
HxRequest(hx_request): HxRequest,
State(AppState { db_connection }): State<AppState>,
) -> GetDebugTemplate {
let db_ping_status = db_connection.ping().await.is_ok();
let debug_entries = get_debug_entries(&db_connection).await.unwrap();
GetDebugTemplate {
hx_request,
db_ping_status,
debug_entries_count: debug_entries.len(),
}
}
pub fn get_routes() -> axum::Router<crate::AppState> {
axum::Router::new()
.route("/", routing::get(debug))
.route("/add_random", routing::post(add_random_debug_entry))
}

View File

@ -1,10 +1,14 @@
use axum::{routing, Router};
use crate::AppState;
mod cps;
mod debug;
mod home;
pub fn get_routes() -> Router {
pub fn get_routes() -> Router<AppState> {
Router::new()
.route("/", routing::get(home::home))
.route("/cps", routing::get(cps::cps))
.nest("/debug", debug::get_routes())
}