Relayout of Augmented Part details page
This commit is contained in:
1 parent
6806caf8d7
commit
2ce4f91e4f
5 files changed
+138
-114
No files matched your search
+15
-27
@@ -505,43 +505,31 @@ textarea:focus {
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fit-item {
|
|
||||||
padding: 0.5rem 0;
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fit-item:last-of-type {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fit-item-main {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-bottom: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fit-item-arrow {
|
.fit-item-arrow {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fit-badge {
|
.fit-badge {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Fits table on the augmented part detail page */
|
||||||
/*font-size: 0.7rem;
|
.fit-table select,
|
||||||
letter-spacing: 0.03em;
|
.fit-table input[type="text"] {
|
||||||
padding: 0.1rem 0.5rem;
|
min-width: 8rem;
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
.augmented-fit-row-group {
|
.fit-table .fit-add-row {
|
||||||
padding: 0.5rem 0;
|
background: var(--surface-2);
|
||||||
border-bottom: 2px solid var(--muted);
|
}
|
||||||
|
|
||||||
|
.fit-table .fit-add-row td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fit-notes-cell {
|
||||||
|
min-width: 14rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fit-badge-possible {
|
.fit-badge-possible {
|
||||||
|
|||||||
@@ -12,42 +12,18 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
<div id="fit-{{ fit.id }}" class="fit-item">
|
<tr id="fit-{{ fit.id }}" class="fit-row">
|
||||||
<div class="fit-item-main">
|
<td><span class="fit-badge fit-badge-{{ fit.label.value }}">{{ fit.label.value | capitalize }}</span></td>
|
||||||
<span class="fit-badge fit-badge-{{ fit.label.value }}">{{ fit.label.value | capitalize }}</span>
|
<td>
|
||||||
<span class="fit-item-side"><strong>{{ own_ap.attachment_point_name.name }}</strong> ({{ conn_desc(own_ap) }})</span>
|
<strong>{{ own_ap.attachment_point_name.name }}</strong>
|
||||||
<span class="fit-item-arrow">↔</span>
|
<div class="muted" style="font-size:0.8rem">{{ conn_desc(own_ap) }}</div>
|
||||||
<span class="fit-item-side"><a href="/admin/augmented-parts/{{ other_part.id }}" title="{{ other_part.description }}">{{ other_part.sku }}</a> <strong>{{ other_part.part_type.name }}</strong></span>
|
</td>
|
||||||
</div>
|
<td class="fit-item-arrow">↔</td>
|
||||||
{% if can_write %}
|
<td>
|
||||||
<div class="row-actions">
|
<a href="/admin/augmented-parts/{{ other_part.id }}" title="{{ other_part.description }}">{{ other_part.sku or other_part.description }}</a>
|
||||||
{% if fit.label.value != "exact" %}
|
<div class="muted" style="font-size:0.8rem">{{ other_part.part_type.name }}</div>
|
||||||
<button class="btn btn-ghost"
|
</td>
|
||||||
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
<td class="fit-notes-cell">
|
||||||
hx-vals='{"label": "exact"}'
|
|
||||||
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Exact</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if fit.label.value != "possible" %}
|
|
||||||
<button class="btn btn-ghost"
|
|
||||||
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
|
||||||
hx-vals='{"label": "possible"}'
|
|
||||||
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Possible</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if fit.label.value != "none" %}
|
|
||||||
<button class="btn btn-ghost"
|
|
||||||
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
|
||||||
hx-vals='{"label": "none"}'
|
|
||||||
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Impossible</button>
|
|
||||||
{% endif %}
|
|
||||||
<button class="btn btn-danger"
|
|
||||||
hx-delete="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}"
|
|
||||||
hx-target="#ap-{{ augmented_part_id }}-fits"
|
|
||||||
hx-swap="outerHTML"
|
|
||||||
hx-confirm="Delete this fit?">Delete</button>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="fit-notes">
|
|
||||||
{% for note in fit.notes %}
|
{% for note in fit.notes %}
|
||||||
<div class="fit-note">
|
<div class="fit-note">
|
||||||
<span class="fit-note-meta">{{ note.username }} · {{ note.created_at.strftime("%Y-%m-%d %H:%M") }}</span>
|
<span class="fit-note-meta">{{ note.username }} · {{ note.created_at.strftime("%Y-%m-%d %H:%M") }}</span>
|
||||||
@@ -59,8 +35,37 @@
|
|||||||
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML"
|
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML"
|
||||||
class="inline-edit fit-note-form">
|
class="inline-edit fit-note-form">
|
||||||
<input type="text" name="body" placeholder="Add a note…" required>
|
<input type="text" name="body" placeholder="Add a note…" required>
|
||||||
<button type="submit" class="btn btn-ghost">Add note</button>
|
<button type="submit" class="btn btn-ghost btn-sm">Add note</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</td>
|
||||||
</div>
|
{% if can_write %}
|
||||||
|
<td>
|
||||||
|
<div class="row-actions">
|
||||||
|
{% if fit.label.value != "exact" %}
|
||||||
|
<button class="btn btn-ghost btn-sm"
|
||||||
|
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
||||||
|
hx-vals='{"label": "exact"}'
|
||||||
|
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Exact</button>
|
||||||
|
{% endif %}
|
||||||
|
{% if fit.label.value != "possible" %}
|
||||||
|
<button class="btn btn-ghost btn-sm"
|
||||||
|
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
||||||
|
hx-vals='{"label": "possible"}'
|
||||||
|
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Possible</button>
|
||||||
|
{% endif %}
|
||||||
|
{% if fit.label.value != "none" %}
|
||||||
|
<button class="btn btn-ghost btn-sm"
|
||||||
|
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}/label"
|
||||||
|
hx-vals='{"label": "none"}'
|
||||||
|
hx-target="#fit-{{ fit.id }}" hx-swap="outerHTML">Mark Impossible</button>
|
||||||
|
{% endif %}
|
||||||
|
<button class="btn btn-danger btn-sm"
|
||||||
|
hx-delete="/admin/augmented-parts/{{ augmented_part_id }}/fits/{{ fit.id }}"
|
||||||
|
hx-target="#ap-{{ augmented_part_id }}-fits"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-confirm="Delete this fit?">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
@@ -4,13 +4,77 @@
|
|||||||
{% if message %}<p class="alert alert-success">{{ message }}</p>{% endif %}
|
{% if message %}<p class="alert alert-success">{{ message }}</p>{% endif %}
|
||||||
{% if error %}<p class="alert alert-error">{{ error }}</p>{% endif %}
|
{% if error %}<p class="alert alert-error">{{ error }}</p>{% endif %}
|
||||||
|
|
||||||
{% for view in fit_views %}
|
{% set add_form_id = "ap-" ~ augmented_part_id ~ "-fit-add-form" %}
|
||||||
{% with fit=view.fit, own_ap=view.own_ap, other_ap=view.other_ap, other_part=view.other_part %}
|
{% if can_write %}
|
||||||
{% include "admin/_augmented_part_fit_row.html" %}
|
<form id="{{ add_form_id }}"
|
||||||
{% endwith %}
|
hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits"
|
||||||
{% else %}
|
hx-target="#ap-{{ augmented_part_id }}-fits"
|
||||||
<p class="muted" style="font-size:0.85rem;margin:0 0 0.5rem">No fits recorded yet.</p>
|
hx-swap="outerHTML"></form>
|
||||||
{% endfor %}
|
{% endif %}
|
||||||
|
|
||||||
|
<table class="table fit-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>This part's point</th>
|
||||||
|
<th></th>
|
||||||
|
<th>Fits with part</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
{% if can_write %}<th></th>{% endif %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if can_write %}
|
||||||
|
<tr class="fit-add-row">
|
||||||
|
<td>
|
||||||
|
<select form="{{ add_form_id }}" name="label">
|
||||||
|
<option value="exact" selected>Exact</option>
|
||||||
|
<option value="possible">Possible</option>
|
||||||
|
<option value="none">None</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select form="{{ add_form_id }}" name="own_attachment_point_id" required>
|
||||||
|
<option value="">— select —</option>
|
||||||
|
{% for p in own_points %}
|
||||||
|
<option value="{{ p.id }}">{{ p.attachment_point_name.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td class="fit-item-arrow">↔</td>
|
||||||
|
<td>
|
||||||
|
<select form="{{ add_form_id }}" name="other_augmented_part_id" required
|
||||||
|
hx-get="/admin/augmented-parts/{{ augmented_part_id }}/fits/other-points"
|
||||||
|
hx-target="#ap-{{ augmented_part_id }}-fit-other-points"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="[name='other_augmented_part_id']">
|
||||||
|
<option value="">— select —</option>
|
||||||
|
{% for p in other_parts %}
|
||||||
|
<option value="{{ p.id }}">{{ p.description | truncate(40) }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<div id="ap-{{ augmented_part_id }}-fit-other-points"></div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input form="{{ add_form_id }}" type="text" name="note" placeholder="Add a note…">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" form="{{ add_form_id }}" class="btn btn-primary btn-sm">Add fit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for view in fit_views %}
|
||||||
|
{% with fit=view.fit, own_ap=view.own_ap, other_ap=view.other_ap, other_part=view.other_part %}
|
||||||
|
{% include "admin/_augmented_part_fit_row.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="{{ 6 if can_write else 5 }}" class="muted" style="font-size:0.85rem">No fits recorded yet.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
{% if can_write %}
|
{% if can_write %}
|
||||||
<div class="row-actions" style="margin:0.5rem 0">
|
<div class="row-actions" style="margin:0.5rem 0">
|
||||||
@@ -19,43 +83,5 @@
|
|||||||
<button type="submit" class="btn btn-ghost">Recompute possible fits</button>
|
<button type="submit" class="btn btn-ghost">Recompute possible fits</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form hx-post="/admin/augmented-parts/{{ augmented_part_id }}/fits"
|
|
||||||
hx-target="#ap-{{ augmented_part_id }}-fits"
|
|
||||||
hx-swap="outerHTML"
|
|
||||||
class="inline-edit" style="margin-top:0.5rem">
|
|
||||||
<label>This part's point
|
|
||||||
<select name="own_attachment_point_id" required>
|
|
||||||
<option value="">— select —</option>
|
|
||||||
{% for p in own_points %}
|
|
||||||
<option value="{{ p.id }}">{{ p.attachment_point_name.name }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>Fits with part
|
|
||||||
<select name="other_augmented_part_id" required
|
|
||||||
hx-get="/admin/augmented-parts/{{ augmented_part_id }}/fits/other-points"
|
|
||||||
hx-target="#ap-{{ augmented_part_id }}-fit-other-points"
|
|
||||||
hx-trigger="change"
|
|
||||||
hx-include="[name='other_augmented_part_id']">
|
|
||||||
<option value="">— select —</option>
|
|
||||||
{% for p in other_parts %}
|
|
||||||
<option value="{{ p.id }}">{{ p.description | truncate(40) }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<div id="ap-{{ augmented_part_id }}-fit-other-points"></div>
|
|
||||||
<label>Fit type
|
|
||||||
<select name="label">
|
|
||||||
<option value="exact" selected>Exact</option>
|
|
||||||
<option value="possible">Possible</option>
|
|
||||||
<option value="none">None</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>Note (optional)
|
|
||||||
<input type="text" name="note" placeholder="Add a note…">
|
|
||||||
</label>
|
|
||||||
<button type="submit" class="btn btn-primary">Add fit</button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
{% if points %}
|
{% if points %}
|
||||||
<select name="other_attachment_point_id" required>
|
<select name="other_attachment_point_id" form="{{ form_id }}" required>
|
||||||
<option value="">— select —</option>
|
<option value="">— select —</option>
|
||||||
{% for p in points %}
|
{% for p in points %}
|
||||||
<option value="{{ p.id }}">{{ p.attachment_point_name.name }}</option>
|
<option value="{{ p.id }}">{{ p.attachment_point_name.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
{% else %}
|
{% else %}
|
||||||
<input type="hidden" name="other_attachment_point_id" value="">
|
<input type="hidden" name="other_attachment_point_id" value="" form="{{ form_id }}">
|
||||||
<p class="muted" style="font-size:0.85rem;margin:0">
|
<p class="muted" style="font-size:0.85rem;margin:0">
|
||||||
This part has no attachment points yet — one matching yours will be created automatically.
|
This part has no attachment points yet — one matching yours will be created automatically.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+6
-1
@@ -2682,7 +2682,12 @@ async def fit_other_points(
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request, "admin/_fit_other_points_select.html", {"points": points}
|
request,
|
||||||
|
"admin/_fit_other_points_select.html",
|
||||||
|
{
|
||||||
|
"points": points,
|
||||||
|
"form_id": f"ap-{augmented_part_id}-fit-add-form",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user