PR review changes
This commit is contained in:
parent
37aea12483
commit
955cc7941c
@ -943,10 +943,22 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
margin: '0 16 0 0',
|
margin: '0 16 0 0',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
xtype: 'progressbar',
|
xtype: 'container',
|
||||||
itemId: 'progress',
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
|
layout: {
|
||||||
|
type: 'vbox',
|
||||||
|
align: 'stretch',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'component',
|
||||||
|
itemId: 'loadText',
|
||||||
|
margin: '0 0 2 0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'progressbar',
|
||||||
|
itemId: 'progress',
|
||||||
height: 5,
|
height: 5,
|
||||||
value: 0,
|
value: 0,
|
||||||
animate: true,
|
animate: true,
|
||||||
@ -954,6 +966,8 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
initComponent: function() {
|
initComponent: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if (!me.title) {
|
if (!me.title) {
|
||||||
@ -975,13 +989,19 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
progress.setVisible(enable);
|
progress.setVisible(enable);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Single source of truth for all DOM writes — called once per refresh
|
||||||
|
// cycle, right after renderer() returns. renderer() only computes data;
|
||||||
|
// it never touches the DOM, so there's no race/flash between the two.
|
||||||
updateValue: function(text, usage) {
|
updateValue: function(text, usage) {
|
||||||
var me = this;
|
var me = this;
|
||||||
if (me.lastText === text && me.lastUsage === usage) {
|
var loadText = me._pendingLoadText || '';
|
||||||
|
|
||||||
|
if (me.lastText === text && me.lastUsage === usage && me.lastLoadText === loadText) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
me.lastText = text;
|
me.lastText = text;
|
||||||
me.lastUsage = usage;
|
me.lastUsage = usage;
|
||||||
|
me.lastLoadText = loadText;
|
||||||
|
|
||||||
var label = me.getComponent('label');
|
var label = me.getComponent('label');
|
||||||
if (label) {
|
if (label) {
|
||||||
@ -997,6 +1017,15 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var loadTextCmp = me.down('#loadText');
|
||||||
|
if (loadTextCmp) {
|
||||||
|
if (loadTextCmp.setHtml) {
|
||||||
|
loadTextCmp.setHtml(loadText);
|
||||||
|
} else {
|
||||||
|
loadTextCmp.update(loadText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var progressBar = me.down('#progress');
|
var progressBar = me.down('#progress');
|
||||||
if (usage !== undefined && me.printBar && Ext.isNumeric(usage) && usage >= 0 && progressBar) {
|
if (usage !== undefined && me.printBar && Ext.isNumeric(usage) && usage >= 0 && progressBar) {
|
||||||
progressBar.updateProgress(usage, '');
|
progressBar.updateProgress(usage, '');
|
||||||
@ -1012,6 +1041,7 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Drives the progress bar's fill — based on battery.charge.
|
||||||
calculate: function(used) {
|
calculate: function(used) {
|
||||||
if (!used || used.disabled === true || typeof used !== 'object') {
|
if (!used || used.disabled === true || typeof used !== 'object') {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1028,6 +1058,10 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
}
|
}
|
||||||
return Math.max(0, Math.min(1, charge / 100));
|
return Math.max(0, Math.min(1, charge / 100));
|
||||||
},
|
},
|
||||||
|
// Pure computation — no DOM writes. Stashes the "Battery capacity ...
|
||||||
|
// X% (Runtime: ...)" line for updateValue to place above the bar, and
|
||||||
|
// returns a 30/70 table (model | other info incl. Load) wrapped in the
|
||||||
|
// standard indent div, matching the other widgets in this panel.
|
||||||
renderer: function(value) {
|
renderer: function(value) {
|
||||||
let objValue;
|
let objValue;
|
||||||
try {
|
try {
|
||||||
@ -1093,7 +1127,9 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
return '<span style="color:' + color + ';">' + label + '</span>';
|
return '<span style="color:' + color + ';">' + label + '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let aboveBarText = '';
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
|
||||||
upsKeys.forEach(function(upsKey) {
|
upsKeys.forEach(function(upsKey) {
|
||||||
const upsData = objValue[upsKey] || {};
|
const upsData = objValue[upsKey] || {};
|
||||||
const charge = parseFloat(upsData['battery.charge']);
|
const charge = parseFloat(upsData['battery.charge']);
|
||||||
@ -1103,35 +1139,54 @@ Ext.define('PVE.node.StatusView', {
|
|||||||
const watts = parseFloat(upsData['ups.realpower']);
|
const watts = parseFloat(upsData['ups.realpower']);
|
||||||
const model = upsData['ups.model'] || upsData['device.model'] || upsKey;
|
const model = upsData['ups.model'] || upsData['device.model'] || upsKey;
|
||||||
const st = statusText(upsData['ups.status']);
|
const st = statusText(upsData['ups.status']);
|
||||||
const bits = [];
|
const testResult = upsData['ups.test.result'];
|
||||||
if (st.text) {
|
const manufacturingDate = upsData['battery.mfr.date'];
|
||||||
bits.push(colorize(st.text, st.color));
|
|
||||||
|
// Above the bar: "Battery capacity" on the left, charge% (Runtime: ...) on the right.
|
||||||
|
let rightSide = !isNaN(charge) ? (Math.round(charge) + '%') : '';
|
||||||
|
if (runtime) {
|
||||||
|
rightSide += (rightSide ? ' ' : '') + '(Runtime: ' + runtime + ' left)';
|
||||||
}
|
}
|
||||||
if (!isNaN(charge)) {
|
aboveBarText =
|
||||||
bits.push('Battery ' + Math.round(charge) + '%');
|
'<div style="display: flex; justify-content: space-between; gap: 8px;">' +
|
||||||
|
'<span>Battery capacity</span>' +
|
||||||
|
'<span style="text-align: right;">' + rightSide + '</span>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
// General information table: Status, Output, Input, Load, Test.
|
||||||
|
const infoBits = [];
|
||||||
|
if (st.text) {
|
||||||
|
infoBits.push('Status: ' + colorize(st.text, st.color));
|
||||||
}
|
}
|
||||||
if (!isNaN(watts)) {
|
if (!isNaN(watts)) {
|
||||||
bits.push(Math.round(watts) + ' W');
|
infoBits.push('Output: ' + Math.round(watts) + 'W');
|
||||||
}
|
|
||||||
if (!isNaN(load)) {
|
|
||||||
bits.push('Load ' + Math.round(load) + '%');
|
|
||||||
}
|
|
||||||
if (runtime) {
|
|
||||||
bits.push(runtime + ' left');
|
|
||||||
}
|
}
|
||||||
if (!isNaN(inputVoltage)) {
|
if (!isNaN(inputVoltage)) {
|
||||||
const places = inputVoltage >= 50 ? 0 : 1;
|
const places = inputVoltage >= 50 ? 0 : 1;
|
||||||
bits.push(inputVoltage.toFixed(places) + ' V in');
|
infoBits.push('Input: ' + inputVoltage.toFixed(places) + ' V');
|
||||||
|
}
|
||||||
|
if (!isNaN(load)) {
|
||||||
|
infoBits.push('Load: ' + Math.round(load) + '%');
|
||||||
|
}
|
||||||
|
if (manufacturingDate) {
|
||||||
|
infoBits.push('Manufacturing Date: ' + manufacturingDate);
|
||||||
|
}
|
||||||
|
if (testResult) {
|
||||||
|
infoBits.push('Test: ' + testResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.push(
|
rows.push(
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td style="padding: 2px 10px 2px 0; text-align: left; width: 30%; vertical-align: top; overflow-wrap: anywhere; word-break: break-word;">' + model + '</td>' +
|
'<td style="padding: 2px 10px 2px 0; text-align: left; width: 30%; vertical-align: top; overflow-wrap: anywhere; word-break: break-word;">' + model + '</td>' +
|
||||||
'<td style="padding: 2px 0 2px 10px; text-align: right; width: 70%; vertical-align: top; overflow-wrap: anywhere; word-break: break-word; white-space: normal;">' + bits.join(' | ') + '</td>' +
|
'<td style="padding: 2px 0 2px 10px; text-align: right; width: 70%; vertical-align: top; overflow-wrap: anywhere; word-break: break-word; white-space: normal;">' + infoBits.join(' | ') + '</td>' +
|
||||||
'</tr>'
|
'</tr>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stash for updateValue to consume — no DOM writes here.
|
||||||
|
this._pendingLoadText = aboveBarText;
|
||||||
|
|
||||||
|
// Becomes the `text` argument passed to updateValue (left column table).
|
||||||
return '<div style="padding-left: 20px; box-sizing: border-box;"><table style="width: 100%; border-collapse: collapse; table-layout: fixed;">' + rows.join('') + '</table></div>';
|
return '<div style="padding-left: 20px; box-sizing: border-box;"><table style="width: 100%; border-collapse: collapse; table-layout: fixed;">' + rows.join('') + '</table></div>';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user