@@ -830,73 +830,100 @@ PulseApp.ui.pbs = (() => {
830
830
sectionDiv . className = `${ CSS_CLASSES . MB3 } ` ;
831
831
832
832
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 } ` ;
834
834
heading . textContent = 'Server Status' ;
835
835
sectionDiv . appendChild ( heading ) ;
836
836
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 ) ;
862
863
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' ) ;
864
868
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 ) ;
870
877
871
878
// 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]` ;
877
888
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 = '-' ;
879
895
}
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]` ;
882
901
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 = '-' ;
886
910
}
911
+ valueRow . appendChild ( memCell ) ;
887
912
888
- // Load Average (1-min)
913
+ // Load
914
+ const loadCell = document . createElement ( 'td' ) ;
915
+ loadCell . className = `${ CSS_CLASSES . P1_PX2 } w-16 truncate` ;
889
916
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 = '-' ;
891
920
}
921
+ valueRow . appendChild ( loadCell ) ;
892
922
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 ) ;
900
927
return sectionDiv ;
901
928
} ;
902
929
0 commit comments