]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/node/Tasks.js
1 Ext
.define('Proxmox.node.Tasks', {
2 extend
: 'Ext.grid.GridPanel',
4 alias
: 'widget.proxmoxNodeTasks',
7 stateId
: 'pve-grid-node-tasks',
10 sortableColumns
: false,
12 // set extra filter components, must have a 'name' property for the parameter, and must
13 // trigger a 'change' event if the value is 'undefined', it will not be sent to the api
17 // fixed filters which cannot be changed after instantiation, for example:
22 xclass
: 'Ext.app.ViewController',
24 showTaskLog: function() {
26 let selection
= me
.getView().getSelection();
27 if (selection
.length
< 1) {
31 let rec
= selection
[0];
33 Ext
.create('Proxmox.window.TaskViewer', {
35 endtime
: rec
.data
.endtime
,
39 updateLayout: function(store
, records
, success
, operation
) {
41 let view
= me
.getView().getView(); // the table view, not the whole grid
42 Proxmox
.Utils
.setErrorMask(view
, false);
43 // update the scrollbar on every store load since the total count might be different.
44 // the buffered grid plugin does this only on (user) scrolling itself and even reduces
45 // the scrollheight again when scrolling up
46 me
.getView().updateLayout();
49 Proxmox
.Utils
.setErrorMask(view
, Proxmox
.Utils
.getResponseErrorMessage(operation
.getError()));
55 let view
= me
.getView();
57 let selection
= view
.getSelection();
58 let store
= me
.getViewModel().get('bufferedstore');
59 if (selection
&& selection
.length
> 0) {
60 // deselect if selection is not there anymore
61 if (!store
.contains(selection
[0])) {
62 view
.setSelection(undefined);
67 sinceChange: function(field
, newval
) {
69 let vm
= me
.getViewModel();
71 vm
.set('since', newval
);
74 untilChange: function(field
, newval
, oldval
) {
76 let vm
= me
.getViewModel();
78 vm
.set('until', newval
);
83 let view
= me
.getView();
84 view
.getStore().load();
87 showFilter: function(btn
, pressed
) {
89 let vm
= me
.getViewModel();
90 vm
.set('showFilter', pressed
);
93 clearFilter: function() {
95 me
.lookup('filtertoolbar').query('field').forEach((field
) => {
96 field
.setValue(undefined);
102 itemdblclick
: 'showTaskLog',
116 filterIcon
: (get) => 'fa fa-filter' + (get('showFilter') ? ' info-blue' : ''),
117 extraParams: function(get) {
120 if (get('typefilter')) {
121 params
.typefilter
= get('typefilter');
123 if (get('statusfilter')) {
124 params
.statusfilter
= get('statusfilter');
127 if (get('extraFilter')) {
128 let extraFilter
= get('extraFilter');
129 for (const [name
, value
] of Object
.entries(extraFilter
)) {
130 if (value
!== undefined && value
!== null && value
!== "") {
131 params
[name
] = value
;
137 params
.since
= get('since').valueOf()/1000;
141 let until
= new Date(get('until').getTime()); // copy object
142 until
.setDate(until
.getDate() + 1); // end of the day
143 params
.until
= until
.valueOf()/1000;
146 me
.getView().getStore().load();
150 filterCount: function(get) {
152 if (get('typefilter')) {
155 let status
= get('statusfilter');
156 if ((Ext
.isArray(status
) && status
.length
> 0) ||
157 (!Ext
.isArray(status
) && status
)) {
167 if (get('extraFilter')) {
168 let preFilter
= get('preFilter') || {};
169 let extraFilter
= get('extraFilter');
170 for (const [name
, value
] of Object
.entries(extraFilter
)) {
171 if (value
!== undefined && value
!== null && value
!== "" &&
172 preFilter
[name
] === undefined
181 clearFilterText: function(get) {
182 let count
= get('filterCount');
185 fieldMsg
= ` (${count} ${gettext('Fields')})`;
186 } else if (count
> 0) {
187 fieldMsg
= ` (1 ${gettext('Field')})`;
189 return gettext('Clear Filter') + fieldMsg
;
199 model
: 'proxmox-tasks',
204 extraParams
: '{extraParams}',
208 prefetch
: 'updateLayout',
216 store
: '{bufferedstore}',
224 xtype
: 'proxmoxButton',
225 text
: gettext('View'),
226 iconCls
: 'fa fa-window-restore',
228 handler
: 'showTaskLog',
232 text
: gettext('Reload'),
233 iconCls
: 'fa fa-refresh',
240 text
: '{clearFilterText}',
241 disabled
: '{!filterCount}',
243 text
: gettext('Clear Filter'),
245 handler
: 'clearFilter',
251 iconCls
: '{filterIcon}',
253 text
: gettext('Filter'),
255 stateId
: 'task-showfilter',
256 stateEvents
: ['toggle'],
257 applyState: function(state
) {
258 if (state
.pressed
!== undefined) {
259 this.setPressed(state
.pressed
);
262 getState: function() {
264 pressed
: this.pressed
,
268 toggle
: 'showFilter',
276 reference
: 'filtertoolbar',
282 hidden
: '{!showFilter}',
295 // cannot bind the values directly, as it then changes also
296 // on blur, causing wrong reloads of the store
300 fieldLabel
: gettext('Since'),
306 change
: 'sinceChange',
311 fieldLabel
: gettext('Until'),
317 change
: 'untilChange',
334 xtype
: 'pmxTaskTypeSelector',
335 fieldLabel
: gettext('Task Type'),
336 emptyText
: gettext('All'),
338 value
: '{typefilter}',
343 fieldLabel
: gettext('Task Result'),
344 emptyText
: gettext('All'),
347 ['ok', gettext('OK')],
348 ['unknown', Proxmox
.Utils
.unknownText
],
349 ['warning', gettext('Warnings')],
350 ['error', gettext('Errors')],
353 value
: '{statusfilter}',
364 stripeRows
: false, // does not work with getRowClass()
365 emptyText
: gettext('No Tasks found'),
367 getRowClass: function(record
, index
) {
368 let status
= record
.get('status');
371 let parsed
= Proxmox
.Utils
.parse_task_status(status
);
372 if (parsed
=== 'error') {
373 return "proxmox-invalid-row";
374 } else if (parsed
=== 'warning') {
375 return "proxmox-warning-row";
384 header
: gettext("Start Time"),
385 dataIndex
: 'starttime',
387 renderer: function(value
) {
388 return Ext
.Date
.format(value
, "M d H:i:s");
392 header
: gettext("End Time"),
393 dataIndex
: 'endtime',
395 renderer: function(value
, metaData
, record
) {
397 metaData
.tdCls
= "x-grid-row-loading";
400 return Ext
.Date
.format(value
, "M d H:i:s");
404 header
: gettext("Duration"),
407 renderer: function(value
, metaData
, record
) {
408 let start
= record
.data
.starttime
;
410 let end
= record
.data
.endtime
|| Date
.now();
411 let duration
= end
- start
;
415 return Proxmox
.Utils
.format_duration_human(duration
);
417 return Proxmox
.Utils
.unknownText
;
421 header
: gettext("User name"),
426 header
: gettext("Description"),
429 renderer
: Proxmox
.Utils
.render_upid
,
432 header
: gettext("Status"),
435 renderer: function(value
, metaData
, record
) {
436 if (value
=== undefined && !record
.data
.endtime
) {
437 metaData
.tdCls
= "x-grid-row-loading";
441 return Proxmox
.Utils
.format_task_status(value
);
446 initComponent: function() {
449 let nodename
= me
.nodename
|| 'localhost';
450 let url
= me
.url
|| `/api2/json/nodes/${nodename}/tasks`;
451 me
.getViewModel().set('url', url
);
453 let updateExtraFilters = function(name
, value
) {
454 let vm
= me
.getViewModel();
455 let extraFilter
= Ext
.clone(vm
.get('extraFilter'));
456 extraFilter
[name
] = value
;
457 vm
.set('extraFilter', extraFilter
);
460 for (const [name
, value
] of Object
.entries(me
.preFilter
)) {
461 updateExtraFilters(name
, value
);
464 me
.getViewModel().set('preFilter', me
.preFilter
);
468 let addFields = function(items
) {
469 me
.lookup('filtertoolbar').add({
483 // start with a userfilter
487 fieldLabel
: gettext('User name'),
496 for (const filterTemplate
of me
.extraFilter
) {
497 let filter
= Ext
.clone(filterTemplate
);
499 filter
.listeners
= filter
.listeners
|| {};
500 filter
.listeners
.change
= Ext
.apply(filter
.changeOptions
|| {}, {
501 fn: function(field
, value
) {
502 updateExtraFilters(filter
.name
, value
);
507 if (items
.length
=== 2) {