]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/dc/Summary.js
gui: {dc, node}/Summary: choose columns by panel size
[pve-manager.git] / www / manager6 / dc / Summary.js
CommitLineData
7c53ee24
DM
1Ext.define('PVE.dc.Summary', {
2 extend: 'Ext.panel.Panel',
cf8b372a 3 alias: 'widget.pveDcSummary',
7c53ee24 4
cf8b372a
DC
5 scrollable: true,
6
5da98a05 7 bodyPadding: 5,
cf8b372a
DC
8
9 layout: 'column',
10
11 defaults: {
5da98a05 12 padding: 5,
f73a7334 13 columnWidth: 1,
cf8b372a
DC
14 },
15
16 items: [
50a1eb7d
DC
17 {
18 itemId: 'dcHealth',
19 xtype: 'pveDcHealth'
20 },
21 {
22 itemId: 'dcGuests',
23 xtype: 'pveDcGuests'
24 },
25 {
8f8ec25d 26 title: gettext('Resources'),
50a1eb7d 27 xtype: 'panel',
5da98a05
DC
28 minHeight: 250,
29 bodyPadding: 5,
701acf20 30 layout: 'hbox',
50a1eb7d 31 defaults: {
5683fb60 32 xtype: 'proxmoxGauge',
701acf20 33 flex: 1
50a1eb7d
DC
34 },
35 items:[
36 {
37 title: gettext('CPU'),
38 itemId: 'cpu'
39 },
40 {
41 title: gettext('Memory'),
42 itemId: 'memory'
43 },
44 {
45 title: gettext('Storage'),
46 itemId: 'storage'
47 }
48 ]
49 },
cf8b372a
DC
50 {
51 itemId: 'nodeview',
52 xtype: 'pveDcNodeView',
53 height: 250
f734486b
DC
54 },
55 {
56 title: gettext('Subscriptions'),
57 height: 220,
58 items: [
59 {
60 itemId: 'subscriptions',
841f1ed4
DC
61 xtype: 'pveHealthWidget',
62 userCls: 'pointer',
63 listeners: {
64 element: 'el',
65 click: function() {
66 if (this.component.userCls === 'pointer') {
67 window.open('https://www.proxmox.com/en/proxmox-ve/pricing', '_blank');
68 }
69 }
70 }
f734486b
DC
71 }
72 ]
cf8b372a
DC
73 }
74 ],
7c53ee24 75
f73a7334
DC
76 listeners: {
77 resize: function(panel) {
78 PVE.Utils.updateColumns(panel);
79 },
80 },
81
7c53ee24
DM
82 initComponent: function() {
83 var me = this;
84
0c7c0d6b 85 var rstore = Ext.create('Proxmox.data.UpdateStore', {
cf8b372a
DC
86 interval: 3000,
87 storeid: 'pve-cluster-status',
88 model: 'pve-dc-nodes',
89 proxy: {
56a353b9 90 type: 'proxmox',
cf8b372a
DC
91 url: "/api2/json/cluster/status"
92 }
7c53ee24
DM
93 });
94
eaa018d7 95 var gridstore = Ext.create('Proxmox.data.DiffStore', {
cf8b372a
DC
96 rstore: rstore,
97 filters: {
98 property: 'type',
99 value: 'node'
100 },
101 sorters: {
102 property: 'id',
103 direction: 'ASC'
7c53ee24
DM
104 }
105 });
106
107 me.callParent();
cf8b372a
DC
108
109 me.getComponent('nodeview').setStore(gridstore);
110
50a1eb7d
DC
111 var gueststatus = me.getComponent('dcGuests');
112
113 var cpustat = me.down('#cpu');
114 var memorystat = me.down('#memory');
115 var storagestat = me.down('#storage');
0d1c1267 116 var sp = Ext.state.Manager.getProvider();
50a1eb7d
DC
117
118 me.mon(PVE.data.ResourceStore, 'load', function(curstore, results) {
119 me.suspendLayout = true;
120
121 var cpu = 0;
122 var maxcpu = 0;
123
124 var nodes = 0;
125
126 var memory = 0;
127 var maxmem = 0;
128
129 var countedStorages = {};
130 var used = 0;
131 var total = 0;
0d1c1267
DC
132 var usableStorages = {};
133 var storages = sp.get('dash-storages') || '';
134 storages.split(',').forEach(function(storage){
135 if (storage !== '') {
136 usableStorages[storage] = true;
137 }
138 });
50a1eb7d
DC
139
140 var qemu = {
141 running: 0,
142 paused: 0,
143 stopped: 0,
144 template: 0
145 };
146 var lxc = {
147 running: 0,
148 paused: 0,
149 stopped: 0,
150 template: 0
151 };
152 var error = 0;
153
154 var i;
155
156 for (i = 0; i < results.length; i++) {
157 var item = results[i];
158 switch(item.data.type) {
159 case 'node':
160 cpu += (item.data.cpu * item.data.maxcpu);
161 maxcpu += item.data.maxcpu || 0;
162 memory += item.data.mem || 0;
163 maxmem += item.data.maxmem || 0;
164 nodes++;
165
166 // update grid also
167 var griditem = gridstore.getById(item.data.id);
168 if (griditem) {
169 griditem.set('cpuusage', item.data.cpu);
170 var max = item.data.maxmem || 1;
171 var val = item.data.mem || 0;
172 griditem.set('memoryusage', val/max);
173 griditem.set('uptime', item.data.uptime);
174 griditem.commit(); //else it marks the fields as dirty
175 }
176 break;
177 case 'storage':
0d1c1267
DC
178 if (!Ext.Object.isEmpty(usableStorages)) {
179 if (usableStorages[item.data.id] === true) {
180 used += item.data.disk;
181 total += item.data.maxdisk;
182 }
183 break;
184 }
50a1eb7d
DC
185 if (!countedStorages[item.data.storage] ||
186 (item.data.storage === 'local' &&
187 !countedStorages[item.data.id])) {
188 used += item.data.disk;
189 total += item.data.maxdisk;
190
191 countedStorages[item.data.storage === 'local'?item.data.id:item.data.storage] = true;
192 }
193 break;
194 case 'qemu':
195 qemu[item.data.template ? 'template' : item.data.status]++;
196 if (item.data.hastate === 'error') {
197 error++;
198 }
199 break;
200 case 'lxc':
201 lxc[item.data.template ? 'template' : item.data.status]++;
202 if (item.data.hastate === 'error') {
203 error++;
204 }
205 break;
206 default: break;
207 }
208 }
209
210 var text = Ext.String.format(gettext('of {0} CPU(s)'), maxcpu);
211 cpustat.updateValue((cpu/maxcpu), text);
212
213 text = Ext.String.format(gettext('{0} of {1}'), PVE.Utils.render_size(memory), PVE.Utils.render_size(maxmem));
214 memorystat.updateValue((memory/maxmem), text);
215
216 text = Ext.String.format(gettext('{0} of {1}'), PVE.Utils.render_size(used), PVE.Utils.render_size(total));
217 storagestat.updateValue((used/total), text);
218
219 gueststatus.updateValues(qemu,lxc,error);
220
221 me.suspendLayout = false;
222 me.updateLayout(true);
223 });
224
225 var dcHealth = me.getComponent('dcHealth');
226 me.mon(rstore, 'load', dcHealth.updateStatus, dcHealth);
227
f734486b
DC
228 var subs = me.down('#subscriptions');
229 me.mon(rstore, 'load', function(store, records, success) {
230 var i;
231 var level;
3747b7a2 232 var mixed = false;
f734486b
DC
233 for (i = 0; i < records.length; i++) {
234 if (records[i].get('type') !== 'node') {
235 continue;
236 }
595d0457
DC
237 var node = records[i];
238 if (node.get('status') === 'offline') {
239 continue;
240 }
241
3747b7a2 242 var curlevel = node.get('level');
595d0457 243
3512569d 244 if (curlevel === '') { // no subscription trumps all, set and break
595d0457
DC
245 level = '';
246 break;
247 }
f734486b 248
3512569d 249 if (level === undefined) { // save level
f734486b 250 level = curlevel;
3747b7a2
TL
251 } else if (level !== curlevel) { // detect different levels
252 mixed = true;
f734486b
DC
253 }
254 }
255
595d0457
DC
256 var data = {
257 title: Proxmox.Utils.unknownText,
258 text: Proxmox.Utils.unknownText,
259 iconCls: PVE.Utils.get_health_icon(undefined, true)
260 };
f734486b 261 if (level === '') {
595d0457 262 data = {
f734486b
DC
263 title: gettext('No Subscription'),
264 iconCls: PVE.Utils.get_health_icon('critical', true),
265 text: gettext('You have at least one node without subscription.')
595d0457 266 };
841f1ed4 267 subs.setUserCls('pointer');
3747b7a2 268 } else if (mixed) {
595d0457 269 data = {
f734486b
DC
270 title: gettext('Mixed Subscriptions'),
271 iconCls: PVE.Utils.get_health_icon('warning', true),
272 text: gettext('Warning: Your subscription levels are not the same.')
595d0457 273 };
841f1ed4 274 subs.setUserCls('pointer');
595d0457
DC
275 } else if (level) {
276 data = {
f734486b
DC
277 title: PVE.Utils.render_support_level(level),
278 iconCls: PVE.Utils.get_health_icon('good', true),
279 text: gettext('Your subscription status is valid.')
595d0457 280 };
841f1ed4 281 subs.setUserCls('');
f734486b 282 }
595d0457
DC
283
284 subs.setData(data);
f734486b
DC
285 });
286
cf8b372a
DC
287 me.on('destroy', function(){
288 rstore.stopUpdate();
289 });
290
291 rstore.startUpdate();
7c53ee24 292 }
50a1eb7d 293
7c53ee24 294});