From 1f959932c18d29c18adeccfac2507c31cc46b7e1 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Thu, 28 May 2026 17:28:34 +0300 Subject: [PATCH] fix(notification): allow clearing the sound on per-app overrides and main row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, both the per-app override sound dropdown and the main notification sound row only attached an EntitySelect when at least one sound asset was registered — and never with allowNone. That left users with no way to pick "no sound" once an entry existed, and made the override dropdown silently inert before any assets were added. Always construct the EntitySelect (so an empty assets list still renders a usable, searchable input) and pass allowNone with the localized none label so "no sound" is a first-class choice in both the override list and the main row. --- .../js/features/color-strips/notification.ts | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/server/src/ledgrab/static/js/features/color-strips/notification.ts b/server/src/ledgrab/static/js/features/color-strips/notification.ts index fad8719..66e157b 100644 --- a/server/src/ledgrab/static/js/features/color-strips/notification.ts +++ b/server/src/ledgrab/static/js/features/color-strips/notification.ts @@ -233,15 +233,14 @@ function _overridesRenderList() { // Wire EntitySelects for sound dropdowns list.querySelectorAll('.notif-override-sound').forEach(sel => { - const items = _getSoundAssetItems(); - if (items.length > 0) { - const es = new EntitySelect({ - target: sel, - getItems: () => _getSoundAssetItems(), - placeholder: t('color_strip.notification.sound.search') || 'Search sounds…', - }); - _overrideEntitySelects.push(es); - } + const es = new EntitySelect({ + target: sel, + getItems: () => _getSoundAssetItems(), + placeholder: t('color_strip.notification.sound.search') || 'Search sounds…', + allowNone: true, + noneLabel: t('color_strip.notification.sound.none'), + }); + _overrideEntitySelects.push(es); }); } @@ -300,14 +299,13 @@ export function ensureNotifSoundEntitySelect() { if (!sel) return; _populateSoundOptions(sel); if (_notifSoundEntitySelect) _notifSoundEntitySelect.destroy(); - const items = _getSoundAssetItems(); - if (items.length > 0) { - _notifSoundEntitySelect = new EntitySelect({ - target: sel, - getItems: () => _getSoundAssetItems(), - placeholder: t('color_strip.notification.sound.search') || 'Search sounds…', - }); - } + _notifSoundEntitySelect = new EntitySelect({ + target: sel, + getItems: () => _getSoundAssetItems(), + placeholder: t('color_strip.notification.sound.search') || 'Search sounds…', + allowNone: true, + noneLabel: t('color_strip.notification.sound.none'), + }); } /* ── Test notification ────────────────────────────────────────── */