{# One database engine, as one swappable section. Every state renders through this fragment - not installed, stopped, running, refused, freshly acted upon - so the databases page and the htmx swaps can never disagree about what an engine's section looks like. Two values on it are shown exactly once and never again. A new user's password exists in clear only in the response to the creation that made it: the engine stores a hash, so no later render can repeat it. And a connection string always carries a masked password for the same reason - there is no stored clear value for the server to reveal. Destructive actions confirm by name, server-side: the form posts what the operator typed and the handler compares it against the resource's exact name. The required attribute on the input is a courtesy; the comparison in the handler is the guard. A refused action renders at 200 with the refusal inline: htmx does not swap an error status, so answering 4xx would freeze the screen and report nothing. #} {% import "_macros.html" as m %}
{% if eng.problem %} {{ m.problem(eng.problem.fix, eng.problem.output) }} {% endif %} {% if eng.notice %}

{{ eng.notice }}

{% endif %} {% if eng.created_user %}

User {{ eng.created_user.username }} created. The password below is shown once and never stored in clear, so copy it now; no screen can repeat it.

{{ eng.created_user.password }}

{% endif %} {% if eng.conn %}

Connection string for {{ eng.conn.database }}. The password is masked because WASM keeps only the hash the engine keeps: substitute the one issued when the user was created.

{{ eng.conn.value }}

{% endif %} {% call m.row(eng.display_name, eng.state, [("version", eng.version or "—"), ("port", eng.port), ("service", eng.service)], none, none, none, eng.state_text) %} {% if not eng.installed %} {% else %} {% if eng.running %} {% else %} {% endif %} {% endif %} {% endcall %} {% if eng.running %} {% if eng.databases %} {% for db in eng.databases %} {% call m.row(db.name, "idle", [("size", db.size or "—"), ("owner", db.owner or "—")]) %}
Connection string
Drop
{% endcall %} {% endfor %} {% else %}

No databases in {{ eng.display_name }} yet. Create the first below, or run wasm db create -e {{ eng.name }} -n myapp.

{% endif %}

Users

{% if eng.users %} {% for user in eng.users %} {% endfor %}
User Host Databases Privileges Actions
{{ user.username }} {{ user.host }} {{ user.databases | join(", ") or "—" }} {{ user.privileges | join(", ") or "—" }} {% if eng.databases and eng.privileges %}
Privileges {# One form, two verbs: the Grant button is the submit, and Revoke posts the same fields to its own route - htmx includes the enclosing form's values on a non-GET. #}
{% endif %}
{% else %}

No users beyond the engine's own. Create one below.

{% endif %}
Leave empty to generate a strong one. Either way it is shown exactly once.
{% elif eng.installed %}

{{ eng.display_name }} is stopped: its databases and users cannot be read until it starts. Start it above, or run wasm db start {{ eng.name }}.

{% else %}

{{ eng.display_name }} is not installed. Install it above, or run wasm db install {{ eng.name }}.

{% endif %} {% if eng.installed %}

Dumps

{% if eng.backups %} {% for backup in eng.backups %} {% endfor %}
Database File Size Created Actions
{{ backup.database }} {{ backup.file }} {{ backup.size_human }} {{ backup.created | since }}
Restore
{% else %}

No dumps on disk for {{ eng.display_name }}. {% if eng.running %}Back up a database from its row above.{% else %}They would appear here once one is taken.{% endif %}

{% endif %} {% endif %}