From 39da894598d83bc4bf80d6a34e582284464b39c8 Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:43:16 +0100 Subject: [PATCH 1/5] feat(search): Enhance search by filtering by URLs --- src/components/MonitorList.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index a579316b38..a69389e54d 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -327,6 +327,7 @@ export default { const loweredSearchText = this.searchText.toLowerCase(); searchTextMatch = monitor.name.toLowerCase().includes(loweredSearchText) + || monitor.url?.toLowerCase().includes(loweredSearchText) || monitor.tags.find(tag => tag.name.toLowerCase().includes(loweredSearchText) || tag.value?.toLowerCase().includes(loweredSearchText)); } From 08a45637c8295caf16e542a0e547fea217e72015 Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:51:19 +0100 Subject: [PATCH 2/5] feat(search): Enhance search by filtering with `hostname` and `dns_resolve_server` --- src/components/MonitorList.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index a69389e54d..43196a11dc 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -328,6 +328,8 @@ export default { searchTextMatch = monitor.name.toLowerCase().includes(loweredSearchText) || monitor.url?.toLowerCase().includes(loweredSearchText) + || monitor.hostname?.toLowerCase().includes(loweredSearchText) + || monitor.dns_resolve_server?.toLowerCase().includes(loweredSearchText) || monitor.tags.find(tag => tag.name.toLowerCase().includes(loweredSearchText) || tag.value?.toLowerCase().includes(loweredSearchText)); } From 1e0342949fdec594838a212835cb6470879db5ec Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Sun, 22 Dec 2024 10:40:33 +0100 Subject: [PATCH 3/5] feat(monitors search): Use regex instead of `LowerCase` Except with less than 20 monitors, regex seems faster. --- src/components/MonitorList.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index 43196a11dc..9dab5e28a5 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -324,14 +324,14 @@ export default { // finds monitor name, tag name or tag value let searchTextMatch = true; if (this.searchText !== "") { - const loweredSearchText = this.searchText.toLowerCase(); + const regex = new RegExp(this.searchText, "i"); + searchTextMatch = - monitor.name.toLowerCase().includes(loweredSearchText) - || monitor.url?.toLowerCase().includes(loweredSearchText) - || monitor.hostname?.toLowerCase().includes(loweredSearchText) - || monitor.dns_resolve_server?.toLowerCase().includes(loweredSearchText) - || monitor.tags.find(tag => tag.name.toLowerCase().includes(loweredSearchText) - || tag.value?.toLowerCase().includes(loweredSearchText)); + regex.test(monitor.name) || + regex.test(monitor.url) || + regex.test(monitor.hostname) || + regex.test(monitor.dns_resolve_server) || + monitor.tags.find((tag) => regex.test(tag.name) || regex.test(tag.value)); } // filter by status From d0d03c05d6a4fdd6bf7513f7470a6e7ac2ab2595 Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Sun, 22 Dec 2024 11:24:36 +0100 Subject: [PATCH 4/5] fix(monitors search): Correctly handle null/undefined/empty values. Also optimize a bit search tags by replacing `.find` with `.some`. Thanks @homelab-alpha --- src/components/MonitorList.vue | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index 9dab5e28a5..34074afab1 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -324,14 +324,21 @@ export default { // finds monitor name, tag name or tag value let searchTextMatch = true; if (this.searchText !== "") { - const regex = new RegExp(this.searchText, "i"); - - searchTextMatch = - regex.test(monitor.name) || - regex.test(monitor.url) || - regex.test(monitor.hostname) || - regex.test(monitor.dns_resolve_server) || - monitor.tags.find((tag) => regex.test(tag.name) || regex.test(tag.value)); + try { + const regex = new RegExp(this.searchText, "i"); // "i" for case-insensitive matching + + const safeRegexTest = (str) => str && regex.test(str); + + searchTextMatch = + regex.test(monitor.name) || + safeRegexTest(monitor.url) || + safeRegexTest(monitor.hostname) || + safeRegexTest(monitor.dns_resolve_server) || + monitor.tags.some(tag => regex.test(tag.name) || safeRegexTest(tag.value)); + } catch (e) { + console.error("Invalid regex pattern:", e); + searchTextMatch = false; + } } // filter by status From c0d7171dbf637f70694586bcb405841378392956 Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:08:35 +0100 Subject: [PATCH 5/5] fix(monitors search): Make sure regex expressions are escaped. This can be reverted if the search should be regex friendly, but for the moment, it's not the case. Thanks @homelab-alpha! --- src/components/MonitorList.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index 34074afab1..80a47ae6e8 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -325,7 +325,11 @@ export default { let searchTextMatch = true; if (this.searchText !== "") { try { - const regex = new RegExp(this.searchText, "i"); // "i" for case-insensitive matching + // Escape special characters for use in the regular expression + const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + + const escapedSearchText = escapeRegExp(this.searchText); + const regex = new RegExp(escapedSearchText, "i"); const safeRegexTest = (str) => str && regex.test(str);