Skip to content

Commit 513ad63

Browse files
lolimmlostclaude
andcommitted
fix: Move protect/unprotect JS out of HTML attributes into Alpine component
Inline Jinja2 tojson in @click attributes was getting double-escaped, causing raw JS to render as button text. Moved to a queueRow() Alpine component function instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0ba7f6b commit 513ad63

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

src/web/templates/partials/queue_table.html

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<tbody>
1717
{% for item in items %}
1818
<tr class="{% if item.strikes %}row-flagged{% endif %}{% if item.protected %} row-protected{% endif %}"
19-
x-data="{ protecting: false }">
19+
x-data="queueRow({{ item | tojson }})">
2020
<td>
2121
<span class="badge" data-arr-type="{{ item.arr_type }}">{{ item.arr_name }}</span>
2222
</td>
@@ -57,19 +57,11 @@
5757
</td>
5858
<td>
5959
{% if not item.protected %}
60-
<button class="outline small-btn"
61-
:aria-busy="protecting"
62-
@click="protecting = true; fetch('/api/protected/' + {{ item.download_id | tojson }}, {
63-
method: 'POST',
64-
headers: {'Content-Type': 'application/json'},
65-
body: JSON.stringify({title: {{ item.title | tojson }}, arr_name: {{ item.arr_name | tojson }}})
66-
}).then(() => { htmx.trigger('#queue-container', 'refresh'); protecting = false; })">
60+
<button class="outline small-btn" :aria-busy="protecting" @click="protect()">
6761
Protect
6862
</button>
6963
{% else %}
70-
<button class="outline secondary small-btn"
71-
@click="fetch('/api/protected/' + {{ item.download_id | tojson }}, { method: 'DELETE' })
72-
.then(() => htmx.trigger('#queue-container', 'refresh'))">
64+
<button class="outline secondary small-btn" @click="unprotect()">
7365
Unprotect
7466
</button>
7567
{% endif %}
@@ -80,6 +72,30 @@
8072
</table>
8173
</figure>
8274
<p><small>{{ total }} items in queue</small></p>
75+
76+
<script>
77+
function queueRow(item) {
78+
return {
79+
protecting: false,
80+
protect() {
81+
this.protecting = true;
82+
fetch('/api/protected/' + encodeURIComponent(item.download_id), {
83+
method: 'POST',
84+
headers: {'Content-Type': 'application/json'},
85+
body: JSON.stringify({title: item.title, arr_name: item.arr_name})
86+
}).then(() => {
87+
htmx.trigger('#queue-container', 'refresh');
88+
this.protecting = false;
89+
});
90+
},
91+
unprotect() {
92+
fetch('/api/protected/' + encodeURIComponent(item.download_id), {
93+
method: 'DELETE'
94+
}).then(() => htmx.trigger('#queue-container', 'refresh'));
95+
}
96+
}
97+
}
98+
</script>
8399
{% else %}
84100
<p>Queue is empty</p>
85101
{% endif %}

0 commit comments

Comments
 (0)