From 120b24454727f38aa9014128321e13eb29f7cf3c Mon Sep 17 00:00:00 2001
From: Nathanael Jourdane <nathanael.jourdane@irap.omp.eu>
Date: Thu, 7 Sep 2017 19:36:46 +0200
Subject: [PATCH] epntap grids: check URLs, tooltip the cell content, improve style

---
 js/app/views/EpnTapUI.js  | 64 ++++++++++++++++++++++++++++++++++++++++++----------------------
 js/resources/css/amda.css | 15 +++++++++++++--
 2 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/js/app/views/EpnTapUI.js b/js/app/views/EpnTapUI.js
index 747070f..7983c2d 100644
--- a/js/app/views/EpnTapUI.js
+++ b/js/app/views/EpnTapUI.js
@@ -203,10 +203,26 @@ Ext.define('App.util.Format', {
 	'prettify': function(data) {
 		return data.charAt(0).toUpperCase() + data.replace(/_/g, ' ').substr(1).toLowerCase();
 	},
+	'url': function(data) {
+		var url_pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
+				'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
+				'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
+				'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
+				'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
+				'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
+		return url_pattern.test(data) ? data : null;
+	},
+	'cell': function(content, tooltip=null, tooltipTitle='') {
+		content = content ? content : '-';
+		if(tooltip !== '') {
+			var ttAttr = " data-qtitle='" + tooltipTitle + "' data-qtip='" + (tooltip ? tooltip : content) + "'";
+		}
+		return "<div class=epntap_cell " + ttAttr + ">" + content + "</div>";
+	},
 
 	// Services grid
 
-	'serviceTooltip': function(value, data) {
+	'serviceTooltip': function(data) {
 		for (var key in data) {
 			if(typeof data[key] == 'string' && data[key] != '') {
 				data[key] = data[key].replace(/'/g, '&#39;').replace(/"/g, '&#34;');
@@ -223,10 +239,10 @@ Ext.define('App.util.Format', {
 				details += '<li><b>' + Ext.util.Format.prettify(colums[key]) + '</b>: ' + val + '</li>';
 			}
 		}
-		return Ext.String.format("<div data-qtitle='{0}' data-qtip='{1}<ul>{2}</ul>'>{0}</div>", value, info, details);
+		return info + '<ul>' + details + '</ul>';
 	},
 	'service.text': function(data, metadata, record) {
-		return Ext.util.Format.serviceTooltip(data, record.data);
+		return Ext.util.Format.cell(data, Ext.util.Format.serviceTooltip(record.data), data);
 	},
 	'service.number': function(data, metadata, record) {
 		value = '' + data;
@@ -237,36 +253,37 @@ Ext.define('App.util.Format', {
 		} else if(data >= 1000) {
 			value = (data/1000).toPrecision(3) + 'k';
 		}
-		return Ext.util.Format.serviceTooltip(value, record.data);
+		return Ext.util.Format.cell(value, Ext.util.Format.serviceTooltip(record.data), record.data.short_name);
 	},
 
 	// Granules grid
 
-	'granuleTooltip': function(value, data) {
-		for (var key in data) {
-			if(typeof data[key] == 'string' && data[key] != '') {
-				data[key] = data[key].replace(/'/g, '&#39;').replace(/"/g, '&#34;');
-			}
-		}
-		var tooltip = '<img src="' + data.thumbnail_url + '">';
-		return Ext.String.format("<div data-qtitle='' data-qtip='{0}'>{1}</div>", tooltip, value);
-	},
 	'granule.text': function(data, metadata, record) {
-		return Ext.util.Format.granuleTooltip('<p style="white-space: normal;">' + data + '</p>', record.data);
+		return Ext.util.Format.cell(data);
 	},
 	'granule.link': function(data, metadata, record) {
-		return Ext.util.Format.granuleTooltip('<a style="font-size:150%" target="_blank" href="' + data + '">&#x1F5D7;</a>', record.data);
+		var icon_b64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxMDI0IiB3aWR0aD0iNzY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik02NDAgNzY4SDEyOFYyNTcuOTA1OTk5OTk5OTk5OTVMMjU2IDI1NlYxMjhIMHY3NjhoNzY4VjU3Nkg2NDBWNzY4ek0zODQgMTI4bDEyOCAxMjhMMzIwIDQ0OGwxMjggMTI4IDE5Mi0xOTIgMTI4IDEyOFYxMjhIMzg0eiIvPjwvc3ZnPg==';
+		var icon = '<img width="15px height="15px" src="' + icon_b64 + '">';
+		url = Ext.util.Format.url(data);
+		if(url) {
+			txt = '<a style="font-size:150%" target="_blank" href="' + url + '">' + icon + '</a>';
+		}
+		return Ext.util.Format.cell(txt, url);
 	},
 	'granule.img': function(data, metadata, record) {
-		return Ext.util.Format.granuleTooltip('<img width="40px height="40px" src="' + data + '">', record.data);
+		img_url = Ext.util.Format.url(data);
+		if(img_url) {
+			icon = '<img style="max-width:100%; max-height:100%" alt="-" src="' + img_url + '">';
+			img = '<img style="max-width:200px; max-height:200px" alt="-" src="' + img_url + '">';
+		}
+		return Ext.util.Format.cell(icon, img);
 	},
 	'granule.type': function(data, metadata, record) {
 		var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map;
-		return Ext.util.Format.granuleTooltip('<p>' + productTypeDict[data].data.name + '</p>', record.data);
+		return Ext.util.Format.cell(productTypeDict[data].data.name);
 	},
 	'granule.size': function(data, metadata, record) {
 		var size = parseInt(data);
-		var txt = '';
 		if (isNaN(size)) {
 		} else if (size >= 1024*1024) {
 			txt = (size/(1024*1024)).toPrecision(3) + 'Go';
@@ -275,11 +292,11 @@ Ext.define('App.util.Format', {
 		} else {
 			txt = size + 'Ko';
 		}
-		return Ext.util.Format.granuleTooltip('<p>' + txt + '</p>', record.data);
+		return Ext.util.Format.cell(txt);
 	},
 	'granule.proc_lvl': function(data, metadata, record) {
 		var levels = {1: 'Raw', 2: 'Edited', 3: 'Calibrated', 4: 'Resampled', 5: 'Derived', 6: 'Ancillary'};
-		return Ext.util.Format.granuleTooltip((data in levels) ? '<p>' + levels[data] + '</p>' : '<em>' + data + '</em>', record.data);
+		return Ext.util.Format.cell((data in levels) ? levels[data] : '<em>' + data + '</em>');
 	},
 	'granule.date': function(data, metadata, record) {
 		if(isNaN(data)) {
@@ -292,7 +309,8 @@ Ext.define('App.util.Format', {
 		var D = Math.floor((h % 153) / 5) + 1;
 		var M = ((Math.floor(h / 153) + 2) % 12) + 1;
 		var Y = Math.floor(e / 1461) - 4716 + Math.floor((12 + 2 - M) / 12);
-		return Ext.util.Format.granuleTooltip('<p>' + Ext.Date.format(new Date(Y, M-1, D), 'Y/m/d') + '</p>', record.data);
+		var date = new Date(Y, M-1, D);
+		return Ext.util.Format.cell(Ext.Date.format(date, 'Y/m/d'), Ext.Date.format(date, 'F j, Y, g:i a'));
 	},
 	'granule.format': function(data, metadata, record) {
 		var mimetypeDict = {
@@ -343,7 +361,7 @@ Ext.define('App.util.Format', {
 			'video/quicktime': 'mov',
 			'video/x-msvideo': 'avi'
 		};
-		return Ext.util.Format.granuleTooltip((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>', record.data);
+		return Ext.util.Format.cell((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>');
 	}
 });
 
@@ -593,6 +611,7 @@ Ext.define('amdaUI.EpnTapUI', {
 	createServicesGrid: function() {
 		return {
 			xtype: 'grid',
+			cls: 'epntap_grid',
 			id: 'epnTapServicesGrid',
 			title: 'Services',
 			store: Ext.data.StoreManager.lookup('servicesStore'),
@@ -640,6 +659,7 @@ Ext.define('amdaUI.EpnTapUI', {
 	createGranulesGrid: function() {
 		return {
 			xtype: 'grid',
+			cls: 'epntap_grid',
 			id: 'epnTapGranulesGrid',
 			title: 'Granules',
 			store: Ext.data.StoreManager.lookup('granulesStore'),
diff --git a/js/resources/css/amda.css b/js/resources/css/amda.css
index a7c627c..9e41d8e 100644
--- a/js/resources/css/amda.css
+++ b/js/resources/css/amda.css
@@ -489,10 +489,21 @@ p + p {
 	opacity: 1.0 !important;
 }
 
-.disabled_row {
+.epntap_grid .disabled_row {
 	color: gray;
 }
 
-.error_row {
+.epntap_grid .error_row {
 	color: IndianRed;
 }
+
+.epntap_grid td, .epntap_grid .x-grid-cell-inner {
+	padding: 0px;
+}
+
+.epntap_cell {
+	padding: 4px;
+	/*width: 100%;
+	height: 100%;*/
+	white-space: normal;
+}
\ No newline at end of file
--
libgit2 0.21.2