mirror of
https://github.com/Cacti/plugin_monitor.git
synced 2026-10-23 19:46:47 +09:00
* Monitor: flex grouping cards to full width, order Tree cards by device count * Monitor: drop inaccurate Site/Template ordering comparison from changelog * CI: install the declared thold dependency so Monitor can install under Cacti's new install-failure reporting * Monitor: remove the filter-status/criticality footer and prompt from the board * Monitor: give the busiest grouping cards (span 3-4) a full row so their tiles span the page * Monitor: changelog for full-width busy cards and footer removal * Monitor: drop Site grouping header, tighten tile uptime spacing, add List column tips * Monitor: add clickable List-view thold/servcheck/ping/criticality pills with filter toggles * Monitor: unit tests for new filter branches and thold/servcheck count helpers * Monitor: selectable status pill, fallback/empty pills, hide absent plugin columns, tile sizing, dialog UX * Monitor: center and keep clickable the tile hostname, remove 'Names only' view option (backend retained) * Monitor: multi-select Events filter + Events column (additive), Status becomes scope-only Show * Monitor: apply the Events multi-select on dropdown close (and on change for native selects) * Add All criticality, Device Template multi-select, servcheck scope - Add an "All" option to the Criticality filter. Its value (-1) matches the default and the pill "clear to default" action, which previously set the select to a non-existent option and submitted crit=null, tripping validate_store_request_vars. - Convert the Device Template filter to a checkbox multi-select (like Events) and actually apply it: renderWhereJoin now adds h.host_template_id IN (...) for the template grouping (0 = Non-Templated). Previously the template selection was never applied, so all hosts returned. - Persist the template selection as a user setting and serialize the multi-value for request/save payloads. - Add a "Devices without Service Checks" scope to the Show filter, shown only when the servcheck plugin is installed and permitted. - Tests + regenerated .pot. * Update template escaping assertions for the multiselect markup * Cover empty-template branch in renderWhereJoin * Left-align Actions glyph and harden Device Detail Panels dialog layout - Left-align the List-view Actions column header and fa-layer-group glyph. - Stack the detail panels as plain blocks and force the jQuery UI dialog content box to always fill the dialog width, so the panels can no longer collapse into a narrow right-hand strip. * Size the detail dialog to its content instead of forcing overflow The #monitorPanelDialog overflow override (higher specificity than the theme's .ui-dialog .ui-dialog-content) turned the content into a fixed-height scroll box that fought the theme's overflow:visible and squashed the panels. Use height:auto (capped by maxHeight) and stop overriding overflow so the dialog sizes to its content and the theme governs scrolling. * Anchor the detail dialog 300px from the top instead of centering * Make the detail panels dialog non-modal * Move Notes out of the List view into the detail dialog The Notes column consumed a lot of horizontal space in List view. Drop it from the table and surface the notes in the Host Information panel of the Device Detail Panels dialog instead (shown only when the device has notes). * Add device-edit action icon and Devices filter button (realm-gated) List view: add a pen-square action icon linking to host.php?action=edit for users with the host.php (device edit) realm, beside the detail-panels icon. Filter bar: add a Devices button (right of Acknowledge) that opens the Cacti Devices page, shown only to users with the same realm. Also move the detail dialog anchor from top+300 to top+150. * Anchor the detail dialog at top+80 * List view: replace Hostname column with a Graphs action glyph Remove the Hostname column and add an orange fas fa-chart-line Graphs glyph (.monitorGraph, matching HMIB's colour) to the Actions column, linking to the device's graphs where the hostname hyperlink used to point. * List columns + filter layout refinements - List columns reordered to Description, Location, Site, ID; add a Location column; Averages, Length in Status, Last Fail are now the last three columns, all right-aligned. - rfilter Search now also matches the device location. - Filter: move the Events multiselect to the second row (right of Search) and the Rows dropdown to the second row (left of Refresh); rename that dropdown from Devices to Rows. - Add a renderWhereJoin test for the description/location rfilter search. * Monitor: realm-gate service-check scope/column, persist events+template, legacy status reset, failed_svc independent, defer list counts, pill keyboard a11y, PHPDoc/changelog fixes
797 lines
18 KiB
CSS
797 lines
18 KiB
CSS
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2025 The Cacti Group |
|
|
| |
|
|
| This program is free software; you can redistribute it and/or |
|
|
| modify it under the terms of the GNU General Public License |
|
|
| as published by the Free Software Foundation; either version 2 |
|
|
| of the License, or (at your option) any later version. |
|
|
| |
|
|
| This program is distributed in the hope that it will be useful, |
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
| GNU General Public License for more details. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDtool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* main container magic */
|
|
.monitor_container {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-content: space-between;
|
|
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;
|
|
align-content: space-between;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
/* flex box table */
|
|
.monitorTableHeader {
|
|
width: 100%;
|
|
}
|
|
|
|
.monitorTable {
|
|
line-height: 16px;
|
|
color: rgb(68, 68, 68);
|
|
}
|
|
|
|
.monitorSubTable {
|
|
min-width: 10vw;
|
|
max-width: 100vw;
|
|
padding: 3px;
|
|
flex-grow: 4;
|
|
}
|
|
|
|
/* footer section */
|
|
.monitorFooter {
|
|
display: table;
|
|
width: 100%;
|
|
}
|
|
|
|
.monitorFooterText {
|
|
color: gray;
|
|
}
|
|
|
|
.monitorFooterTextBold {
|
|
color: black;
|
|
}
|
|
|
|
.monitorLinkIcon {
|
|
vertical-align: middle;
|
|
padding: 3px;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.monitor_device_frame {
|
|
text-align: center;
|
|
display: inline-block;
|
|
}
|
|
|
|
.monitor_device_frame a {
|
|
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
|
|
* width across all rows, as rounded chips with spacing between them.
|
|
* A legend is a colour key, so the chips use their own solid, opaque colours
|
|
* with white text to stay legible on every theme rather than inheriting the
|
|
* subtle tile tints. Per-theme tuning lives in each theme's css (see
|
|
* deepness.css for the emerald-accented variant).
|
|
*/
|
|
.monitorLegend {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(var(--monitor-chip-min, 8ch), 1fr));
|
|
gap: 4px;
|
|
width: 100%;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
/* Legend footer: keeps the legend centered beneath the device list in normal
|
|
document flow, so it never overlays the final rows or action controls. */
|
|
.monitorLegendFooter {
|
|
display: table;
|
|
width: 100%;
|
|
margin: 8px auto 0;
|
|
}
|
|
|
|
.monitorLegend .monitorLegendItem {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
min-width: 0;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
padding: 4px 6px;
|
|
border-radius: 3px;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.monitorLegend .deviceUpFull {
|
|
background-color: #2b8235;
|
|
}
|
|
|
|
.monitorLegend .deviceDownFull {
|
|
background-color: #a12820;
|
|
}
|
|
|
|
.monitorLegend .deviceDownMutedFull {
|
|
background-color: #93302a;
|
|
}
|
|
|
|
.monitorLegend .deviceRecoveringFull {
|
|
background-color: #9a6a1a;
|
|
}
|
|
|
|
.monitorLegend .deviceThresholdFull {
|
|
background-color: #a85712;
|
|
}
|
|
|
|
.monitorLegend .deviceThresholdMutedFull {
|
|
background-color: #6a4a9c;
|
|
}
|
|
|
|
.monitorLegend .deviceWarningFull {
|
|
background-color: #7d6f18;
|
|
}
|
|
|
|
.monitorLegend .deviceAlertFull {
|
|
background-color: #86407a;
|
|
}
|
|
|
|
.monitorLegend .deviceUnknownFull {
|
|
background-color: #5f5f57;
|
|
}
|
|
|
|
.monitorLegend .deviceUnmonitoredFull {
|
|
background-color: #3f6a8a;
|
|
}
|
|
|
|
.monitorLegend .deviceServiceCheckFull {
|
|
background-color: #157f87;
|
|
}
|
|
|
|
/* Device status icons share the legend's solid palette so a tile's colour
|
|
matches its legend key. Core themes set .deviceXxx colours with !important,
|
|
so these need it too. */
|
|
.mon_icon.deviceUp { color: #2b8235 !important; }
|
|
.mon_icon.deviceDown { color: #a12820 !important; }
|
|
.mon_icon.deviceDownMuted { color: #93302a !important; }
|
|
.mon_icon.deviceRecovering { color: #9a6a1a !important; }
|
|
.mon_icon.deviceThreshold { color: #a85712 !important; }
|
|
.mon_icon.deviceThresholdMuted { color: #6a4a9c !important; }
|
|
.mon_icon.deviceWarning { color: #7d6f18 !important; }
|
|
.mon_icon.deviceAlert { color: #86407a !important; }
|
|
.mon_icon.deviceUnknown { color: #5f5f57 !important; }
|
|
.mon_icon.deviceUnmonitored { color: #3f6a8a !important; }
|
|
.mon_icon.deviceServiceCheck { color: #157f87 !important; }
|
|
|
|
/* List-view status pill: adopts the Cacti deviceStatus pill shape and uses the
|
|
same solid palette as the legend chips (colour the pill, not the row). */
|
|
.monitorStatus {
|
|
display: inline-block;
|
|
padding: 2px 10px;
|
|
border-radius: 10px;
|
|
color: #ffffff;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.monitorStatus.deviceUp { background-color: #2b8235; }
|
|
.monitorStatus.deviceDown { background-color: #a12820; }
|
|
.monitorStatus.deviceDownMuted { background-color: #93302a; }
|
|
.monitorStatus.deviceRecovering { background-color: #9a6a1a; }
|
|
.monitorStatus.deviceThreshold { background-color: #a85712; }
|
|
.monitorStatus.deviceThresholdMuted { background-color: #6a4a9c; }
|
|
.monitorStatus.deviceWarning { background-color: #7d6f18; }
|
|
.monitorStatus.deviceAlert { background-color: #86407a; }
|
|
.monitorStatus.deviceUnknown { background-color: #5f5f57; }
|
|
.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;
|
|
width: 35px;
|
|
}
|
|
|
|
.monitor_exsmall_title {
|
|
display: table-cell;
|
|
text-align: center;
|
|
width: 90px !important;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.monitor_exsmall_tiles {
|
|
height: 20px;
|
|
min-width: 20px;
|
|
}
|
|
|
|
.monitor_exsmall_tilesadt {
|
|
min-height: 35px;
|
|
width: 94px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.monitor_exsmall td {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.monitor_exsmall .monitorLinkIcon {
|
|
font-size: 20px;
|
|
}
|
|
|
|
.monitor_exsmall i, .monitor_exsmall_tiles i, .monitor_exsmall_tilesadt i {
|
|
font-size: 10px;
|
|
}
|
|
|
|
.monitor_device_exsmall {
|
|
font-size: 10px;
|
|
padding: 2px;
|
|
}
|
|
|
|
/* small styles */
|
|
.monitor_small {
|
|
height: 58px;
|
|
min-width: 28px;
|
|
}
|
|
|
|
.monitor_small_title {
|
|
display: table-cell;
|
|
text-align: center;
|
|
width: 90px !important;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.monitor_small_tiles {
|
|
height: 28px;
|
|
min-width: 28px;
|
|
}
|
|
|
|
.monitor_small_tilesadt {
|
|
min-height: 45px;
|
|
width: 94px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.monitor_small i, .monitor_small_tiles i, .monitor_small_tilesadt i {
|
|
font-size: 20px;
|
|
min-width: 28px;
|
|
}
|
|
|
|
.monitor_small .monitorLinkIcon {
|
|
font-size: 20px;
|
|
}
|
|
|
|
.monitor_small td {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.monitor_device_small {
|
|
font-size: 10px;
|
|
padding: 2px;
|
|
min-width: 28px;
|
|
}
|
|
|
|
/* medium styles */
|
|
.monitor_medium {
|
|
height: 78px;
|
|
min-width: 58px;
|
|
}
|
|
|
|
.monitor_medium_title {
|
|
display: table-cell;
|
|
text-align: center;
|
|
width: 100px !important;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.monitor_medium_tiles {
|
|
height: 48px;
|
|
min-width: 58px;
|
|
}
|
|
|
|
.monitor_medium_tilesadt {
|
|
min-height: 65px;
|
|
width: 108px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.monitor_medium i, .monitor_medium_tiles i, .monitor_medium_tilesadt i {
|
|
font-size: 40px;
|
|
min-width: 58px;
|
|
}
|
|
|
|
.monitor_medium td {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.monitor_medium a, .monitor_medium_tiles a, .monitor_medium_tilesadt a {
|
|
font-size: 13px;
|
|
min-width: 58px;
|
|
}
|
|
|
|
.monitor_medium .monitorLinkIcon {
|
|
font-size: 20px;
|
|
}
|
|
|
|
.monitor_medium .monitorLinkIcon {
|
|
font-size: 20px;
|
|
}
|
|
|
|
.monitor_device_medium {
|
|
font-size: 13px;
|
|
min-width: 58px;
|
|
padding: 2px;
|
|
}
|
|
|
|
/* large styles */
|
|
.monitor_large {
|
|
height: 118px;
|
|
width: 128px !important;
|
|
}
|
|
|
|
.monitor_large_title {
|
|
display: table-cell;
|
|
text-align: center;
|
|
width: 128px !important;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.monitor_large_tiles {
|
|
height: 88px;
|
|
min-width: 88px;
|
|
}
|
|
|
|
.monitor_large_tilesadt {
|
|
min-height: 102px;
|
|
width: 128px;
|
|
box-sizing: border-box;
|
|
justify-content: center;
|
|
}
|
|
|
|
.monitor_large i, .monitor_large_tiles i, .monitor_large_tilesadt i {
|
|
font-size: 80px;
|
|
min-width: 98px;
|
|
}
|
|
|
|
.monitor_large td {
|
|
font-size: 15px;
|
|
}
|
|
|
|
.monitor_large a, .monitor_large_tiles a, .monitor_large_tilesadt a {
|
|
font-size: 15px;
|
|
min-width: 98px;
|
|
}
|
|
|
|
.monitor_large .monitorLinkIcon {
|
|
font-size: 28px;
|
|
}
|
|
|
|
.monitor_device_large {
|
|
font-size: 10px;
|
|
padding: 2px;
|
|
min-width: 148px;
|
|
}
|
|
|
|
/* ex-large styles */
|
|
.monitor_exlarge {
|
|
height: 168px;
|
|
min-width: 128px;
|
|
}
|
|
|
|
.monitor_exlarge_title {
|
|
display: table-cell;
|
|
text-align: center;
|
|
width: 128px !important;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.monitor_exlarge_tiles {
|
|
height: 128px;
|
|
min-width: 128px;
|
|
}
|
|
|
|
.monitor_exlarge_tilesadt {
|
|
min-height: 148px;
|
|
width: 128px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.monitor_exlarge i, .monitor_exlarge_tiles i, .monitor_exlarge_tilesadt i {
|
|
font-size: 120px;
|
|
min-width: 128px;
|
|
}
|
|
|
|
.monitor_exlarge td {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.monitor_exlarge, .monitor_exlarge .monitorLinkIcon {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.monitor_exlarge .monitorLinkIcon {
|
|
font-size: 38px;
|
|
}
|
|
|
|
|
|
.monitor_exlarge a, .monitor_exlarge_tiles a, .monitor_exlarge_tilesadt a {
|
|
font-size: 16px;
|
|
min-width: 128px;
|
|
}
|
|
|
|
.monitor_device_exlarge {
|
|
font-size: 10px;
|
|
padding: 2px;
|
|
}
|
|
|
|
/* zoom error styles */
|
|
.monitor_errorzoom {
|
|
height: 118px;
|
|
width: 200px !important;
|
|
}
|
|
|
|
.monitor_errorzoom_title {
|
|
text-align: center;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.monitor_errorzoom_tiles {
|
|
height: 88px;
|
|
min-width: 88px;
|
|
}
|
|
|
|
.monitor_errorzoom_tilesadt {
|
|
min-height: 102px;
|
|
width: 128px;
|
|
box-sizing: border-box;
|
|
justify-content: center;
|
|
}
|
|
|
|
.monitor_errorzoom i, .monitor_errorzoom_tiles i, .monitor_errorzoom_tilesadt i {
|
|
font-size: 80px;
|
|
min-width: 98px;
|
|
}
|
|
|
|
.monitor_errorzoom td {
|
|
font-size: 15px;
|
|
}
|
|
|
|
.monitor_errorzoom a, .monitor_errorzoom_tiles a, .monitor_errorzoom_tilesadt a {
|
|
font-size: 15px;
|
|
min-width: 98px;
|
|
}
|
|
|
|
.monitor_errorzoom .monitorLinkIcon {
|
|
font-size: 28px;
|
|
}
|
|
|
|
.monitor_device_errorzoom {
|
|
font-size: 10px;
|
|
padding: 2px;
|
|
min-width: 148px;
|
|
}
|
|
|
|
.monitorHover {
|
|
min-width: 400px;
|
|
max-width: 1000px;
|
|
}
|
|
|
|
.monitorHover td:first-child {
|
|
padding-right: 5px;
|
|
vertical-align: text-top;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.monitorFilterTable {
|
|
display: table;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
width: 50%;
|
|
}
|
|
|
|
.monitorFilterRow {
|
|
display: table-row;
|
|
margin: auto;
|
|
width: 100%;
|
|
}
|
|
|
|
.monitorFilterCell {
|
|
display: table-cell;
|
|
}
|
|
|
|
.monitorFilterCell .ui-button, .monitorFilterCell button {
|
|
margin: 2px ! important;
|
|
}
|
|
|
|
.monitorFilterCell .ui-selectmenu-button, .monitorFilterCell select {
|
|
min-width: 150px ! important;
|
|
max-width: 150px ! important;
|
|
margin: 2px ! important;
|
|
}
|
|
|
|
.monitorFilterForm {
|
|
padding-bottom: 2px;
|
|
width: 100%;
|
|
}
|
|
|
|
.monitorFilterText {
|
|
padding-left: 5px;
|
|
padding-right: 5px;
|
|
}
|
|
|
|
.cactiPageBottom {
|
|
z-index: -1;
|
|
}
|
|
|
|
/* List-view Actions column icon */
|
|
.monitorActions {
|
|
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 {
|
|
/* 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;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.monitorPanelHeader i {
|
|
margin-right: 6px;
|
|
}
|
|
|
|
.monitorPanelBody {
|
|
padding: 6px 10px;
|
|
}
|
|
|
|
.monitorPanelProps,
|
|
.monitorPanelLinks,
|
|
.monitorPanelSyslog {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.monitorPanelProps li {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 3px 0;
|
|
border-bottom: 1px dotted rgba(128, 128, 128, 0.2);
|
|
}
|
|
|
|
.monitorPanelProps li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.monitorPanelLabel {
|
|
color: gray;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.monitorPanelValue {
|
|
text-align: right;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.monitorPanelLinks li {
|
|
padding: 3px 0;
|
|
}
|
|
|
|
.monitorPanelLinks i {
|
|
width: 18px;
|
|
text-align: center;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.monitorPanelSyslog li {
|
|
display: flex;
|
|
gap: 8px;
|
|
padding: 2px 0;
|
|
font-size: 12px;
|
|
border-bottom: 1px dotted rgba(128, 128, 128, 0.2);
|
|
}
|
|
|
|
.monitorPanelSyslog li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.monitorSyslogTime {
|
|
color: gray;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.monitorSyslogMsg {
|
|
word-break: break-word;
|
|
}
|
|
|
|
.monitorPanelLoading {
|
|
padding: 20px;
|
|
text-align: center;
|
|
color: gray;
|
|
}
|
|
|
|
/* 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: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
align-items: flex-start;
|
|
width: 100%;
|
|
}
|
|
|
|
.monitorGroupCard {
|
|
flex: 1 1 260px;
|
|
min-width: 260px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
|
|
.monitorGroupCard .monitor_container {
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.monitorGroupDrag {
|
|
cursor: move;
|
|
margin-right: 6px;
|
|
opacity: 0.65;
|
|
}
|
|
|
|
.monitorGroupPlaceholder {
|
|
border: 2px dashed rgba(128, 128, 128, 0.5);
|
|
border-radius: 6px;
|
|
min-height: 60px;
|
|
}
|
|
|
|
/* Group card titles coloured by the group's worst device status. Marked
|
|
!important so the Cacti core device-status classes (e.g. .deviceDown, which
|
|
force a red text/background) cannot override the title's palette and leave
|
|
unreadable low-contrast text on the coloured header. */
|
|
.monitorGroupTitle.deviceUp { background-color: #2b8235 !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceDown { background-color: #a12820 !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceDownMuted { background-color: #93302a !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceRecovering { background-color: #9a6a1a !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceThreshold { background-color: #a85712 !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceThresholdMuted { background-color: #6a4a9c !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceWarning { background-color: #7d6f18 !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceAlert { background-color: #86407a !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceUnknown { background-color: #5f5f57 !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceUnmonitored { background-color: #3f6a8a !important; color: #ffffff !important; }
|
|
.monitorGroupTitle.deviceServiceCheck { background-color: #157f87 !important; color: #ffffff !important; }
|
|
|