From 7dcf15a08a18ac02d062c74dda0e0c71c1b9e629 Mon Sep 17 00:00:00 2001 From: limad <35463455+limad@users.noreply.github.com> Date: Tue, 5 May 2026 20:14:37 +0200 Subject: [PATCH 1/2] feat(log): multi-term comma-separated search with :not() exclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhance the log filter search to support multiple comma-separated terms. Before: single term, optionally negated with ':not(term)' After: comma-separated terms, each independently negatable Examples: - 'error,warning' → show entries matching error OR warning - 'error,:not(daemon)' → show entries matching error OR not matching daemon - ':not(debug),:not(info)' → hide debug and info entries Implements the approach proposed in #3270 (Enhance search log filter with term support), which also covered this global improvement. --- desktop/js/log.js | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/desktop/js/log.js b/desktop/js/log.js index bd7e191a60..52abaf3a1a 100644 --- a/desktop/js/log.js +++ b/desktop/js/log.js @@ -37,28 +37,26 @@ if (!jeeFrontEnd.log) { //searching document.getElementById('in_searchLogFilter')?.addEventListener('keyup', function(event) { - var search = event.target.value - if (search == '') { + var raw = event.target.value + if (raw == '') { jeeP.logListButtons.seen() return } - var not = search.startsWith(":not(") - if (not) { - search = search.replace(':not(', '') - } - search = jeedomUtils.normTextLower(search) + + // Multi-term: comma-separated terms, each term can be prefixed with :not() + // e.g. "error,warning" → show entries matching either + // "error,:not(daemon)" → show entries matching "error" but not "daemon" + var terms = raw.split(',').map(function(t) { return t.trim() }).filter(function(t) { return t.length > 0 }) + jeeP.logListButtons.unseen() - var match, text jeeP.logListButtons.forEach(_bt => { - match = false - text = jeedomUtils.normTextLower(_bt.textContent) - if (text.includes(search)) { - match = true - } - if (not) match = !match - if (match) { - _bt.seen() - } + var text = jeedomUtils.normTextLower(_bt.textContent) + var match = terms.some(function(term) { + var not = term.startsWith(':not(') + var search = jeedomUtils.normTextLower(not ? term.slice(5, -1) : term) + return not ? !text.includes(search) : text.includes(search) + }) + if (match) _bt.seen() }) }) From 36edfaeee79c4ecb37cb74d2aca03e97ae66d311 Mon Sep 17 00:00:00 2001 From: limad Date: Fri, 8 May 2026 15:21:29 +0200 Subject: [PATCH 2/2] fix: replace var with const in multi-term search handler --- desktop/js/log.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/desktop/js/log.js b/desktop/js/log.js index 53fd78a2d8..998ca779c3 100644 --- a/desktop/js/log.js +++ b/desktop/js/log.js @@ -37,7 +37,7 @@ if (!jeeFrontEnd.log) { //searching document.getElementById('in_searchLogFilter')?.addEventListener('keyup', function(event) { - var raw = event.target.value + const raw = event.target.value if (raw == '') { jeeP.logListButtons.seen() return @@ -46,14 +46,14 @@ document.getElementById('in_searchLogFilter')?.addEventListener('keyup', functio // Multi-term: comma-separated terms, each term can be prefixed with :not() // e.g. "error,warning" → show entries matching either // "error,:not(daemon)" → show entries matching "error" but not "daemon" - var terms = raw.split(',').map(function(t) { return t.trim() }).filter(function(t) { return t.length > 0 }) + const terms = raw.split(',').map(function(t) { return t.trim() }).filter(function(t) { return t.length > 0 }) jeeP.logListButtons.unseen() jeeP.logListButtons.forEach(_bt => { - var text = jeedomUtils.normTextLower(_bt.textContent) - var match = terms.some(function(term) { - var not = term.startsWith(':not(') - var search = jeedomUtils.normTextLower(not ? term.slice(5, -1) : term) + const text = jeedomUtils.normTextLower(_bt.textContent) + const match = terms.some(function(term) { + const not = term.startsWith(':not(') + const search = jeedomUtils.normTextLower(not ? term.slice(5, -1) : term) return not ? !text.includes(search) : text.includes(search) }) if (match) _bt.seen()