]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/TaskViewer.js
tasks: include API token ID if available
[proxmox-widget-toolkit.git] / src / window / TaskViewer.js
1 Ext.define('Proxmox.window.TaskProgress', {
2 extend: 'Ext.window.Window',
3 alias: 'widget.proxmoxTaskProgress',
4
5 taskDone: Ext.emptyFn,
6
7 initComponent: function() {
8 let me = this;
9
10 if (!me.upid) {
11 throw "no task specified";
12 }
13
14 let task = Proxmox.Utils.parse_task_upid(me.upid);
15
16 let statstore = Ext.create('Proxmox.data.ObjectStore', {
17 url: "/api2/json/nodes/" + task.node + "/tasks/" + me.upid + "/status",
18 interval: 1000,
19 rows: {
20 status: { defaultValue: 'unknown' },
21 exitstatus: { defaultValue: 'unknown' },
22 },
23 });
24
25 me.on('destroy', statstore.stopUpdate);
26
27 let getObjectValue = function(key, defaultValue) {
28 let rec = statstore.getById(key);
29 if (rec) {
30 return rec.data.value;
31 }
32 return defaultValue;
33 };
34
35 let pbar = Ext.create('Ext.ProgressBar', { text: 'running...' });
36
37 me.mon(statstore, 'load', function() {
38 let status = getObjectValue('status');
39 if (status === 'stopped') {
40 let exitstatus = getObjectValue('exitstatus');
41 if (exitstatus === 'OK') {
42 pbar.reset();
43 pbar.updateText("Done!");
44 Ext.Function.defer(me.close, 1000, me);
45 } else {
46 me.close();
47 Ext.Msg.alert('Task failed', exitstatus);
48 }
49 me.taskDone(exitstatus === 'OK');
50 }
51 });
52
53 let descr = Proxmox.Utils.format_task_description(task.type, task.id);
54
55 Ext.apply(me, {
56 title: gettext('Task') + ': ' + descr,
57 width: 300,
58 layout: 'auto',
59 modal: true,
60 bodyPadding: 5,
61 items: pbar,
62 buttons: [
63 {
64 text: gettext('Details'),
65 handler: function() {
66 let win = Ext.create('Proxmox.window.TaskViewer', {
67 taskDone: me.taskDone,
68 upid: me.upid,
69 });
70 win.show();
71 me.close();
72 },
73 },
74 ],
75 });
76
77 me.callParent();
78
79 statstore.startUpdate();
80
81 pbar.wait();
82 },
83 });
84
85 // fixme: how can we avoid those lint errors?
86
87 Ext.define('Proxmox.window.TaskViewer', {
88 extend: 'Ext.window.Window',
89 alias: 'widget.proxmoxTaskViewer',
90
91 extraTitle: '', // string to prepend after the generic task title
92
93 taskDone: Ext.emptyFn,
94
95 initComponent: function() {
96 let me = this;
97
98 if (!me.upid) {
99 throw "no task specified";
100 }
101
102 let task = Proxmox.Utils.parse_task_upid(me.upid);
103
104 let statgrid;
105
106 let rows = {
107 status: {
108 header: gettext('Status'),
109 defaultValue: 'unknown',
110 renderer: function(value) {
111 if (value !== 'stopped') {
112 return value;
113 }
114 let es = statgrid.getObjectValue('exitstatus');
115 if (es) {
116 return value + ': ' + es;
117 }
118 return 'unknown';
119 },
120 },
121 exitstatus: {
122 visible: false,
123 },
124 type: {
125 header: gettext('Task type'),
126 required: true,
127 },
128 user: {
129 header: gettext('User name'),
130 renderer: Ext.String.htmlEncode,
131 required: true,
132 },
133 tokenid: {
134 header: gettext('API Token'),
135 renderer: Ext.String.htmlEncode,
136 },
137 node: {
138 header: gettext('Node'),
139 required: true,
140 },
141 pid: {
142 header: gettext('Process ID'),
143 required: true,
144 },
145 task_id: {
146 header: gettext('Task ID'),
147 },
148 starttime: {
149 header: gettext('Start Time'),
150 required: true,
151 renderer: Proxmox.Utils.render_timestamp,
152 },
153 upid: {
154 header: gettext('Unique task ID'),
155 renderer: Ext.String.htmlEncode,
156 },
157 };
158
159 if (me.endtime) {
160 if (typeof me.endtime === 'object') {
161 // convert to epoch
162 me.endtime = parseInt(me.endtime.getTime()/1000, 10);
163 }
164 rows.endtime = {
165 header: gettext('End Time'),
166 required: true,
167 renderer: function() {
168 return Proxmox.Utils.render_timestamp(me.endtime);
169 },
170 };
171 }
172
173 rows.duration = {
174 header: gettext('Duration'),
175 required: true,
176 renderer: function() {
177 let starttime = statgrid.getObjectValue('starttime');
178 let endtime = me.endtime || Date.now()/1000;
179 let duration = endtime - starttime;
180 return Proxmox.Utils.format_duration_human(duration);
181 },
182 };
183
184 let statstore = Ext.create('Proxmox.data.ObjectStore', {
185 url: "/api2/json/nodes/" + task.node + "/tasks/" + me.upid + "/status",
186 interval: 1000,
187 rows: rows,
188 });
189
190 me.on('destroy', statstore.stopUpdate);
191
192 let stop_task = function() {
193 Proxmox.Utils.API2Request({
194 url: "/nodes/" + task.node + "/tasks/" + me.upid,
195 waitMsgTarget: me,
196 method: 'DELETE',
197 failure: function(response, opts) {
198 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
199 },
200 });
201 };
202
203 let stop_btn1 = new Ext.Button({
204 text: gettext('Stop'),
205 disabled: true,
206 handler: stop_task,
207 });
208
209 let stop_btn2 = new Ext.Button({
210 text: gettext('Stop'),
211 disabled: true,
212 handler: stop_task,
213 });
214
215 statgrid = Ext.create('Proxmox.grid.ObjectGrid', {
216 title: gettext('Status'),
217 layout: 'fit',
218 tbar: [stop_btn1],
219 rstore: statstore,
220 rows: rows,
221 border: false,
222 });
223
224 let logView = Ext.create('Proxmox.panel.LogView', {
225 title: gettext('Output'),
226 tbar: [stop_btn2],
227 border: false,
228 url: "/api2/extjs/nodes/" + task.node + "/tasks/" + me.upid + "/log",
229 });
230
231 me.mon(statstore, 'load', function() {
232 let status = statgrid.getObjectValue('status');
233
234 if (status === 'stopped') {
235 logView.scrollToEnd = false;
236 logView.requestUpdate();
237 statstore.stopUpdate();
238 me.taskDone(statgrid.getObjectValue('exitstatus') === 'OK');
239 }
240
241 stop_btn1.setDisabled(status !== 'running');
242 stop_btn2.setDisabled(status !== 'running');
243 });
244
245 statstore.startUpdate();
246
247 Ext.apply(me, {
248 title: "Task viewer: " + task.desc + me.extraTitle,
249 width: 800,
250 height: 400,
251 layout: 'fit',
252 modal: true,
253 items: [{
254 xtype: 'tabpanel',
255 region: 'center',
256 items: [logView, statgrid],
257 }],
258 });
259
260 me.callParent();
261
262 logView.fireEvent('show', logView);
263 },
264 });
265