Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ChangeLog

--- develop ---
* feature: Add a Fleet (Summary) Dashboard reached by a dashboard glyph on the Summary tab's Device Type rows: a draggable, add/remove card grid scoped to all devices or one OS type, with min/avg/max bullet charts (CPU/memory/swap/processes/uptime), a device-status stacked bar, OS type distribution, storage utilization, fleet stat tiles, and top processes by CPU and by memory; scope, card order, expanded state and refresh interval persist per user
* issue: Fix 'Uncaught TypeError: runCollector(): Argument #2 ($lastrun) must be of type float, null given' in the poller when a collector's *_lastrun/*_freq setting has never been written (e.g. a task's first run); runCollector() now accepts null and normalizes it
* issue: Fix the per-device Dashboard Storage, Per-Processor Load, Hardware and Installed Software cards rendering empty because they filtered on 'present = 1' while the underlying Storage/Hardware/Inventory tabs never did, and add a Process Use History card
* feature: Add a per-device Dashboard that drills into a single host with a draggable, add/remove card grid (CPU/memory/swap gauges, per-processor load, storage, top processes, hardware, installed software, logins and system information); card order, expanded state, the selected device and the auto-refresh interval persist per user, and a dashboard glyph on the Devices tab opens a stateful Dashboard tab that remembers the last host opened
Expand Down
201 changes: 201 additions & 0 deletions css/hmib.css
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,204 @@
grid-column: 1 / -1;
}
}

/*
* Fleet (Summary) Dashboard visuals: min/avg/max bullet charts, stat tiles, a
* status stacked bar and in-table mini bars. Theme-adaptive via
* color-mix(currentColor ...); severity accents use fixed colours.
*/

/* Min / avg / max bullet chart. The track is 0..scale; a translucent band spans
min..max; a strong marker sits at avg. */
.hmibBullet {
margin: 9px 0;
}

.hmibBulletHead {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 8px;
margin-bottom: 4px;
}

.hmibBulletLabel {
font-size: 12px;
font-weight: 600;
}

.hmibBulletAvg {
font-size: 12px;
font-variant-numeric: tabular-nums;
color: color-mix(in srgb, currentColor 78%, transparent);
}

.hmibBulletTrack {
position: relative;
height: 16px;
border-radius: 8px;
background: color-mix(in srgb, currentColor 12%, transparent);
overflow: hidden;
}

.hmibBulletRange {
position: absolute;
top: 0;
bottom: 0;
border-radius: 8px;
}

.hmibBulletRange--up { background: color-mix(in srgb, #3c9a5f 55%, transparent); }
.hmibBulletRange--recovering { background: color-mix(in srgb, #d9830f 55%, transparent); }
.hmibBulletRange--down { background: color-mix(in srgb, #cc0000 55%, transparent); }
.hmibBulletRange--none { background: color-mix(in srgb, currentColor 32%, transparent); }

.hmibBulletMarker {
position: absolute;
top: -2px;
bottom: -2px;
width: 3px;
transform: translateX(-1px);
background: currentColor;
border-radius: 2px;
}

.hmibBulletScale {
display: flex;
justify-content: space-between;
margin-top: 2px;
font-size: 10px;
font-variant-numeric: tabular-nums;
color: color-mix(in srgb, currentColor 60%, transparent);
}

/* Stat tiles for the fleet overview. */
.hmibFleetTiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
gap: 8px;
}

.hmibFleetTile {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
padding: 8px 6px;
border-radius: 7px;
border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
background: color-mix(in srgb, currentColor 4%, transparent);
}

.hmibFleetTileValue {
font-size: 22px;
font-weight: 700;
line-height: 1;
font-variant-numeric: tabular-nums;
}

.hmibFleetTileLabel {
font-size: 11px;
text-align: center;
color: color-mix(in srgb, currentColor 70%, transparent);
}

.hmibFleetTile--up { border-color: color-mix(in srgb, #3c9a5f 55%, transparent); }
.hmibFleetTile--rec { border-color: color-mix(in srgb, #d9830f 55%, transparent); }
.hmibFleetTile--down { border-color: color-mix(in srgb, #cc0000 55%, transparent); }
.hmibFleetTile--up .hmibFleetTileValue { color: #3c9a5f; }
.hmibFleetTile--rec .hmibFleetTileValue { color: #d9830f; }
.hmibFleetTile--down .hmibFleetTileValue { color: #cc0000; }

/* Horizontal status stacked bar (up / recovering / down / disabled). */
.hmibStackBar {
display: flex;
height: 20px;
border-radius: 6px;
overflow: hidden;
background: color-mix(in srgb, currentColor 12%, transparent);
}

.hmibStackSeg {
height: 100%;
}

.hmibStackSeg--up { background: #3c9a5f; }
.hmibStackSeg--rec { background: #d9830f; }
.hmibStackSeg--down { background: #cc0000; }
.hmibStackSeg--dis { background: color-mix(in srgb, currentColor 35%, transparent); }

.hmibStackLegend {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 8px;
font-size: 11px;
}

.hmibStackLegend span {
display: inline-flex;
align-items: center;
gap: 5px;
}

.hmibStackChip {
width: 10px;
height: 10px;
border-radius: 2px;
display: inline-block;
}

/* Horizontal distribution bars (OS type counts) and in-table mini bars. */
.hmibDistRow {
display: grid;
grid-template-columns: minmax(80px, 34%) 1fr auto;
align-items: center;
gap: 8px;
margin: 6px 0;
font-size: 12px;
}

.hmibDistLabel {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.hmibDistTrack {
height: 12px;
border-radius: 6px;
background: color-mix(in srgb, currentColor 12%, transparent);
overflow: hidden;
}

.hmibDistFill {
display: block;
height: 100%;
border-radius: 6px;
background: color-mix(in srgb, currentColor 45%, transparent);
}

.hmibDistValue {
font-variant-numeric: tabular-nums;
color: color-mix(in srgb, currentColor 80%, transparent);
}

.hmibMiniBar {
display: block;
position: relative;
height: 10px;
min-width: 60px;
border-radius: 5px;
background: color-mix(in srgb, currentColor 12%, transparent);
overflow: hidden;
}

.hmibMiniBarFill {
position: absolute;
top: 0;
left: 0;
bottom: 0;
border-radius: 5px;
background: color-mix(in srgb, currentColor 45%, transparent);
}
Loading
Loading