]> git.proxmox.com Git - proxmox-backup.git/blob - www/Dashboard.js
ui: some eslint auto-fixes
[proxmox-backup.git] / www / Dashboard.js
1 Ext.define('PBS.Dashboard', {
2 extend: 'Ext.panel.Panel',
3 xtype: 'pbsDashboard',
4
5 controller: {
6 xclass: 'Ext.app.ViewController',
7
8 openDashboardOptions: function() {
9 var me = this;
10 var viewModel = me.getViewModel();
11 Ext.create('Ext.window.Window', {
12 modal: true,
13 width: 300,
14 title: gettext('Dashboard Options'),
15 layout: {
16 type: 'auto',
17 },
18 items: [{
19 xtype: 'form',
20 bodyPadding: '10 10 10 10',
21 defaultButton: 'savebutton',
22 items: [{
23 xtype: 'proxmoxintegerfield',
24 itemId: 'hours',
25 labelWidth: 100,
26 anchor: '100%',
27 allowBlank: false,
28 minValue: 1,
29 maxValue: 24,
30 value: viewModel.get('hours'),
31 fieldLabel: gettext('Hours to show'),
32 }],
33 buttons: [{
34 text: gettext('Save'),
35 reference: 'loginButton',
36 formBind: true,
37 handler: function() {
38 var win = this.up('window');
39 var hours = win.down('#hours').getValue();
40 me.setHours(hours, true);
41 win.close();
42 },
43 }],
44 }],
45 }).show();
46 },
47
48 setHours: function(hours, setState) {
49 var me = this;
50 var viewModel = me.getViewModel();
51 viewModel.set('hours', hours);
52 viewModel.notify();
53
54 if (setState) {
55 var sp = Ext.state.Manager.getProvider();
56 sp.set('dashboard-hours', hours);
57 }
58 },
59
60
61 updateSubscription: function(store, records, success) {
62 if (!success) { return; }
63 let me = this;
64 let subStatus = records[0].data.status === 'Active' ? 2 : 0; // 2 = all good, 1 = different leves, 0 = none
65 me.lookup('subscription').setSubStatus(subStatus);
66 },
67
68 updateUsageStats: function(store, records, success) {
69 if (!success) {
70 return;
71 }
72 if (records === undefined || records.length < 1) {
73 return;
74 }
75 let me = this;
76 let viewmodel = me.getViewModel();
77
78 let res = records[0].data;
79 viewmodel.set('fingerprint', res.info.fingerprint || Proxmox.Utils.unknownText);
80
81 let cpu = res.cpu,
82 mem = res.memory,
83 root = res.root;
84
85 var cpuPanel = me.lookup('cpu');
86 cpuPanel.updateValue(cpu);
87
88 var memPanel = me.lookup('mem');
89 memPanel.updateValue(mem.used / mem.total);
90
91 var hdPanel = me.lookup('root');
92 hdPanel.updateValue(root.used / root.total);
93 },
94
95 showFingerPrint: function() {
96 let me = this;
97 let vm = me.getViewModel();
98 let fingerprint = vm.get('fingerprint');
99 Ext.create('Ext.window.Window', {
100 modal: true,
101 width: 600,
102 title: gettext('Fingerprint'),
103 layout: 'form',
104 bodyPadding: '10 0',
105 items: [
106 {
107 xtype: 'textfield',
108 inputId: 'fingerprintField',
109 value: fingerprint,
110 editable: false,
111 },
112 ],
113 buttons: [
114 {
115 xtype: 'button',
116 iconCls: 'fa fa-clipboard',
117 handler: function(b) {
118 var el = document.getElementById('fingerprintField');
119 el.select();
120 document.execCommand("copy");
121 },
122 text: gettext('Copy'),
123 },
124 {
125 text: gettext('Ok'),
126 handler: function() {
127 this.up('window').close();
128 },
129 },
130 ],
131 }).show();
132 },
133
134 updateTasks: function(store, records, success) {
135 if (!success) return;
136 let me = this;
137
138 records.sort((a, b) => a.data.duration - b.data.duration);
139 let top10 = records.slice(-10);
140 me.lookup('longesttasks').updateTasks(top10);
141
142 let data = {
143 backup: { error: 0, warning: 0, ok: 0 },
144 prune: { error: 0, warning: 0, ok: 0 },
145 garbage_collection: { error: 0, warning: 0, ok: 0 },
146 sync: { error: 0, warning: 0, ok: 0 },
147 };
148
149 records.forEach(record => {
150 let type = record.data.worker_type;
151 if (type === 'syncjob') {
152 type = 'sync';
153 }
154
155 if (data[type] && record.data.status) {
156 let parsed = Proxmox.Utils.parse_task_status(record.data.status);
157 data[type][parsed]++;
158 }
159 });
160
161 me.lookup('tasksummary').updateTasks(data);
162 },
163
164 init: function(view) {
165 var me = this;
166 var sp = Ext.state.Manager.getProvider();
167 var hours = sp.get('dashboard-hours') || 12;
168 me.setHours(hours, false);
169 },
170 },
171
172 viewModel: {
173 data: {
174 timespan: 300, // in seconds
175 hours: 12, // in hours
176 error_shown: false,
177 fingerprint: "",
178 'bytes_in': 0,
179 'bytes_out': 0,
180 'avg_ptime': 0.0,
181 },
182
183 formulas: {
184 disableFPButton: (get) => get('fingerprint') === "",
185 },
186
187 stores: {
188 usage: {
189 storeid: 'dash-usage',
190 type: 'update',
191 interval: 3000,
192 autoStart: true,
193 autoLoad: true,
194 autoDestroy: true,
195 proxy: {
196 type: 'proxmox',
197 url: '/api2/json/nodes/localhost/status',
198 },
199 listeners: {
200 load: 'updateUsageStats',
201 },
202 },
203 subscription: {
204 storeid: 'dash-subscription',
205 type: 'update',
206 interval: 10000,
207 autoStart: true,
208 autoLoad: true,
209 autoDestroy: true,
210 proxy: {
211 type: 'proxmox',
212 url: '/api2/json/nodes/localhost/subscription',
213 },
214 listeners: {
215 load: 'updateSubscription',
216 },
217 },
218 tasks: {
219 storeid: 'dash-tasks',
220 type: 'update',
221 interval: 15000,
222 autoStart: true,
223 autoLoad: true,
224 autoDestroy: true,
225 model: 'proxmox-tasks',
226 proxy: {
227 type: 'proxmox',
228 url: '/api2/json/status/tasks',
229 },
230 listeners: {
231 load: 'updateTasks',
232 },
233 },
234 },
235 },
236
237 title: gettext('Dashboard') + ' - WIP',
238
239 layout: {
240 type: 'column',
241 },
242
243 bodyPadding: '20 0 0 20',
244
245 defaults: {
246 columnWidth: 0.49,
247 xtype: 'panel',
248 margin: '0 20 20 0',
249 },
250
251 scrollable: true,
252
253 items: [
254 {
255 height: 250,
256 iconCls: 'fa fa-tasks',
257 title: gettext('Server Resources'),
258 bodyPadding: '0 20 0 20',
259 tools: [
260 {
261 xtype: 'button',
262 text: gettext('Show Fingerprint'),
263 handler: 'showFingerPrint',
264 bind: {
265 disabled: '{disableFPButton}',
266 },
267 },
268 ],
269 layout: {
270 type: 'hbox',
271 align: 'center',
272 },
273 defaults: {
274 xtype: 'proxmoxGauge',
275 spriteFontSize: '20px',
276 flex: 1,
277 },
278 items: [
279 {
280 title: gettext('CPU'),
281 reference: 'cpu',
282 },
283 {
284 title: gettext('Memory'),
285 reference: 'mem',
286 },
287 {
288 title: gettext('Root Disk'),
289 reference: 'root',
290 },
291 ],
292 },
293 {
294 xtype: 'pbsDatastoresStatistics',
295 height: 250,
296 },
297 {
298 xtype: 'pbsLongestTasks',
299 reference: 'longesttasks',
300 height: 250,
301 },
302 {
303 xtype: 'pbsRunningTasks',
304 height: 250,
305 },
306 {
307 xtype: 'pbsTaskSummary',
308 reference: 'tasksummary',
309 },
310 {
311 iconCls: 'fa fa-ticket',
312 title: 'Subscription',
313 height: 166,
314 reference: 'subscription',
315 xtype: 'pbsSubscriptionInfo',
316 },
317 ],
318 });
319
320 Ext.define('PBS.dashboard.SubscriptionInfo', {
321 extend: 'Ext.panel.Panel',
322 xtype: 'pbsSubscriptionInfo',
323
324 style: {
325 cursor: 'pointer',
326 },
327
328 layout: {
329 type: 'hbox',
330 align: 'middle',
331 },
332
333 items: [
334 {
335 xtype: 'box',
336 itemId: 'icon',
337 data: {
338 icon: 'question-circle',
339 },
340 width: 100,
341 tpl: '<center><i class="fa fa-3x fa-{icon}"></i></center>',
342 },
343 {
344 flex: 1,
345 xtype: 'box',
346 data: {
347 message: gettext('Unknown'),
348 },
349 itemId: 'message',
350 tpl: '<center>{message}</center>',
351 },
352 ],
353
354 setSubStatus: function(status) {
355 var me = this;
356 let icon = '';
357 let message = '';
358
359 switch (status) {
360 case 2:
361 icon = 'check good';
362 message = gettext('Your subscription status is valid.');
363 break;
364 case 1:
365 icon = 'exclamation-triangle warning';
366 message = gettext('Warning: Your subscription levels are not the same.');
367 break;
368 case 0:
369 icon = 'times-circle critical';
370 message = gettext('This node does not have a subscription.');
371 break;
372 default:
373 throw 'invalid subscription status';
374 }
375 me.getComponent('icon').update({ icon });
376 me.getComponent('message').update({ message });
377 },
378
379 listeners: {
380 click: {
381 element: 'body',
382 fn: function() {
383 var mainview = this.component.up('mainview');
384 mainview.getController().redirectTo('pbsSubscription');
385 },
386 },
387 },
388 });