Groups allow multiple modules to be run sequentially in a defined order. Adds full CRUD (repo, engine orchestrator, web routes, templates) for grp, group_member, and group_run tables that were previously schema-only. Module index now shows group membership badges per module. Wizard default dest name now sanitizes source column names with spaces or special characters to valid identifiers rather than failing at CREATE TABLE time. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
70 lines
2.6 KiB
HTML
70 lines
2.6 KiB
HTML
{% extends "base.html" %}
|
|
{% set section = "groups" %}
|
|
{% block title %}Group run #{{ group_run.id }} — Pipekit{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="panel">
|
|
<header>
|
|
Group run #{{ group_run.id }}
|
|
<span class="subtitle">
|
|
<a href="/groups/{{ group_run.group_id }}">{{ group_run.group_name }}</a> ·
|
|
started {{ group_run.started_at }}
|
|
</span>
|
|
<span style="margin-left:auto">
|
|
<span class="pill {{ group_run.status }}">{{ group_run.status }}</span>
|
|
</span>
|
|
</header>
|
|
<div class="body">
|
|
<dl class="keyval">
|
|
<dt>started</dt> <dd class="mono">{{ group_run.started_at }}</dd>
|
|
<dt>finished</dt> <dd class="mono">{{ group_run.finished_at or "—" }}</dd>
|
|
<dt>duration</dt> <dd class="mono">{{ group_run.duration_s | duration }}</dd>
|
|
<dt>triggered by</dt><dd class="mono">{{ group_run.triggered_by or "—" }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="group-run-live"
|
|
{% if group_run.status == 'running' %}
|
|
hx-get="/group-runs/{{ group_run.id }}/live"
|
|
hx-trigger="load, every 3s"
|
|
hx-swap="outerHTML"
|
|
{% endif %}>
|
|
<div class="panel">
|
|
<header>Module runs</header>
|
|
<div class="body tight">
|
|
{% if module_runs %}
|
|
<table class="grid">
|
|
<thead>
|
|
<tr>
|
|
<th>run</th>
|
|
<th>module</th>
|
|
<th>started</th>
|
|
<th>duration</th>
|
|
<th>status</th>
|
|
<th>rows</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in module_runs %}
|
|
<tr>
|
|
<td><a href="/runs/{{ r.id }}">#{{ r.id }}</a></td>
|
|
<td><a href="/modules/{{ r.module_id }}">{{ r.module_name }}</a></td>
|
|
<td class="mono">{{ r.started_at or "—" }}</td>
|
|
<td class="mono">{{ r.duration_s | duration }}</td>
|
|
<td><span class="pill {{ r.status }}">{{ r.status }}</span></td>
|
|
<td class="mono">{{ r.row_count if r.row_count is not none else "—" }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% elif group_run.status == 'running' %}
|
|
<div class="empty">Waiting for module runs to start…</div>
|
|
{% else %}
|
|
<div class="empty">No module runs recorded.</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|