ui: ceph: improve discoverability of warning details
by * replacing the info button with expandable rows that contain the details of the warning * adding two action buttons to copy the summary and details * making the text selectable The row expander works like the one in the mail gateway tracking center -> doubleclick only opens it. The height of the warning grid is limited to not grow too large. A Diffstore is used to avoid expanded rows being collapsed on an update. The rowexpander cannot hide the toggle out of the box. Therefore, if there is no detailed message for a warning, we show a placeholder text. We could consider extending it in the future to only show the toggle if a defined condition is met. Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
fddf562bf9
commit
459b6c3136
@ -709,3 +709,9 @@ table.osds td:first-of-type {
|
||||
opacity: 0.0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.pve-ceph-warning-detail {
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
Ext.define('pve-ceph-warnings', {
|
||||
extend: 'Ext.data.Model',
|
||||
fields: ['id', 'summary', 'detail', 'severity'],
|
||||
idProperty: 'id',
|
||||
});
|
||||
|
||||
|
||||
Ext.define('PVE.node.CephStatus', {
|
||||
extend: 'Ext.panel.Panel',
|
||||
alias: 'widget.pveNodeCephStatus',
|
||||
@ -70,35 +77,51 @@ Ext.define('PVE.node.CephStatus', {
|
||||
xtype: 'grid',
|
||||
itemId: 'warnings',
|
||||
flex: 2,
|
||||
maxHeight: 430,
|
||||
stateful: true,
|
||||
stateId: 'ceph-status-warnings',
|
||||
viewConfig: {
|
||||
enableTextSelection: true,
|
||||
},
|
||||
// we load the store manually, to show an emptyText specify an empty intermediate store
|
||||
store: {
|
||||
type: 'diff',
|
||||
trackRemoved: false,
|
||||
data: [],
|
||||
rstore: {
|
||||
storeid: 'pve-ceph-warnings',
|
||||
type: 'update',
|
||||
model: 'pve-ceph-warnings',
|
||||
},
|
||||
},
|
||||
updateHealth: function(health) {
|
||||
let checks = health.checks || {};
|
||||
|
||||
let checkRecords = Object.keys(checks).sort().map(key => {
|
||||
let check = checks[key];
|
||||
return {
|
||||
let data = {
|
||||
id: key,
|
||||
summary: check.summary.message,
|
||||
detail: check.detail.reduce((acc, v) => `${acc}\n${v.message}`, ''),
|
||||
detail: check.detail.reduce((acc, v) => `${acc}\n${v.message}`, '').trimStart(),
|
||||
severity: check.severity,
|
||||
};
|
||||
if (data.detail.length === 0) {
|
||||
data.detail = "no additional data";
|
||||
}
|
||||
return data;
|
||||
});
|
||||
|
||||
this.getStore().loadRawData(checkRecords, false);
|
||||
let rstore = this.getStore().rstore;
|
||||
rstore.loadData(checkRecords, false);
|
||||
rstore.fireEvent('load', rstore, checkRecords, true);
|
||||
},
|
||||
emptyText: gettext('No Warnings/Errors'),
|
||||
columns: [
|
||||
{
|
||||
dataIndex: 'severity',
|
||||
header: gettext('Severity'),
|
||||
tooltip: gettext('Severity'),
|
||||
align: 'center',
|
||||
width: 70,
|
||||
width: 38,
|
||||
renderer: function(value) {
|
||||
let health = PVE.Utils.map_ceph_health[value];
|
||||
let icon = PVE.Utils.get_health_icon(health);
|
||||
@ -118,38 +141,48 @@ Ext.define('PVE.node.CephStatus', {
|
||||
},
|
||||
{
|
||||
xtype: 'actioncolumn',
|
||||
width: 40,
|
||||
width: 50,
|
||||
align: 'center',
|
||||
tooltip: gettext('Detail'),
|
||||
tooltip: gettext('Actions'),
|
||||
items: [
|
||||
{
|
||||
iconCls: 'x-fa fa-info-circle',
|
||||
iconCls: 'x-fa fa-files-o',
|
||||
tooltip: gettext('Copy summary'),
|
||||
handler: function(grid, rowindex, colindex, item, e, record) {
|
||||
var win = Ext.create('Ext.window.Window', {
|
||||
title: gettext('Detail'),
|
||||
resizable: true,
|
||||
modal: true,
|
||||
width: 650,
|
||||
height: 400,
|
||||
layout: {
|
||||
type: 'fit',
|
||||
},
|
||||
items: [{
|
||||
scrollable: true,
|
||||
padding: 10,
|
||||
xtype: 'box',
|
||||
html: [
|
||||
'<span>' + Ext.htmlEncode(record.data.summary) + '</span>',
|
||||
'<pre>' + Ext.htmlEncode(record.data.detail) + '</pre>',
|
||||
],
|
||||
}],
|
||||
});
|
||||
win.show();
|
||||
navigator.clipboard.writeText(record.data.summary);
|
||||
},
|
||||
},
|
||||
{
|
||||
iconCls: 'x-fa fa-clipboard',
|
||||
tooltip: gettext('Copy details'),
|
||||
handler: function(grid, rowindex, colindex, item, e, record) {
|
||||
navigator.clipboard.writeText(record.data.detail);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
listeners: {
|
||||
itemdblclick: function(view, record, row, rowIdx, e) {
|
||||
// inspired by RowExpander.js
|
||||
|
||||
let rowNode = view.getNode(rowIdx); let
|
||||
normalRow = Ext.fly(rowNode);
|
||||
|
||||
let collapsedCls = view.rowBodyFeature.rowCollapsedCls;
|
||||
|
||||
if (normalRow.hasCls(collapsedCls)) {
|
||||
view.rowBodyFeature.rowExpander.toggleRow(rowIdx, record);
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
ptype: 'rowexpander',
|
||||
expandOnDblClick: false,
|
||||
rowBodyTpl: '<pre class="pve-ceph-warning-detail">{detail}</pre>',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user