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

@@ -28,7 +28,88 @@ LISTEN_ADDRESS=127.0.0.1:8080 \
cargo run -p server -- server
```
The first SQL result column is used for category labels. Bar and line charts use
## Structure
HTML lives in `.html` files, never in Rust strings. Templates are
[askama](https://docs.rs/askama): compiled at build time, type-checked against
their struct, and HTML-escaped automatically.
**`templates/` mirrors `src/` directory for directory.** The Rust for a page
and the markup for that page live at the same path in the two trees, and
`src/pages/` itself matches the client crate — the same page names, the same
`loader / logic / state / ui` split. A `#[template(path = …)]` is therefore the
module's own path, which is also where the file is in `templates/`.
```
src/ templates/
ui/ ui/
mod.rs base.html <html>, <head>, navbar
(Nav, Alert, Notice, navbar.html the one navbar
ErrorPage, render) form_page.html admin form card layout
alert.html error/success macros
alert_fragment.html standalone POST reply
notice.html one-line inline notice
error.html full-page load failure
pages/ pages/
admin/admin/ admin/admin/
mod loader logic state ui admin.html
workspace.html
add_table/ add_table/
mod loader logic state ui add_table.html
add_logic/ add_logic/
… add_logic.html
add_validation/ add_validation/
… field.html rule.html set.html
shared_fields.html
analytics/ analytics/
… analytics.html catalog.html
profile_options.html query_result.html
import_export/import/ import_export/import/
… import.html
import_export/export/ import_export/export/
… export.html
login/ login/
mod logic state ui login.html
static/app.css the only stylesheet, at /static/app.css
```
Every full page extends `ui/base.html`, which links the stylesheet and renders
`ui/navbar.html`, so the navbar is on every page without a page opting in. The
six admin forms extend `ui/form_page.html` for the back link and card chrome on
top of that.
Each endpoint maps to exactly one template. The Rust side of the mapping is the
`#[derive(Template)]` struct in the page's `ui.rs`; the template names its
endpoint in a comment on line 1.
| Endpoint | Page directory | Template |
| --- | --- | --- |
| `GET /` | `pages/analytics/` | `analytics.html` |
| `GET /api/profiles` | `pages/analytics/` | `profile_options.html` |
| `POST /api/catalog` | `pages/analytics/` | `catalog.html` |
| `POST /api/query` | `pages/analytics/` | `query_result.html` |
| `GET /login` | `pages/login/` | `login.html` |
| `POST /login` | `pages/login/` | sets the cookie, `hx-redirect` |
| `GET /admin` | `pages/admin/admin/` | `admin.html` |
| `GET /admin/workspace` | `pages/admin/admin/` | `workspace.html` |
| `POST /logout` | `pages/admin/admin/` | clears the cookie, `hx-redirect` |
| `GET /admin/tables/new` | `pages/add_table/` | `add_table.html` |
| `GET /admin/logic/new` | `pages/add_logic/` | `add_logic.html` |
| `GET /admin/validation/new` | `pages/add_validation/` | `field.html` |
| `GET /admin/validation/rules/new` | `pages/add_validation/` | `rule.html` |
| `GET /admin/validation/sets/new` | `pages/add_validation/` | `set.html` |
| `GET /admin/import` | `pages/import_export/import/` | `import.html` |
| `GET /admin/export` | `pages/import_export/export/` | `export.html` |
Every form `POST` answers with `ui/alert_fragment.html`, swapped into the page's
`#submission-status`. Analytics errors use the lighter `ui/notice.html`.
Inside a page module the split is the same everywhere, and the same as the
client: `mod.rs` declares the routes, `loader.rs` calls gRPC and shapes the
result, `state.rs` holds the view model and form parsing, `logic.rs` is the
handlers, and `ui.rs` binds state to the templates in that directory.
## Admin panel
The admin panel mirrors the client workflow with browser-oriented pages:
@@ -48,6 +129,7 @@ existing `TablesData` gRPC service.
## Analytics
The first SQL result column is used for category labels. Bar and line charts use
all remaining columns as numeric series, pie uses the second column, and scatter
uses the first two columns. Table view displays every returned value.