diff --git a/js/app/controllers/EpnTapModule.js b/js/app/controllers/EpnTapModule.js
index cfd0622..23073c0 100644
--- a/js/app/controllers/EpnTapModule.js
+++ b/js/app/controllers/EpnTapModule.js
@@ -7,26 +7,6 @@
  * @author  Nathanael Jourdane
  */
 
-// for(let service of Ext.getCmp('servicesPanel').getStore().getRange()) {
-// 	var filter = Array(service.data.schema, service.data.accessurl, targetName, productType, startTime, stopTime);
-// 	AmdaAction.epnTapMgr('getServiceNbResults', filter, function(epnTapServices) {
-// 		service.set('nb_responses', epnTapServices===null ? "-" : epnTapServices);
-// 		console.log(epnTapServices);
-// 	});
-// }
-
-// var grid = Ext.getCmp('servicesPanel');
-// var selection = grid.getSelectionModel();
-// access_url = [];
-// table_name = [];
-// for(i=0 ; i<grid.store.getCount() ; i++) {
-// 	if(selection.isSelected(i)) {
-// 		table_name.push(grid.store.getAt(i).data.table_name);
-// 		access_url.push(grid.store.getAt(i).data.access_url);
-// 	}
-//
-// }
-
 // Load text with Ajax synchronously: takes path to file and optional MIME type
 function loadTextFileAjaxSync(filePath, mimeType) {
 	var xmlhttp=new XMLHttpRequest();
@@ -61,11 +41,11 @@ Ext.define('amdaDesktop.EpnTapModule', {
 	/** The name of the documentation file related to the module. */
 	helpFile : 'epnTapHelp',
 
-	width : 600,
+	width : 800,
 	height: 550,
 
 	dpt_dic: { "im": "Image", "ma": "Map", "sp": "Spectrum", "ds": "Dynamic spectrum", "sc": "Spectral cube", "pr": "Profile",
-	"vo": "Volume", "mo": "Movie", "cu": "Cube", "ts": "Time series", "ca": "Catalogue", "ci": "Catalogue item"	},
+	"vo": "Volume", "mo": "Movie", "cu": "Cube", "ts": "Time series", "ca": "Catalogue", "ci": "Catalogue item" },
 
 	prettify: function(name) {
 		return name.charAt(0).toUpperCase() + name.replace(/_/g, ' ').substr(1).toLowerCase();
@@ -81,32 +61,32 @@ Ext.define('amdaDesktop.EpnTapModule', {
 
 		var filter_dic = new Array();
 		if(this.dpt_cb.value == 'all') {
-			for (var dpt in this.services) {
-				for (var tc in this.services[dpt]) {
-					for (tn in this.services[dpt][tc]) {
-						for (serv in this.services[dpt][tc][tn]) {
-							filter_dic[serv] = this.services[dpt][tc][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
+			for (var dpt in this.metadata) {
+				for (var tc in this.metadata[dpt]) {
+					for (tn in this.metadata[dpt][tc]) {
+						for (serv in this.metadata[dpt][tc][tn]) {
+							filter_dic[serv] = this.metadata[dpt][tc][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
 						}
 					}
 				}
 			}
 		} else if (this.tc_cb.value == 'all') {
-			for (var tc in this.services[this.dpt_cb.value]) {
-				for (tn in this.services[this.dpt_cb.value][tc]) {
-					for (serv in this.services[this.dpt_cb.value][tc][tn]) {
-						filter_dic[serv] = this.services[this.dpt_cb.value][tc][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
+			for (var tc in this.metadata[this.dpt_cb.value]) {
+				for (tn in this.metadata[this.dpt_cb.value][tc]) {
+					for (serv in this.metadata[this.dpt_cb.value][tc][tn]) {
+						filter_dic[serv] = this.metadata[this.dpt_cb.value][tc][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
 					}
 				}
 			}
 		} else if (this.tn_cb.value == 'all') {
-			for (tn in this.services[this.dpt_cb.value][this.tc_cb.value]) {
-				for (serv in this.services[this.dpt_cb.value][this.tc_cb.value][tn]) {
-					filter_dic[serv] = this.services[this.dpt_cb.value][this.tc_cb.value][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
+			for (tn in this.metadata[this.dpt_cb.value][this.tc_cb.value]) {
+				for (serv in this.metadata[this.dpt_cb.value][this.tc_cb.value][tn]) {
+					filter_dic[serv] = this.metadata[this.dpt_cb.value][this.tc_cb.value][tn][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
 				}
 			}
 		} else {
-			for (serv in this.services[this.dpt_cb.value][this.tc_cb.value][this.tn_cb.value]) {
-				filter_dic[serv] = this.services[this.dpt_cb.value][this.tc_cb.value][this.tn_cb.value][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
+			for (serv in this.metadata[this.dpt_cb.value][this.tc_cb.value][this.tn_cb.value]) {
+				filter_dic[serv] = this.metadata[this.dpt_cb.value][this.tc_cb.value][this.tn_cb.value][serv][0] + (serv in filter_dic ? filter_dic[serv] : 0);
 			}
 		}
 
@@ -122,7 +102,9 @@ Ext.define('amdaDesktop.EpnTapModule', {
 	},
 
 	onWindowLoaded: function(services) {
-		this.services = JSON.parse(loadTextFileAjaxSync('../../generic_data/EpnTapData/services.json', "application/json"));
+		this.metadata = JSON.parse(loadTextFileAjaxSync('../../generic_data/EpnTapData/metadata.json', "application/json"));
+		this.services = JSON.parse(loadTextFileAjaxSync('../../generic_data/EpnTapData/EpnTapServices.json', "application/json"));
+		console.log(Object.keys(this.metadata).length + " dataproduct_type répertoriés.");
 
 		this.dpt_cb = Ext.getCmp('productTypeCB');
 		this.tc_cb = Ext.getCmp('targetClassCB');
@@ -137,8 +119,10 @@ Ext.define('amdaDesktop.EpnTapModule', {
 		this.tn_cb.disable();
 
 		this.dpt_cb.getStore().add({'id': 'all', 'name': 'All data product types'});
+		this.tc_cb.getStore().add({'id': 'all', 'name': 'All target names'});
+		this.tn_cb.getStore().add({'id': 'all', 'name': 'All target classes'});
 
-		for (var dpt_id in this.services) {
+		for (var dpt_id in this.metadata) {
 			if (dpt_id in this.dpt_dic) {
 				this.dpt_cb.getStore().add({'id': dpt_id, 'name': this.prettify(this.dpt_dic[dpt_id])});
 			} else {
@@ -146,6 +130,8 @@ Ext.define('amdaDesktop.EpnTapModule', {
 			}
 		}
 		this.dpt_cb.select('all');
+		this.tc_cb.select('all');
+		this.tn_cb.select('all');
 		this.update_services();
 	},
 
@@ -157,7 +143,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
 		if (this.dpt_cb.value == 'all') {
 			this.tc_cb.disable();
 		} else {
-			var target_classes = this.services[this.dpt_cb.value];
+			var target_classes = this.metadata[this.dpt_cb.value];
 
 			if (Object.keys(target_classes).length == 1) {
 				this.tc_cb.getStore().add({'id': Object.keys(target_classes)[0], 'name': this.prettify(Object.keys(target_classes)[0])});
@@ -173,6 +159,8 @@ Ext.define('amdaDesktop.EpnTapModule', {
 				this.tc_cb.enable();
 			}
 		}
+		this.tn_cb.getStore().add({'id': 'all', 'name': 'All target names'});
+		this.tn_cb.select('all');
 		this.update_services();
 	},
 
@@ -180,9 +168,11 @@ Ext.define('amdaDesktop.EpnTapModule', {
 		this.tn_cb.getStore().removeAll();
 
 		if (this.tc_cb.value == 'all') {
+			this.tn_cb.getStore().add({'id': 'all', 'name': 'All target names'});
+			this.tn_cb.select('all');
 			this.tn_cb.disable();
 		} else {
-			var target_names = this.services[this.dpt_cb.value][this.tc_cb.value];
+			var target_names = this.metadata[this.dpt_cb.value][this.tc_cb.value];
 
 			if (Object.keys(target_names).length == 1) {
 				this.tn_cb.getStore().add({'id': Object.keys(target_names)[0], 'name': this.prettify(Object.keys(target_names)[0])});
@@ -205,20 +195,39 @@ Ext.define('amdaDesktop.EpnTapModule', {
 	},
 
 	onSearchBtnClicked: function() {
-		console.log("onSearchBtnClicked");
+		// console.log("onSearchBtnClicked");
 	},
 
-	onServiceSelected: function(service) {
-		var filter = Array(service['schema'], service['accessurl'], Ext.getCmp('targetNameCB').value,
-				this.dpt_cb.value, Ext.getCmp('startTimeDF').rawValue, Ext.getCmp('stopTimeDF').rawValue);
+	fillGranules: function(granules) {
+		console.log(granules);
 
-		AmdaAction.epnTapMgr('getGranules', filter, function(granules) {
-			console.log(granules);
-		});
+		Ext.getCmp('granulesPanel').getStore().removeAll();
+		Ext.getCmp('granulesPanel').getStore().add(granules);
+	},
+
+	onServiceSelected: function(service) {
+		var select = Array();
+		for (var i_s = 0 ; i_s < this.services.length ; i_s++) {
+			if (this.services[i_s]['schema'] === service['id']) {
+				var columns = this.services[i_s]['columns'].split(',');
+				for (var i_c=0 ; i_c<this.gp_grid.columns.length ; i_c++) {
+					if (columns.indexOf(this.gp_grid.columns[i_c].dataIndex) != -1)
+						select.push(this.gp_grid.columns[i_c].dataIndex)
+				}
+				var filter = Array(
+					this.dpt_cb.value !== 'all' ? this.dpt_cb.value : null,
+					this.tn_cb.value !== 'all' ? this.dpt_cb.value : null,
+					Ext.getCmp('startTimeDF').rawValue !== '' ? this.dpt_cb.value : null,
+					Ext.getCmp('stopTimeDF').rawValue !== '' ? this.dpt_cb.value : null);
+				break;
+			}
+		}
+		console.log("Getting granules of " + service['id'] + "...");
+		AmdaAction.epnTapGetGranules(service['id'], this.services[i_s]['accessurl'], filter, select, this.fillGranules);
 	},
 
 	onGranuleSelected: function(granule) {
-		console.log('selected granule: ' + granule.target_name);
+		// console.log('selected granule: ' + granule.target_name);
 	},
 
 	/** @class Module initialisation. */
diff --git a/js/app/views/EpnTapUI.js b/js/app/views/EpnTapUI.js
index 548dbc1..c6e82a4 100644
--- a/js/app/views/EpnTapUI.js
+++ b/js/app/views/EpnTapUI.js
@@ -30,7 +30,7 @@ Ext.create('Ext.data.Store', {
 
 Ext.create('Ext.data.Store', {
 	storeId:'granules_store',
-	fields:['type', 'target_name', 'time_min', 'time_max']
+	fields:['dataproduct_type', 'target_name', 'time_min', 'time_max', 'access_format', 'granule_uid', 'access_estsize', 'access_url', 'thumbnail_url']
 });
 
 var serviceFilterPanel = {
@@ -144,24 +144,47 @@ var servicesPanel = {
 	}
 }
 
-var granulesPanel = {
+var txt_render = function(val) { return '<p style="white-space: normal;">' + val + '</p>'; };
+var link_render = function(val) { return '<a href="' + val + '">get</a>'; };
+var img_render = function(val) { return '<img src="' + val + '">' };
+
+var granulesPanel = Ext.create('Ext.grid.Panel', {
 	id: 'granulesPanel',
-	xtype : 'grid',
 	title: 'Granules',
-	store: Ext.data.StoreManager.lookup('granulesStore'),
+	store: Ext.data.StoreManager.lookup('granules_store'),
 	flex: 3,
+	cls: 'epntap_granules',
 	columns: [
-		{ text: 'Type',  dataIndex: 'type', flex: 1 },
-		{ text: 'Target', dataIndex: 'target_name', flex: 1 },
-		{ text: 'Time min', dataIndex: 'time_min', flex: 2 },
-		{ text: 'Time max', dataIndex: 'time_max', flex: 2 }
+		{ text: 'Type',  dataIndex: 'dataproduct_type', flex: 1, renderer: txt_render },
+		{ text: 'Target', dataIndex: 'target_name', flex: 2, renderer: txt_render },
+		{ text: 'Time min', dataIndex: 'time_min', flex: 2, renderer: txt_render },
+		{ text: 'Time max', dataIndex: 'time_max', flex: 2, renderer: txt_render },
+		{ text: 'Format', dataIndex: 'access_format', flex: 2, renderer: txt_render },
+		{ text: 'uid', dataIndex: 'granule_uid', flex: 2, renderer: txt_render },
+		{ text: 'Size', dataIndex: 'access_estsize', flex: 2, renderer: txt_render },
+		{ text: 'URL', dataIndex: 'access_url', flex: 1, renderer: link_render },
+		{ text: 'Thumbnail', dataIndex: 'thumbnail_url', flex: 2, renderer: img_render}
 	],
 	listeners: {
 		'cellclick': function(grid, td, cellIndex, record, tr, rowIndex, e, eOpts) {
 			myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.epntap.id).onGranuleSelected(record.data);
 		}
+	},
+	renderTo: Ext.getBody()
+});
+
+var tooltip = Ext.create('Ext.tip.ToolTip', {
+	target: granulesPanel.getView().el,
+	delegate: granulesPanel.getView().itemSelector,
+	trackMouse: true,
+	renderTo: Ext.getBody(),
+	listeners: {
+		beforeshow: function updateTipBody(tip) {
+			var thumb = granulesPanel.getView().getRecord(tooltip.triggerElement).get('thumbnail_url');
+			tooltip.update('<img src="' + thumb + '">');
+		}
 	}
-}
+});
 
 var mainPanel = {
 	id: 'mainPanel',
@@ -202,7 +225,7 @@ Ext.define('amdaUI.EpnTapUI', {
 
 	init : function(config) {
 		var myConf = {
-			width: 600,
+			width: 800,
 			height: 550,
 			layout: 'border',
 			items: [
diff --git a/js/resources/css/amda.css b/js/resources/css/amda.css
index f74a45d..d82ec66 100644
--- a/js/resources/css/amda.css
+++ b/js/resources/css/amda.css
@@ -487,3 +487,16 @@ p + p {
 	filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100) !important;
 	opacity: 1.0 !important;
 }
+
+.epntap_granules img {
+	max-width: 40px;
+	max-height: 40px;
+}
+
+#granule_tooltip {
+    /*position:absolute;*/
+    margin:5px;
+    width:200px;
+    height:50px;
+    border:1px solid black;
+}
--
libgit2 0.21.2