Adding Attachment Points

This commit is contained in:
Ian Roddis committed 2026-07-02 14:06:18 -03:00
1 parent 2767fb1c8e
commit ceae27a12e
15 files changed
+729 -3

No files matched your search

+9 -1
View File
@@ -3,7 +3,7 @@
{% set can_admin = su or "users:read" in p or "roles:read" in p or "audit_log:read" in p %}
{% set can_connections = su or "clamp_connections:read" in p or "iso_threads:read" in p or "static_connections:read" in p or "unc_threads:read" in p %}
{% set can_labels = su or "attachment_point_names:read" in p or "manufacturers:read" in p or "part_colours:read" in p or "part_types:read" in p or "scope_models:read" in p or "sub_part_types:read" in p %}
{% set can_database = su or "imported_parts:read" in p or "augmented_parts:read" in p %}
{% set can_database = su or "imported_parts:read" in p or "augmented_parts:read" in p or "attachment_points:read" in p %}
{% set can_parts = can_connections or can_labels or can_database %}
{# ── SVG icon sprite ───────────────────────────────────────────────────────── #}
@@ -107,6 +107,11 @@
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/>
<circle cx="12" cy="10" r="3"/>
</symbol>
<symbol id="icon-anchor" viewBox="0 0 24 24">
<circle cx="12" cy="5" r="3"/>
<line x1="12" x2="12" y1="8" y2="22"/>
<path d="M5 12H2a10 10 0 0 0 20 0h-3"/>
</symbol>
</svg>
{# ── Nav macro for DRY icon use ────────────────────────────────────────────── #}
@@ -195,6 +200,9 @@
{% if su or "augmented_parts:read" in p %}
<a href="/admin/augmented-parts">{{ icon("layers") }} Augmented Parts</a>
{% endif %}
{% if su or "attachment_points:read" in p %}
<a href="/admin/attachment-points">{{ icon("anchor") }} Attachment Points</a>
{% endif %}
{% if su or "augmented_parts:write" in p %}
<a href="/admin/augmented-parts/skipped">{{ icon("alert-circle") }} Skipped Parts</a>
{% endif %}
@@ -0,0 +1,51 @@
{% if connection_type == "iso_thread" %}
<label>ISO Thread
<select name="iso_thread_id" required>
<option value="">— select —</option>
{% for t in iso_threads %}
<option value="{{ t.id }}"
{% if ap and ap.iso_thread_id == t.id %}selected{% endif %}>
M{{ t.diameter_mm }}×{{ t.pitch_mm }}{% if t.depth_mm %} ({{ t.depth_mm }} mm deep){% endif %}
</option>
{% endfor %}
</select>
</label>
{% elif connection_type == "unc_thread" %}
<label>UNC Thread
<select name="unc_thread_id" required>
<option value="">— select —</option>
{% for t in unc_threads %}
<option value="{{ t.id }}"
{% if ap and ap.unc_thread_id == t.id %}selected{% endif %}>
{{ t.diameter_fraction }}-{{ t.tpi }} {{ t.series.value }}{% if t.depth_in %} ({{ t.depth_in }} in deep){% endif %}
</option>
{% endfor %}
</select>
</label>
{% elif connection_type == "clamp_connection" %}
<label>Clamp Connection
<select name="clamp_connection_id" required>
<option value="">— select —</option>
{% for c in clamp_connections %}
<option value="{{ c.id }}"
{% if ap and ap.clamp_connection_id == c.id %}selected{% endif %}>
#{{ c.id }}
{% if c.min_mm is not none %} {{ c.min_mm }}–{{ c.max_mm }} mm{% endif %}
{% if c.min_in is not none %} / {{ c.min_in }}–{{ c.max_in }} in{% endif %}
</option>
{% endfor %}
</select>
</label>
{% elif connection_type == "static_connection" %}
<label>Static Connection
<select name="static_connection_id" required>
<option value="">— select —</option>
{% for s in static_connections %}
<option value="{{ s.id }}"
{% if ap and ap.static_connection_id == s.id %}selected{% endif %}>
{{ s.od_mm }} mm / {{ s.od_in }} in OD
</option>
{% endfor %}
</select>
</label>
{% endif %}
@@ -0,0 +1,38 @@
{% if ap.iso_thread %}
{% set conn_type = "ISO Thread" %}
{% set conn_label = "M" ~ ap.iso_thread.diameter_mm ~ "×" ~ ap.iso_thread.pitch_mm %}
{% elif ap.unc_thread %}
{% set conn_type = "UNC Thread" %}
{% set conn_label = ap.unc_thread.diameter_fraction ~ "-" ~ ap.unc_thread.tpi ~ " " ~ ap.unc_thread.series.value %}
{% elif ap.clamp_connection %}
{% set conn_type = "Clamp Connection" %}
{% if ap.clamp_connection.min_mm is not none %}
{% set conn_label = ap.clamp_connection.min_mm ~ "–" ~ ap.clamp_connection.max_mm ~ " mm" %}
{% else %}
{% set conn_label = ap.clamp_connection.min_in ~ "–" ~ ap.clamp_connection.max_in ~ " in" %}
{% endif %}
{% elif ap.static_connection %}
{% set conn_type = "Static Connection" %}
{% set conn_label = ap.static_connection.od_mm ~ " mm OD" %}
{% else %}
{% set conn_type = "—" %}
{% set conn_label = "—" %}
{% endif %}
<tr id="attachment-point-{{ ap.id }}">
<td>{{ ap.id }}</td>
<td>{{ ap.augmented_part.description | truncate(40) }}</td>
<td>{{ ap.attachment_point_name.name }}</td>
<td>{{ conn_type }}</td>
<td><code>{{ conn_label }}</code></td>
<td class="row-actions">
<button class="btn btn-ghost"
hx-get="/admin/attachment-points/{{ ap.id }}/edit"
hx-target="#attachment-point-{{ ap.id }}"
hx-swap="outerHTML">Edit</button>
<button class="btn btn-danger"
hx-delete="/admin/attachment-points/{{ ap.id }}"
hx-target="#attachment-point-{{ ap.id }}"
hx-swap="outerHTML"
hx-confirm="Delete attachment point #{{ ap.id }}?">Delete</button>
</td>
</tr>
@@ -0,0 +1,59 @@
{% if ap.iso_thread_id %}{% set current_type = "iso_thread" %}
{% elif ap.unc_thread_id %}{% set current_type = "unc_thread" %}
{% elif ap.clamp_connection_id %}{% set current_type = "clamp_connection" %}
{% elif ap.static_connection_id %}{% set current_type = "static_connection" %}
{% else %}{% set current_type = "" %}{% endif %}
<tr id="attachment-point-{{ ap.id }}">
<td colspan="6">
<form hx-post="/admin/attachment-points/{{ ap.id }}"
hx-target="#attachment-point-{{ ap.id }}"
hx-swap="outerHTML"
class="inline-edit">
<span class="muted">#{{ ap.id }}</span>
<label>Part
<select name="augmented_part_id" required>
{% for part in augmented_parts %}
<option value="{{ part.id }}"
{% if part.id == ap.augmented_part_id %}selected{% endif %}>
{{ part.description | truncate(50) }}
</option>
{% endfor %}
</select>
</label>
<label>Point Name
<select name="attachment_point_name_id" required>
{% for apn in attachment_point_names %}
<option value="{{ apn.id }}"
{% if apn.id == ap.attachment_point_name_id %}selected{% endif %}>
{{ apn.name }}
</option>
{% endfor %}
</select>
</label>
<label>Connection Type
<select name="connection_type" required
hx-get="/admin/attachment-points/connection-options"
hx-target="#edit-connection-options-{{ ap.id }}"
hx-trigger="change"
hx-include="[name='connection_type']">
<option value="">— select type —</option>
<option value="iso_thread" {% if current_type == "iso_thread" %}selected{% endif %}>ISO Thread</option>
<option value="unc_thread" {% if current_type == "unc_thread" %}selected{% endif %}>UNC Thread</option>
<option value="clamp_connection" {% if current_type == "clamp_connection" %}selected{% endif %}>Clamp Connection</option>
<option value="static_connection" {% if current_type == "static_connection" %}selected{% endif %}>Static Connection</option>
</select>
</label>
{# Render the current connection select pre-filled #}
<div id="edit-connection-options-{{ ap.id }}">
{% include "admin/_attachment_point_connection_select.html" %}
</div>
<div class="row-actions">
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-ghost"
hx-get="/admin/attachment-points/{{ ap.id }}/row"
hx-target="#attachment-point-{{ ap.id }}"
hx-swap="outerHTML">Cancel</button>
</div>
</form>
</td>
</tr>
@@ -0,0 +1,21 @@
<div id="attachment-point-list" class="card" style="overflow-x:auto">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Augmented Part</th>
<th>Point Name</th>
<th>Connection Type</th>
<th>Connection</th>
<th></th>
</tr>
</thead>
<tbody>
{% for ap in attachment_points %}
{% include "admin/_attachment_point_row.html" %}
{% else %}
<tr><td colspan="6" class="muted">No attachment points recorded.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
@@ -0,0 +1,50 @@
{% extends "base.html" %}
{% block title %}Attachment Points · {{ app_name }}{% endblock %}
{% block body %}
{% include "_nav.html" %}
<main class="container">
<h1>Attachment Points</h1>
<div class="card">
<h2>Add attachment point</h2>
<form hx-post="/admin/attachment-points"
hx-target="#attachment-point-list"
hx-swap="outerHTML"
class="form-grid">
<label>Augmented Part
<select name="augmented_part_id" required>
<option value="">— select —</option>
{% for part in augmented_parts %}
<option value="{{ part.id }}">{{ part.description }}</option>
{% endfor %}
</select>
</label>
<label>Point Name
<select name="attachment_point_name_id" required>
<option value="">— select —</option>
{% for apn in attachment_point_names %}
<option value="{{ apn.id }}">{{ apn.name }}</option>
{% endfor %}
</select>
</label>
<label>Connection Type
<select name="connection_type" required
hx-get="/admin/attachment-points/connection-options"
hx-target="#add-connection-options"
hx-trigger="change"
hx-include="[name='connection_type']">
<option value="">— select type —</option>
<option value="iso_thread">ISO Thread</option>
<option value="unc_thread">UNC Thread</option>
<option value="clamp_connection">Clamp Connection</option>
<option value="static_connection">Static Connection</option>
</select>
</label>
<div id="add-connection-options"></div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
{% include "admin/_attachment_points_table.html" %}
</main>
{% endblock %}