refactor(ui): extract duplicated row-expand handler into shared function

The same ~250-character inline onclick handler was copy-pasted across
all 7 list templates. Extract it into a toggleRow() function in
base.html and replace the inline copies with a single call.
This commit is contained in:
Jon Seager 2026-02-06 18:19:12 +00:00
parent f2fcada799
commit 26e1a4d930
No known key found for this signature in database
8 changed files with 19 additions and 7 deletions

View file

@ -23,6 +23,18 @@
<script defer src="/components/photo-capture.js"></script> <script defer src="/components/photo-capture.js"></script>
<script defer src="/components/searchable-select.js"></script> <script defer src="/components/searchable-select.js"></script>
{% block head %}{% endblock %} {% block head %}{% endblock %}
<script>
const toggleRow = (event) => {
if (event.target.closest('.card-detail')) return;
const row = event.currentTarget;
row.classList.toggle('expanded');
row.querySelector('.card-detail')?.classList.toggle('hidden');
const r = row.nextElementSibling;
if (r?.classList.contains('detail-row')) r.classList.toggle('hidden');
row.querySelector('.icon-expand')?.classList.toggle('hidden');
row.querySelector('.icon-collapse')?.classList.toggle('hidden');
};
</script>
<script> <script>
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
const mobileQuery = window.matchMedia("(max-width: 767px)"); const mobileQuery = window.matchMedia("(max-width: 767px)");

View file

@ -36,7 +36,7 @@
<tbody class="divide-y/70"> <tbody class="divide-y/70">
{% for bag in bags.items %} {% for bag in bags.items %}
<tr class="transition hover:bg-surface-alt" <tr class="transition hover:bg-surface-alt"
{% if is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ bag.created_date }}</div> <div>{{ bag.created_date }}</div>

View file

@ -65,7 +65,7 @@
<tbody class="divide-y/70"> <tbody class="divide-y/70">
{% for brew in brews.items %} {% for brew in brews.items %}
<tr class="transition hover:bg-surface-alt" <tr class="transition hover:bg-surface-alt"
{% if is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ brew.created_date }}</div> <div>{{ brew.created_date }}</div>

View file

@ -39,7 +39,7 @@
data-sort-country="{{ cafe.country }}" data-sort-country="{{ cafe.country }}"
data-sort-city="{{ cafe.city }}" data-sort-city="{{ cafe.city }}"
class="transition hover:bg-surface-alt" class="transition hover:bg-surface-alt"
onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');" onclick="toggleRow(event)"
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ cafe.created_date }}</div> <div>{{ cafe.created_date }}</div>

View file

@ -38,7 +38,7 @@
<tr <tr
data-star-key="{{ cup.id }}" data-star-key="{{ cup.id }}"
class="transition hover:bg-surface-alt" class="transition hover:bg-surface-alt"
{% if is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ cup.created_date }}</div> <div>{{ cup.created_date }}</div>

View file

@ -36,7 +36,7 @@
<tbody class="divide-y/70"> <tbody class="divide-y/70">
{% for item in gear.items %} {% for item in gear.items %}
<tr class="transition hover:bg-surface-alt" <tr class="transition hover:bg-surface-alt"
{% if is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ item.created_date }}</div> <div>{{ item.created_date }}</div>

View file

@ -42,7 +42,7 @@
data-sort-origin="{{ roast.origin }}" data-sort-origin="{{ roast.origin }}"
data-sort-producer="{{ roast.producer }}" data-sort-producer="{{ roast.producer }}"
class="transition hover:bg-surface-alt" class="transition hover:bg-surface-alt"
{% if is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ roast.created_date }}</div> <div>{{ roast.created_date }}</div>

View file

@ -39,7 +39,7 @@
data-sort-country="{{ roaster.country }}" data-sort-country="{{ roaster.country }}"
data-sort-city="{{ roaster.city }}" data-sort-city="{{ roaster.city }}"
class="transition hover:bg-surface-alt" class="transition hover:bg-surface-alt"
{% if roaster.has_homepage || is_authenticated %}onclick="if(event.target.closest('.card-detail'))return;this.classList.toggle('expanded');this.querySelector('.card-detail')?.classList.toggle('hidden');const r=this.nextElementSibling;if(r?.classList.contains('detail-row'))r.classList.toggle('hidden');this.querySelector('.icon-expand')?.classList.toggle('hidden');this.querySelector('.icon-collapse')?.classList.toggle('hidden');"{% endif %} {% if roaster.has_homepage || is_authenticated %}onclick="toggleRow(event)"{% endif %}
> >
<td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary"> <td data-label="Added" class="card-date whitespace-nowrap px-4 py-3 text-xs font-medium text-text-secondary">
<div>{{ roaster.created_date }}</div> <div>{{ roaster.created_date }}</div>