From ca2868a888630c3335a42dd44f5c7a1c611f29cb Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Thu, 9 Jul 2026 16:52:44 -0400 Subject: [PATCH] feat: settings UI renders per-user edit rights and owner controls Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01NfPpSpccTWBfZg1FTveyaU --- hbd/server/templates/settings.html | 51 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/hbd/server/templates/settings.html b/hbd/server/templates/settings.html index 384bd9c..390da3e 100644 --- a/hbd/server/templates/settings.html +++ b/hbd/server/templates/settings.html @@ -572,11 +572,12 @@ + {% if not current_user or current_user.admin %}
- + +
+ {% endif %}
@@ -709,12 +712,18 @@ {{ h.name | e }} + {% if h.is_owner %} {{ mpick(all_usernames, h.managers, 'host-managers') }} {{ mpick(all_usernames, h.monitors, 'host-monitors') }} + {% else %} + {{ h.owner | e }} + {% for m in h.managers %}{{ m | e }}{% else %}(none){% endfor %} + {% for m in h.monitors %}{{ m | e }}{% else %}(none){% endfor %} + {% endif %} {{ mpick(all_threshold_configs, h.threshold_configs, 'host-tc') }} {{ mpick(all_channel_names, h.notification_channels, 'host-channels') }} - + {% if h.is_owner %}{% endif %} {% endfor %} @@ -748,12 +757,13 @@ {{ ch.name | e }} {{ ch.type_label | e }} {% if ch.min_level and ch.min_level != 'WARNING' %}{{ ch.min_level | e }}+{% endif %} - {% if ch.private %}private{% endif %} {% if ch.owner %}{{ ch.owner | e }}{% endif %} + {% if ch.editable %} + {% endif %}
{% for f in ch.fields %} @@ -790,13 +800,20 @@ {% endfor %}
{% for tc in section.threshold_configs %} -
+
{{ tc.name | e }} - {% if tc.name != 'default' %} + {% if (not current_user or current_user.admin) and tc.name != 'default' %} + + {% elif tc.owner %} + {{ tc.owner | e }} + {% endif %} + {% if tc.editable and tc.name != 'default' %} {% endif %}
+
@@ -845,6 +862,7 @@ + {% endfor %} @@ -928,6 +946,7 @@ const _allChannels = {{ all_channel_names | tojson }}; const _allUsers = {{ all_usernames | tojson }}; const _allThresholdConfigs = {{ all_threshold_configs | tojson }}; + const _isAdmin = {{ 'true' if (not current_user or current_user.admin) else 'false' }}; // ---- Channel CRUD ---- let _channelSchemas = {}; @@ -981,7 +1000,8 @@ document.getElementById('ch-type').value = ''; document.getElementById('ch-type-fields').innerHTML = ''; document.getElementById('ch-min-level').value = 'WARNING'; - document.getElementById('ch-private').checked = false; + const ownerInp = document.getElementById('ch-owner'); + if (ownerInp) ownerInp.value = ''; if (name) { // Load existing channel data via API @@ -993,7 +1013,7 @@ document.getElementById('ch-type').value = ch.type; onChTypeChange(); document.getElementById('ch-min-level').value = ch.min_level || 'WARNING'; - document.getElementById('ch-private').checked = ch.private || false; + if (ownerInp) ownerInp.value = ch.owner || ''; (ch.fields || []).forEach(f => { const inp = document.getElementById('chf-' + f.key); if (inp) inp.value = f.value || ''; @@ -1012,14 +1032,15 @@ const name = document.getElementById('ch-name').value.trim(); const type = document.getElementById('ch-type').value; const minLevel = document.getElementById('ch-min-level').value; - const isPrivate = document.getElementById('ch-private').checked; const statusEl = document.getElementById('ch-modal-status'); statusEl.textContent = ''; if (!name) { statusEl.textContent = 'Channel name is required.'; statusEl.style.color = '#c62828'; return; } if (!type) { statusEl.textContent = 'Please select a type.'; statusEl.style.color = '#c62828'; return; } - const body = { name, type, min_level: minLevel, private: isPrivate }; + const body = { name, type, min_level: minLevel }; + const ownerInp = document.getElementById('ch-owner'); + if (ownerInp) body.owner = ownerInp.value.trim(); if (_channelSchemas[type]) { (_channelSchemas[type].fields || []).forEach(sf => { const inp = document.getElementById('chf-' + sf.key); @@ -1177,8 +1198,11 @@ watch: row.querySelector('.host-watch').checked, dyndns: row.querySelector('.host-dyndns').checked, }; - const owner = row.querySelector('.host-owner').value.trim(); - if (owner) entry.owner = owner; + const ownerInput = row.querySelector('.host-owner'); + if (ownerInput) { + const owner = ownerInput.value.trim(); + if (owner) entry.owner = owner; + } const managers = [...(row.querySelector('.host-managers')?.selectedOptions || [])].map(o => o.value); if (managers.length) entry.managers = managers; const monitors = [...(row.querySelector('.host-monitors')?.selectedOptions || [])].map(o => o.value); @@ -1618,6 +1642,7 @@ card.innerHTML = `
+ ${_isAdmin ? '' : ''}