Blame view

js/app/views/EpnTapUI.js 22.2 KB
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
1
2
3
4
5
/**
 * Project: AMDA-NG
 * Name: EpnTapUI.js
 * @class amdaUI.EpnTapUI
 * @extends Ext.tab.Panel
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
6
7
8
9
 * @author Nathanael JOURDANE
 * 24/10/2016: file creation
 */

016bdaae   Nathanael Jourdane   Fix bad rendering...
10
Ext.require(['Ext.grid.plugin.BufferedRenderer']);
b185823c   Nathanael Jourdane   Use IntervalUI mo...
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
`productTypesStore`: An ExtJS Store containing the list of the different data product types defined on all granules, on
all available EPN-TAP services (defined in `generic_data/EpnTapData/metadata.json`, updated periodically with a cron
script).

This list is used to fill the `productTypeCB` combo box, which is initilized in `EpnTapModule` at the panel creation.

- `id`: the data product type IDs, according to the EPN-TAP specification (see
		https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=1148225);
- `name`: the data product name, according to the EPN-TAP specification (ibid).

These IDs and names are hard-defined in the JSon file `generic_data/EpnTapData/dataproduct_types.json`.

Notes:
- if a granule contains a data product type which is not conform to the EPN-TAP definition (ibid), it is not displayed
in this store and an information message is displayed on the JavaScript console during the panel creation.
- if a data product type is not present in any of the granules from the EPN-TAP services, it is not present in this
store.
b185823c   Nathanael Jourdane   Use IntervalUI mo...
29
*/
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
30
Ext.create('Ext.data.Store', {
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
31
32
	storeId: 'productTypesStore',
	autoLoad: true,
977e2c07   Nathanael Jourdane   Add tooltips on p...
33
	fields: ['id', 'name', 'desc'],
ebdc15a7   Nathanael Jourdane   remove targetclas...
34
	data: [
977e2c07   Nathanael Jourdane   Add tooltips on p...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		{'id': 'all', 'name': '--All--', 'desc': 'Select all produt types.'},
		{'id': 'clear', 'name': '--Clear--', 'desc': 'Clear the selection.'},
		{'id': 'im', 'name': 'Image', 'desc': '2D series of values depending on 2 spatial axes, with measured parameters.'},
		{'id': 'ma', 'name': 'Map', 'desc': '2D series of values depending on 2 spatial axes, with derived parameters.'},
		{'id': 'sp', 'name': 'Spectrum', 'desc': '1D series of values depending on a spectral axis (or Frequency, Energy, Mass,...).'},
		{'id': 'ds', 'name': 'Dynamic spectrum', 'desc': '2D series of values depending on time and on a spectral axis (Frequency, Energy, Mass,...), FoV is homogeneous.'},
		{'id': 'sc', 'name': 'Spectral cube', 'desc': '3D series of values depending on 2 spatial axes and on a spectral axis (Frequency, Energy, Mass,..).'},
		{'id': 'pr', 'name': 'Profile', 'desc': '1D series of values depending on a spatial axis.'},
		{'id': 'vo', 'name': 'Volume', 'desc': '3D series of values depending on 3 spatial axes (spatial coordinates or tabulated values in a volumic grid).'},
		{'id': 'mo', 'name': 'Movie', 'desc': '3D series of values depending on 2 spatial axes and on time.'},
		// {'id': 'cu', 'name': 'Cube', 'desc': '.'},
		{'id': 'ts', 'name': 'Time series', 'desc': '1D series of values depending on time.'},
		{'id': 'ca', 'name': 'Catalogue', 'desc': '1D list of elements.'},
		{'id': 'ci', 'name': 'Catalogue item', 'desc': '0D list of elements.'}
ebdc15a7   Nathanael Jourdane   remove targetclas...
49
	]
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
50
51
});

b185823c   Nathanael Jourdane   Use IntervalUI mo...
52
53
54
55
56
57
58
59
60
61
62
/**
`targetNamesStore`: An ExtJS Store containing the list of the different target names defined on all granules, on
all available EPN-TAP services (defined in `generic_data/EpnTapData/metadata.json`, updated periodically with a cron
script), which match with the selected data product and target class.

This list is used to fill the `targetNameCB` combo box, which is updated by `EpnTapModule` each time a new target class
(or, by transitivity, product type) is selected.

- `id`: the target name in lowercase, with the underscore between each word;
- `name`: the target name, capitalized with spaces between each word (done `EpnTapModule.prettify()`).
*/
68664dca   Nathanael Jourdane   make epntap php f...
63
Ext.create('Ext.data.Store', {
7055f5d6   Nathanael Jourdane   Code refactoring
64
	storeId: 'targetNamesStore',
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
65
66
67
	fields: ['id', 'name', 'type', 'parent', 'aliases'],
	proxy: {
		type: 'ajax',
68664dca   Nathanael Jourdane   make epntap php f...
68
		url: 'php/epntap.php',
50dd7220   Nathanael Jourdane   epntap.php works ...
69
70
71
72
73
74
		extraParams: { action: 'resolver' }
		// listeners: {
		// 	exception: function(proxy, response, operation) {
		// 		console.log('Error ', response); //TODO: Use ExtJs alert instead
		// 	}
		// }
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
75
	}
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
76
77
});

12c10cdb   Nathanael Jourdane   Get the list of s...
78
79
80
81
82
83
84
/**
`servicesStore`: An ExtJS Store containing the list of the EPN-TAP services (defined in
`generic_data/EpnTapData/metadata.json`, updated periodically with a cron script), which contains at least one granule
matching with the granules filter (the selected data product type, target class and target name).

This list is used to fill the `servicesGrid` table, which is updated by `EpnTapModule` each time a new target name
(or, by transitivity, target class or product type) is selected.
8d5634e3   Nathanael Jourdane   Use epn-tap store...
85

12c10cdb   Nathanael Jourdane   Get the list of s...
86
87
88
89
90
91
92
93
94
- `id`: the database name of the service, according to the `table_name` column from the `rr.res_table` in the
		registry database;
- `nbResults`: the number of granules matching with the granules filter for this service;
- `shortName`: the service short name, according to the `short_name` column from the `rr.resource` table in the registry
		database;
- `title`: the service title, according to the `res_title` column from the `rr.resource` table in the registry database;
- `accessURL`: the service access URL, according to the `access_url` column from the `rr.interface` table in the
		registry database.
*/
8d5634e3   Nathanael Jourdane   Use epn-tap store...
95
Ext.create('Ext.data.Store', {
12c10cdb   Nathanael Jourdane   Get the list of s...
96
	storeId: 'servicesStore',
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
97
	autoLoad: true,
12c10cdb   Nathanael Jourdane   Get the list of s...
98
99
100
101
102
103
104
105
106
107
108
109
110
	fields: [
		{name: 'id', type: 'string'},
		{name: 'short_name', type: 'string'},
		{name: 'res_title', type: 'string'},
		{name: 'ivoid', type: 'string'},
		{name: 'access_url', type: 'string'},
		{name: 'table_name', type: 'string'},
		{name: 'content_type', type: 'string'},
		{name: 'creator_seq', type: 'string'},
		{name: 'content_level', type: 'string'},
		{name: 'reference_url', type: 'string'},
		{name: 'created', type: 'date', dateFormat: 'c'},
		{name: 'updated', type: 'date', dateFormat: 'c'},
d6674d39   Nathanael Jourdane   Add error and inf...
111
		{name: 'nb_results', type: 'integer'},
016bdaae   Nathanael Jourdane   Fix bad rendering...
112
		{name: 'info', type: 'string'}
8d5634e3   Nathanael Jourdane   Use epn-tap store...
113
114
115
	],
	proxy: {
		type: 'ajax',
49401187   Nathanael Jourdane   epntap: Do not us...
116
		url: 'php/epntap.php',
8c2fa14d   Nathanael Jourdane   Update services g...
117
118
119
120
121
		extraParams : {action: 'getServices'}
	},
	sorters: [
		{property: 'nb_results', direction: 'DESC'},
		{property: 'short_name', direction: 'ASC'}
a8a12768   Nathanael Jourdane   Create the grid m...
122
123
124
125
	],
	listeners: {
		// load: function(record) { console.log(record); }
	}
8d5634e3   Nathanael Jourdane   Use epn-tap store...
126
127
});

b185823c   Nathanael Jourdane   Use IntervalUI mo...
128
/**
b185823c   Nathanael Jourdane   Use IntervalUI mo...
129
`granulesStore`: An ExtJS Store containing the list of granules of the selected service (on `servicesGrid`), which match
ba6dfa5e   Nathanael Jourdane   (regression bug) ...
130
with the granules filter (the selected data product type, target class and target name).
b185823c   Nathanael Jourdane   Use IntervalUI mo...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

This list is used to fill the `granulesGrid` table, which is updated by `EpnTapModule` each time a new service is
selected.

- `num`: the line number, according to the order of the query response and the current page (see `currentPageLb`);
- `dataproduct_type`: the dataproduct_type EPN-TAP parameter, as defined in
	https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters.
- `target_name`: the target_name EPN-TAP parameter (ibid);
- `time_min`: the time_min EPN-TAP parameter (ibid);
- `time_max`: the time_max EPN-TAP parameter (ibid);
- `access_format`: the access_format EPN-TAP parameter (ibid);
- `granule_uid`: the granule_uid EPN-TAP parameter (ibid);
- `access_estsize`: the access_estsize EPN-TAP parameter (ibid);
- `access_url`: the access_url EPN-TAP parameter (ibid);
- `thumbnail_url`: the thumbnail_url EPN-TAP parameter (ibid).
*/
6d616600   Nathanael Jourdane   Fix granules sorter
147
// TODO: Add granules filter (see http://docs.sencha.com/extjs/4.0.7/#!/example/grid-filtering/grid-filter-local.html)
016bdaae   Nathanael Jourdane   Fix bad rendering...
148
149
150
151
152
153

Ext.define('GranulesModel', {
	extend: 'Ext.data.Model'
	// columns are created dynamically
});

3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
154
Ext.create('Ext.data.Store', {
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
155
	storeId: 'granulesStore',
016bdaae   Nathanael Jourdane   Fix bad rendering...
156
	model: 'GranulesModel',
11f8b45b   Nathanael Jourdane   Use buffered scro...
157
	buffered: true,
87467502   Nathanael Jourdane   Replace page butt...
158
	autoload: false,
016bdaae   Nathanael Jourdane   Fix bad rendering...
159
160
	pageSize: 500,
	leadingBufferZone: 0,
87467502   Nathanael Jourdane   Replace page butt...
161
162
163
	proxy: {
		type: 'ajax',
		url: 'php/epntap.php',
11f8b45b   Nathanael Jourdane   Use buffered scro...
164
		reader: { type: 'json', root: 'data'},
6d616600   Nathanael Jourdane   Fix granules sorter
165
		simpleSortMode: true
016bdaae   Nathanael Jourdane   Fix bad rendering...
166
167
	},
	listeners: {
11f8b45b   Nathanael Jourdane   Use buffered scro...
168
		'beforeprefetch': function(store, operation) {
016bdaae   Nathanael Jourdane   Fix bad rendering...
169
			var service = Ext.data.StoreManager.lookup('servicesStore').getById(store.selectedService).data;
11f8b45b   Nathanael Jourdane   Use buffered scro...
170
171
172
173
174
175
176
177
178
179
180
			store.getProxy().extraParams = {
				'action': 'getGranules',
				'url': service['access_url'],
				'tableName': service['table_name'],
				'targetName': Ext.getCmp('epnTapTargetNameCB').rawValue,
				'productTypes': Ext.getCmp('epnTapProductTypeCB').value.join(';'),
				'timeMin': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStartTime(), 'd/m/Y H:i:s'),
				'timeMax': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStopTime(), 'd/m/Y H:i:s'),
				'nbRes': service['nb_results']
			};
		},
6d616600   Nathanael Jourdane   Fix granules sorter
181
		'prefetch': function(store, records, successful, operation) {
30cd92df   Roipoussiere   Fix merge conflicts
182
			// console.log('(prefetch) operation ' + (successful ? 'success' : 'failed') + ': ', operation);
6d616600   Nathanael Jourdane   Fix granules sorter
183
184
185
			// console.log(operation.params);
			// console.log(Ext.decode(operation.response.responseText));
		},
a8a12768   Nathanael Jourdane   Create the grid m...
186
		'metachange': function(store, meta) {
a5475297   Nathanael Jourdane   use a hash for me...
187
188
189
190
			if(meta.metaHash != store.metaHash) {
				Ext.getCmp('epnTapGranulesGrid').reconfigure(store, meta.columns);
				store.metaHash = meta.metaHash;
			}
a8a12768   Nathanael Jourdane   Create the grid m...
191
192
		}
	}
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
193
194
});

465b7a40   Nathanael Jourdane   Escape quotes in ...
195
196
197
/**
Error are not displayed here, use try/catch each time it's necessary.
*/
7211d9b5   Nathanael Jourdane   Move util.Format ...
198
199
Ext.define('App.util.Format', {
	override: 'Ext.util.Format',
465b7a40   Nathanael Jourdane   Escape quotes in ...
200
201
202

	// Utils

24fcdbc7   Nathanael Jourdane   Fix crash when ep...
203
204
205
	'prettify': function(data) {
		return data.charAt(0).toUpperCase() + data.replace(/_/g, ' ').substr(1).toLowerCase();
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
206
207
208

	// Services grid

24fcdbc7   Nathanael Jourdane   Fix crash when ep...
209
	'serviceTooltip': function(value, data) {
465b7a40   Nathanael Jourdane   Escape quotes in ...
210
211
212
213
214
		for (var key in data) {
			if(typeof data[key] == 'string' && data[key] != '') {
				data[key] = data[key].replace(/'/g, ''').replace(/"/g, '"');
			}
		}
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
215
		var infoColor = data.nb_results == -2 ? 'IndianRed' : 'green';
465b7a40   Nathanael Jourdane   Escape quotes in ...
216
		var info = data.info.length > 0 ? '<p style="color:' + infoColor + '">' + data.info + '</p>' : '';
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
217
218
219

		var colums = ['res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated'];
		var details = '';
465b7a40   Nathanael Jourdane   Escape quotes in ...
220
221
222
223
		for (var key in colums) {
			if(data[colums[key]] !== '') {
				var val = colums[key] === 'content_level' ? data[colums[key]].replace(/#/g, ', ') : data[colums[key]];
				details += '<li><b>' + Ext.util.Format.prettify(colums[key]) + '</b>: ' + val + '</li>';
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
224
225
			}
		}
465b7a40   Nathanael Jourdane   Escape quotes in ...
226
		return Ext.String.format("<div data-qtitle='{0}' data-qtip='{1}<ul>{2}</ul>'>{0}</div>", value, info, details);
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	},
	'service.text': function(data, metadata, record) {
		return Ext.util.Format.serviceTooltip(data, record.data);
	},
	'service.number': function(data, metadata, record) {
		value = '' + data;
		if(data < 0) {
			value = '-';
		} else if(data >= 1000*1000) {
			value = (data/(1000*1000)).toPrecision(3) + 'm';
		} else if(data >= 1000) {
			value = (data/1000).toPrecision(3) + 'k';
		}
		return Ext.util.Format.serviceTooltip(value, record.data);
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
242
243
244
245
246
247
248
249
250
251
252
253
254
255

	// 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);
7211d9b5   Nathanael Jourdane   Move util.Format ...
256
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
257
	'granule.link': function(data, metadata, record) {
e0a60d33   Nathanael Jourdane   Fix link bug and ...
258
		return Ext.util.Format.granuleTooltip('<a style="font-size:150%" target="_blank" href="' + data + '">&#x1F5D7;</a>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
259
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
260
261
	'granule.img': function(data, metadata, record) {
		return Ext.util.Format.granuleTooltip('<img width="40px height="40px" src="' + data + '">', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
262
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
263
	'granule.type': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
264
		var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map;
465b7a40   Nathanael Jourdane   Escape quotes in ...
265
		return Ext.util.Format.granuleTooltip('<p>' + productTypeDict[data].data.name + '</p>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
266
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
267
	'granule.size': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
268
269
270
271
272
273
274
275
276
277
		var size = parseInt(data);
		var txt = '';
		if (isNaN(size)) {
		} else if (size >= 1024*1024) {
			txt = (size/(1024*1024)).toPrecision(3) + 'Go';
		} else if (size >= 1024) {
			txt = (size/1024).toPrecision(3) + 'Mo';
		} else {
			txt = size + 'Ko';
		}
465b7a40   Nathanael Jourdane   Escape quotes in ...
278
		return Ext.util.Format.granuleTooltip('<p>' + txt + '</p>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
279
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
280
	'granule.proc_lvl': function(data, metadata, record) {
c7967cba   Nathanael Jourdane   Improve display f...
281
		var levels = {1: 'Raw', 2: 'Edited', 3: 'Calibrated', 4: 'Resampled', 5: 'Derived', 6: 'Ancillary'};
465b7a40   Nathanael Jourdane   Escape quotes in ...
282
		return Ext.util.Format.granuleTooltip((data in levels) ? '<p>' + levels[data] + '</p>' : '<em>' + data + '</em>', record.data);
c7967cba   Nathanael Jourdane   Improve display f...
283
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
284
	'granule.date': function(data, metadata, record) {
07382ff2   Nathanael Jourdane   Format dates
285
286
287
288
289
290
291
292
293
294
		if(isNaN(data)) {
			return '';
		}
		var f = Number(data) + 1401 + Math.floor((Math.floor((4 * Number(data) + 274277) / 146097) * 3) / 4) - 38;
		var e = 4 * f + 3;
		var g = Math.floor((e % 1461) / 4);
		var h = 5 * g + 2;
		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);
465b7a40   Nathanael Jourdane   Escape quotes in ...
295
		return Ext.util.Format.granuleTooltip('<p>' + Ext.Date.format(new Date(Y, M-1, D), 'Y/m/d') + '</p>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
296
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
297
	'granule.format': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
		var mimetypeDict = {
			'application/fits': 'fits',
			'application/x-pds': 'pds',
			'image/x-pds': 'pds',
			'application/gml+xml': 'gml',
			'application/json': 'json',
			'application/octet-stream': 'bin, idl, envi or matlab',
			'application/pdf': 'pdf',
			'application/postscript': 'ps',
			'application/vnd.geo+json': 'geojson',
			'application/vnd.google-earth.kml+xml': 'kml',
			'application/vnd.google-earth.kmz': 'kmz',
			'application/vnd.ms-excel': 'xls',
			'application/x-asdm': 'asdm',
			'application/x-cdf': 'cdf',
			'application/x-cdf-istp': 'cdf',
			'application/x-cdf-pds4': 'cdf',
			'application/x-cef1': 'cef1',
			'application/x-cef2': 'cef2',
			'application/x-directory': 'dir',
			'application/x-fits-bintable': 'bintable',
			'application/x-fits-euro3d': 'euro3d',
			'application/x-fits-mef': 'mef',
			'application/x-geotiff': 'geotiff',
			'application/x-hdf': 'hdf',
			'application/x-netcdf': 'nc',
			'application/x-netcdf4': 'nc',
			'application/x-tar': 'tar',
			'application/x-tar-gzip': 'gtar',
			'application/x-votable+xml': 'votable',
			'application/x-votable+xml;content=datalink': 'votable',
			'application/zip': 'zip',
			'image/fits': 'fits',
			'image/gif': 'gif',
			'image/jpeg': 'jpeg',
			'image/png': 'png',
			'image/tiff': 'tiff',
			'image/x-fits-gzip': 'fits',
			'image/x-fits-hcompress': 'fits',
			'text/csv': 'csv',
			'text/html': 'html',
			'text/plain': 'txt',
			'text/tab-separated-values': 'tsv',
			'text/xml': 'xml',
			'video/mpeg': 'mpeg',
			'video/quicktime': 'mov',
			'video/x-msvideo': 'avi'
		};
465b7a40   Nathanael Jourdane   Escape quotes in ...
346
		return Ext.util.Format.granuleTooltip((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
347
348
349
	}
});

b185823c   Nathanael Jourdane   Use IntervalUI mo...
350
351
352
353
354
355
/**
`EpnTapUI`: The view of the AMDA EPN-TAP module, allowing the user to query and display granules information from
EPN-TAP services.

Note: The controller part of this module is defined in `js/app/controller/EpnTapModule`.
*/
78c2f505   Nathanael Jourdane   Improve granules ...
356
Ext.define('amdaUI.EpnTapUI', {
b185823c   Nathanael Jourdane   Use IntervalUI mo...
357
	extend: 'Ext.panel.Panel',
78c2f505   Nathanael Jourdane   Improve granules ...
358
	alias: 'widget.panelEpnTap',
b185823c   Nathanael Jourdane   Use IntervalUI mo...
359
	requires: ['amdaUI.IntervalUI'],
78c2f505   Nathanael Jourdane   Improve granules ...
360

b185823c   Nathanael Jourdane   Use IntervalUI mo...
361
362
363
	/**
	Method constructor, which basically call the `init()` method to create the EpnTap panel.
	*/
78c2f505   Nathanael Jourdane   Improve granules ...
364
	constructor: function(config) {
78c2f505   Nathanael Jourdane   Improve granules ...
365
366
367
368
		this.init(config);
		this.callParent(arguments);
	},

10162678   Nathanael Jourdane   Fix the infoPanel...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	/**
	Create all the EpnTapPanel UI elements, and apply the AMDA module `config` (which includes the created items).

	When the panel is correctly rendered, the panel triggers `EpnTapModule.onWindowLoaded()`.

	Note: All the UI elements creation are defined as functions in this init method and not as methods in order to make
	them private (ie. to avoid `EpnTapUI.createServicesGrid();`, which doesn't make sense).
	*/
	init: function(config) {
		var myConf = {
			id: 'epntapTab',
			title: 'EPN-TAP',
			layout: 'fit',
			items: [{
				xtype: 'container',
				layout: { type: 'vbox', pack: 'start', align: 'stretch'},
				items: [
					this.createServiceFilterPanel(),
cc6e16eb   Nathanael Jourdane   Remove info panel
387
					this.createGridsPanel()
10162678   Nathanael Jourdane   Fix the infoPanel...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
				]
			}]
		};
		Ext.apply(this, Ext.apply(arguments, myConf));
	},

	/***************************
	*** Service filter panel ***
	***************************/

	/**
	Create `epnTapServiceFilterPanel`, an ExtJS Panel containing two containers:
	- the left container, containing the combo boxes (for product type, target class and target name)
		and the navigation panel;
	- the right container, containing the time selector.
	*/
	createServiceFilterPanel: function() {
		return {
30281591   Nathanael Jourdane   [WIP] Send reques...
406
			xtype: 'form',
10162678   Nathanael Jourdane   Fix the infoPanel...
407
408
409
			id: 'epnTapServiceFilterPanel',
			layout: { type: 'hbox', pack: 'start', align: 'stretch' },
			region: 'north',
33db0a91   Nathanael Jourdane   Add Get button (wip)
410
			defaults: { margin: '5 0 5 5'},
10162678   Nathanael Jourdane   Fix the infoPanel...
411
412
			items: [{ // Left part
				xtype : 'container',
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
413
				flex: 1,
10162678   Nathanael Jourdane   Fix the infoPanel...
414
				items: [
10162678   Nathanael Jourdane   Fix the infoPanel...
415
					this.createTargetNameCB(),
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
416
					this.createProductTypeCB()
10162678   Nathanael Jourdane   Fix the infoPanel...
417
				]
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
418
419
420
			}, { // Middle part
				xtype : 'container',
				flex: 1,
10162678   Nathanael Jourdane   Fix the infoPanel...
421
422
423
				items: [
					this.createTimeSelector()
				]
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
424
425
			}, { // Right part
				xtype : 'container',
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
426
				items: [
33db0a91   Nathanael Jourdane   Add Get button (wip)
427
					this.createSendButton()
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
428
429
				]

10162678   Nathanael Jourdane   Fix the infoPanel...
430
431
432
433
			}]
		};
	},

230b2236   Nathanael Jourdane   Add tooltip to pr...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
		/**
		Create `epnTapTargetNameCB`, an ExtJS ComboBox, containing a list of target names corresponding to the selected
		target class, as defined in `targetNamesStore`, which is initilized by `EpnTapModule`.

		The selection of a target name triggers `EpnTapModule.onTargetNameCBChanged()`, which basically updates
		`granulesGrid`.
		*/
		createTargetNameCB: function() {
			return {
				xtype: 'combobox',
				id: 'epnTapTargetNameCB',
				fieldLabel: 'Target name',
				emptyText: 'Earth, Saturn, 67P, ...',
				store: Ext.data.StoreManager.lookup('targetNamesStore'),
				queryMode: 'remote',
				queryParam: 'input',
				displayField: 'name',
				valueField: 'id',
				margin: '15 0 5 0',
				labelWidth: 71,
				minWidth: 20,
				minChars: 2,
				hideTrigger: true,
				listConfig: {
					getInnerTpl: function() {
977e2c07   Nathanael Jourdane   Add tooltips on p...
459
						return '<div data-qtitle="{name}" data-qtip="<p>type: {type}</p><p>parent: {parent}</p><p>aliases:</p><ul>{aliases}</ul>">{name}</div>';
230b2236   Nathanael Jourdane   Add tooltip to pr...
460
461
462
463
464
465
466
467
468
469
470
471
472
					}
				},
				listeners: {
					render: function(cb) {
						new Ext.ToolTip({
							target: cb.getEl(),
							html: 'Start to type a text then select a target name (required).'
						});
					}
				}
			};
		},

10162678   Nathanael Jourdane   Fix the infoPanel...
473
474
475
476
477
	/**
	Create `epnTapProductTypeCB`, an ExtJS ComboBox, containing a list of product types as defined in
	`epnTapProductTypesStore`, which is initilized by `EpnTapModule`.

	The selection of a produt type triggers `EpnTapModule.onProductTypeCBChanged()`, which basically update
ebdc15a7   Nathanael Jourdane   remove targetclas...
478
	`epnTapGranulesGrid`.
10162678   Nathanael Jourdane   Fix the infoPanel...
479
480
481
482
483
484
	*/
	createProductTypeCB: function() {
		return {
			xtype: 'combobox',
			id: 'epnTapProductTypeCB',
			fieldLabel: 'Product type',
96550534   Nathanael Jourdane   epntap: Make prod...
485
			emptyText: 'Image, Time series, ...',
10162678   Nathanael Jourdane   Fix the infoPanel...
486
487
488
			store: Ext.data.StoreManager.lookup('productTypesStore'),
			queryMode: 'local',
			valueField: 'id',
96550534   Nathanael Jourdane   epntap: Make prod...
489
			multiSelect: true,
10162678   Nathanael Jourdane   Fix the infoPanel...
490
			displayField: 'name',
33db0a91   Nathanael Jourdane   Add Get button (wip)
491
			labelWidth: 71,
96550534   Nathanael Jourdane   epntap: Make prod...
492
			editable: false,
977e2c07   Nathanael Jourdane   Add tooltips on p...
493
494
495
496
497
			listConfig: {
				getInnerTpl: function() {
					return '<div data-qtitle="{name}" data-qwidth=200 data-qtip="<p>{desc}</p>">{name}</div>';
				}
			},
96550534   Nathanael Jourdane   epntap: Make prod...
498
			listeners: {
264edda7   Nathanael Jourdane   Set product types...
499
				change: function(cb, records) {
3345b95b   Nathanael Jourdane   nbResults refacto...
500
501
502
503
504
					var val = cb.value[cb.value.length - 1];
					if(val === 'all') {
						cb.select(cb.store.getRange().slice(2));
					} else if (val === 'clear') {
						cb.reset();
96550534   Nathanael Jourdane   epntap: Make prod...
505
					}
230b2236   Nathanael Jourdane   Add tooltip to pr...
506
507
				},
				render: function(cb) {
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
508
					new Ext.ToolTip({
230b2236   Nathanael Jourdane   Add tooltip to pr...
509
510
						target: cb.getEl(),
						html: 'Select one or several data product types (required).'
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
511
					});
ebdc15a7   Nathanael Jourdane   remove targetclas...
512
513
				}
			}
10162678   Nathanael Jourdane   Fix the infoPanel...
514
515
		};
	},
ebdc15a7   Nathanael Jourdane   remove targetclas...
516

10162678   Nathanael Jourdane   Fix the infoPanel...
517
518
519
520
521
522
523
524
525
	/**
	Create `epnTapTimeSelector`, an IntervalUI object, allowing the user to select a time interval (by filling two
	dates and/or a duration).

	See `js/app/views/IntervalUI.js` for more information about this component.
	*/
	createTimeSelector: function() {
		return {
			xtype: 'intervalSelector',
0de2b2fd   Nathanael Jourdane   fix and improve i...
526
			id: 'epnTapTimeSelector'
10162678   Nathanael Jourdane   Fix the infoPanel...
527
528
529
530
531
532
533
534
		};
	},

	/***********************
	*** Navigation panel ***
	***********************/

	/**
33db0a91   Nathanael Jourdane   Add Get button (wip)
535
536
537
538
539
540
	The button used to send the query.
	*/
	createSendButton: function() {
		return {
			xtype: 'button',
			id: 'epnTapGetBtn',
f7556592   Nathanael Jourdane   clear granules gr...
541
			text: 'Get services',
33db0a91   Nathanael Jourdane   Add Get button (wip)
542
543
			disabled: true,
			width: 140,
87467502   Nathanael Jourdane   Replace page butt...
544
545
			height: 50,
			margin: 10
33db0a91   Nathanael Jourdane   Add Get button (wip)
546
547
548
		}
	},

9655907c   Nathanael Jourdane   use a more extjs-...
549
550
551
552
	/************
	*** Grids ***
	************/

b185823c   Nathanael Jourdane   Use IntervalUI mo...
553
	/**
10162678   Nathanael Jourdane   Fix the infoPanel...
554
555
556
557
558
559
560
561
562
563
	Create `epnTapGridsPanel`, an ExtJS Panel, containing `epnTapServicesGrid` and `epnTapGranulesGrid`.

	After the rendering of the grids, it triggers `epnTapModule.onWindowLoaded()`, which basically fill
	`epnTapServicesGrid` for the first time.
	*/
	createGridsPanel: function() {
		return {
			xtype: 'panel',
			id: 'epnTapGridsPanel',
			layout: 'fit',
33db0a91   Nathanael Jourdane   Add Get button (wip)
564
			height: 440,
10162678   Nathanael Jourdane   Fix the infoPanel...
565
566
567
568
569
570
571
572
573
574
575
576
			region: 'center',
			items: [{
				xtype: 'container',
				layout: { type: 'hbox', pack: 'start', align: 'stretch'},
				items: [
					this.createServicesGrid(),
					this.createGranulesGrid()
				]
			}]
		};
	},

10162678   Nathanael Jourdane   Fix the infoPanel...
577
	/**
9655907c   Nathanael Jourdane   use a more extjs-...
578
579
	Create `epnTapServicesGrid`, an ExtJS grid containing the EPN-TAP services matching with the filter form
	(`serviceFilterPanel`).
b185823c   Nathanael Jourdane   Use IntervalUI mo...
580

9655907c   Nathanael Jourdane   use a more extjs-...
581
582
583
	For each service, this grid displays:
	- the service name;
	- the number of granules matching with the filter.
b185823c   Nathanael Jourdane   Use IntervalUI mo...
584

9655907c   Nathanael Jourdane   use a more extjs-...
585
586
587
588
589
590
591
	Other informations are available through an ExtJS Tooltip, on each row:
	- short name;
	- title;
	- access URL.

	A click on a service triggers `EpnTapModule.onServiceSelected()`, which basically fills `GranulesGrid` by the
	service granules.
b185823c   Nathanael Jourdane   Use IntervalUI mo...
592
	*/
9655907c   Nathanael Jourdane   use a more extjs-...
593
	createServicesGrid: function() {
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
594
595
		return {
			xtype: 'grid',
9655907c   Nathanael Jourdane   use a more extjs-...
596
597
598
599
			id: 'epnTapServicesGrid',
			title: 'Services',
			store: Ext.data.StoreManager.lookup('servicesStore'),
			flex: 1,
9655907c   Nathanael Jourdane   use a more extjs-...
600
			columns: [
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
601
602
				{text: 'Name', dataIndex: 'short_name', flex: 1, renderer: 'service.text'},
				{text: 'Nb res.', dataIndex: 'nb_results', width: 50, renderer: 'service.number'}
9655907c   Nathanael Jourdane   use a more extjs-...
603
			],
9655907c   Nathanael Jourdane   use a more extjs-...
604
			viewConfig: {
9655907c   Nathanael Jourdane   use a more extjs-...
605
				getRowClass: function(record, index) {
49401187   Nathanael Jourdane   epntap: Do not us...
606
					var nb_res = record.get('nb_results');
3345b95b   Nathanael Jourdane   nbResults refacto...
607
					if(nb_res == 0 || nb_res == -1) {
9655907c   Nathanael Jourdane   use a more extjs-...
608
						return 'disabled_row';
3345b95b   Nathanael Jourdane   nbResults refacto...
609
610
					} else if (nb_res == -2) {
						return 'error_row';
8d5634e3   Nathanael Jourdane   Use epn-tap store...
611
					}
9655907c   Nathanael Jourdane   use a more extjs-...
612
				}
9655907c   Nathanael Jourdane   use a more extjs-...
613
			}
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
614
		};
9655907c   Nathanael Jourdane   use a more extjs-...
615
	},
b185823c   Nathanael Jourdane   Use IntervalUI mo...
616

9655907c   Nathanael Jourdane   use a more extjs-...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
	/**
	Create `epnTapGranulesGrid`, an ExtJS grid containing the granules of the selected service in
	`epnTapServicesGrid`.

	For each granule, this grid displays:
	- the row number;
	- the dataproduct type;
	- the target name;
	- the min and max times;
	- the format;
	- the UID (granule identifier);
	- the estimated size;
	- the URL;
	- the thumbnail.

	Each of these information are displayed in a specific rendering to improve user experience.
	For more information about these parameters, see https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters.

	Other informations are available through an ExtJS Tooltip on each row:
	- currently only the granule thumbnail, in full size.

	A click on a granule triggers `EpnTapModule.onGranuleSelected()`.
9655907c   Nathanael Jourdane   use a more extjs-...
639
640
	*/
	createGranulesGrid: function() {
465b7a40   Nathanael Jourdane   Escape quotes in ...
641
642
		return {
			xtype: 'grid',
9655907c   Nathanael Jourdane   use a more extjs-...
643
644
645
646
			id: 'epnTapGranulesGrid',
			title: 'Granules',
			store: Ext.data.StoreManager.lookup('granulesStore'),
			flex: 4,
016bdaae   Nathanael Jourdane   Fix bad rendering...
647
648
649
650
651
			plugins: {
				ptype: 'bufferedrenderer',
				trailingBufferZone: 20,
				leadingBufferZone: 50
			},
11f8b45b   Nathanael Jourdane   Use buffered scro...
652
			columns: []
465b7a40   Nathanael Jourdane   Escape quotes in ...
653
		};
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
654
655
	}
});