## Changelog --- 3.0 --- * bug: Restore alert audio for down and triggered devices; getMonitorSound() looked for sounds in includes/sounds/ after the controller moved, so the audio element was never rendered * feature: Replace the single Status column/filter with a multi-select Events filter (additive) and an Events column that shows a short pill per active event (Down, Recovering, Triggered, Down/Triggered M/A, Warn/Alert Ping, Failed Svc), 'None' when clean; the Status scope dropdown now only selects All Monitored / All Devices / Not Monitored / Without Thresholds * bug: Centre the tile hostname under the glyph and keep it clickable in the Tiles & Time view * bug: Remove the 'Names only' View option from the dropdown (the renderer is retained for direct ?view=names use) * bug: Size grouping-card tiles to the longest visible host description so long hostnames no longer overlap neighbouring tiles * bug: Center the device Actions dialog, make it taller and scrollable so panel text is not cut off, and pause the page refresh countdown while it is open * bug: Remove the stray 'Monitored Devices' box header on the Site grouping so it matches the other groupings * feature: Add clickable List-view pills — Thresholds (breached / triggered / total), Service Checks (failed / total), Events, and a Criticality pill (including a 'Not Set' pill for unset devices) — that toggle the matching filter on and off * feature: Offer Warning Ping, Alert Ping and Service Check Failed as additive selections in the multi-select Events filter, and make the Criticality 'None' selection filter to devices with no criticality set * bug: Give the busiest grouping cards (many devices) a full row of their own so their tiles span the whole page instead of being squeezed to part of the width beside smaller cards * bug: Remove the filter status/criticality summary footer and the "Remember to first select eligible Devices" prompt from the Monitor board * bug: Lay the grouping cards out with a wrapping flexbox instead of a CSS grid so they always stretch to fill the full horizontal space; inside Cacti's shrink-to-fit html_start_box div the grid mis-counted its tracks and clipped the cards to roughly half the page width * bug: Default-order the Tree grouping cards by device count (busiest first) while still honouring any saved drag order * feature: Restructure plugin_monitor_dashboards to store filter state as a JSON `properties` object (migrating the legacy raw `url` into it and dropping the url column on upgrade), and construct dashboard URLs from that structure instead of persisting raw urls * feature: Render the Site and Device Template groupings as a responsive full-width grid of draggable card panels (up to 8 columns, shrinking on narrower screens) whose titles are coloured by each group's worst device status, persisting card order per dashboard or per user * bug: Let a grouping card with many devices span several grid columns so it flows across the page instead of stacking into one tall, narrow column that scrolls off the screen * bug: Render the Tree grouping as card panels (one per tree, plus a Non-Tree card) like the Site and Device Template groupings, instead of leaving it on the legacy section layout * bug: Force the grouping card title colours with !important so Cacti core's device-status classes can no longer override them and leave unreadable low-contrast text on a coloured header (e.g. a device template with down devices) * feature: Add a distinct 'Service Check Failed' device status with its own legend chip, tile/list colour and status-filter coverage, driven by a realm-gated, schema-aware servcheck host set * feature: Add an Actions column to the List view that opens a device detail dialog of intropage-style panels (host information, data collection timing, service checks, thresholds, last-hour syslog, and device links) * feature: Add a plugin_servcheck integration so a triggered/failing service check on a device promotes its hover status and adds a hover glyph linking to the failing check, alongside the existing thold and syslog integrations * bug: Restrict the Rows filter to the List view so non-list views always show all devices, and hide the Rows dropdown entirely on non-list pages * bug: Fix the Tiles & Time tile bounding box so it grows to encompass the host glyph, hostname and uptime instead of overflowing into neighbouring tiles * bug: Pass a boolean (not the integer 1) to api_plugin_register_hook()'s $enable argument so the hook registration stays type-correct under Cacti 1.3's strict bool type-hint (the int only coerces while the file lacks declare(strict_types=1)) * feature: Adopt the Cacti plugin table API and relocate schema provisioning into includes/database.php * feature: Add a fleet-wide manifest.json with upgrade-time file pruning * feature: Consolidate per-theme override stylesheets from themes/ into css/ * feature: Redesign the status legend as evenly sized, rounded colour chips with solid, theme-appropriate colours across every theme (including Deepness), matching the thold and syslog legends * feature: Colour the device-tile icons and the List-view status pill from the same legend palette, adopt the Cacti pill design for the List view (colouring the pill instead of the whole row), and keep legend chips from overflowing their bounds * dev: Size every status-legend chip to the longest label so the chips stay equal width as the legend wraps responsively * dev: Lay the status legend out as a CSS grid so every chip is truly equal width across wrapped rows (a shared min-width under flex-wrap still let a partial final row stretch its chips) * dev: Extract the status legend into a testable monitor_legend() helper in includes/functions.php and add unit coverage asserting the longest-label chip minimum * dev: Rename includes/db_functions.php to includes/functions.php and move bundled libraries under includes/ * dev: Set the Cacti compatibility floor to 1.2.29 * dev: Pin the CI database image and shared test dependencies, disable persisted checkout credentials, and limit workflow permissions and runtime --- 2.9 --- * dev: Measure CI coverage with xdebug instead of pcov so the plugin's own sources are instrumented (pcov auto-scopes to the Composer root and skipped cacti/plugins/, leaving the patch-coverage gate with nothing to measure) * dev: Enforce patch coverage of changed lines in CI and remove the inert COMPOSER_ROOT_VERSION env from the Pest step * security: Add a version-safe CSP nonce (`plugin_monitor_csp_nonce()`) to every inline `