]> git.proxmox.com Git - proxmox-backup.git/blame - www/dashboard/TaskSummary.js
update to rrd-api-types 1.0.2
[proxmox-backup.git] / www / dashboard / TaskSummary.js
CommitLineData
6f3146c0
DC
1Ext.define('PBS.TaskSummary', {
2 extend: 'Ext.panel.Panel',
3 alias: 'widget.pbsTaskSummary',
4
ad9d1625 5 title: gettext('Task Summary'),
6f3146c0 6
4623cd64
DC
7 states: [
8 "",
9 "error",
10 "warning",
11 "ok",
12 ],
13
14 types: [
15 "backup",
16 "prune",
17 "garbage_collection",
18 "sync",
19 "verify",
0763ac14
DC
20 "tape-backup",
21 "tape-restore",
4623cd64
DC
22 ],
23
d64c4eea
DC
24 typeFilterMap: {
25 'verify': 'verif', // some verify task start with 'verification''
26 },
27
4623cd64
DC
28 titles: {
29 "backup": gettext('Backups'),
30 "prune": gettext('Prunes'),
31 "garbage_collection": gettext('Garbage collections'),
32 "sync": gettext('Syncs'),
33 "verify": gettext('Verify'),
0763ac14
DC
34 "tape-backup": gettext('Tape Backup'),
35 "tape-restore": gettext('Tape Restore'),
4623cd64
DC
36 },
37
a3cdb19e
DC
38 // set true to show the onclick panel as modal grid
39 subPanelModal: false,
40
41 // the datastore the onclick panel is filtered by
42 datastore: undefined,
43
6f3146c0
DC
44 controller: {
45 xclass: 'Ext.app.ViewController',
46
dee74aa4
DC
47
48 openTaskList: function(grid, td, cellindex, record, tr, rowindex) {
49 let me = this;
50 let view = me.getView();
51
52 if (cellindex > 0) {
53 let tasklist = view.tasklist;
4623cd64
DC
54 let state = view.states[cellindex];
55 let type = view.types[rowindex];
d64c4eea
DC
56 let typefilter = type;
57 if (view.typeFilterMap[type] !== undefined) {
58 typefilter = view.typeFilterMap[type];
59 }
60
dee74aa4 61 let filterParam = {
a2a7dd15 62 limit: 0,
dee74aa4 63 'statusfilter': state,
d64c4eea 64 'typefilter': typefilter,
dee74aa4
DC
65 };
66
67 if (me.since) {
68 filterParam.since = me.since;
69 }
70
a3cdb19e
DC
71 if (view.datastore) {
72 filterParam.store = view.datastore;
73 }
74
63c07d95 75 if (record.data[state] === 0 || record.data[state] === undefined) {
dee74aa4
DC
76 return;
77 }
78
79 if (tasklist === undefined) {
80 tasklist = Ext.create('Ext.grid.Panel', {
81 tools: [{
4c00391d 82 type: 'close',
dee74aa4
DC
83 handler: () => tasklist.setVisible(false),
84 }],
85 floating: true,
86 scrollable: true,
87
88 height: 400,
89 width: 600,
90
91 columns: [
92 {
93 text: gettext('Task'),
94 dataIndex: 'upid',
95 renderer: Proxmox.Utils.render_upid,
96 flex: 1,
97 },
98 {
99 header: gettext("Start Time"),
100 dataIndex: 'starttime',
101 width: 130,
102 renderer: function(value) {
103 return Ext.Date.format(value, "M d H:i:s");
104 },
105 },
106 {
107 xtype: 'actioncolumn',
108 width: 40,
109 items: [
110 {
111 iconCls: 'fa fa-chevron-right',
112 tooltip: gettext('Open Task'),
113 handler: function(g, rowIndex) {
114 let rec = tasklist.getStore().getAt(rowIndex);
115 tasklist.setVisible(false);
116 Ext.create('Proxmox.window.TaskViewer', {
117 upid: rec.data.upid,
118 endtime: rec.data.endtime,
119 listeners: {
120 close: () => tasklist.setVisible(true),
121 },
122 }).show();
123 },
124 },
125 ],
126 },
127 ],
128
129 store: {
130 sorters: [
131 {
132 property: 'starttime',
133 direction: 'DESC',
134 },
135 ],
136 type: 'store',
137 model: 'proxmox-tasks',
138 proxy: {
139 type: 'proxmox',
a2a7dd15 140 url: "/api2/json/nodes/localhost/tasks",
dee74aa4
DC
141 },
142 },
143 });
144
145 view.on('destroy', function() {
146 tasklist.setVisible(false);
147 tasklist.destroy();
148 tasklist = undefined;
149 });
150
151 view.tasklist = tasklist;
152 } else {
153 let cidx = tasklist.cidx;
154 let ridx = tasklist.ridx;
155
156 if (cidx === cellindex && ridx === rowindex && tasklist.isVisible()) {
157 tasklist.setVisible(false);
158 return;
159 }
160 }
161
162 tasklist.cidx = cellindex;
163 tasklist.ridx = rowindex;
164
4623cd64 165 let task = view.titles[type];
dee74aa4
DC
166 let status = "";
167 switch (state) {
168 case 'ok': status = gettext("OK"); break;
169 case 'warnings': status = gettext("Warning"); break;
170 case 'error': status = Proxmox.Utils.errorText; break;
171 }
172 let icon = me.render_icon(state, 1);
173 tasklist.setTitle(`${task} - ${status} ${icon}`);
174 tasklist.getStore().getProxy().setExtraParams(filterParam);
175 tasklist.getStore().removeAll();
176
a3cdb19e
DC
177 if (view.subPanelModal) {
178 tasklist.modal = true;
179 tasklist.showBy(Ext.getBody(), 'c-c');
180 } else {
181 tasklist.modal = false;
182 tasklist.showBy(td, 'bl-tl');
183 }
dee74aa4
DC
184 setTimeout(() => tasklist.getStore().reload(), 10);
185 }
9608ac34
DC
186 },
187
90d7425a 188 render_icon: function(state, count) {
6f3146c0 189 let cls = 'question';
be30e7d2 190 let color = 'faded';
90d7425a
DC
191 switch (state) {
192 case "error":
be30e7d2
DC
193 cls = "times-circle";
194 color = "critical";
195 break;
90d7425a 196 case "warning":
be30e7d2
DC
197 cls = "exclamation-circle";
198 color = "warning";
199 break;
90d7425a 200 case "ok":
be30e7d2
DC
201 cls = "check-circle";
202 color = "good";
203 break;
6f3146c0
DC
204 default: break;
205 }
be30e7d2 206
90d7425a 207 if (count < 1) {
be30e7d2
DC
208 color = "faded";
209 }
210 cls += " " + color;
90d7425a
DC
211 return `<i class="fa fa-${cls}"></i>`;
212 },
213
214 render_count: function(value, md, record, rowindex, colindex) {
215 let me = this;
4623cd64 216 let view = me.getView();
d9503950
TL
217 let count = value || 0;
218 if (count > 0) {
219 md.tdCls = 'pointer';
220 }
221 let icon = me.render_icon(view.states[colindex], count);
63c07d95 222 return `${icon} ${value || 0}`;
6f3146c0
DC
223 },
224 },
225
dee74aa4 226 updateTasks: function(source, since) {
6f3146c0 227 let me = this;
9608ac34
DC
228 let controller = me.getController();
229 let data = [];
63c07d95
DC
230 if (!source) {
231 source = {};
232 }
4623cd64 233 me.types.forEach((type) => {
63c07d95
DC
234 if (!source[type]) {
235 source[type] = {
236 error: 0,
237 warning: 0,
238 ok: 0,
239 };
240 }
4623cd64 241 source[type].type = me.titles[type];
9608ac34
DC
242 data.push(source[type]);
243 });
244 me.lookup('grid').getStore().setData(data);
dee74aa4 245 controller.since = since;
6f3146c0
DC
246 },
247
248 layout: 'fit',
249 bodyPadding: 15,
250 minHeight: 166,
251
252 // we have to wrap the grid in a panel to get the padding right
253 items: [
254 {
255 xtype: 'grid',
256 reference: 'grid',
257 hideHeaders: true,
258 border: false,
259 bodyBorder: false,
260 rowLines: false,
261 viewConfig: {
262 stripeRows: false,
625c7bfc 263 trackOver: true,
6f3146c0
DC
264 },
265 scrollable: false,
266 disableSelection: true,
267
268 store: {
6ab77df3 269 data: [],
6f3146c0
DC
270 },
271
dee74aa4
DC
272 listeners: {
273 cellclick: 'openTaskList',
274 },
275
6f3146c0
DC
276 columns: [
277 {
278 dataIndex: 'type',
279 flex: 1,
280 },
281 {
282 dataIndex: 'error',
283 renderer: 'render_count',
284 },
285 {
286 dataIndex: 'warning',
287 renderer: 'render_count',
288 },
289 {
290 dataIndex: 'ok',
291 renderer: 'render_count',
292 },
293 ],
6ab77df3 294 },
6f3146c0
DC
295 ],
296
297});