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
Expand Up @@ -3,6 +3,7 @@
--- develop ---
* dev: Remove the inert COMPOSER_ROOT_VERSION env from the Pest CI step
* feature: Restyle the Thold, Host status and Log status legends as rounded, evenly-spaced solid-colour chips for a clearer, more readable status key across every theme
* dev: Keep the status-legend chips equal width (sized to the longest label) as the legend wraps responsively
* security: Add a version-safe CSP nonce (`plugin_thold_csp_nonce()`) to every inline `<script>` tag so pages stay compatible with Cacti's Content-Security-Policy nonce enforcement, while falling back cleanly on older Cacti releases that lack the `CactiSecureHeaders` class
* issue: Center-align the "Not Monitored" status cell on the Device Status page (thold_graph.php) so it matches the other status values instead of rendering right-aligned
* issue: Define `plugin_thold_csp_nonce()` in thold_functions.php instead of setup.php so it is always available on plugin pages, fixing a fatal "Call to undefined function plugin_thold_csp_nonce()" that disabled the plugin when a page loaded without setup.php
Expand Down
11 changes: 5 additions & 6 deletions css/classic.css
Original file line number Diff line number Diff line change
Expand Up @@ -283,21 +283,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/deepness.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/midwinter.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/modern.css
Original file line number Diff line number Diff line change
Expand Up @@ -299,21 +299,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/paper-plane.css
Original file line number Diff line number Diff line change
Expand Up @@ -279,21 +279,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/paw.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
11 changes: 5 additions & 6 deletions css/sunrise.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,20 @@
}

/*
* Status legend. Laid out as an evenly sized, wrapping flex row (flex: 1 1 0
* gives every chip the same width) with rounded corners and spacing between
* chips. A legend is a colour key, so the chips use their own solid, opaque
* Status legend. Laid out as a wrapping CSS grid whose columns share one
* width (seeded from the longest label via --thold-chip-min) so every chip is
* equal width across all rows, with rounded corners and spacing between chips. A legend is a colour key, so the chips use their own solid, opaque
* colours with white text so they stay legible on every theme rather than
* inheriting the subtle row tints.
*/
.tholdLegend {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--thold-chip-min, 8ch), 1fr));
gap: 4px;
width: 100%;
}

.tholdLegend .tholdLegendItem {
flex: 1 1 0;
text-align: center;
white-space: nowrap;
padding: 4px 6px;
Expand Down
30 changes: 24 additions & 6 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,17 @@ function thold_legend() {

html_start_box('', '100%', false, '3', 'center', '');

$chip_min = 0;

foreach ($thold_states as $state) {
$chip_min = max($chip_min, mb_strlen($state['display']));
Comment thread
TheWitness marked this conversation as resolved.
}

print '<tr class="tableRow"><td>';
print '<div class="tholdLegend">';
print '<div class="tholdLegend" style="--thold-chip-min: calc(' . $chip_min . 'ch + 1.5rem)">';
Comment thread
TheWitness marked this conversation as resolved.

foreach ($thold_states as $index => $state) {
print '<div class="tholdLegendItem ' . $state['class'] . '">' . $state['display'] . '</div>';
print '<div class="tholdLegendItem ' . $state['class'] . '">' . html_escape($state['display']) . '</div>';
}

print '</div>';
Expand All @@ -397,11 +403,17 @@ function host_legend() {

html_start_box('', '100%', false, '3', 'center', '');

$chip_min = 0;

foreach ($thold_host_states as $state) {
$chip_min = max($chip_min, mb_strlen($state['display']));
}

print '<tr class="tableRow"><td>';
print '<div class="tholdLegend">';
print '<div class="tholdLegend" style="--thold-chip-min: calc(' . $chip_min . 'ch + 1.5rem)">';

foreach ($thold_host_states as $index => $state) {
print '<div class="tholdLegendItem ' . $state['class'] . '">' . $state['display'] . '</div>';
print '<div class="tholdLegendItem ' . $state['class'] . '">' . html_escape($state['display']) . '</div>';
}

print '</div>';
Expand All @@ -423,11 +435,17 @@ function log_legend() {

html_start_box('', '100%', false, '3', 'center', '');

$chip_min = 0;

foreach ($thold_log_states as $state) {
$chip_min = max($chip_min, mb_strlen($state['display_short']));
}

print '<tr class="tableRow"><td>';
print '<div class="tholdLegend">';
print '<div class="tholdLegend" style="--thold-chip-min: calc(' . $chip_min . 'ch + 1.5rem)">';

foreach ($thold_log_states as $index => $state) {
print '<div class="tholdLegendItem ' . $state['class'] . '">' . $state['display_short'] . '</div>';
print '<div class="tholdLegendItem ' . $state['class'] . '">' . html_escape($state['display_short']) . '</div>';
}

print '</div>';
Expand Down
21 changes: 18 additions & 3 deletions tests/Unit/TholdLegendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ public function test_thold_legend_renders_one_chip_per_threshold_state(): void {

$states = $GLOBALS['thold_states'];

$this->assertStringContainsString('<div class="tholdLegend">', $output);
$expected = 0;
foreach ($states as $state) {
$expected = max($expected, mb_strlen($state['display']));
}

$this->assertStringContainsString('<div class="tholdLegend" style="--thold-chip-min: calc(' . $expected . 'ch + 1.5rem)">', $output);
$this->assertSame(count($states), substr_count($output, 'tholdLegendItem'));

foreach ($states as $state) {
Expand All @@ -63,7 +68,12 @@ public function test_host_legend_renders_one_chip_per_device_state(): void {

$states = $GLOBALS['thold_host_states'];

$this->assertStringContainsString('<div class="tholdLegend">', $output);
$expected = 0;
foreach ($states as $state) {
$expected = max($expected, mb_strlen($state['display']));
}

$this->assertStringContainsString('<div class="tholdLegend" style="--thold-chip-min: calc(' . $expected . 'ch + 1.5rem)">', $output);
$this->assertSame(count($states), substr_count($output, 'tholdLegendItem'));

foreach ($states as $state) {
Expand All @@ -81,7 +91,12 @@ public function test_log_legend_renders_one_chip_per_log_state_using_short_label

$states = $GLOBALS['thold_log_states'];

$this->assertStringContainsString('<div class="tholdLegend">', $output);
$expected = 0;
foreach ($states as $state) {
$expected = max($expected, mb_strlen($state['display_short']));
}

$this->assertStringContainsString('<div class="tholdLegend" style="--thold-chip-min: calc(' . $expected . 'ch + 1.5rem)">', $output);
$this->assertSame(count($states), substr_count($output, 'tholdLegendItem'));

foreach ($states as $state) {
Expand Down
Loading