function update

This commit is contained in:
2026-05-19 04:30:14 +00:00
parent 1293bafffa
commit 3f82dfd9e9
13 changed files with 8080 additions and 152 deletions
+105 -59
View File
@@ -78,67 +78,100 @@
</div>
</div>
<div class="panel">
<form method="POST" action="/decisions/delete" id="bulk-form">
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
<div class="panel-header">
<span class="panel-title">
Page {{.Page}}{{if .HasNext}} (more available){{end}}
</span>
<div style="display:flex;gap:8px;align-items:center">
<button type="button" class="btn-ghost-sm" onclick="toggleAll()">Select all</button>
<button type="submit" class="btn-danger-sm" data-confirm-fn="confirmBulkDelete">Delete selected</button>
</div>
</div>
{{/* Bulk-delete form lives outside the table so row-level forms are never nested inside it.
Checkboxes reference it via form="bulk-form". */}}
<form id="bulk-form" method="POST" action="/decisions/delete" style="display:none">
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
</form>
{{if .Decisions}}
<div style="overflow-x:auto">
<table class="data-table">
<thead>
<tr>
<th style="width:36px"><input type="checkbox" id="chk-all" onchange="selectAll(this)"></th>
<th>Value</th>
<th>Type</th>
<th>Scope</th>
<th>Origin</th>
<th>Scenario</th>
<th>Duration</th>
<th>Expires</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{{range .Decisions}}
<tr>
<td><input type="checkbox" name="id" value="{{.ID}}" class="row-chk"></td>
<td style="font-family:'JetBrains Mono',monospace;font-size:12px">
{{if eq .Scope "Country"}}{{countryFlag .Value}} {{end}}{{.Value}}
</td>
<td><span class="badge {{decisionBadgeClass .Type}}">{{.Type}}</span></td>
<td><span class="badge badge-gray">{{.Scope}}</span></td>
<td><span class="badge {{originBadgeClass .Origin}}">{{.Origin}}</span></td>
<td style="font-size:12px;color:var(--muted)">{{truncate .Scenario 24}}</td>
<td style="font-family:'JetBrains Mono',monospace;font-size:12px">{{.Duration}}</td>
<td style="font-size:12px;color:var(--muted)">{{if .Until}}{{truncate .Until 16}}{{else}}{{.Duration}}{{end}}</td>
<td>
<form method="POST" action="/decisions/delete" style="display:inline">
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
<input type="hidden" name="id" value="{{.ID}}">
<button type="submit" class="btn-danger-sm" data-confirm="Delete this decision?">Delete</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
<div class="panel">
<div class="panel-header">
<span class="panel-title">
Page {{.Page}}{{if .HasNext}} (more available){{end}}
</span>
<div style="display:flex;gap:8px;align-items:center">
<button type="button" class="btn-ghost-sm" onclick="toggleAll()">Select all</button>
<button type="submit" form="bulk-form" class="btn-danger-sm"
data-confirm-fn="confirmBulkDelete">Delete selected</button>
</div>
{{else}}
<div class="empty-state">
<div class="empty-text">No decisions found</div>
<div class="empty-sub">No active decisions match the current filters</div>
</div>
{{end}}
</form>
</div>
{{if .Decisions}}
<div style="overflow-x:auto">
<table class="data-table">
<thead>
<tr>
<th style="width:36px"><input type="checkbox" id="chk-all" onchange="selectAll(this)"></th>
<th>Value</th>
<th>Type</th>
<th>Scope</th>
<th>Origin</th>
<th>Scenario</th>
<th>Duration</th>
<th>Expires</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{{range .Decisions}}
<tr>
{{/* form="bulk-form" associates this checkbox with the external bulk form */}}
<td><input type="checkbox" name="id" value="{{.ID}}" class="row-chk" form="bulk-form"></td>
<td style="font-family:'JetBrains Mono',monospace;font-size:12px">
{{if eq .Scope "Country"}}{{countryFlag .Value}} {{end}}{{.Value}}
</td>
<td><span class="badge {{decisionBadgeClass .Type}}">{{.Type}}</span></td>
<td><span class="badge badge-gray">{{.Scope}}</span></td>
<td><span class="badge {{originBadgeClass .Origin}}">{{.Origin}}</span></td>
<td style="font-size:12px;color:var(--muted)">{{truncate .Scenario 24}}</td>
<td style="font-family:'JetBrains Mono',monospace;font-size:12px">{{.Duration}}</td>
<td style="font-size:12px;color:var(--muted)">{{if .Until}}{{truncate .Until 16}}{{else}}{{.Duration}}{{end}}</td>
<td style="display:flex;gap:4px;flex-wrap:wrap;align-items:center">
{{/* Permanent — standalone form, not inside bulk-form */}}
<form method="POST" action="/decisions/add">
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
<input type="hidden" name="value" value="{{.Value}}">
<input type="hidden" name="scope" value="{{.Scope}}">
<input type="hidden" name="type" value="{{.Type}}">
<input type="hidden" name="duration" value="999999h">
<input type="hidden" name="scenario" value="manual">
<button type="submit" class="btn-ghost-sm"
data-confirm="Make {{.Value}} permanent (999999h)?">Permanent</button>
</form>
{{/* Extend — standalone hidden form, submitted by JS after modal */}}
<form id="ext-{{.ID}}" method="POST" action="/decisions/add">
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
<input type="hidden" name="value" value="{{.Value}}">
<input type="hidden" name="scope" value="{{.Scope}}">
<input type="hidden" name="type" value="{{.Type}}">
<input type="hidden" name="duration" id="ext-dur-{{.ID}}" value="">
<input type="hidden" name="scenario" value="manual">
</form>
<button type="button" class="btn-ghost-sm"
onclick="extendDecision({{.ID}})">Extend</button>
{{/* Delete — standalone form, not inside bulk-form */}}
<form method="POST" action="/decisions/delete">
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
<input type="hidden" name="id" value="{{.ID}}">
<button type="submit" class="btn-danger-sm"
data-confirm="Delete decision for {{.Value}}?">Delete</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{else}}
<div class="empty-state">
<div class="empty-text">No decisions found</div>
<div class="empty-sub">No active decisions match the current filters</div>
</div>
{{end}}
{{if or (gt .Page 1) .HasNext}}
<div class="pagination">
@@ -174,5 +207,18 @@ function confirmBulkDelete() {
if (n === 0) { appModal.info('Select at least one decision.'); return null; }
return 'Delete ' + n + ' decision(s)? This cannot be undone.';
}
var _durPattern = /^\d+[smhdw]$/;
function extendDecision(id) {
appModal.prompt(
'Extend decision\n\nEnter new duration:',
'48h',
_durPattern,
'Extend'
).then(function(dur) {
if (!dur) return;
document.getElementById('ext-dur-' + id).value = dur;
document.getElementById('ext-' + id).submit();
});
}
</script>
{{end}}