webs unified

This commit is contained in:
Priec
2026-08-03 13:32:25 +02:00
parent 35d85de556
commit c8afe99d79
59 changed files with 1991 additions and 952 deletions

View File

@@ -49,7 +49,12 @@ pub(crate) async fn load_page(
})
})
.collect();
Ok(AddLogicPageState { tables, form, error })
Ok(AddLogicPageState {
nav: crate::ui::Nav::new(headers, "admin").with_role(authorization.role),
tables,
form,
error,
})
}
pub(crate) enum LoadError {

View File

@@ -15,6 +15,7 @@ pub(crate) struct CreateLogicForm {
}
pub(crate) struct AddLogicPageState {
pub nav: crate::ui::Nav,
pub tables: Vec<TableOption>,
pub form: CreateLogicForm,
pub error: Option<String>,

View File

@@ -1,45 +1,34 @@
use askama::Template;
use crate::ui::{Alert, Nav, render};
use super::state::AddLogicPageState;
const ADMIN_CSS: &str = include_str!("../../../static/admin.css");
pub(crate) fn render_page(page: &AddLogicPageState) -> String {
let tables = page
.tables
.iter()
.map(|table| {
format!(
"<option value=\"{}\" {}>{}.{}</option>",
table.id,
if page.form.table_definition_id == table.id { "selected" } else { "" },
crate::escape_html(&table.profile_name),
crate::escape_html(&table.table_name),
)
})
.collect::<String>();
let error = page.error.as_deref().map(render_submission_error).unwrap_or_default();
format!(
"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Add logic</title><script src=\"https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js\"></script><style>{ADMIN_CSS}</style></head><body><header class=\"topbar\"><div><strong>Komp Accounting</strong></div><nav><a href=\"/admin\">Admin</a><a href=\"/\">Analytics</a></nav></header><main class=\"form-main\"><a class=\"back-link\" href=\"/admin\">← Admin panel</a><section class=\"form-card\"><p class=\"eyebrow\">Computed column</p><h1>Add logic</h1><p>Create or update a Steel script through the existing table-script service.</p><form hx-post=\"/admin/logic\" hx-target=\"#submission-status\" hx-swap=\"innerHTML\" hx-disabled-elt=\"button[type=submit]\"><div class=\"form-grid\"><label class=\"wide\">Table<select name=\"table_definition_id\" required><option value=\"0\">Choose a table</option>{tables}</select></label><label>Logic name<input name=\"logic_name\" value=\"{}\" placeholder=\"invoice total\"></label><label>Target column<input name=\"target_column\" value=\"{}\" required placeholder=\"total\"></label><label class=\"wide\">Steel expression<textarea name=\"script\" rows=\"12\" required placeholder=\"(+ (get-var &quot;subtotal&quot;) (get-var &quot;tax&quot;))\">{}</textarea></label><label class=\"wide\">Description<input name=\"description\" value=\"{}\"></label></div><div id=\"submission-status\" aria-live=\"polite\">{error}</div><div class=\"form-actions\"><a href=\"/admin\">Cancel</a><button type=\"submit\">Save logic</button></div></form></section></main></body></html>",
crate::escape_html(&page.form.logic_name),
crate::escape_html(&page.form.target_column),
crate::escape_html(&page.form.script),
crate::escape_html(&page.form.description),
)
/// GET /admin/logic/new
#[derive(Template)]
#[template(path = "pages/add_logic/add_logic.html")]
struct AddLogicPage<'a> {
nav: Nav,
page: &'a AddLogicPageState,
}
pub(crate) fn render_page(page: &AddLogicPageState) -> String {
render(&AddLogicPage {
nav: page.nav.clone(),
page,
})
}
/// POST /admin/logic — the #submission-status swaps.
pub(crate) fn render_submission_error(message: &str) -> String {
format!(
"<div class=\"form-error\"><strong>Could not save the logic</strong><p>{}</p></div>",
crate::escape_html(message),
)
render(&Alert::error("Could not save the logic", message))
}
pub(crate) fn render_success(id: i64, warnings: &str) -> String {
let warnings = if warnings.trim().is_empty() {
String::new()
let message = if warnings.trim().is_empty() {
format!("Script #{id} was saved.")
} else {
format!("<p><strong>Warnings:</strong> {}</p>", crate::escape_html(warnings))
format!("Script #{id} was saved. Warnings: {warnings}")
};
format!(
"<div class=\"form-success\"><strong>Logic saved</strong><p>Script #{id} was saved.</p>{warnings}</div>"
)
render(&Alert::success("Logic saved", &message))
}