]> git.proxmox.com Git - pmg-gui.git/blob - js/Dashboard.js
4684a58786fd59b4c3dabaeb88098450f183ab66
[pmg-gui.git] / js / Dashboard.js
1 /*global Proxmox*/
2 /*jslint confusion: true*/
3 /* load is a function and string
4 * hours is a number and string
5 * timespan is a number and string
6 * bind is a function and object
7 * handler is a function and string
8 */
9 Ext.define('PMG.Dashboard', {
10 extend: 'Ext.panel.Panel',
11 xtype: 'pmgDashboard',
12
13 controller: {
14 xclass: 'Ext.app.ViewController',
15
16 openDashboardOptions: function() {
17 var me = this;
18 var viewModel = me.getViewModel();
19 Ext.create('Ext.window.Window', {
20 modal: true,
21 width: 300,
22 title: gettext('Dashboard Options'),
23 layout: {
24 type: 'auto'
25 },
26 items: [{
27 xtype: 'form',
28 bodyPadding: '10 10 10 10',
29 defaultButton: 'savebutton',
30 items: [{
31 xtype: 'proxmoxintegerfield',
32 itemId: 'hours',
33 labelWidth: 100,
34 anchor: '100%',
35 allowBlank: false,
36 minValue: 1,
37 maxValue: 24,
38 value: viewModel.get('hours'),
39 fieldLabel: gettext('Hours to show')
40 }],
41 buttons: [{
42 text: gettext('Save'),
43 reference: 'loginButton',
44 formBind: true,
45 handler: function() {
46 var win = this.up('window');
47 var hours = win.down('#hours').getValue();
48 me.setHours(hours, true);
49 win.close();
50 }
51 }]
52 }]
53 }).show();
54 },
55
56 setHours: function(hours, setState) {
57 var me = this;
58 var viewModel = me.getViewModel();
59 viewModel.set('hours', hours);
60 viewModel.notify();
61
62 Ext.Array.forEach(['recentmails', 'receivers'], function(item) {
63 viewModel.getStore(item).reload();
64 });
65
66 if (setState) {
67 var sp = Ext.state.Manager.getProvider();
68 sp.set('dashboard-hours', hours);
69 }
70 },
71
72 updateMailStats: function(store, records, success) {
73 if (!success) {
74 return;
75 }
76 var me = this;
77 var viewModel = me.getViewModel();
78
79 var count = 0;
80 var bytes_in = 0;
81 var bytes_out = 0;
82 var ptime = 0;
83 var avg_ptime = 'N/A';
84
85 records.forEach(function(item) {
86 bytes_in += item.data.bytes_in;
87 bytes_out += item.data.bytes_out;
88 // unnormalize
89 count += (item.data.count*item.data.timespan)/60;
90 ptime += item.data.ptimesum;
91 });
92
93 if (count) {
94 avg_ptime = (ptime/count).toFixed(2) + " s";
95 }
96
97 viewModel.set('bytes_in', Proxmox.Utils.format_size(bytes_in));
98 viewModel.set('bytes_out', Proxmox.Utils.format_size(bytes_out));
99 viewModel.set('avg_ptime', avg_ptime);
100 },
101
102 updateClusterStats: function(store, records, success) {
103 if (!success) {
104 return;
105 }
106 var me = this;
107 var viewmodel = me.getViewModel();
108
109 var subStatus = 2; // 2 = all good, 1 = different leves, 0 = none
110 var subLevel = "";
111
112 var cpu = 0;
113 var mem = 0;
114 var hd = 0;
115 var count = records.length;
116
117 records.forEach(function(item) {
118 // subscription level check
119 if (subStatus && item.data.level) {
120 if (subLevel !== "" && subLevel !== item.data.level) {
121 subStatus = 1;
122 } else if (subLevel === "") {
123 subLevel = item.data.level;
124 }
125 } else {
126 subStatus = 0;
127 }
128
129 // resources count
130 cpu += item.data.cpu || 0;
131
132 var memory = item.data.memory || { used: 0, total: 1 };
133 mem += (memory.used/memory.total);
134
135 var rootfs = item.data.rootfs || { used: 0, total: 1 };
136 hd += (rootfs.used/rootfs.total);
137
138 });
139
140 var subscriptionPanel = me.lookup('subscription');
141 subscriptionPanel.setSubStatus(subStatus);
142
143 cpu = cpu/count;
144 mem = mem/count;
145 hd = hd/count;
146
147 var cpuPanel = me.lookup('cpu');
148 cpuPanel.updateValue(cpu);
149
150 var memPanel = me.lookup('mem');
151 memPanel.updateValue(mem);
152
153 var hdPanel = me.lookup('hd');
154 hdPanel.updateValue(hd);
155 },
156
157 init: function(view) {
158 var me = this;
159 var sp = Ext.state.Manager.getProvider();
160 var hours = sp.get('dashboard-hours') || 12;
161 me.setHours(hours, false);
162 }
163 },
164
165 viewModel: {
166 data: {
167 timespan: 300, // in seconds
168 hours: 12, // in hours
169 'bytes_in': 0,
170 'bytes_out': 0,
171 'avg_ptime': 0.0
172 },
173
174 stores: {
175 cluster: {
176 storeid: 'dash-cluster',
177 type: 'update',
178 interval: 5000,
179 autoStart: true,
180 autoLoad: true,
181 autoDestroy: true,
182 proxy: {
183 extraParams: { list_single_node: 1 },
184 type: 'proxmox',
185 url: '/api2/json/config/cluster/status'
186 },
187 listeners: {
188 load: 'updateClusterStats'
189 }
190 },
191 recentmails: {
192 storeid: 'dash-recent',
193 interval: 5000,
194 type: 'update',
195 autoStart: true,
196 autoLoad: true,
197 autoDestroy: true,
198 proxy: {
199 type: 'proxmox',
200 url: '/api2/json/statistics/recent',
201 extraParams: {
202 hours: '{hours}',
203 timespan: '{timespan}'
204 }
205 },
206 fields: [
207 {
208 type: 'number', name: 'count',
209 convert: PMG.Utils.convert_field_to_per_min
210 },
211 {
212 type: 'number', name: 'count_in',
213 convert: PMG.Utils.convert_field_to_per_min
214 },
215 {
216 type: 'number', name: 'count_out',
217 convert: PMG.Utils.convert_field_to_per_min
218 },
219 {
220 type: 'number', name: 'spam',
221 convert: PMG.Utils.convert_field_to_per_min
222 },
223 {
224 type: 'number', name: 'spam_in',
225 convert: PMG.Utils.convert_field_to_per_min
226 },
227 {
228 type: 'number', name: 'spam_out',
229 convert: PMG.Utils.convert_field_to_per_min
230 },
231 {
232 type: 'number', name: 'virus',
233 convert: PMG.Utils.convert_field_to_per_min
234 },
235 {
236 type: 'number', name: 'virus_in',
237 convert: PMG.Utils.convert_field_to_per_min
238 },
239 { type: 'integer', name: 'virus_out' },
240 { type: 'integer', name: 'bytes_in' },
241 { type: 'integer', name: 'bytes_out' },
242 { type: 'number', name: 'ptimesum' },
243 { type: 'date', dateFormat: 'timestamp', name: 'time' }
244 ],
245 listeners: {
246 load: 'updateMailStats'
247 }
248 },
249 receivers: {
250 storeid: 'dash-receivers',
251 interval: 10000,
252 type: 'update',
253 autoStart: true,
254 autoLoad: true,
255 autoDestroy: true,
256 proxy: {
257 type: 'proxmox',
258 url: '/api2/json/statistics/recentreceivers',
259 extraParams: {
260 hours: '{hours}'
261 }
262 },
263 fields: [
264 { type: 'integer', name: 'count' },
265 { type: 'string', name: 'receiver' }
266 ]
267 }
268 }
269 },
270
271 bind: {
272 title: gettext('Dashboard') + ' (' +
273 Ext.String.format(gettext('{0} hours'), '{hours}') + ')'
274 },
275
276 layout: {
277 type: 'column'
278 },
279 border: false,
280
281 bodyPadding: '20 0 0 20',
282
283 defaults: {
284 columnWidth: 0.5,
285 xtype: 'panel',
286 margin: '0 20 20 0'
287 },
288
289 tools: [
290 {
291 type: 'gear',
292 handler: 'openDashboardOptions'
293 }
294 ],
295
296 scrollable: true,
297
298 items: [
299 {
300 height: 300,
301 flex: 1,
302 iconCls: 'fa fa-tachometer',
303 title: gettext('E-Mail Volume'),
304 layout: {
305 type: 'vbox',
306 align: 'stretch'
307 },
308 defaults: {
309 xtype: 'pmgMiniGraph',
310 bind: {
311 store: '{recentmails}'
312 }
313 },
314 items: [
315 {
316 fields: ['count'],
317 fieldTitles: [ gettext('Mails / min') ],
318 seriesConfig: {
319 colors: [ '#00617F' ],
320 style: {
321 opacity: 0.60,
322 lineWidth: 1
323 },
324 highlightCfg: {
325 opacity: 1,
326 scaling: 1
327 }
328 }
329 },
330 {
331 fields: ['spam'],
332 fieldTitles: [ gettext('Spam / min') ],
333 seriesConfig: {
334 colors: [ '#E67300' ],
335 style: {
336 opacity: 0.60,
337 lineWidth: 1
338 },
339 highlightCfg: {
340 opacity: 1,
341 scaling: 1
342 }
343 }
344 }
345 ]
346 },
347 {
348 xtype: 'container',
349 height: 300,
350 layout: {
351 type: 'vbox',
352 align: 'stretch'
353 },
354 items: [
355 {
356 xtype: 'pmgMailProcessing',
357 title: gettext('E-Mail Processing'),
358 iconCls: 'fa fa-hourglass-half',
359 height: 180,
360 bind: {
361 data: {
362 'bytes_in': '{bytes_in}',
363 'bytes_out': '{bytes_out}',
364 'avg_ptime': '{avg_ptime}'
365 }
366 }
367 },
368 {
369 iconCls: 'fa fa-ticket',
370 title: 'Subscription',
371 reference: 'subscription',
372 xtype: 'pmgSubscriptionInfo',
373 margin: '10 0 0 0',
374 height: 110
375 }
376 ]
377 },
378 {
379 height: 250,
380 iconCls: 'fa fa-tasks',
381 title: gettext('Node Resources'),
382 bodyPadding: '0 20 0 20',
383 layout: {
384 type: 'hbox',
385 align: 'center'
386 },
387 defaults: {
388 xtype: 'proxmoxGauge',
389 spriteFontSize: '20px',
390 flex: 1
391 },
392 items: [
393 {
394 title: gettext('CPU'),
395 reference: 'cpu'
396 },
397 {
398 title: gettext('Memory'),
399 reference: 'mem'
400 },
401 {
402 title: gettext('Storage'),
403 reference: 'hd'
404 }
405 ]
406 },
407 {
408 height: 250,
409 iconCls: 'fa fa-list',
410 title: gettext('Top Receivers'),
411
412 bodyPadding: '20 20 20 20',
413 layout: {
414 type: 'vbox',
415 pack: 'center',
416 align: 'stretch'
417 },
418 items: [{
419 xtype: 'grid',
420 bind: {
421 store: '{receivers}'
422 },
423
424 emptyText: gettext('No data in database'),
425
426 // remove all borders/lines/headers
427 border: false,
428 bodyBorder: false,
429 hideHeaders: true,
430 header: false,
431 columnLines: false,
432 rowLines: false,
433 viewConfig: {
434 stripeRows: false
435 },
436
437 columns: [
438 {
439 dataIndex: 'receiver',
440 flex: 1,
441 text: gettext('Receiver')
442 },
443 {
444 dataIndex: 'count',
445 align: 'right',
446 text: gettext('Count')
447 }
448 ]
449 }]
450 }
451 ]
452 });