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

@@ -0,0 +1,34 @@
{# GET /admin/export — crate::pages::import_export::export::ui::ExportPage #}
{% extends "ui/form_page.html" %}
{% block title %}Export CSV{% endblock %}
{% block eyebrow %}Data transfer{% endblock %}
{% block heading %}Export CSV{% endblock %}
{% block lead %}<p>The download is generated from live table data through gRPC.</p>{% endblock %}
{% block form %}
{# A real form post, not HTMX: the response is a file download. #}
<form method="post" action="/admin/export.csv">
<div class="form-grid">
<label>Profile
<select name="profile_name" required>
<option value="">Choose a profile</option>
{% for profile in page.catalog.profiles %}
<option value="{{ profile.name }}">{{ profile.name }}</option>
{% endfor %}
</select>
</label>
<label>Tables
<input name="table_names" list="export-tables" required placeholder="invoices, customers">
<small>Separate multiple tables with commas.</small>
</label>
</div>
<datalist id="export-tables">
{%- for profile in page.catalog.profiles %}{% for table in profile.tables %}<option value="{{ table }}"></option>{% endfor %}{% endfor -%}
</datalist>
<div class="form-actions">
<a href="/admin">Cancel</a>
<button type="submit">Download CSV</button>
</div>
</form>
{% endblock %}

View File

@@ -0,0 +1,40 @@
{# GET /admin/import — crate::pages::import_export::import::ui::ImportPage #}
{% extends "ui/form_page.html" %}
{% import "ui/alert.html" as alert %}
{% block title %}Import CSV{% endblock %}
{% block eyebrow %}Data transfer{% endblock %}
{% block heading %}Import CSV{% endblock %}
{% block lead %}<p>Choose a browser-local file or paste CSV. Rows are validated against live table structures before gRPC bulk insertion.</p>{% endblock %}
{% block form %}
<form hx-post="/admin/import" hx-target="#submission-status" hx-swap="innerHTML"
hx-disabled-elt="button[type=submit]">
<div class="form-grid">
<label>Profile
<select name="profile_name" required>
<option value="">Choose a profile</option>
{% for profile in page.catalog.profiles %}
<option value="{{ profile.name }}" {% if page.form.profile_name == profile.name %}selected{% endif %}>{{ profile.name }}</option>
{% endfor %}
</select>
</label>
<label>Target tables<input name="table_names" list="import-tables" value="{{ page.form.table_names }}" required placeholder="invoices, customers"></label>
<label class="wide">CSV file
<input type="file" accept=".csv,text/csv"
onchange="this.files[0]?.text().then(value =&gt; document.getElementById('csv-data').value = value)">
</label>
<label class="wide">CSV data<textarea id="csv-data" name="csv_data" rows="14" required>{{ page.form.csv_data }}</textarea></label>
</div>
<datalist id="import-tables">
{%- for profile in page.catalog.profiles %}{% for table in profile.tables %}<option value="{{ table }}"></option>{% endfor %}{% endfor -%}
</datalist>
<div id="submission-status" aria-live="polite">
{%- if let Some(message) = page.error %}{% call alert::error("Could not import CSV", message) %}{% endcall %}{% endif -%}
</div>
<div class="form-actions">
<a href="/admin">Cancel</a>
<button type="submit">Import rows</button>
</div>
</form>
{% endblock %}