Skip to content

Commit fa21c1d

Browse files
authored
Darkmode (#2)
* dark_mode * Mark scripts executable
1 parent 5cf9b87 commit fa21c1d

File tree

4 files changed

+97
-25
lines changed

4 files changed

+97
-25
lines changed

install-gui.sh

100644100755
File mode changed.

install.sh

100644100755
File mode changed.

uninstall.sh

100644100755
File mode changed.

www/MultipathDisplay.js

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,75 @@ function getTransportInfo(transport) {
2525

2626
// Hook into the storage Summary panel to add multipath status
2727
(function() {
28+
function ensureMultipathStyles() {
29+
if (Ext.get('pve-multipath-styles')) return;
30+
31+
Ext.DomHelper.append(Ext.getHead(), {
32+
tag: 'style',
33+
id: 'pve-multipath-styles',
34+
html: [
35+
'.pve-mpath {',
36+
' --pve-mpath-surface: var(--pwt-panel-background, #f8f8f8);',
37+
' --pve-mpath-border: var(--pwt-chart-grid-stroke, #e0e0e0);',
38+
' --pve-mpath-header-bg: var(--pwt-gauge-back, #e8e8e8);',
39+
' --pve-mpath-summary-bg: var(--pwt-gauge-back, #f0f0f0);',
40+
' --pve-mpath-muted: var(--pwt-text-color, #666);',
41+
' --pve-mpath-accent: var(--pwt-chart-primary, #337ab7);',
42+
' --pve-mpath-code-bg: #2d2d2d;',
43+
' --pve-mpath-code-fg: #f8f8f2;',
44+
'}',
45+
'.pve-mpath .pve-mpath-device {',
46+
' margin-bottom: 15px;',
47+
' padding: 10px;',
48+
' background: var(--pve-mpath-surface);',
49+
' border: 1px solid var(--pve-mpath-border);',
50+
' border-radius: 4px;',
51+
'}',
52+
'.pve-mpath .pve-mpath-muted {',
53+
' color: var(--pve-mpath-muted);',
54+
'}',
55+
'.pve-mpath .pve-mpath-accent {',
56+
' color: var(--pve-mpath-accent);',
57+
'}',
58+
'.pve-mpath .pve-mpath-summary {',
59+
' margin-top: 10px;',
60+
' padding: 8px;',
61+
' background: var(--pve-mpath-summary-bg);',
62+
' border-radius: 4px;',
63+
'}',
64+
'.pve-mpath .pve-mpath-empty {',
65+
' margin-top: 15px;',
66+
' padding: 10px;',
67+
' background: var(--pve-mpath-surface);',
68+
' border: 1px solid var(--pve-mpath-border);',
69+
' border-radius: 3px;',
70+
'}',
71+
'.pve-mpath .pve-mpath-command {',
72+
' display: block;',
73+
' margin-top: 8px;',
74+
' padding: 8px;',
75+
' background: var(--pve-mpath-code-bg);',
76+
' color: var(--pve-mpath-code-fg);',
77+
' border-radius: 3px;',
78+
'}',
79+
'.pve-mpath .pve-mpath-table {',
80+
' width: 100%;',
81+
' border-collapse: collapse;',
82+
' margin-top: 8px;',
83+
'}',
84+
'.pve-mpath .pve-mpath-table th,',
85+
'.pve-mpath .pve-mpath-table td {',
86+
' padding: 6px;',
87+
' border: 1px solid var(--pve-mpath-border);',
88+
' text-align: left;',
89+
'}',
90+
'.pve-mpath .pve-mpath-table thead tr {',
91+
' background: var(--pve-mpath-header-bg);',
92+
'}',
93+
].join('\n'),
94+
});
95+
}
96+
2897
// Store the original initComponent
2998
let originalInit = PVE.storage.Summary.prototype.initComponent;
3099

@@ -65,6 +134,8 @@ function getTransportInfo(transport) {
65134
PVE.storage.Summary.prototype.addMultipathStatusPanel = function(storageConfig, storeid, nodename) {
66135
let me = this;
67136

137+
ensureMultipathStyles();
138+
68139
// Do not add if already exists
69140
if (me.down('#multipathStatus')) return;
70141

@@ -124,7 +195,7 @@ function getTransportInfo(transport) {
124195
};
125196

126197
PVE.storage.Summary.prototype.renderMultipathStatus = function(panel, storageConfig, statusData, pathData) {
127-
let html = '<table class="pve-infotable" style="width: 100%;">';
198+
let html = '<div class="pve-mpath"><table class="pve-infotable" style="width: 100%;">';
128199

129200
// Determine storage type display
130201
let hasMultipath = statusData.multipathStatus &&
@@ -195,7 +266,7 @@ function getTransportInfo(transport) {
195266
}
196267
});
197268

198-
html += '<div style="margin-top: 10px; padding: 8px; background: #f0f0f0; border-radius: 4px;">';
269+
html += '<div class="pve-mpath-summary">';
199270
if (activePaths === totalPaths) {
200271
html += '<span style="color: #5cb85c;"><i class="fa fa-check-circle"></i> ' +
201272
activePaths + '/' + totalPaths + ' ' + gettext('paths active') + '</span>';
@@ -206,18 +277,19 @@ function getTransportInfo(transport) {
206277
html += '</div>';
207278
html += '</div>';
208279
} else {
209-
html += '<div style="margin-top: 15px; padding: 10px; background: #f8f8f8; border: 1px solid #e0e0e0; border-radius: 3px;">';
210-
html += '<div style="color: #999;"><i class="fa fa-info-circle"></i> ' +
280+
html += '<div class="pve-mpath-empty">';
281+
html += '<div class="pve-mpath-muted"><i class="fa fa-info-circle"></i> ' +
211282
gettext('Path details not available. Run on the node:') + '</div>';
212-
html += '<code style="display: block; margin-top: 8px; padding: 8px; background: #2d2d2d; color: #f8f8f2; border-radius: 3px;">multipath -ll</code>';
283+
html += '<code class="pve-mpath-command">multipath -ll</code>';
213284
html += '</div>';
214285
}
215286

287+
html += '</div>';
216288
panel.update(html);
217289
};
218290

219291
PVE.storage.Summary.prototype.renderMultipathDevice = function(device, storageType) {
220-
let html = '<div style="margin-bottom: 15px; padding: 10px; background: #f8f8f8; border: 1px solid #e0e0e0; border-radius: 4px;">';
292+
let html = '<div class="pve-mpath-device">';
221293

222294
// Detect NVMe native multipath based on storage type or device properties
223295
// LVM on NVMe will have nqn/subsystem set, or paths starting with 'nvme'
@@ -246,15 +318,15 @@ function getTransportInfo(transport) {
246318
html += '<i class="fa fa-hdd-o"></i> /dev/mapper/' + Ext.htmlEncode(device.name);
247319
}
248320
if (device.size) {
249-
html += ' <span style="color: #666; font-weight: normal;">(' + Ext.htmlEncode(device.size) + ')</span>';
321+
html += ' <span class="pve-mpath-muted" style="font-weight: normal;">(' + Ext.htmlEncode(device.size) + ')</span>';
250322
}
251323
if (device.pv_path) {
252-
html += ' <span style="color: #337ab7; font-weight: normal;">&rarr; PV: ' + Ext.htmlEncode(device.pv_path) + '</span>';
324+
html += ' <span class="pve-mpath-accent" style="font-weight: normal;">&rarr; PV: ' + Ext.htmlEncode(device.pv_path) + '</span>';
253325
}
254326
html += '</div>';
255327

256328
// Device details - different for NVMe vs SCSI
257-
html += '<div style="font-size: 0.9em; color: #666; margin-bottom: 8px;">';
329+
html += '<div class="pve-mpath-muted" style="font-size: 0.9em; margin-bottom: 8px;">';
258330
if (isNvmeNative) {
259331
html += 'NQN: ' + Ext.htmlEncode(device.nqn || device.wwid || 'unknown');
260332
if (device.subsystem) {
@@ -274,18 +346,18 @@ function getTransportInfo(transport) {
274346

275347
// Path table - adjust columns based on multipath type
276348
if (device.paths && device.paths.length > 0) {
277-
html += '<table style="width: 100%; border-collapse: collapse; margin-top: 8px;">';
278-
html += '<thead><tr style="background: #e8e8e8;">';
279-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('Device') + '</th>';
349+
html += '<table class="pve-mpath-table">';
350+
html += '<thead><tr>';
351+
html += '<th>' + gettext('Device') + '</th>';
280352
if (isNvmeNative) {
281-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('Controller') + '</th>';
353+
html += '<th>' + gettext('Controller') + '</th>';
282354
} else {
283-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">HCTL</th>';
355+
html += '<th>HCTL</th>';
284356
}
285-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('Transport') + '</th>';
286-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('Portal/Address') + '</th>';
287-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('Interface') + '</th>';
288-
html += '<th style="padding: 6px; border: 1px solid #ddd; text-align: left;">' + gettext('State') + '</th>';
357+
html += '<th>' + gettext('Transport') + '</th>';
358+
html += '<th>' + gettext('Portal/Address') + '</th>';
359+
html += '<th>' + gettext('Interface') + '</th>';
360+
html += '<th>' + gettext('State') + '</th>';
289361
html += '</tr></thead><tbody>';
290362

291363
device.paths.forEach(function(path) {
@@ -301,19 +373,19 @@ function getTransportInfo(transport) {
301373
let transportInfo = getTransportInfo(path.transport || 'unknown');
302374

303375
html += '<tr>';
304-
html += '<td style="padding: 6px; border: 1px solid #ddd;"><code>/dev/' + Ext.htmlEncode(path.device) + '</code></td>';
376+
html += '<td><code>/dev/' + Ext.htmlEncode(path.device) + '</code></td>';
305377
if (isNvmeNative) {
306378
// Show controller name for NVMe (e.g., nvme0, nvme1)
307-
html += '<td style="padding: 6px; border: 1px solid #ddd;">' + Ext.htmlEncode(path.controller || '-') + '</td>';
379+
html += '<td>' + Ext.htmlEncode(path.controller || '-') + '</td>';
308380
} else {
309-
html += '<td style="padding: 6px; border: 1px solid #ddd;">' + Ext.htmlEncode(path.hctl || '-') + '</td>';
381+
html += '<td>' + Ext.htmlEncode(path.hctl || '-') + '</td>';
310382
}
311-
html += '<td style="padding: 6px; border: 1px solid #ddd; color: ' + transportInfo.color + ';">';
383+
html += '<td style="color: ' + transportInfo.color + ';">';
312384
html += '<i class="fa ' + transportInfo.icon + '"></i> ' + transportInfo.label;
313385
html += '</td>';
314-
html += '<td style="padding: 6px; border: 1px solid #ddd;">' + Ext.htmlEncode(path.portal || '-') + '</td>';
315-
html += '<td style="padding: 6px; border: 1px solid #ddd;">' + Ext.htmlEncode(path.hostIface || '-') + '</td>';
316-
html += '<td style="padding: 6px; border: 1px solid #ddd; color: ' + stateColor + ';">';
386+
html += '<td>' + Ext.htmlEncode(path.portal || '-') + '</td>';
387+
html += '<td>' + Ext.htmlEncode(path.hostIface || '-') + '</td>';
388+
html += '<td style="color: ' + stateColor + ';">';
317389
html += '<i class="fa ' + stateIcon + '"></i> ' + Ext.htmlEncode(path.state);
318390
html += '</td>';
319391
html += '</tr>';

0 commit comments

Comments
 (0)