]> git.proxmox.com Git - pmg-gui.git/blame - js/Dashboard.js
quarantine action: use shadow for toast "window"
[pmg-gui.git] / js / Dashboard.js
CommitLineData
ff735274 1/*global Proxmox*/
de0ebd99
DC
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 */
5936e3ef
DC
9Ext.define('PMG.Dashboard', {
10 extend: 'Ext.panel.Panel',
11 xtype: 'pmgDashboard',
12
b047eec0
DC
13 controller: {
14 xclass: 'Ext.app.ViewController',
5936e3ef 15
b047eec0
DC
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',
de0ebd99 28 bodyPadding: '10 10 10 10',
b047eec0
DC
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 }]
771bd0b9 52 }]
b047eec0
DC
53 }).show();
54 },
5936e3ef 55
b047eec0
DC
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) {
86109d3a 63 viewModel.getStore(item).reload();
b047eec0
DC
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;
b6248f6e 83 var avg_ptime = 'N/A';
b047eec0
DC
84
85 records.forEach(function(item) {
86 bytes_in += item.data.bytes_in;
87 bytes_out += item.data.bytes_out;
b79fbba8
DC
88 // unnormalize
89 count += (item.data.count*item.data.timespan)/60;
b047eec0
DC
90 ptime += item.data.ptimesum;
91 });
92
93 if (count) {
b6248f6e 94 avg_ptime = (ptime/count).toFixed(2) + " s";
b047eec0
DC
95 }
96
97 viewModel.set('bytes_in', Proxmox.Utils.format_size(bytes_in));
98 viewModel.set('bytes_out', Proxmox.Utils.format_size(bytes_out));
b6248f6e 99 viewModel.set('avg_ptime', avg_ptime);
b047eec0
DC
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;
bb7ab2ba 116 var errors = [];
b047eec0
DC
117
118 records.forEach(function(item) {
119 // subscription level check
120 if (subStatus && item.data.level) {
121 if (subLevel !== "" && subLevel !== item.data.level) {
122 subStatus = 1;
123 } else if (subLevel === "") {
124 subLevel = item.data.level;
125 }
126 } else {
127 subStatus = 0;
128 }
129
130 // resources count
91c74e81
DC
131 cpu += item.data.cpu || 0;
132
133 var memory = item.data.memory || { used: 0, total: 1 };
134 mem += (memory.used/memory.total);
135
136 var rootfs = item.data.rootfs || { used: 0, total: 1 };
137 hd += (rootfs.used/rootfs.total);
138
bb7ab2ba
DC
139 if (item.data.conn_error && count > 1) {
140 count--;
141 errors.push({
142 name: item.data.name,
143 msg: item.data.conn_error
144 });
145 }
b047eec0
DC
146 });
147
148 var subscriptionPanel = me.lookup('subscription');
149 subscriptionPanel.setSubStatus(subStatus);
150
151 cpu = cpu/count;
152 mem = mem/count;
153 hd = hd/count;
154
155 var cpuPanel = me.lookup('cpu');
156 cpuPanel.updateValue(cpu);
157
131ba4f6 158 var memPanel = me.lookup('mem');
b047eec0
DC
159 memPanel.updateValue(mem);
160
131ba4f6 161 var hdPanel = me.lookup('hd');
b047eec0 162 hdPanel.updateValue(hd);
bb7ab2ba
DC
163
164 if (errors.length && !viewmodel.get('error_shown')) {
165 var text = "";
166 errors.forEach(function(error) {
167 text += error.name + ':<br>' + error.msg + '<br>';
168 });
169 Ext.Msg.alert(gettext('Error'), text);
170 viewmodel.set('error_shown', true);
171 }
b047eec0
DC
172 },
173
174 init: function(view) {
175 var me = this;
176 var sp = Ext.state.Manager.getProvider();
177 var hours = sp.get('dashboard-hours') || 12;
178 me.setHours(hours, false);
179 }
180 },
181
182 viewModel: {
183 data: {
184 timespan: 300, // in seconds
185 hours: 12, // in hours
bb7ab2ba 186 error_shown: false,
b047eec0
DC
187 'bytes_in': 0,
188 'bytes_out': 0,
771bd0b9 189 'avg_ptime': 0.0
b047eec0
DC
190 },
191
192 stores: {
193 cluster: {
194 storeid: 'dash-cluster',
195 type: 'update',
196 interval: 5000,
197 autoStart: true,
b047eec0
DC
198 autoDestroy: true,
199 proxy: {
929f40ff 200 extraParams: { list_single_node: 1 },
b047eec0
DC
201 type: 'proxmox',
202 url: '/api2/json/config/cluster/status'
203 },
204 listeners: {
205 load: 'updateClusterStats'
206 }
207 },
208 recentmails: {
209 storeid: 'dash-recent',
210 interval: 5000,
211 type: 'update',
212 autoStart: true,
b047eec0
DC
213 autoDestroy: true,
214 proxy: {
215 type: 'proxmox',
216 url: '/api2/json/statistics/recent',
217 extraParams: {
218 hours: '{hours}',
219 timespan: '{timespan}'
220 }
221 },
222 fields: [
b79fbba8
DC
223 {
224 type: 'number', name: 'count',
225 convert: PMG.Utils.convert_field_to_per_min
226 },
227 {
228 type: 'number', name: 'count_in',
229 convert: PMG.Utils.convert_field_to_per_min
230 },
231 {
232 type: 'number', name: 'count_out',
233 convert: PMG.Utils.convert_field_to_per_min
234 },
235 {
236 type: 'number', name: 'spam',
237 convert: PMG.Utils.convert_field_to_per_min
238 },
239 {
240 type: 'number', name: 'spam_in',
241 convert: PMG.Utils.convert_field_to_per_min
242 },
243 {
244 type: 'number', name: 'spam_out',
245 convert: PMG.Utils.convert_field_to_per_min
246 },
247 {
248 type: 'number', name: 'virus',
249 convert: PMG.Utils.convert_field_to_per_min
250 },
251 {
252 type: 'number', name: 'virus_in',
253 convert: PMG.Utils.convert_field_to_per_min
254 },
b047eec0
DC
255 { type: 'integer', name: 'virus_out' },
256 { type: 'integer', name: 'bytes_in' },
257 { type: 'integer', name: 'bytes_out' },
258 { type: 'number', name: 'ptimesum' },
259 { type: 'date', dateFormat: 'timestamp', name: 'time' }
260 ],
261 listeners: {
262 load: 'updateMailStats'
263 }
264 },
265 receivers: {
266 storeid: 'dash-receivers',
267 interval: 10000,
268 type: 'update',
269 autoStart: true,
b047eec0
DC
270 autoDestroy: true,
271 proxy: {
272 type: 'proxmox',
273 url: '/api2/json/statistics/recentreceivers',
274 extraParams: {
771bd0b9 275 hours: '{hours}'
b047eec0
DC
276 }
277 },
278 fields: [
279 { type: 'integer', name: 'count' },
280 { type: 'string', name: 'receiver' }
281 ]
282 }
283 }
284 },
285
286 bind: {
287 title: gettext('Dashboard') + ' (' +
288 Ext.String.format(gettext('{0} hours'), '{hours}') + ')'
289 },
290
de0ebd99
DC
291 layout: {
292 type: 'column'
293 },
b047eec0
DC
294 border: false,
295
296 bodyPadding: '20 0 0 20',
297
298 defaults: {
299 columnWidth: 0.5,
300 xtype: 'panel',
301 margin: '0 20 20 0'
302 },
303
304 tools: [
305 {
306 type: 'gear',
307 handler: 'openDashboardOptions'
308 }
309 ],
310
311 scrollable: true,
312
313 items: [
314 {
315 height: 300,
316 flex: 1,
317 iconCls: 'fa fa-tachometer',
318 title: gettext('E-Mail Volume'),
319 layout: {
320 type: 'vbox',
771bd0b9 321 align: 'stretch'
b047eec0
DC
322 },
323 defaults: {
324 xtype: 'pmgMiniGraph',
325 bind: {
326 store: '{recentmails}'
327 }
328 },
329 items: [
330 {
331 fields: ['count'],
b79fbba8 332 fieldTitles: [ gettext('Mails / min') ],
b047eec0
DC
333 seriesConfig: {
334 colors: [ '#00617F' ],
335 style: {
336 opacity: 0.60,
337 lineWidth: 1
338 },
339 highlightCfg: {
340 opacity: 1,
341 scaling: 1
771bd0b9
DC
342 }
343 }
b047eec0
DC
344 },
345 {
346 fields: ['spam'],
b79fbba8 347 fieldTitles: [ gettext('Spam / min') ],
b047eec0
DC
348 seriesConfig: {
349 colors: [ '#E67300' ],
350 style: {
351 opacity: 0.60,
352 lineWidth: 1
353 },
354 highlightCfg: {
355 opacity: 1,
356 scaling: 1
771bd0b9
DC
357 }
358 }
359 }
b047eec0
DC
360 ]
361 },
362 {
363 xtype: 'container',
364 height: 300,
365 layout: {
366 type: 'vbox',
771bd0b9 367 align: 'stretch'
b047eec0
DC
368 },
369 items: [
370 {
371 xtype: 'pmgMailProcessing',
372 title: gettext('E-Mail Processing'),
373 iconCls: 'fa fa-hourglass-half',
374 height: 180,
375 bind: {
376 data: {
7b18f75e
DC
377 'bytes_in': '{bytes_in}',
378 'bytes_out': '{bytes_out}',
379 'avg_ptime': '{avg_ptime}'
b047eec0 380 }
771bd0b9 381 }
b047eec0
DC
382 },
383 {
384 iconCls: 'fa fa-ticket',
385 title: 'Subscription',
386 reference: 'subscription',
387 xtype: 'pmgSubscriptionInfo',
388 margin: '10 0 0 0',
771bd0b9 389 height: 110
b047eec0
DC
390 }
391 ]
392 },
393 {
394 height: 250,
395 iconCls: 'fa fa-tasks',
64fb657f 396 title: gettext('Node Resources'),
b047eec0
DC
397 bodyPadding: '0 20 0 20',
398 layout: {
399 type: 'hbox',
400 align: 'center'
401 },
402 defaults: {
403 xtype: 'proxmoxGauge',
404 spriteFontSize: '20px',
405 flex: 1
406 },
407 items: [
408 {
409 title: gettext('CPU'),
410 reference: 'cpu'
411 },
412 {
413 title: gettext('Memory'),
414 reference: 'mem'
415 },
416 {
417 title: gettext('Storage'),
418 reference: 'hd'
419 }
420 ]
421 },
422 {
423 height: 250,
424 iconCls: 'fa fa-list',
425 title: gettext('Top Receivers'),
426
de0ebd99 427 bodyPadding: '20 20 20 20',
b047eec0
DC
428 layout: {
429 type: 'vbox',
430 pack: 'center',
431 align: 'stretch'
432 },
433 items: [{
434 xtype: 'grid',
435 bind: {
436 store: '{receivers}'
437 },
438
439 emptyText: gettext('No data in database'),
440
441 // remove all borders/lines/headers
442 border: false,
443 bodyBorder: false,
444 hideHeaders: true,
445 header: false,
446 columnLines: false,
447 rowLines: false,
448 viewConfig: {
771bd0b9 449 stripeRows: false
b047eec0
DC
450 },
451
452 columns: [
453 {
454 dataIndex: 'receiver',
455 flex: 1,
456 text: gettext('Receiver')
457 },
458 {
459 dataIndex: 'count',
460 align: 'right',
461 text: gettext('Count')
462 }
463 ]
464 }]
465 }
466 ]
5936e3ef 467});