Add free-text filter on ruleset pages, exclusive with Relevant only
This commit is contained in:
parent
d3beeb887c
commit
4dabc35932
3 changed files with 93 additions and 1 deletions
|
|
@ -5,6 +5,11 @@ All notable changes to **Checkmk SwissKnife** are documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2.23.0] - 2026-09-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Free-text filter on every rule list page (`mode=edit_ruleset`), with or without host/service context: a search box above the list hides the rules (and folders left empty) whose row text doesn't contain the typed string, with a "N / total rules shown" counter. It is mutually exclusive with the "Relevant only" toggle: typing turns "Relevant only" off, and turning "Relevant only" on clears the search box.
|
||||||
|
|
||||||
## [2.22.4] - 2026-09-24
|
## [2.22.4] - 2026-09-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ A [Tampermonkey](https://www.tampermonkey.net/) userscript that enhances the Che
|
||||||
| **Ineffective Rule Highlight** | Replaces the hard-to-spot hyphen icon on ineffective rules with a visible ⚠ badge and amber row border | `highlightIneffectiveRules` |
|
| **Ineffective Rule Highlight** | Replaces the hard-to-spot hyphen icon on ineffective rules with a visible ⚠ badge and amber row border | `highlightIneffectiveRules` |
|
||||||
| **Rule Match Status** | Colors each rule row green (match) or dimmed (no match) when a ruleset is opened with host/service context | `highlightRuleMatchStatus` |
|
| **Rule Match Status** | Colors each rule row green (match) or dimmed (no match) when a ruleset is opened with host/service context | `highlightRuleMatchStatus` |
|
||||||
| **Relevant Only Filter** | Adds a "Relevant only" toggle above the rule list to hide all non-matching and non-highlighted rows | `addRulesetFilterToggle` |
|
| **Relevant Only Filter** | Adds a "Relevant only" toggle above the rule list to hide all non-matching and non-highlighted rows | `addRulesetFilterToggle` |
|
||||||
|
| **Ruleset Free-Text Filter** | Adds a search box above the rule list on any ruleset page to hide rules and folders whose row text doesn't contain the typed string; mutually exclusive with "Relevant only" | `addRulesetTextFilter` |
|
||||||
| **Extra Column — Host Actions** | Inserts an Extra column in monitoring tables with per-host buttons: Service Discovery, copy FQDN, copy short hostname, copy IP | `addInventoryButtons` |
|
| **Extra Column — Host Actions** | Inserts an Extra column in monitoring tables with per-host buttons: Service Discovery, copy FQDN, copy short hostname, copy IP | `addInventoryButtons` |
|
||||||
| **Monitor Button in WATO Folder** | Adds a green eye icon next to each active host in WATO folder listings to open its monitoring view in a new tab | `addWatoFolderMonitorButtons` |
|
| **Monitor Button in WATO Folder** | Adds a green eye icon next to each active host in WATO folder listings to open its monitoring view in a new tab | `addWatoFolderMonitorButtons` |
|
||||||
| **Configure in WATO Menu** | Adds a host-selector dropdown and Open button to the monitoring view menu bar for bulk-opening hosts in WATO | `addViewWatoMenu` |
|
| **Configure in WATO Menu** | Adds a host-selector dropdown and Open button to the monitoring view menu bar for bulk-opening hosts in WATO | `addViewWatoMenu` |
|
||||||
|
|
@ -82,6 +83,13 @@ Applies to: `mode=edit_ruleset` (when at least one `✓ match` or ineffective ro
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Ruleset Free-Text Filter
|
||||||
|
A search box above the rule list hides every rule whose row text (conditions, value, description…) doesn't contain the typed string (case-insensitive) and every folder left with no visible rule; a counter shows "N / total rules shown". It is mutually exclusive with "Relevant only": typing in the box turns "Relevant only" off, and turning "Relevant only" on clears the box.
|
||||||
|
|
||||||
|
Applies to: every `mode=edit_ruleset` page, with or without host/service context.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Extra Column with Host Actions
|
### Extra Column with Host Actions
|
||||||
Adds a dedicated **Extra** column before the Host column in all monitoring view tables. Each row gets up to four icon buttons:
|
Adds a dedicated **Extra** column before the Host column in all monitoring view tables. Each row gets up to four icon buttons:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Checkmk SwissKnife
|
// @name Checkmk SwissKnife
|
||||||
// @namespace https://luigidacunto.com/
|
// @namespace https://luigidacunto.com/
|
||||||
// @version 2.22.4
|
// @version 2.23.0
|
||||||
// @checkmk 2.3.x - 2.4.x
|
// @checkmk 2.3.x - 2.4.x
|
||||||
// @description Collection of UI improvements for Checkmk WATO. Each fix or enhancement is added here as an independent feature.
|
// @description Collection of UI improvements for Checkmk WATO. Each fix or enhancement is added here as an independent feature.
|
||||||
// @author Luigi D'Acunto
|
// @author Luigi D'Acunto
|
||||||
|
|
@ -805,6 +805,12 @@
|
||||||
const isActive = doc.body.classList.toggle('cmk-sk-filter-active');
|
const isActive = doc.body.classList.toggle('cmk-sk-filter-active');
|
||||||
btn.classList.toggle('active', isActive);
|
btn.classList.toggle('active', isActive);
|
||||||
btn.textContent = isActive ? 'Show all' : 'Relevant only';
|
btn.textContent = isActive ? 'Show all' : 'Relevant only';
|
||||||
|
// Mutually exclusive with the free-text filter
|
||||||
|
const text = doc.getElementById('cmk-sk-text-filter-input');
|
||||||
|
if (isActive && text && text.value) {
|
||||||
|
text.value = '';
|
||||||
|
text.dispatchEvent(new Event('input'));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bar.appendChild(btn);
|
bar.appendChild(btn);
|
||||||
|
|
@ -815,6 +821,78 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// FEATURE: Ruleset Free-Text Filter
|
||||||
|
//
|
||||||
|
// Search box on every edit_ruleset page: hides the rules (and folders left
|
||||||
|
// empty) whose row text does not contain the typed string. Mutually
|
||||||
|
// exclusive with the "Relevant only" toggle (typing turns it off, turning
|
||||||
|
// it on clears the box).
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
function addRulesetTextFilter(doc) {
|
||||||
|
if (doc.body.dataset.cmkTextFilter === '1') return;
|
||||||
|
const rows = doc.querySelectorAll('tr.data');
|
||||||
|
if (!rows.length) return;
|
||||||
|
doc.body.dataset.cmkTextFilter = '1';
|
||||||
|
|
||||||
|
injectStyles(doc, 'cmk-sk-text-filter-styles', `
|
||||||
|
#cmk-sk-text-filter-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin: 6px 0 4px 0;
|
||||||
|
background: rgba(0,0,0,0.25);
|
||||||
|
border: 1px solid #3a3a3a;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #999;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
#cmk-sk-text-filter-input { width: 280px; font-size: 11px; font-family: monospace; }
|
||||||
|
.cmk-sk-text-hidden { display: none !important; }
|
||||||
|
`);
|
||||||
|
|
||||||
|
const bar = doc.createElement('div');
|
||||||
|
bar.id = 'cmk-sk-text-filter-bar';
|
||||||
|
|
||||||
|
const input = doc.createElement('input');
|
||||||
|
input.id = 'cmk-sk-text-filter-input';
|
||||||
|
input.type = 'search';
|
||||||
|
input.placeholder = 'Filter rules by text…';
|
||||||
|
|
||||||
|
const info = doc.createElement('span');
|
||||||
|
|
||||||
|
input.addEventListener('input', () => {
|
||||||
|
const q = input.value.trim().toLowerCase();
|
||||||
|
if (q) {
|
||||||
|
// Mutually exclusive with "Relevant only"
|
||||||
|
doc.body.classList.remove('cmk-sk-filter-active');
|
||||||
|
const relBtn = doc.getElementById('cmk-sk-filter-toggle-btn');
|
||||||
|
if (relBtn) { relBtn.classList.remove('active'); relBtn.textContent = 'Relevant only'; }
|
||||||
|
}
|
||||||
|
let shown = 0;
|
||||||
|
rows.forEach(row => {
|
||||||
|
const hide = !!q && !row.textContent.toLowerCase().includes(q);
|
||||||
|
row.classList.toggle('cmk-sk-text-hidden', hide);
|
||||||
|
if (!hide) shown++;
|
||||||
|
});
|
||||||
|
doc.querySelectorAll('div.foldable_wrapper').forEach(w => {
|
||||||
|
const empty = !!q && !w.querySelector('tr.data:not(.cmk-sk-text-hidden)');
|
||||||
|
w.classList.toggle('cmk-sk-text-hidden', empty);
|
||||||
|
});
|
||||||
|
info.textContent = q ? `${shown} / ${rows.length} rules shown` : '';
|
||||||
|
});
|
||||||
|
|
||||||
|
bar.appendChild(input);
|
||||||
|
bar.appendChild(info);
|
||||||
|
|
||||||
|
const anchor = doc.querySelector('div.foldable_wrapper') || doc.querySelector('div.wato') || rows[0].closest('table');
|
||||||
|
if (anchor) anchor.before(bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// FEATURE: Inventory Button on view.py
|
// FEATURE: Inventory Button on view.py
|
||||||
//
|
//
|
||||||
|
|
@ -1970,6 +2048,7 @@
|
||||||
highlightIneffectiveRules(doc);
|
highlightIneffectiveRules(doc);
|
||||||
highlightRuleMatchStatus(doc);
|
highlightRuleMatchStatus(doc);
|
||||||
addRulesetFilterToggle(doc);
|
addRulesetFilterToggle(doc);
|
||||||
|
addRulesetTextFilter(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryAddInventoryButtons() {
|
function tryAddInventoryButtons() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue