Improve health messages

This commit is contained in:
Joshua Boniface 2025-02-28 02:00:08 -05:00
parent 28b03222f0
commit f41c71608d

View File

@ -173,27 +173,31 @@
<h6 class="card-title mb-0 metric-label">Cluster Health Messages</h6> <h6 class="card-title mb-0 metric-label">Cluster Health Messages</h6>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="messages-grid"> <div class="messages-list">
<template v-if="displayMessages.length"> <template v-if="displayMessages.length">
<div <div
v-for="(msg, idx) in displayMessages" v-for="(msg, idx) in displayMessages"
:key="idx" :key="idx"
:class="[ :class="[
'health-message', 'health-message',
getDeltaClass(msg.health_delta), getDeltaClass(msg.health_delta, msg),
{'full-width-message': isSpecialMessage(msg)}
]" ]"
:title="msg.text || 'No details available'"
> >
<i class="fas fa-circle-exclamation me-1"></i> <div class="message-header">
<span class="message-text"> <i class="fas fa-circle-exclamation me-1"></i>
{{ msg.id || 'Unknown Issue' }} <span class="message-id">{{ msg.id || 'Unknown Issue' }}</span>
<span v-if="msg.health_delta" class="health-delta"> <span v-if="msg.health_delta" class="health-delta">
({{ msg.health_delta }}%) ({{ msg.health_delta }}%)
</span> </span>
</span> </div>
<div class="message-content">
{{ msg.text || 'No details available' }}
</div>
</div> </div>
</template> </template>
<div v-else class="no-messages">
No health messages to display
</div>
</div> </div>
</div> </div>
</div> </div>
@ -289,7 +293,7 @@ const displayMessages = computed(() => {
messages.push({ messages.push({
id: "Cluster is in maintenance", id: "Cluster is in maintenance",
health_delta: null, health_delta: null,
text: "Cluster is currently in maintenance mode", text: "Cluster is currently in maintenance mode - health checks are not reported and fencing is disabled",
maintenance: true maintenance: true
}); });
} }
@ -327,12 +331,28 @@ const getHealthColors = (health) => {
return { bg: 'rgba(220, 53, 69, 0.1)', border: 'rgba(220, 53, 69, 0.2)' }; // Red return { bg: 'rgba(220, 53, 69, 0.1)', border: 'rgba(220, 53, 69, 0.2)' }; // Red
}; };
const getDeltaClass = (delta) => { const getDeltaClass = (delta, msg) => {
if (delta === null) return 'delta-info'; // For maintenance and healthy messages // Special case for maintenance mode message
const value = Math.abs(delta); if (msg && msg.id === 'Cluster is in maintenance') {
if (value <= 5) return 'delta-low'; return 'delta-info';
if (value <= 10) return 'delta-medium'; }
return 'delta-high';
// Special case for plugin error messages (the ones with 25%)
if (msg && (msg.id === 'NODE_PLUGIN_PSQL_HV3' || msg.id === 'NODE_PLUGIN_ZKPR_HV3')) {
return 'delta-high'; // These should be red
}
// Special case for "No problems" message
if (msg && msg.id === 'CLUSTER_HEALTHY') {
return 'delta-low';
}
// Handle numeric deltas
if (delta === undefined || delta === null) return '';
if (delta === 0) return ''; // Zero delta - default gray
if (Math.abs(delta) > 10) return 'delta-high'; // Large delta (>10%) - red
if (Math.abs(delta) > 0) return 'delta-medium'; // Small delta (1-10%) - yellow
return 'delta-info';
}; };
const healthChartData = computed(() => { const healthChartData = computed(() => {
@ -546,12 +566,6 @@ const chartOptions = {
} }
}; };
// Add a new function to identify special messages
const isSpecialMessage = (msg) => {
return msg.maintenance === true ||
msg.id === "No issues detected";
};
// Helper function to group objects by state // Helper function to group objects by state
const groupByState = (items, stateExtractor) => { const groupByState = (items, stateExtractor) => {
const groups = {}; const groups = {};
@ -708,13 +722,7 @@ const processStateHistory = (currentStateGroups, historyArray, timeLabels, color
datasets.push({ datasets.push({
label: capitalizeState(state), label: capitalizeState(state),
data: data, data: data,
borderColor: stateInfo.color, borderColor: ctx => ctx.p0.parsed.y === 0 && ctx.p1.parsed.y === 0 ? 'transparent' : undefined
borderWidth: 2,
fill: false,
tension: 0.1,
pointRadius: 0,
currentCount: stateInfo.currentCount,
hidden: true // Hide from chart but keep in legend
}); });
} }
return; return;
@ -997,11 +1005,20 @@ onMounted(() => {
width: 100%; width: 100%;
} }
.messages-grid { .messages-list {
display: grid; display: flex;
grid-template-columns: repeat(4, 1fr); flex-direction: column;
gap: 0.5rem; gap: 0.5rem;
width: 100%; width: 100%;
max-height: 300px;
overflow-y: auto;
}
.no-messages {
text-align: center;
color: #666;
padding: 1rem;
font-style: italic;
} }
.metric-card { .metric-card {
@ -1091,14 +1108,14 @@ onMounted(() => {
} }
/* Match graphs: 2 across at this breakpoint */ /* Match graphs: 2 across at this breakpoint */
.messages-grid { .messages-list {
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
} }
} }
@media (max-width: 1148px) { @media (max-width: 1148px) {
/* Match graphs: 1 across at this breakpoint */ /* Match graphs: 1 across at this breakpoint */
.messages-grid { .messages-list {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }
@ -1109,7 +1126,7 @@ onMounted(() => {
} }
/* Allow messages to be narrower on very small screens */ /* Allow messages to be narrower on very small screens */
.messages-grid { .messages-list {
grid-template-columns: 1fr; /* Already 1fr from previous breakpoint */ grid-template-columns: 1fr; /* Already 1fr from previous breakpoint */
} }
@ -1135,26 +1152,36 @@ onMounted(() => {
.health-message { .health-message {
font-size: 0.875rem; font-size: 0.875rem;
text-align: left; text-align: left;
padding: 0.25rem 0.5rem; padding: 0.5rem;
border-radius: 0.25rem; border-radius: 0.25rem;
overflow: hidden;
text-overflow: ellipsis;
position: relative; position: relative;
height: auto; height: auto;
min-height: 2.5em;
white-space: nowrap; /* Prevent text wrapping */
display: flex; display: flex;
align-items: center; flex-direction: column;
min-width: 0; /* Allow shrinking within grid cell */ min-width: 0; /* Allow shrinking within grid cell */
flex: 1; /* Take up available space */ flex: 1; /* Take up available space */
background: rgba(220, 53, 69, 0.15); /* Default red background */ /* Default styling - will be overridden by delta classes */
color: #721c24; /* Default red text */ background: rgba(108, 117, 125, 0.15); /* Default gray background */
color: #495057; /* Default gray text */
} }
.message-text { .message-header {
white-space: nowrap; display: flex;
overflow: hidden; align-items: center;
text-overflow: ellipsis; font-weight: 500;
margin-bottom: 0.25rem;
}
.message-id {
font-weight: 600;
}
.message-content {
font-size: 0.8rem;
line-height: 1.4;
white-space: normal;
color: inherit;
opacity: 0.9;
} }
.health-message.healthy { .health-message.healthy {
@ -1162,55 +1189,28 @@ onMounted(() => {
color: #28a745; color: #28a745;
} }
.health-message:hover::after {
content: attr(title);
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
background: #fff;
border: 1px solid rgba(0,0,0,0.1);
border-radius: 0.25rem;
padding: 0.5rem;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
z-index: 1000;
width: max-content;
max-width: 300px;
margin-left: 0.5rem;
white-space: normal;
}
@media (min-width: 768px) {
.health-message:hover::after {
left: auto;
right: 100%;
margin-left: 0;
margin-right: 0.5rem;
}
}
.health-delta { .health-delta {
margin-left: 0.5rem; margin-left: 0.5rem;
font-size: 0.8em; font-size: 0.8em;
} }
.delta-low { .delta-low {
background: rgba(40, 167, 69, 0.15); /* Darker green background */ background: rgba(40, 167, 69, 0.15); /* Green background */
color: #0d5524; color: #0d5524;
} }
.delta-medium { .delta-medium {
background: rgba(255, 193, 7, 0.15); /* Darker yellow background */ background: rgba(255, 193, 7, 0.15); /* Yellow background */
color: #856404; color: #856404;
} }
.delta-high { .delta-high {
background: rgba(220, 53, 69, 0.15); /* Darker red background */ background: rgba(220, 53, 69, 0.15); /* Red background */
color: #721c24; color: #721c24;
} }
.delta-info { .delta-info {
background: rgba(13, 110, 253, 0.15); /* Darker blue background */ background: rgba(13, 110, 253, 0.15); /* Blue background */
color: #0d6efd; color: #0d6efd;
} }