From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <d.csapak@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id 757CE63949
 for <pbs-devel@lists.proxmox.com>; Mon,  5 Oct 2020 15:43:51 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 6F7B21B109
 for <pbs-devel@lists.proxmox.com>; Mon,  5 Oct 2020 15:43:21 +0200 (CEST)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [212.186.127.180])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS id 0971C1B0EC
 for <pbs-devel@lists.proxmox.com>; Mon,  5 Oct 2020 15:43:19 +0200 (CEST)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C961344959
 for <pbs-devel@lists.proxmox.com>; Mon,  5 Oct 2020 15:43:18 +0200 (CEST)
From: Dominik Csapak <d.csapak@proxmox.com>
To: pbs-devel@lists.proxmox.com
Date: Mon,  5 Oct 2020 15:43:17 +0200
Message-Id: <20201005134317.12425-7-d.csapak@proxmox.com>
X-Mailer: git-send-email 2.20.1
In-Reply-To: <20201005134317.12425-1-d.csapak@proxmox.com>
References: <20201005134317.12425-1-d.csapak@proxmox.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.523 Adjusted score from AWL reputation of From: address
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 RCVD_IN_DNSWL_MED        -2.3 Sender listed at https://www.dnswl.org/,
 medium trust
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pbs-devel] [PATCH proxmox-backup 7/7] ui: Dashboard/TaskSummary:
 show task overlay when clicking on a count
X-BeenThere: pbs-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Backup Server development discussion
 <pbs-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/>
List-Post: <mailto:pbs-devel@lists.proxmox.com>
List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Mon, 05 Oct 2020 13:43:51 -0000

when clicking on a count in the summary, a small task overlay now pops
up that shows those tasks. this way, the user has an easy way
of seeing which tasks failed exactly

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
if wanted or necessary, i could implement the grid overlay in its own
file, but it is 'special' enough that we probably will only use it here
(it is different enough from the 'running' tasks grid, that i did
not try to use that)

 www/Dashboard.js             |   2 +-
 www/dashboard/TaskSummary.js | 138 ++++++++++++++++++++++++++++++++++-
 2 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/www/Dashboard.js b/www/Dashboard.js
index ff89c519..4f2bae13 100644
--- a/www/Dashboard.js
+++ b/www/Dashboard.js
@@ -166,7 +166,7 @@ Ext.define('PBS.Dashboard', {
 		}
 	    });
 
-	    me.lookup('tasksummary').updateTasks(data);
+	    me.lookup('tasksummary').updateTasks(data, viewModel.get('sinceEpoch'));
 	},
 
 	init: function(view) {
diff --git a/www/dashboard/TaskSummary.js b/www/dashboard/TaskSummary.js
index d7b13f64..6a503979 100644
--- a/www/dashboard/TaskSummary.js
+++ b/www/dashboard/TaskSummary.js
@@ -7,6 +7,13 @@ Ext.define('PBS.TaskSummary', {
     controller: {
 	xclass: 'Ext.app.ViewController',
 
+	states: [
+	    "",
+	    "error",
+	    "warning",
+	    "ok",
+	],
+
 	types: [
 	    "backup",
 	    "prune",
@@ -20,6 +27,130 @@ Ext.define('PBS.TaskSummary', {
 	    "prune": gettext('Prunes'),
 	    "garbage_collection": gettext('Garbage collections'),
 	    "sync": gettext('Syncs'),
+	    "verify": gettext('Verify'),
+	},
+
+	openTaskList: function(grid, td, cellindex, record, tr, rowindex) {
+	    let me = this;
+	    let view = me.getView();
+
+	    if (cellindex > 0) {
+		let tasklist = view.tasklist;
+		let state = me.states[cellindex];
+		let type = me.types[rowindex];
+		let filterParam = {
+		    'statusfilter': state,
+		    'typefilter': type,
+		};
+
+		if (me.since) {
+		    filterParam.since = me.since;
+		}
+
+		if (record.data[state] === 0) {
+		    return;
+		}
+
+		if (tasklist === undefined) {
+		    tasklist = Ext.create('Ext.grid.Panel', {
+			tools: [{
+			    handler: () => tasklist.setVisible(false),
+			}],
+			floating: true,
+			scrollable: true,
+
+			height: 400,
+			width: 600,
+
+			columns: [
+			    {
+				text: gettext('Task'),
+				dataIndex: 'upid',
+				renderer: Proxmox.Utils.render_upid,
+				flex: 1,
+			    },
+			    {
+				header: gettext("Start Time"),
+				dataIndex: 'starttime',
+				width: 130,
+				renderer: function(value) {
+				    return Ext.Date.format(value, "M d H:i:s");
+				},
+			    },
+			    {
+				xtype: 'actioncolumn',
+				width: 40,
+				items: [
+				    {
+					iconCls: 'fa fa-chevron-right',
+					tooltip: gettext('Open Task'),
+					handler: function(g, rowIndex) {
+					    let rec = tasklist.getStore().getAt(rowIndex);
+					    tasklist.setVisible(false);
+					    Ext.create('Proxmox.window.TaskViewer', {
+						upid: rec.data.upid,
+						endtime: rec.data.endtime,
+						listeners: {
+						    close: () => tasklist.setVisible(true),
+						},
+					    }).show();
+					},
+				    },
+				],
+			    },
+			],
+
+			store: {
+			    sorters: [
+				{
+				    property: 'starttime',
+				    direction: 'DESC',
+				},
+			    ],
+			    type: 'store',
+			    model: 'proxmox-tasks',
+			    proxy: {
+				type: 'proxmox',
+				url: "/api2/json/status/tasks",
+			    },
+			},
+		    });
+
+		    view.on('destroy', function() {
+			tasklist.setVisible(false);
+			tasklist.destroy();
+			tasklist = undefined;
+		    });
+
+		    view.tasklist = tasklist;
+		} else {
+		    let cidx = tasklist.cidx;
+		    let ridx = tasklist.ridx;
+
+		    if (cidx === cellindex && ridx === rowindex && tasklist.isVisible()) {
+			tasklist.setVisible(false);
+			return;
+		    }
+		}
+
+		tasklist.cidx = cellindex;
+		tasklist.ridx = rowindex;
+
+		let task = me.titles[type];
+		let status = "";
+		switch (state) {
+		    case 'ok': status = gettext("OK"); break;
+		    case 'warnings': status = gettext("Warning"); break;
+		    case 'error': status = Proxmox.Utils.errorText; break;
+		}
+		let icon = me.render_icon(state, 1);
+		tasklist.setTitle(`${task} - ${status} ${icon}`);
+		tasklist.getStore().getProxy().setExtraParams(filterParam);
+		tasklist.getStore().removeAll();
+
+		tasklist.showBy(td, 'bl-tl');
+		setTimeout(() => tasklist.getStore().reload(), 10);
+	    }
 	},
 
 	render_icon: function(state, count) {
@@ -55,7 +186,7 @@ Ext.define('PBS.TaskSummary', {
 	},
     },
 
-    updateTasks: function(data) {
+    updateTasks: function(source, since) {
 	let me = this;
 	let controller = me.getController();
 	let data = [];
@@ -64,6 +195,7 @@ Ext.define('PBS.TaskSummary', {
 	    data.push(source[type]);
 	});
 	me.lookup('grid').getStore().setData(data);
+	controller.since = since;
     },
 
     layout: 'fit',
@@ -90,6 +222,10 @@ Ext.define('PBS.TaskSummary', {
 		data: [],
 	    },
 
+	    listeners: {
+		cellclick: 'openTaskList',
+	    },
+
 	    columns: [
 		{
 		    dataIndex: 'type',
-- 
2.20.1