Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
23373b7
Monitor: flex grouping cards to full width, order Tree cards by devic…
TheWitness Oct 11, 2026
919cea5
Monitor: drop inaccurate Site/Template ordering comparison from chang…
TheWitness Oct 11, 2026
bd914e5
CI: install the declared thold dependency so Monitor can install unde…
TheWitness Oct 11, 2026
06758d0
Monitor: remove the filter-status/criticality footer and prompt from …
TheWitness Oct 11, 2026
db9a24f
Monitor: give the busiest grouping cards (span 3-4) a full row so the…
TheWitness Oct 11, 2026
db17e93
Monitor: changelog for full-width busy cards and footer removal
TheWitness Oct 11, 2026
d69b106
Monitor: drop Site grouping header, tighten tile uptime spacing, add …
TheWitness Oct 11, 2026
7bd63ef
Monitor: add clickable List-view thold/servcheck/ping/criticality pil…
TheWitness Oct 11, 2026
7c92529
Monitor: unit tests for new filter branches and thold/servcheck count…
TheWitness Oct 11, 2026
eecdd9d
Monitor: selectable status pill, fallback/empty pills, hide absent pl…
TheWitness Oct 11, 2026
ce3d00f
Monitor: center and keep clickable the tile hostname, remove 'Names o…
TheWitness Oct 11, 2026
ceb800c
Monitor: multi-select Events filter + Events column (additive), Statu…
TheWitness Oct 11, 2026
6cadfae
Monitor: apply the Events multi-select on dropdown close (and on chan…
TheWitness Oct 11, 2026
9074412
Add All criticality, Device Template multi-select, servcheck scope
TheWitness Oct 11, 2026
db9390f
Update template escaping assertions for the multiselect markup
TheWitness Oct 11, 2026
e796c6b
Cover empty-template branch in renderWhereJoin
TheWitness Oct 11, 2026
0b38bb2
Left-align Actions glyph and harden Device Detail Panels dialog layout
TheWitness Oct 11, 2026
fa9a1d1
Size the detail dialog to its content instead of forcing overflow
TheWitness Oct 11, 2026
c2848ce
Anchor the detail dialog 300px from the top instead of centering
TheWitness Oct 11, 2026
72b156f
Make the detail panels dialog non-modal
TheWitness Oct 11, 2026
e8d49e4
Move Notes out of the List view into the detail dialog
TheWitness Oct 11, 2026
1953150
Add device-edit action icon and Devices filter button (realm-gated)
TheWitness Oct 11, 2026
543f20e
Anchor the detail dialog at top+80
TheWitness Oct 11, 2026
5eedbaa
List view: replace Hostname column with a Graphs action glyph
TheWitness Oct 11, 2026
be18deb
List columns + filter layout refinements
TheWitness Oct 11, 2026
d216aea
Monitor: realm-gate service-check scope/column, persist events+templa…
TheWitness Oct 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/plugin-ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ jobs:
# patch-coverage.php diffs against the base branch below.
fetch-depth: 0

# Monitor declares `requires = thold:1.2.1` in its INFO file, so a Cacti
# that now reports install failures refuses to install Monitor without it.
- name: Checkout Thold Plugin
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: Cacti/plugin_thold
ref: develop
path: cacti/plugins/thold

- name: Install PHP ${{ matrix.php }}
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
Expand Down Expand Up @@ -168,6 +177,11 @@ jobs:
cd ${{ github.workspace }}/cacti
sudo php cli/install_cacti.php --accept-eula --install --force

- name: Install Thold Plugin
run: |
cd ${{ github.workspace }}/cacti
sudo php cli/plugin_manage.php --plugin=thold --install --enable

- name: Install Monitor Plugin
run: |
cd ${{ github.workspace }}/cacti
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

--- 3.0 ---

* 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
Expand Down
4 changes: 4 additions & 0 deletions css/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,7 @@
.monitorLog {
white-space: pre-wrap !important;
}

.monitorGraph {
color: #d6a13a;
}
4 changes: 4 additions & 0 deletions css/deepness.css
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,7 @@
.monitorLog {
white-space: pre-wrap !important;
}

.monitorGraph {
color: #d6a13a;
}
4 changes: 4 additions & 0 deletions css/midwinter.css
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,7 @@
.monitorLog {
white-space: pre-wrap !important;
}

.monitorGraph {
color: #d6a13a;
}
136 changes: 111 additions & 25 deletions css/monitor.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@
justify-content: space-between;
}

/* When the server sets --monitor-title-ch (the longest trimmed description in
view), widen every tile title to it so long hostnames wrap within their own
tile instead of blending into neighbours. inline-block keeps the title
centred under the glyph (via the frame's text-align) in every view, and
max-width stops it overflowing a fixed-width tile. */
.monitor_container[style*='--monitor-title-ch'] [class$='_title'] {
display: inline-block;
width: calc(var(--monitor-title-ch, 11) * 1ch + 8px) !important;
max-width: 100%;
box-sizing: border-box;
vertical-align: top;
}

.monitor_sub_container {
display: flex;
flex-wrap: wrap;
Expand Down Expand Up @@ -79,10 +92,20 @@
}

.monitor_device_frame a {
padding: 3px;
padding: 3px 3px 8px;
display: block;
}

/* Uptime/time-in-state line under a tile hostname: normal weight (not bold),
pulled up tight to the hostname, with the frame padding below separating
rows. */
.monitor_uptime {
display: block;
font-weight: normal;
line-height: 1.1;
margin-top: -2px;
}

/*
* Status legend. Rendered as a wrapping CSS grid whose columns share one width
* (seeded from the longest label via --monitor-chip-min) so every chip is equal
Expand Down Expand Up @@ -200,6 +223,42 @@
.monitorStatus.deviceUnmonitored { background-color: #3f6a8a; }
.monitorStatus.deviceServiceCheck { background-color: #157f87; }

/* Clickable list-view pills (events, thresholds, service checks, criticality).
Share the status palette for event pills and a graduated, deliberately
non-alarming palette for criticality (no red for Mission Critical). */
.monitorPill {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
color: #ffffff;
white-space: nowrap;
font-size: 11px;
line-height: 1.5;
margin: 1px;
}

.monitorFilterPill {
cursor: pointer;
}

.monitorPillMuted { background-color: #5f5f57; }
.monitorPill.deviceDown { background-color: #a12820; }
.monitorPill.deviceDownMuted { background-color: #93302a; }
.monitorPill.deviceRecovering { background-color: #9a6a1a; }
.monitorPill.deviceWarning { background-color: #7d6f18; }
.monitorPill.deviceAlert { background-color: #86407a; }
.monitorPill.deviceThreshold { background-color: #a85712; }
.monitorPill.deviceThresholdMuted { background-color: #6a4a9c; }
.monitorPill.deviceServiceCheck { background-color: #157f87; }

/* Criticality: Not Set (grey) -> Low (blue) -> Medium (teal) -> High (amber)
-> Mission Critical (violet). */
.monitorCrit0 { background-color: #5f5f57; }
.monitorCrit1 { background-color: #3f6a8a; }
.monitorCrit2 { background-color: #157f87; }
.monitorCrit3 { background-color: #a85712; }
.monitorCrit4 { background-color: #6a4a9c; }

/* extra small styles */
.monitor_exsmall {
height: 55px;
Expand Down Expand Up @@ -548,19 +607,47 @@
font-size: 16px;
}

.monitorActions + .monitorActions {
margin-left: 8px;
}

/* Graphs action glyph (orange), matching the convention used by HMIB. */
.monitorGraph {
color: #cc6600;
}

/* Device detail panels (intropage-style cards) in the Actions dialog */
.monitorPanels {
display: flex;
flex-direction: column;
gap: 10px;
/* Plain block stacking (not flex) so a card can never collapse to its
min-content width inside the jQuery UI dialog content box. */
display: block;
width: 100%;
box-sizing: border-box;
}

/* Don't override the content box's overflow: the dialog sizes to its content
(height: auto in openHostPanel), so forcing overflow here created a scroll
box that fought the theme's own .ui-dialog .ui-dialog-content rules and
squashed the panels. Keep border-box only so padding can't overflow. */
#monitorPanelDialog.ui-dialog-content,
#monitorPanelDialog {
box-sizing: border-box;
}

.monitorPanel {
display: block;
width: 100%;
box-sizing: border-box;
margin-bottom: 10px;
border: 1px solid rgba(128, 128, 128, 0.35);
border-radius: 6px;
overflow: hidden;
}

.monitorPanel:last-child {
margin-bottom: 0;
}

.monitorPanelHeader {
background-color: rgba(128, 128, 128, 0.15);
padding: 6px 10px;
Expand Down Expand Up @@ -643,34 +730,33 @@
color: gray;
}

/* Grouping card grid: responsive, flows full screen up to ~8 columns and
shrinks to fewer columns as the viewport narrows. Large groups span several
columns (see data-span) so their devices flow across the page. */
/* Grouping card grid: a wrapping flexbox so cards always stretch to fill the
full horizontal space. A CSS grid was tried first, but Cacti renders this
content inside a shrink-to-fit `display:table` box (html_start_box with
$div=true), which breaks grid auto-fill track counting and clipped the cards
to roughly half the page. Flexbox grows each card to fill its row regardless
of that containing block. */
.monitorGroupGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
grid-auto-flow: row dense;
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: start;
align-items: flex-start;
width: 100%;
container-type: inline-size;
}

/* Cap each card's span to the number of 260px tracks the grid can actually
show at its current width (track + 10px gap), so a wide card never forces an
extra implicit track and horizontal overflow on narrow layouts. */
@container (max-width: 529px) {
.monitorGroupCard { grid-column: auto !important; }
}

@container (min-width: 530px) and (max-width: 799px) {
.monitorGroupCard[data-span="3"],
.monitorGroupCard[data-span="4"] { grid-column: span 2 !important; }
.monitorGroupCard {
flex: 1 1 260px;
min-width: 260px;
box-sizing: border-box;
}

@container (min-width: 800px) and (max-width: 1069px) {
.monitorGroupCard[data-span="4"] { grid-column: span 3 !important; }
}
/* A busier group (span 2) gets a wider basis and matching flex-grow so it takes
proportionally more room when sharing a row with smaller cards. The busiest
groups (span 3-4) take a full row of their own so their many tiles flow the
whole page width instead of being squeezed beside smaller cards. */
.monitorGroupCard[data-span="2"] { flex-grow: 2; flex-basis: 530px; }
.monitorGroupCard[data-span="3"],
.monitorGroupCard[data-span="4"] { flex-basis: 100%; }

.monitorGroupCard .monitorPanelBody {
padding: 6px;
Expand Down
4 changes: 4 additions & 0 deletions css/paper-plane.css
Original file line number Diff line number Diff line change
Expand Up @@ -366,3 +366,7 @@
.monitorLog {
white-space: pre-wrap !important;
}

.monitorGraph {
color: #d6a13a;
}
4 changes: 4 additions & 0 deletions css/sunrise.css
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,7 @@
.monitorLog {
white-space: pre-wrap !important;
}

.monitorGraph {
color: #d6a13a;
}
Loading
Loading