Moving post-import reconciliation to a separate page

This commit is contained in:
Ian Roddis committed 2026-07-02 13:22:28 -03:00
1 parent 87019ff2af
commit 0168b023af
5 files changed
+183 -36

No files matched your search

+3
View File
@@ -32,6 +32,9 @@
{% if user.is_superuser or "augmented_parts:read" in user.permissions %}
<a href="/admin/augmented-parts">Augmented Parts</a>
{% endif %}
{% if user.is_superuser or "augmented_parts:write" in user.permissions %}
<a href="/admin/augmented-parts/skipped">Skipped Parts</a>
{% endif %}
{% if user.is_superuser or "part_colours:read" in user.permissions %}
<a href="/admin/part-colours">Part Colours</a>
{% endif %}
@@ -0,0 +1,61 @@
<div id="skipped-parts-list">
{% if sync_result %}<p class="alert alert-success">{{ sync_result }}</p>{% endif %}
{% if sync_error %}<p class="alert alert-error">{{ sync_error }}</p>{% endif %}
{% if unlinked_parts %}
<form hx-post="/admin/augmented-parts/skipped"
hx-target="#skipped-parts-list"
hx-swap="outerHTML">
<div class="card">
<div class="form-grid">
<label>Type
<select name="part_type_id" required>
<option value="">— select type —</option>
{% for pt in part_types %}
<option value="{{ pt.id }}">{{ pt.name }}</option>
{% endfor %}
</select>
</label>
<label>Sub Type
<select name="sub_part_type_id">
<option value="">— none —</option>
{% for spt in sub_part_types %}
<option value="{{ spt.id }}">{{ spt.name }} ({{ spt.part_type.name }})</option>
{% endfor %}
</select>
</label>
<button id="sync-selected-btn" type="submit" class="btn btn-primary">Sync selected</button>
</div>
</div>
<div class="card" style="overflow-x:auto">
<table class="table">
<thead>
<tr>
<th><input type="checkbox" id="select-all" title="Select all"></th>
<th>Inventory ID</th>
<th>Description</th>
<th>Colour</th>
</tr>
</thead>
<tbody>
{% for ip in unlinked_parts %}
<tr>
<td><input type="checkbox" name="inventory_ids" value="{{ ip.InventoryID }}"></td>
<td><code>{{ ip.InventoryID }}</code></td>
<td>{{ ip.Description | truncate(80) if ip.Description else '—' }}</td>
<td>{{ ip.TBXColour or '—' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</form>
{% else %}
<div class="card">
<p class="muted">No skipped parts — all imported parts have been synchronised.</p>
</div>
{% endif %}
</div>
+7 -4
View File
@@ -57,11 +57,14 @@
<div class="card">
<h2>Sync with Imported Parts</h2>
<p class="muted">Creates Augmented Part entries for new Imported Parts, and removes entries for deleted Imported Parts.</p>
<form hx-post="/admin/augmented-parts/sync" hx-target="#augmented-parts-sections" hx-swap="outerHTML">
<button type="submit" class="btn btn-primary">Sync now</button>
</form>
<div class="row-actions">
<form hx-post="/admin/augmented-parts/sync" hx-target="#augmented-part-list" hx-swap="outerHTML">
<button type="submit" class="btn btn-primary">Sync now</button>
</form>
<a href="/admin/augmented-parts/skipped" class="btn btn-ghost">View skipped parts →</a>
</div>
</div>
{% include "admin/_augmented_parts_sections.html" %}
{% include "admin/_augmented_parts_table.html" %}
</main>
{% endblock %}
@@ -0,0 +1,46 @@
{% extends "base.html" %}
{% block title %}Skipped Parts · {{ app_name }}{% endblock %}
{% block body %}
{% include "_nav.html" %}
<main class="container">
<h1>Skipped Imported Parts</h1>
<p class="muted">
These parts were skipped during sync because no Part Type could be inferred
from their description. Select one or more rows, choose a Type (and optionally
a Sub Type), then click <strong>Sync selected</strong> to create their
Augmented Part entries.
</p>
<p><a href="/admin/augmented-parts" class="btn btn-ghost">← Augmented Parts</a></p>
{% include "admin/_skipped_parts_table.html" %}
</main>
<script>
(function () {
function updateButton() {
var count = document.querySelectorAll('input[name="inventory_ids"]:checked').length;
var btn = document.getElementById('sync-selected-btn');
if (btn) {
btn.textContent = count > 0 ? 'Sync selected (' + count + ')' : 'Sync selected';
}
}
document.addEventListener('change', function (e) {
if (!e.target) return;
if (e.target.id === 'select-all') {
document.querySelectorAll('input[name="inventory_ids"]').forEach(function (cb) {
cb.checked = e.target.checked;
});
}
if (e.target.id === 'select-all' || e.target.name === 'inventory_ids') {
updateButton();
}
});
// Re-run after every HTMX swap so the button state reflects the new content.
document.addEventListener('htmx:afterSwap', updateButton);
}());
</script>
{% endblock %}