aboutsummaryrefslogtreecommitdiffstats
path: root/browser
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2025-02-11 12:12:37 +0200
committerJan Tuomi <jan@jantuomi.fi>2025-02-11 12:13:00 +0200
commite8f3a470ce693bef9303d3dd4c46523cdc691826 (patch)
treed5d33eb96de070ccfa2b138295b623a8516cf7ad /browser
parentcc07b3fdc4b8860a1ee1b25f09039ba3f13ee509 (diff)
Add structure, introduce progressive enhancement
Diffstat (limited to 'browser')
-rw-r--r--browser/app.py34
-rw-r--r--browser/static/styles.css6
-rw-r--r--browser/templates/base.html.j221
-rw-r--r--browser/templates/frag_aside.html.j2 (renamed from browser/templates/aside.html.j2)4
-rw-r--r--browser/templates/frag_error.html.j210
-rw-r--r--browser/templates/frag_form_find.html.j2 (renamed from browser/templates/form_find.html.j2)3
-rw-r--r--browser/templates/frag_form_range.html.j2 (renamed from browser/templates/form_range.html.j2)3
-rw-r--r--browser/templates/page_error.html.j2 (renamed from browser/templates/error.html.j2)3
-rw-r--r--browser/templates/page_main.html.j2 (renamed from browser/templates/index.html.j2)10
9 files changed, 58 insertions, 36 deletions
diff --git a/browser/app.py b/browser/app.py
index 1398e93..ebe590d 100644
--- a/browser/app.py
+++ b/browser/app.py
@@ -5,7 +5,7 @@ import os
import sys
import traceback
import tempfile
-from flask import Flask, render_template
+from flask import Flask, render_template, request
from flask_compress import Compress # type: ignore
from log_db import DB, Bound
@@ -28,21 +28,19 @@ db = DB \
.secondary_keys(["name"]) \
.initialize()
-def error_page(message: str, code: int = 400):
- return render_template("error.html.j2", error = message), code
-
-@app.errorhandler(404)
-def not_found(e: Exception):
- return error_page("Not found", 404)
-
-@app.errorhandler(405)
-def method_not_allowed(e: Exception):
- return error_page(str(e), 405)
-
@app.errorhandler(Exception)
def error_handler(e: Exception):
- traceback.print_exception(e, file=sys.stderr)
- return error_page("Internal server error", 500)
+ if e.code >= 500: # type: ignore
+ traceback.print_exception(e, file=sys.stderr)
+ error_text = "Internal Server Error"
+ else:
+ error_text = str(e)
+
+ htmz_target = request.form.get("htmz")
+ if htmz_target:
+ return render_template("frag_error.html.j2", error = error_text, container = htmz_target)
+ else:
+ return render_template("page_error.html.j2", error = error_text)
@app.get("/")
def index():
@@ -52,8 +50,8 @@ def index():
def page_find():
rows = db.range_by("id", Bound.unbounded(), Bound.unbounded(), limit=100)
- return render_template('index.html.j2',
- selected_form = "form_find.html.j2",
+ return render_template('page_main.html.j2',
+ selected_form = "frag_form_find.html.j2",
field_names = ["id", "name"],
rows = rows,
)
@@ -62,8 +60,8 @@ def page_find():
def page_range():
rows = db.range_by("id", Bound.unbounded(), Bound.unbounded(), limit=100)
- return render_template('index.html.j2',
- selected_form = "form_range.html.j2",
+ return render_template('page_main.html.j2',
+ selected_form = "frag_form_range.html.j2",
field_names = ["id", "name"],
rows = rows,
)
diff --git a/browser/static/styles.css b/browser/static/styles.css
index 73379e7..0faa49f 100644
--- a/browser/static/styles.css
+++ b/browser/static/styles.css
@@ -31,7 +31,7 @@ body {
line-height: 24px;
}
-main {
+#container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
@@ -104,11 +104,11 @@ input[type*="date"]:disabled {
color: var(--gray);
}
-main > aside {
+aside {
width: 250px;
}
-main > .results {
+main {
flex: 1;
overflow-y: scroll;
max-height: 100%;
diff --git a/browser/templates/base.html.j2 b/browser/templates/base.html.j2
index a8a6cf7..8b41a85 100644
--- a/browser/templates/base.html.j2
+++ b/browser/templates/base.html.j2
@@ -9,12 +9,27 @@
<title>Database browser</title>
<meta name="description" content="Database browser for log_db">
{% endblock %}
-
- <!-- -- https://leanrada.com/htmz/ -->
- <iframe hidden name=htmz onload="setTimeout(()=>document.querySelector(contentWindow.location.hash||null)?.replaceWith(...contentDocument.body.childNodes))"></iframe>
</head>
<body>
<h1><a href="/">Database browser</a></h1>
{% block content %}{% endblock %}
+
+ <!-- https://leanrada.com/htmz/ -->
+ <iframe hidden name=htmz onload="setTimeout(()=>document.querySelector(contentWindow.location.hash||null)?.replaceWith(...contentDocument.body.childNodes))"></iframe>
+ <!-- Enable progressive enhancement for htmz -->
+ <script>
+ document.querySelectorAll("form[htmz]").forEach(function (element) {
+ const input = document.createElement("input");
+ input.type = "hidden";
+ input.name = "htmz";
+ input.value = element.attributes.replace.value;
+ element.appendChild(input);
+
+ const action = new URL(element.action);
+ action.hash = element.attributes.replace.value;
+ element.action = action.toString();
+ element.target = "htmz";
+ });
+ </script>
</body>
</html>
diff --git a/browser/templates/aside.html.j2 b/browser/templates/frag_aside.html.j2
index eb8c9cf..8366436 100644
--- a/browser/templates/aside.html.j2
+++ b/browser/templates/frag_aside.html.j2
@@ -1,5 +1,4 @@
-{% block aside %}
-<aside>
+<aside id="aside">
<h3>Read operations</h3>
<ul>
<li><a href="/find">Find</a></li>
@@ -13,4 +12,3 @@
{% include selected_form %}
</aside>
-{% endblock %}
diff --git a/browser/templates/frag_error.html.j2 b/browser/templates/frag_error.html.j2
new file mode 100644
index 0000000..f014f0a
--- /dev/null
+++ b/browser/templates/frag_error.html.j2
@@ -0,0 +1,10 @@
+{% if container %}
+<{{ container }}>
+{% endif %}
+
+<h2>Error</h2>
+{{ error }}
+
+{% if container %}
+</{{ container }}>
+{% endif %}
diff --git a/browser/templates/form_find.html.j2 b/browser/templates/frag_form_find.html.j2
index 54608b6..a8fe493 100644
--- a/browser/templates/form_find.html.j2
+++ b/browser/templates/frag_form_find.html.j2
@@ -1,6 +1,7 @@
-<form action="/find" method="post">
+<form action="/find" method="post" htmz replace=main>
<label for="field">Field</label>
<input type="text" name="field" id="field" required>
<label for="values">Values</label>
<input type="text" name="values" id="values" required>
<button type="submit">Run query</button>
+</form>
diff --git a/browser/templates/form_range.html.j2 b/browser/templates/frag_form_range.html.j2
index 76eb4d2..b343b6d 100644
--- a/browser/templates/form_range.html.j2
+++ b/browser/templates/frag_form_range.html.j2
@@ -1,4 +1,4 @@
-<form action="/range" method="post">
+<form action="/range" method="post" htmz replace=main>
<label for="field">Field</label>
<input type="text" name="field" id="field" required>
<label for="values">From...</label>
@@ -6,3 +6,4 @@
<label for="values">...To</label>
<input type="text" name="to" id="to" required>
<button type="submit">Run query</button>
+</form>
diff --git a/browser/templates/error.html.j2 b/browser/templates/page_error.html.j2
index 2d0dc19..3233283 100644
--- a/browser/templates/error.html.j2
+++ b/browser/templates/page_error.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% block content %}
-<h2>Error</h2>
-{{ error }}
+{% include "frag_error.html.j2" %}
{% endblock %}
diff --git a/browser/templates/index.html.j2 b/browser/templates/page_main.html.j2
index 9713944..8ce4a13 100644
--- a/browser/templates/index.html.j2
+++ b/browser/templates/page_main.html.j2
@@ -1,10 +1,10 @@
{% extends "base.html.j2" %}
{% block content %}
-<main>
- {% include "aside.html.j2" %}
+<div id="container">
+ {% include "frag_aside.html.j2" %}
- <div class="results">
+ <main id="main">
<table>
<thead>
<tr>
@@ -23,6 +23,6 @@
{% endfor %}
</tbody>
</table>
- </div>
-</main>
+ </main>
+</div>
{% endblock %}