feat: add layout to all pages

This commit is contained in:
Matthieu Bessat 2024-07-23 17:25:22 +02:00
parent 02639175f4
commit de3defefa6
12 changed files with 155 additions and 66 deletions

4
Cargo.lock generated
View file

@ -971,9 +971,9 @@ dependencies = [
[[package]] [[package]]
name = "minijinja" name = "minijinja"
version = "1.0.21" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e877d961d4f96ce13615862322df7c0b6d169d40cab71a7ef3f9b9e594451e" checksum = "45f7e8e35b6c7b169bf40b0176d2c79291ab8ee53290b84e0668ab21d841aa9d"
dependencies = [ dependencies = [
"serde", "serde",
] ]

View file

@ -13,7 +13,7 @@ anyhow = "1.0.75"
clap = "4.5.4" clap = "4.5.4"
tokio = { version = "1.37.0", features = ["full"] } tokio = { version = "1.37.0", features = ["full"] }
axum = { version = "0.7.5", features = ["json"] } axum = { version = "0.7.5", features = ["json"] }
minijinja = { version = "1.0.20", features = ["builtins"] } minijinja = { version = "2.1", features = ["builtins"] }
uuid = { version = "1.8.0", features = ["serde", "v4"] } uuid = { version = "1.8.0", features = ["serde", "v4"] }
fully_pub = "0.1.4" fully_pub = "0.1.4"
log = "0.4.22" log = "0.4.22"

View file

@ -0,0 +1,6 @@
table {
width: 100%;
}
table tbody tr td:first-child {
padding-right: 3rem !important;
}

View file

@ -74,7 +74,7 @@ body {
font-size: 1.15rem; font-size: 1.15rem;
line-height: 1.5; line-height: 1.5;
display: grid; display: grid;
grid-template-columns: 1fr min(45rem, 90%) 1fr; grid-template-columns: 1fr min(50rem, 90%) 1fr;
margin: 0; margin: 0;
} }
body > * { body > * {

View file

@ -19,7 +19,7 @@ tasks:
- ls - ls
- /etc/fstab - /etc/fstab
schedule: schedule:
seconds: 15 hours: 1
clean_up: clean_up:
name: Clean up things name: Clean up things
@ -27,6 +27,6 @@ tasks:
command: command:
- cat - cat
- /etc/environment - /etc/environment
schedule: # schedule:
"0 * * * * *" # "0 * * * * *"

View file

@ -19,11 +19,14 @@ pub async fn home(
) )
} }
pub async fn list_tasks(State(app_state): State<AppState>) -> Html<String> { pub async fn list_tasks(State(app_state): State<AppState>) -> impl IntoResponse {
Html(render!( Html(
include_str!("./templates/pages/list_tasks.html"), app_state.templating_env.get_template("pages/list_tasks.html").unwrap()
.render(context!(
tasks => Vec::from_iter(app_state.config.tasks.iter()) tasks => Vec::from_iter(app_state.config.tasks.iter())
)) ))
.unwrap()
)
} }
pub async fn trigger_task( pub async fn trigger_task(
@ -50,10 +53,13 @@ pub async fn trigger_task(
( (
StatusCode::OK, StatusCode::OK,
Html(render!( Html(
include_str!("./templates/pages/run_task.html"), app_state.templating_env.get_template("pages/run_task.html").unwrap()
.render(context!(
task => task task => task
)), ))
.unwrap()
)
) )
} }
@ -70,7 +76,7 @@ pub async fn list_task_runs(
State(app_state): State<AppState>, State(app_state): State<AppState>,
ExtractPath(task_id): ExtractPath<String>, ExtractPath(task_id): ExtractPath<String>,
) -> Html<String> { ) -> Html<String> {
let runs = sqlx::query_as::<_, TaskRunSummary>("SELECT id,status,trigger_mode,submitted_at,started_at,ended_at FROM task_runs WHERE task_id = $1 LIMIT 100") let runs = sqlx::query_as::<_, TaskRunSummary>("SELECT id,status,trigger_mode,submitted_at,started_at,ended_at FROM task_runs WHERE task_id = $1")
.bind(&task_id) .bind(&task_id)
.fetch_all(&app_state.db) .fetch_all(&app_state.db)
.await .await
@ -81,11 +87,15 @@ pub async fn list_task_runs(
return Html("<h1>Task not found</h1>".to_string()); return Html("<h1>Task not found</h1>".to_string());
} }
}; };
Html(render!( Html(
include_str!("./templates/pages/list_task_runs.html"), app_state.templating_env.get_template("pages/list_task_runs.html").unwrap()
.render(context!(
task_id => task_id,
task => task, task => task,
runs => runs, runs => runs
)) ))
.unwrap()
)
} }
pub async fn get_task_run( pub async fn get_task_run(
@ -102,8 +112,12 @@ pub async fn get_task_run(
} }
}; };
Html(render!( Html(
include_str!("./templates/pages/task_run_details.html"), app_state.templating_env.get_template("pages/task_run_details.html").unwrap()
.render(context!(
run => run_details run => run_details
)) ))
.unwrap()
)
} }

View file

@ -48,12 +48,19 @@ async fn main() -> Result<()> {
let config: Config = get_config().expect("Cannot get config"); let config: Config = get_config().expect("Cannot get config");
let mut templating_env = Environment::new(); let mut templating_env = Environment::new();
templating_env templating_env
.add_template("layouts/base.html", include_str!("./templates/layouts/base.html")) .add_template("layouts/base.html", include_str!("./templates/layouts/base.html"))
.unwrap(); .unwrap();
for path in fs::read_dir("./src/templates/pages").unwrap() {
let file_name = path.unwrap().file_name().into_string().unwrap();
let path = format!("./src/templates/pages/{}", file_name);
let content: &'static str = Box::leak(fs::read_to_string(&path).unwrap().into_boxed_str());
let path: &'static str = Box::leak(format!("pages/{}", file_name).into_boxed_str());
templating_env templating_env
.add_template("pages/home.html", include_str!("./templates/pages/home.html")) .add_template(&path, &content)
.unwrap(); .unwrap();
}
let state = AppState { let state = AppState {
config, config,

View file

@ -8,8 +8,18 @@
<link href="/assets/styles/app.css" rel="stylesheet"> <link href="/assets/styles/app.css" rel="stylesheet">
</head> </head>
<body> <body>
<div class="container"> <header>
<nav>
<ul>
<li><a href="/tasks">Tasks</a></li>
</ul>
</nav>
</header>
<main class="container">
{% block body %}{% endblock %} {% block body %}{% endblock %}
</div> </main>
<footer>
Autotasker
</footer>
</body> </body>
</html> </html>

View file

@ -1,6 +1,32 @@
<h1>List of task runs for "{{ task.name }}"</h1> {% extends "layouts/base.html" %}
<ul> {% block body %}
{% for task_run in runs %} <h1>List of task runs for "{{ task.name }}"</h1>
<li><a href="/tasks/{{ task.id }}/runs/{{ task_run.id }}">{{ task_run.id }}</a> {{ task_run.status }}</li> <table>
{% endfor %} <thead>
</ul> <tr>
<th>Id</th>
<th>Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for task_run in runs %}
<tr>
<td>
{{ task_run.id | split("-") | first }}
</td>
<td>
{{ task_run.started_at }}
</td>
<td>
{{ task_run.status }}
</td>
<td>
<a href="/tasks/{{ task_id }}/runs/{{ task_run.id }}">Details</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -1,13 +1,34 @@
<h1>Tasks</h1> {% extends "layouts/base.html" %}
{% if tasks | length == 0 %} {% block body %}
No tasks were configured. <h1>Tasks</h1>
{% endif %} {% if tasks | length == 0 %}
<ul> <p>
{% for (id, task) in tasks %} No tasks were configured.
<li> </p>
{% endif %}
<table>
<thead>
<tr>
<th>Name</th>
<th>Trigger</th>
<th>See runs</th>
</tr>
</thead>
<tbody>
{% for (id, task) in tasks %}
<tr>
<td>
{{ task.name }} {{ task.name }}
</td>
<td>
<a href="/tasks/{{ id }}/trigger">Trigger task</a> <a href="/tasks/{{ id }}/trigger">Trigger task</a>
</td>
<td>
<a href="/tasks/{{ id }}/runs">See runs</a> <a href="/tasks/{{ id }}/runs">See runs</a>
</li> </td>
{% endfor %} </tr>
</ul> {% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -1 +1,6 @@
Task "{{ task.name }}" triggered! {% extends "layouts/base.html" %}
{% block body %}
<p>
Task "{{ task.name }}" triggered!
</p>
{% endblock %}

View file

@ -1,16 +1,16 @@
<h1>Task run {{ run.id }}</h1> {% extends "layouts/base.html" %}
{% block body %}
<ul> <h1>Task run details</h1>
<ul>
<li>Id: {{ run.id }}</li> <li>Id: {{ run.id }}</li>
<li>State: {{ run.status }}</li> <li>State: {{ run.status }}</li>
<li>Submitted at: {{ run.submitted_at }}</li> <li>Submitted at: {{ run.submitted_at }}</li>
<li>Started at: {{ run.started_at }}</li> <li>Started at: {{ run.started_at }}</li>
<li>Ended at: {{ run.ended_at }}</li> <li>Ended at: {{ run.ended_at }}</li>
<li>Trigger Mode: {{ run.trigger_mode }}</li> <li>Trigger Mode: {{ run.trigger_mode }}</li>
</ul> </ul>
<h3>Logs</h3> <h3>Logs</h3>
<p>Exit code is {{ run.exit_code }}</p> <p>Exit code is {{ run.exit_code }}</p>
<pre> <pre>{{ run.logs }}</pre>
{{ run.logs }} {% endblock %}
</pre>