statics: {
typeDefaults: {
node: {
- iconCls: 'fa fa-building x-fa-tree',
+ iconCls: 'fa fa-building',
text: gettext('Nodes')
},
pool: {
- iconCls: 'fa fa-tags fa-dark x-fa-tree',
+ iconCls: 'fa fa-tags',
text: gettext('Resource Pool')
},
storage: {
- iconCls: 'fa fa-database fa-dark x-fa-tree',
+ iconCls: 'fa fa-database',
text: gettext('Storage')
},
qemu: {
- iconCls: 'fa fa-desktop x-fa-tree',
+ iconCls: 'fa fa-desktop',
text: gettext('Virtual Machine')
},
lxc: {
//iconCls: 'x-tree-node-lxc',
- iconCls: 'fa fa-cube x-fa-tree',
+ iconCls: 'fa fa-cube',
text: gettext('LXC Container')
},
template: {
- iconCls: 'fa fa-file-o fa-dark x-fa-tree-template'
- },
- datacenter: {
- iconCls: 'fa fa-server x-fa-tree-datacenter'
+ iconCls: 'fa fa-file-o'
}
}
},
}
}
- return n1.text > n2.text ? 1 : (n1.text < n2.text ? -1 : 0);
+ return n1.id > n2.id ? 1 : (n1.id < n2.id ? -1 : 0);
} else if (n1.groupbyid) {
return -1;
} else if (n2.groupbyid) {
setIconCls: function(info) {
var me = this;
- var defaults = PVE.tree.ResourceTree.typeDefaults[info.type];
- if (info.id === 'root') {
- defaults = PVE.tree.ResourceTree.typeDefaults.datacenter;
- } else if (info.type === 'type') {
- defaults = PVE.tree.ResourceTree.typeDefaults[info.groupbyid];
+ var cls = PVE.Utils.get_object_icon_class(info.type, info);
+
+ if (cls !== '') {
+ info.iconCls = cls;
}
- if (defaults && defaults.iconCls) {
- var iconClsAdd = '';
-
- if (info.running && info.type === 'node') {
- iconClsAdd = '-online';
- } else if (info.running) {
- iconClsAdd = '-running';
- if (info.status === 'paused') {
- iconClsAdd = '-paused';
- }
- } else if (info.type === 'lxc' || info.type === 'qemu') {
- iconClsAdd = '-stopped';
- } else if (info.type === 'node') {
- iconClsAdd = '-offline';
- }
+ },
- info.iconCls = defaults.iconCls + iconClsAdd;
+ // add additional elements to text
+ // at the moment only the usage indicator for storages
+ setText: function(info) {
+ var me = this;
- if (info.template) {
- iconClsAdd = '-template';
- info.iconCls = PVE.tree.ResourceTree.typeDefaults.template.iconCls + '-' + info.type;
+ var status = '';
+ if (info.type === 'storage') {
+ var maxdisk = info.maxdisk;
+ var disk = info.disk;
+ var usage = disk/maxdisk;
+ var cls = '';
+ if (usage <= 1.0 && usage >= 0.0) {
+ var height = (usage*100).toFixed(0);
+ var neg_height = (100-usage*100).toFixed(0);
+ status = '<div class="usage-wrapper">';
+ status += '<div class="usage-negative" style="height: ';
+ status += neg_height + '%"></div>';
+ status += '<div class="usage" style="height: '+ height +'%"></div>';
+ status += '</div> ';
}
+ }
+
+ info.text = status + info.text;
+ },
+
+ setToolTip: function(info) {
+ if (info.type === 'pool' || info.groupbyid !== undefined) {
+ return;
+ }
+ var qtips = [gettext('Status') + ': ' + (info.qmpstatus || info.status)];
+ if (info.hastate != 'unmanaged') {
+ qtips.push(gettext('HA State') + ": " + info.hastate);
}
+
+ info.qtip = qtips.join(', ');
},
// private
var me = this;
me.setIconCls(info);
+ me.setText(info);
+ me.setToolTip(info);
var defaults;
if (info.groupbyid) {
- info.text = info.groupbyid;
+ info.text = info.groupbyid;
if (info.type === 'type') {
defaults = PVE.tree.ResourceTree.typeDefaults[info.groupbyid];
if (defaults && defaults.text) {
groupinfo.leaf = false;
groupinfo.groupbyid = v;
group = me.addChildSorted(node, groupinfo);
- // fixme: remove when EXTJS has fixed those bugs?!
- group.expand(); group.collapse();
}
if (info.type === groupby) {
return group;
root: {
expanded: true,
id: 'root',
- text: gettext('Datacenter')
+ text: gettext('Datacenter'),
+ iconCls: 'fa fa-server'
}
});
var updateTree = function() {
var tmp;
- // fixme: suspend events ?
+ store.suspendEvents();
var rootnode = me.store.getRootNode();
- me.setIconCls(rootnode.data);
// remember selected node (and all parents)
var sm = me.getSelectionModel();
var lastsel = sm.getSelection()[0];
+ var reselect = false;
var parents = [];
var p = lastsel;
while (p && !!(p = p.parentNode)) {
}
// tree item has been updated
- if ((item.data.text !== olditem.data.text) ||
- (item.data.running !== olditem.data.running) ||
- (item.data.template !== olditem.data.template) ||
- (item.data.status !== olditem.data.status)) {
- //console.log("changed node/text/running " + olditem.data.id);
- changed = true;
+ var fields = [
+ 'text', 'running', 'template', 'status',
+ 'qmpstatus', 'hastate', 'lock'
+ ];
+
+ var field;
+ for (i = 0; i < fields.length; i++) {
+ field = fields[i];
+ if (item.data[field] !== olditem.data[field]) {
+ changed = true;
+ break;
+ }
}
// fixme: also test filterfn()?
var info = olditem.data;
Ext.apply(info, item.data);
me.setIconCls(info);
+ me.setText(info);
+ me.setToolTip(info);
olditem.commit();
}
if ((!item || moved) && olditem.isLeaf()) {
//console.log("REM UID: " + key + " ITEM " + olditem.data.id);
delete index[key];
var parentNode = olditem.parentNode;
+ // when the selected item disappears,
+ // we have to deselect it here, and reselect it
+ // later
+ if (lastsel && olditem.data.id === lastsel.data.id) {
+ reselect = true;
+ sm.deselect(olditem);
+ }
+ // since the store events are suspended, we
+ // manually remove the item from the store also
+ store.remove(olditem);
parentNode.removeChild(olditem, true);
}
}
}
});
+ store.resumeEvents();
+ store.fireEvent('refresh', store);
+
// select parent node is selection vanished
if (lastsel && !rootnode.findChild('id', lastsel.data.id, true)) {
lastsel = rootnode;
}
}
me.selectById(lastsel.data.id);
+ } else if (lastsel && reselect) {
+ me.selectById(lastsel.data.id);
}
// on first tree load set the selection from the stateful provider
if (!pdata.updateCount) {
- rootnode.collapse();
rootnode.expand();
me.applyState(sp.get(stateid));
}
destroy: function() {
rstore.un("load", updateTree);
},
- beforecellmousedown: function (tree, record,item,index,ev) {
+ beforecellmousedown: function (tree, td, cellIndex, record, tr, rowIndex, ev) {
+ var sm = me.getSelectionModel();
// disable selection when right clicking
- me.allowSelection = (event.button !== 2);
+ // except the record is already selected
+ me.allowSelection = (ev.button !== 2) || sm.isSelected(record);
},
beforeselect: function (tree, record, index, eopts) {
var allow = me.allowSelection;
me.allowSelection = true;
return allow;
- }
+ },
+ itemdblclick: PVE.Utils.openTreeConsole
},
setViewFilter: function(view) {
me.viewFilter = view;
me.clearTree();
updateTree();
},
+ setDatacenterText: function(clustername) {
+ var rootnode = me.store.getRootNode();
+
+ var rnodeText = gettext('Datacenter');
+ if (clustername !== undefined) {
+ rnodeText += ' (' + clustername + ')';
+ }
+
+ rootnode.beginEdit();
+ rootnode.data.text = rnodeText;
+ rootnode.commit();
+ },
clearTree: function() {
pdata.updateCount = 0;
var rootnode = me.store.getRootNode();
cn.expand();
}
}
+ me.getView().focusRow(node);
}
},
selectById: function(nodeid) {
if (node) {
me.selectExpand(node);
}
- },
- checkVmMigration: function(record) {
- if (!(record.data.type === 'qemu' || record.data.type === 'lxc')) {
- throw "not a vm type";
- }
-
- var rootnode = me.store.getRootNode();
- var node = rootnode.findChild('id', record.data.id, true);
-
- if (node && node.data.type === record.data.type &&
- node.data.node !== record.data.node) {
- // defer select (else we get strange errors)
- Ext.defer(function() { me.selectExpand(node); }, 100, me);
- }
+ return node;
},
applyState : function(state) {
var sm = me.getSelectionModel();