Skip to content

Commit ece4e16

Browse files
committed
ui: improve PBS server status table layout to match datastore table, with wide CPU/Mem columns and truncated PBS VER/Uptime columns
1 parent 58eb534 commit ece4e16

File tree

1 file changed

+79
-52
lines changed

1 file changed

+79
-52
lines changed

src/public/js/ui/pbs.js

Lines changed: 79 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -830,73 +830,100 @@ PulseApp.ui.pbs = (() => {
830830
sectionDiv.className = `${CSS_CLASSES.MB3}`;
831831

832832
const heading = document.createElement('h4');
833-
heading.className = `${CSS_CLASSES.TEXT_MD} ${CSS_CLASSES.FONT_SEMIBOLD} mb-2 ${CSS_CLASSES.TEXT_GRAY_700_DARK_GRAY_300}`;
833+
heading.className = `${CSS_CLASSES.TEXT_MD} ${CSS_CLASSES.FONT_SEMIBOLD} ${CSS_CLASSES.MB2} ${CSS_CLASSES.TEXT_GRAY_700_DARK_GRAY_300}`;
834834
heading.textContent = 'Server Status';
835835
sectionDiv.appendChild(heading);
836836

837-
const statusContainer = document.createElement('div');
838-
statusContainer.className = `${CSS_CLASSES.BORDER_GRAY_200_DARK_BORDER_GRAY_700} ${CSS_CLASSES.ROUNDED} ${CSS_CLASSES.BG_GRAY_50_DARK_BG_GRAY_800_30} p-2`; // Reduced padding for a tighter overall look
839-
840-
const nodeStatus = pbsInstanceData.nodeStatus || {};
841-
const versionInfo = pbsInstanceData.versionInfo || {};
842-
843-
const metricsRow = document.createElement('div');
844-
metricsRow.className = 'flex flex-wrap -mx-px'; // Use negative margin to counteract border width on items
845-
846-
const createMetricBlock = (label, value, details, isLast = false) => {
847-
const block = document.createElement('div');
848-
let blockClasses = 'flex-1 px-2 py-1 text-center min-w-[80px]'; // min-width to prevent excessive squishing
849-
if (!isLast) {
850-
blockClasses += ' border-r border-gray-300 dark:border-gray-600';
851-
}
852-
block.className = blockClasses;
853-
854-
let innerHTML = `<div class="text-xs text-gray-500 dark:text-gray-400">${label}</div>
855-
<div class="text-sm font-semibold text-gray-900 dark:text-gray-100">${value}</div>`;
856-
if (details) {
857-
innerHTML += `<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">${details}</div>`;
858-
}
859-
block.innerHTML = innerHTML;
860-
return block;
861-
};
837+
const tableContainer = document.createElement('div');
838+
tableContainer.className = `${CSS_CLASSES.OVERFLOW_X_AUTO} ${CSS_CLASSES.BORDER_GRAY_200_DARK_BORDER_GRAY_700} ${CSS_CLASSES.ROUNDED}`;
839+
const table = document.createElement('table');
840+
table.className = `${CSS_CLASSES.MIN_W_FULL} ${CSS_CLASSES.DIVIDE_Y_GRAY_200_DARK_DIVIDE_GRAY_700} ${CSS_CLASSES.TEXT_SM}`;
841+
842+
// Table header
843+
const thead = document.createElement('thead');
844+
thead.className = `${CSS_CLASSES.STICKY} ${CSS_CLASSES.TOP_0} ${CSS_CLASSES.Z_10} ${CSS_CLASSES.BG_GRAY_100_DARK_BG_GRAY_800}`;
845+
const headerRow = document.createElement('tr');
846+
headerRow.className = `${CSS_CLASSES.TEXT_XS} ${CSS_CLASSES.FONT_MEDIUM} ${CSS_CLASSES.TRACKING_WIDER} ${CSS_CLASSES.TEXT_LEFT} ${CSS_CLASSES.TEXT_GRAY_600_UPPERCASE_DARK_TEXT_GRAY_300} ${CSS_CLASSES.BORDER_B_GRAY_300_DARK_BORDER_GRAY_600}`;
847+
const headerClasses = [
848+
'w-24 truncate', // PBS VER
849+
'w-24 truncate', // Uptime
850+
'min-w-[180px]', // CPU
851+
'min-w-[180px]', // Mem
852+
'w-16 truncate' // Load
853+
];
854+
['PBS VER', 'Uptime', 'CPU', 'Mem', 'Load'].forEach((headerText, i) => {
855+
const th = document.createElement('th');
856+
th.scope = 'col';
857+
th.className = `${CSS_CLASSES.P1_PX2} ${headerClasses[i]}`;
858+
th.textContent = headerText;
859+
headerRow.appendChild(th);
860+
});
861+
thead.appendChild(headerRow);
862+
table.appendChild(thead);
862863

863-
const metricItems = [];
864+
// Table body
865+
const tbody = document.createElement('tbody');
866+
tbody.className = CSS_CLASSES.DIVIDE_Y_GRAY_200_DARK_DIVIDE_GRAY_700;
867+
const valueRow = document.createElement('tr');
864868

865-
// PBS Version
866-
if (versionInfo.version) {
867-
const versionText = versionInfo.release ? `${versionInfo.version}-${versionInfo.release}` : versionInfo.version;
868-
metricItems.push({ label: 'PBS VER', value: versionText });
869-
}
869+
// PBS VER
870+
const versionInfo = pbsInstanceData.versionInfo || {};
871+
const versionText = versionInfo.version ? (versionInfo.release ? `${versionInfo.version}-${versionInfo.release}` : versionInfo.version) : '-';
872+
const versionCell = document.createElement('td');
873+
versionCell.className = `${CSS_CLASSES.P1_PX2} w-24 truncate`;
874+
versionCell.title = versionText;
875+
versionCell.textContent = versionText;
876+
valueRow.appendChild(versionCell);
870877

871878
// Uptime
872-
if (nodeStatus.uptime) {
873-
metricItems.push({ label: 'UPTIME', value: PulseApp.utils.formatUptime(nodeStatus.uptime) });
874-
}
875-
876-
// CPU Usage
879+
const nodeStatus = pbsInstanceData.nodeStatus || {};
880+
const uptimeCell = document.createElement('td');
881+
uptimeCell.className = `${CSS_CLASSES.P1_PX2} w-24 truncate`;
882+
uptimeCell.textContent = nodeStatus.uptime ? PulseApp.utils.formatUptime(nodeStatus.uptime) : '-';
883+
valueRow.appendChild(uptimeCell);
884+
885+
// CPU
886+
const cpuCell = document.createElement('td');
887+
cpuCell.className = `${CSS_CLASSES.P1_PX2} min-w-[180px]`;
877888
if (nodeStatus.cpu !== null && nodeStatus.cpu !== undefined) {
878-
metricItems.push({ label: 'CPU', value: `${Math.round(nodeStatus.cpu * 100)}%` });
889+
const cpuPercent = nodeStatus.cpu * 100;
890+
const cpuColorClass = PulseApp.utils.getUsageColor(cpuPercent, 'cpu');
891+
const cpuTooltipText = `${cpuPercent.toFixed(1)}%`;
892+
cpuCell.innerHTML = PulseApp.utils.createProgressTextBarHTML(cpuPercent, cpuTooltipText, cpuColorClass);
893+
} else {
894+
cpuCell.textContent = '-';
879895
}
880-
881-
// Memory Usage
896+
valueRow.appendChild(cpuCell);
897+
898+
// Mem
899+
const memCell = document.createElement('td');
900+
memCell.className = `${CSS_CLASSES.P1_PX2} min-w-[180px]`;
882901
if (nodeStatus.memory && nodeStatus.memory.total && nodeStatus.memory.used !== null) {
883-
const memoryPercent = Math.round((nodeStatus.memory.used / nodeStatus.memory.total) * 100);
884-
const memoryDetails = `(${PulseApp.utils.formatBytes(nodeStatus.memory.used)} / ${PulseApp.utils.formatBytes(nodeStatus.memory.total)})`;
885-
metricItems.push({ label: 'MEMORY', value: `${memoryPercent}%`, details: memoryDetails });
902+
const memUsed = nodeStatus.memory.used;
903+
const memTotal = nodeStatus.memory.total;
904+
const memPercent = (memUsed && memTotal > 0) ? (memUsed / memTotal * 100) : 0;
905+
const memColorClass = PulseApp.utils.getUsageColor(memPercent, 'memory');
906+
const memTooltipText = `${PulseApp.utils.formatBytes(memUsed)} / ${PulseApp.utils.formatBytes(memTotal)} (${memPercent.toFixed(1)}%)`;
907+
memCell.innerHTML = PulseApp.utils.createProgressTextBarHTML(memPercent, memTooltipText, memColorClass);
908+
} else {
909+
memCell.textContent = '-';
886910
}
911+
valueRow.appendChild(memCell);
887912

888-
// Load Average (1-min)
913+
// Load
914+
const loadCell = document.createElement('td');
915+
loadCell.className = `${CSS_CLASSES.P1_PX2} w-16 truncate`;
889916
if (nodeStatus.loadavg && Array.isArray(nodeStatus.loadavg) && nodeStatus.loadavg.length >= 1) {
890-
metricItems.push({ label: 'LOAD', value: nodeStatus.loadavg[0].toFixed(2) });
917+
loadCell.textContent = nodeStatus.loadavg[0].toFixed(2);
918+
} else {
919+
loadCell.textContent = '-';
891920
}
921+
valueRow.appendChild(loadCell);
892922

893-
metricItems.forEach((item, index) => {
894-
metricsRow.appendChild(createMetricBlock(item.label, item.value, item.details, index === metricItems.length - 1));
895-
});
896-
897-
statusContainer.appendChild(metricsRow);
898-
sectionDiv.appendChild(statusContainer);
899-
923+
tbody.appendChild(valueRow);
924+
table.appendChild(tbody);
925+
tableContainer.appendChild(table);
926+
sectionDiv.appendChild(tableContainer);
900927
return sectionDiv;
901928
};
902929

0 commit comments

Comments
 (0)