fix: replace channel checkboxes in Users table with multi-select

The per-user notification channel selector in the admin settings Users
section was a column of checkboxes; replaced with a <select multiple>
for consistency with the profile chip picker and to reduce table width.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Andreas Wrede
2026-05-11 07:38:56 -04:00
parent 500d256d76
commit 9b5d8ac9b1
+8 -9
View File
@@ -500,12 +500,12 @@
<td><input class="field-input user-full-name" value="{{ u.full_name | e }}"></td>
<td><input class="field-input user-avatar" value="{{ u.avatar | e }}"></td>
<td style="text-align:center"><input type="checkbox" class="user-admin" {% if u.admin %}checked{% endif %}></td>
<td style="min-width:120px">
<td style="min-width:140px">
<select class="field-input user-ch-select" multiple size="{{ [all_channel_names|length, 4]|min }}" style="min-width:130px">
{% for ch in all_channel_names %}
<label style="display:block;font-size:.82em;white-space:nowrap">
<input type="checkbox" class="user-ch" value="{{ ch | e }}" {% if ch in u.notification_channels %}checked{% endif %}> {{ ch | e }}
</label>
<option value="{{ ch | e }}" {% if ch in u.notification_channels %}selected{% endif %}>{{ ch | e }}</option>
{% endfor %}
</select>
</td>
<td><input type="password" class="field-input user-password" placeholder="(leave blank to keep)"></td>
<td><button class="btn-danger" onclick="toggleDeleteRow(this)"></button></td>
@@ -847,7 +847,7 @@
full_name: row.querySelector('.user-full-name').value,
avatar: row.querySelector('.user-avatar').value,
admin: row.querySelector('.user-admin').checked,
notification_channels: [...row.querySelectorAll('.user-ch:checked')].map(cb => cb.value),
notification_channels: [...(row.querySelector('.user-ch-select')?.selectedOptions || [])].map(o => o.value),
};
const pw = row.querySelector('.user-password').value;
if (pw) entry.password = pw;
@@ -861,7 +861,7 @@
full_name: row.querySelector('.user-full-name').value,
avatar: row.querySelector('.user-avatar').value,
admin: row.querySelector('.user-admin').checked,
notification_channels: [...row.querySelectorAll('.user-ch:checked')].map(cb => cb.value),
notification_channels: [...(row.querySelector('.user-ch-select')?.selectedOptions || [])].map(o => o.value),
};
const pw = row.querySelector('.user-password').value;
if (pw) entry.password = pw;
@@ -974,9 +974,8 @@
function addUserRow() {
const tbody = document.getElementById('users-tbody');
const chHtml = _allChannels.map(ch =>
`<label style="display:block;font-size:.82em;white-space:nowrap"><input type="checkbox" class="user-ch" value="${escHtml(ch)}"> ${escHtml(ch)}</label>`
).join('');
const opts = _allChannels.map(ch => `<option value="${escHtml(ch)}">${escHtml(ch)}</option>`).join('');
const chHtml = `<select class="field-input user-ch-select" multiple size="${Math.min(_allChannels.length, 4)}" style="min-width:130px">${opts}</select>`;
const row = document.createElement('tr');
row.setAttribute('data-new-user', 'true');
row.innerHTML = `