proxmox-backup/www/panel/Tasks.js

387 lines
7.7 KiB
JavaScript

Ext.define('PBS.node.Tasks', {
extend: 'Ext.grid.GridPanel',
alias: 'widget.pbsNodeTasks',
stateful: true,
stateId: 'pbs-grid-node-tasks',
loadMask: true,
sortableColumns: false,
controller: {
xclass: 'Ext.app.ViewController',
showTaskLog: function() {
let me = this;
let selection = me.getView().getSelection();
if (selection.length < 1) {
return;
}
let rec = selection[0];
Ext.create('Proxmox.window.TaskViewer', {
upid: rec.data.upid,
endtime: rec.data.endtime,
}).show();
},
updateLayout: function() {
let me = this;
// we want to update the scrollbar on every store load
// since the total count might be different
// the buffered grid plugin does this only on scrolling itself
// and even reduces the scrollheight again when scrolling up
me.getView().updateLayout();
},
sinceChange: function(field, newval) {
let me = this;
let vm = me.getViewModel();
vm.set('since', newval);
},
untilChange: function(field, newval, oldval) {
let me = this;
let vm = me.getViewModel();
vm.set('until', newval);
},
reload: function() {
let me = this;
let view = me.getView();
view.getStore().load();
},
showFilter: function(btn, pressed) {
let me = this;
let vm = me.getViewModel();
vm.set('showFilter', pressed);
},
init: function(view) {
let me = this;
Proxmox.Utils.monStoreErrors(view, view.getStore(), true);
},
},
listeners: {
itemdblclick: 'showTaskLog',
},
viewModel: {
data: {
typefilter: '',
statusfilter: '',
datastore: '',
showFilter: false,
since: null,
until: null,
},
formulas: {
filterIcon: (get) => 'fa fa-filter' + (get('showFilter') ? ' info-blue' : ''),
extraParams: function(get) {
let me = this;
let params = {};
if (get('typefilter')) {
params.typefilter = get('typefilter');
}
if (get('statusfilter')) {
params.statusfilter = get('statusfilter');
}
if (get('datastore')) {
params.store = get('datastore');
}
if (get('since')) {
params.since = get('since').valueOf()/1000;
}
if (get('until')) {
let until = new Date(get('until').getTime()); // copy object
until.setDate(until.getDate() + 1); // end of the day
params.until = until.valueOf()/1000;
}
me.getView().getStore().load();
return params;
},
},
stores: {
bufferedstore: {
type: 'buffered',
pageSize: 500,
autoLoad: true,
remoteFilter: true,
model: 'proxmox-tasks',
proxy: {
type: 'proxmox',
startParam: 'start',
limitParam: 'limit',
extraParams: '{extraParams}',
url: "/api2/json/nodes/localhost/tasks",
},
listeners: {
prefetch: 'updateLayout',
},
},
},
},
bind: {
store: '{bufferedstore}',
},
dockedItems: [
{
xtype: 'toolbar',
items: [
{
xtype: 'proxmoxButton',
text: gettext('View'),
iconCls: 'fa fa-window-restore',
disabled: true,
handler: 'showTaskLog',
},
{
xtype: 'button',
text: gettext('Reload'),
iconCls: 'fa fa-refresh',
handler: 'reload',
},
'->',
{
xtype: 'button',
enableToggle: true,
bind: {
iconCls: '{filterIcon}',
},
text: gettext('Filter'),
stateful: true,
stateId: 'task-showfilter',
stateEvents: ['toggle'],
applyState: function(state) {
if (state.pressed !== undefined) {
this.setPressed(state.pressed);
}
},
getState: function() {
return {
pressed: this.pressed,
};
},
listeners: {
toggle: 'showFilter',
},
},
],
},
{
xtype: 'toolbar',
dock: 'top',
layout: {
type: 'hbox',
align: 'top',
},
bind: {
hidden: '{!showFilter}',
},
items: [
{
xtype: 'container',
padding: 10,
layout: {
type: 'vbox',
align: 'stretch',
},
defaults: {
labelWidth: 80,
},
// cannot bind the values directly, as it then changes also
// on blur, causing wrong reloads of the store
items: [
{
xtype: 'datefield',
fieldLabel: gettext('Since'),
format: 'Y-m-d',
bind: {
maxValue: '{until}',
},
listeners: {
change: 'sinceChange',
},
},
{
xtype: 'datefield',
fieldLabel: gettext('Until'),
format: 'Y-m-d',
bind: {
minValue: '{since}',
},
listeners: {
change: 'untilChange',
},
},
],
},
{
xtype: 'container',
padding: 10,
layout: {
type: 'vbox',
align: 'stretch',
},
defaults: {
labelWidth: 80,
},
items: [
{
xtype: 'pmxTaskTypeSelector',
fieldLabel: gettext('Task Type'),
emptyText: gettext('All'),
bind: {
value: '{typefilter}',
},
},
{
xtype: 'combobox',
fieldLabel: gettext('Task Result'),
emptyText: gettext('All'),
multiSelect: true,
store: [
['ok', gettext('OK')],
['unknown', Proxmox.Utils.unknownText],
['warning', gettext('Warnings')],
['error', gettext('Errors')],
],
bind: {
value: '{statusfilter}',
},
},
],
},
{
xtype: 'container',
padding: 10,
layout: {
type: 'vbox',
align: 'stretch',
},
defaults: {
labelWidth: 80,
},
items: [
{
xtype: 'pbsDataStoreSelector',
fieldLabel: gettext('Datastore'),
emptyText: gettext('All'),
bind: {
value: '{datastore}',
},
allowBlank: true,
},
],
},
],
},
],
viewConfig: {
trackOver: false,
stripeRows: false, // does not work with getRowClass()
emptyText: gettext('No Tasks found'),
getRowClass: function(record, index) {
let status = record.get('status');
if (status) {
let parsed = Proxmox.Utils.parse_task_status(status);
if (parsed === 'error') {
return "proxmox-invalid-row";
} else if (parsed === 'warning') {
return "proxmox-warning-row";
}
}
return '';
},
},
columns: [
{
header: gettext("Start Time"),
dataIndex: 'starttime',
width: 130,
renderer: function(value) {
return Ext.Date.format(value, "M d H:i:s");
},
},
{
header: gettext("End Time"),
dataIndex: 'endtime',
width: 130,
renderer: function(value, metaData, record) {
if (!value) {
metaData.tdCls = "x-grid-row-loading";
return '';
}
return Ext.Date.format(value, "M d H:i:s");
},
},
{
header: gettext("Duration"),
hidden: true,
width: 80,
renderer: function(value, metaData, record) {
let start = record.data.starttime;
if (start) {
let end = record.data.endtime || Date.now();
let duration = end - start;
if (duration > 0) {
duration /= 1000;
}
return Proxmox.Utils.format_duration_human(duration);
}
return Proxmox.Utils.unknownText;
},
},
{
header: gettext("User name"),
dataIndex: 'user',
width: 150,
},
{
header: gettext("Description"),
dataIndex: 'upid',
flex: 1,
renderer: Proxmox.Utils.render_upid,
},
{
header: gettext("Status"),
dataIndex: 'status',
width: 200,
renderer: function(value, metaData, record) {
if (value === undefined && !record.data.endtime) {
metaData.tdCls = "x-grid-row-loading";
return '';
}
let parsed = Proxmox.Utils.parse_task_status(value);
switch (parsed) {
case 'unknown': return Proxmox.Utils.unknownText;
case 'error': return Proxmox.Utils.errorText + ': ' + value;
case 'ok': // fall-through
case 'warning': // fall-through
default: return value;
}
},
},
],
});