pipekit/pipekit/web/templates/group_form.html
Paul Trowbridge 31d670b4e6 Add group runs and fix wizard identifier sanitization for spaced column names
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>
2026-06-02 00:05:37 -04:00

104 lines
4.5 KiB
HTML

{% extends "base.html" %}
{% set section = "groups" %}
{% block title %}{% if group %}Edit group · {{ group.name }}{% else %}New group{% endif %} — Pipekit{% endblock %}
{% block content %}
<div class="panel">
<header>
{% if group %}Edit group &middot; {{ group.name }}{% else %}New group{% endif %}
<span style="margin-left:auto"><a href="{{ cancel_url }}">&larr; back</a></span>
</header>
<div class="body">
<form method="post" action="{{ form_action }}" id="group-form">
<label class="field">
<span>name</span>
<input type="text" name="name" required value="{{ group.name if group else '' }}">
</label>
<div class="panel" style="margin-top:1rem">
<header>
Members
<span class="subtitle">run in order, lowest first; disabled modules are skipped</span>
<button type="button" class="btn ghost" style="margin-left:auto"
onclick="addMemberRow()">+ add</button>
</header>
<div class="body tight">
<table class="grid" id="members-table">
<thead>
<tr>
<th style="width:5rem">order</th>
<th>module</th>
<th style="width:5rem"></th>
</tr>
</thead>
<tbody id="members-tbody">
{% for m in members %}
<tr>
<td>
<input type="number" name="member_run_order"
value="{{ m.run_order }}" min="0" style="width:4rem">
</td>
<td>
<select name="member_module_id" style="width:100%">
{% for mod in all_modules %}
<option value="{{ mod.id }}"
{% if mod.id == m.module_id %}selected{% endif %}>
{{ mod.name }}{% if not mod.enabled %} (disabled){% endif %}
</option>
{% endfor %}
</select>
</td>
<td>
<button type="button" class="ghost"
style="color:var(--danger);border:none"
onclick="this.closest('tr').remove()">remove</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if not members %}
<div id="members-empty" class="empty" style="margin-top:0.4rem">No members yet.</div>
{% endif %}
</div>
</div>
<div class="actions" style="justify-content:flex-end;margin-top:0.8rem">
<a class="btn ghost" href="{{ cancel_url }}">cancel</a>
<button type="submit" class="primary">{% if group %}save changes{% else %}create group{% endif %}</button>
</div>
</form>
</div>
</div>
<template id="member-row-template">
<tr>
<td>
<input type="number" name="member_run_order" value="0" min="0" style="width:4rem">
</td>
<td>
<select name="member_module_id" style="width:100%">
{% for mod in all_modules %}
<option value="{{ mod.id }}">{{ mod.name }}{% if not mod.enabled %} (disabled){% endif %}</option>
{% endfor %}
</select>
</td>
<td>
<button type="button" class="ghost"
style="color:var(--danger);border:none"
onclick="this.closest('tr').remove()">remove</button>
</td>
</tr>
</template>
<script>
function addMemberRow() {
const tmpl = document.getElementById('member-row-template');
const row = tmpl.content.cloneNode(true);
document.getElementById('members-tbody').appendChild(row);
const empty = document.getElementById('members-empty');
if (empty) empty.style.display = 'none';
}
</script>
{% endblock %}