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
170
171
			Ext.Ajax.suspendEvent('requestexception');
			Ext.Ajax.abortAll();
			var service = Ext.data.StoreManager.lookup('servicesStore').getById(store.selectedService).data;
11f8b45b   Nathanael Jourdane   Use buffered scro...
172
173
174
175
176
177
178
179
180
181
182
			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
183
		'prefetch': function(store, records, successful, operation) {
30cd92df   Roipoussiere   Fix merge conflicts
184
			// console.log('(prefetch) operation ' + (successful ? 'success' : 'failed') + ': ', operation);
6d616600   Nathanael Jourdane   Fix granules sorter
185
186
187
			// console.log(operation.params);
			// console.log(Ext.decode(operation.response.responseText));
		},
a8a12768   Nathanael Jourdane   Create the grid m...
188
		'metachange': function(store, meta) {
a5475297   Nathanael Jourdane   use a hash for me...
189
190
191
192
			if(meta.metaHash != store.metaHash) {
				Ext.getCmp('epnTapGranulesGrid').reconfigure(store, meta.columns);
				store.metaHash = meta.metaHash;
			}
a8a12768   Nathanael Jourdane   Create the grid m...
193
194
		}
	}
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
195
196
});

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

	// Utils

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

	// Services grid

24fcdbc7   Nathanael Jourdane   Fix crash when ep...
211
	'serviceTooltip': function(value, data) {
465b7a40   Nathanael Jourdane   Escape quotes in ...
212
213
214
215
216
		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...
217
		var infoColor = data.nb_results == -2 ? 'IndianRed' : 'green';
465b7a40   Nathanael Jourdane   Escape quotes in ...
218
		var info = data.info.length > 0 ? '<p style="color:' + infoColor + '">' + data.info + '</p>' : '';
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
219
220
221

		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 ...
222
223
224
225
		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...
226
227
			}
		}
465b7a40   Nathanael Jourdane   Escape quotes in ...
228
		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...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
	},
	'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 ...
244
245
246
247
248
249
250
251
252
253
254
255
256
257

	// 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 ...
258
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
259
	'granule.link': function(data, metadata, record) {
e0a60d33   Nathanael Jourdane   Fix link bug and ...
260
		return Ext.util.Format.granuleTooltip('<a style="font-size:150%" target="_blank" href="' + data + '">&#x1F5D7;</a>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
261
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
262
263
	'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 ...
264
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
265
	'granule.type': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
266
		var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map;
465b7a40   Nathanael Jourdane   Escape quotes in ...
267
		return Ext.util.Format.granuleTooltip('<p>' + productTypeDict[data].data.name + '</p>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
268
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
269
	'granule.size': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
270
271
272
273
274
275
276
277
278
279
		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 ...
280
		return Ext.util.Format.granuleTooltip('<p>' + txt + '</p>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
281
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
282
	'granule.proc_lvl': function(data, metadata, record) {
c7967cba   Nathanael Jourdane   Improve display f...
283
		var levels = {1: 'Raw', 2: 'Edited', 3: 'Calibrated', 4: 'Resampled', 5: 'Derived', 6: 'Ancillary'};
465b7a40   Nathanael Jourdane   Escape quotes in ...
284
		return Ext.util.Format.granuleTooltip((data in levels) ? '<p>' + levels[data] + '</p>' : '<em>' + data + '</em>', record.data);
c7967cba   Nathanael Jourdane   Improve display f...
285
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
286
	'granule.date': function(data, metadata, record) {
07382ff2   Nathanael Jourdane   Format dates
287
288
289
290
291
292
293
294
295
296
		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 ...
297
		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 ...
298
	},
465b7a40   Nathanael Jourdane   Escape quotes in ...
299
	'granule.format': function(data, metadata, record) {
7211d9b5   Nathanael Jourdane   Move util.Format ...
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
346
347
		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 ...
348
		return Ext.util.Format.granuleTooltip((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>', record.data);
7211d9b5   Nathanael Jourdane   Move util.Format ...
349
350
351
	}
});

b185823c   Nathanael Jourdane   Use IntervalUI mo...
352
353
354
355
356
357
/**
`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 ...
358
Ext.define('amdaUI.EpnTapUI', {
b185823c   Nathanael Jourdane   Use IntervalUI mo...
359
	extend: 'Ext.panel.Panel',
78c2f505   Nathanael Jourdane   Improve granules ...
360
	alias: 'widget.panelEpnTap',
b185823c   Nathanael Jourdane   Use IntervalUI mo...
361
	requires: ['amdaUI.IntervalUI'],
78c2f505   Nathanael Jourdane   Improve granules ...
362

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

10162678   Nathanael Jourdane   Fix the infoPanel...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
	/**
	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
389
					this.createGridsPanel()
10162678   Nathanael Jourdane   Fix the infoPanel...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
				]
			}]
		};
		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...
408
			xtype: 'form',
10162678   Nathanael Jourdane   Fix the infoPanel...
409
410
411
			id: 'epnTapServiceFilterPanel',
			layout: { type: 'hbox', pack: 'start', align: 'stretch' },
			region: 'north',
33db0a91   Nathanael Jourdane   Add Get button (wip)
412
			defaults: { margin: '5 0 5 5'},
10162678   Nathanael Jourdane   Fix the infoPanel...
413
414
			items: [{ // Left part
				xtype : 'container',
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
415
				flex: 1,
10162678   Nathanael Jourdane   Fix the infoPanel...
416
				items: [
10162678   Nathanael Jourdane   Fix the infoPanel...
417
					this.createTargetNameCB(),
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
418
					this.createProductTypeCB()
10162678   Nathanael Jourdane   Fix the infoPanel...
419
				]
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
420
421
422
			}, { // Middle part
				xtype : 'container',
				flex: 1,
10162678   Nathanael Jourdane   Fix the infoPanel...
423
424
425
				items: [
					this.createTimeSelector()
				]
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
426
427
			}, { // Right part
				xtype : 'container',
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
428
				items: [
33db0a91   Nathanael Jourdane   Add Get button (wip)
429
					this.createSendButton()
ebd733ce   Nathanael Jourdane   epntap: Reorder f...
430
431
				]

10162678   Nathanael Jourdane   Fix the infoPanel...
432
433
434
435
			}]
		};
	},

230b2236   Nathanael Jourdane   Add tooltip to pr...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
		/**
		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...
461
						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...
462
463
464
465
466
467
468
469
470
471
472
473
474
					}
				},
				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...
475
476
477
478
479
	/**
	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...
480
	`epnTapGranulesGrid`.
10162678   Nathanael Jourdane   Fix the infoPanel...
481
482
483
484
485
486
	*/
	createProductTypeCB: function() {
		return {
			xtype: 'combobox',
			id: 'epnTapProductTypeCB',
			fieldLabel: 'Product type',
96550534   Nathanael Jourdane   epntap: Make prod...
487
			emptyText: 'Image, Time series, ...',
10162678   Nathanael Jourdane   Fix the infoPanel...
488
489
490
			store: Ext.data.StoreManager.lookup('productTypesStore'),
			queryMode: 'local',
			valueField: 'id',
96550534   Nathanael Jourdane   epntap: Make prod...
491
			multiSelect: true,
10162678   Nathanael Jourdane   Fix the infoPanel...
492
			displayField: 'name',
33db0a91   Nathanael Jourdane   Add Get button (wip)
493
			labelWidth: 71,
96550534   Nathanael Jourdane   epntap: Make prod...
494
			editable: false,
977e2c07   Nathanael Jourdane   Add tooltips on p...
495
496
497
498
499
			listConfig: {
				getInnerTpl: function() {
					return '<div data-qtitle="{name}" data-qwidth=200 data-qtip="<p>{desc}</p>">{name}</div>';
				}
			},
96550534   Nathanael Jourdane   epntap: Make prod...
500
			listeners: {
264edda7   Nathanael Jourdane   Set product types...
501
				change: function(cb, records) {
3345b95b   Nathanael Jourdane   nbResults refacto...
502
503
504
505
506
					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...
507
					}
230b2236   Nathanael Jourdane   Add tooltip to pr...
508
509
				},
				render: function(cb) {
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
510
					new Ext.ToolTip({
230b2236   Nathanael Jourdane   Add tooltip to pr...
511
512
						target: cb.getEl(),
						html: 'Select one or several data product types (required).'
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
513
					});
ebdc15a7   Nathanael Jourdane   remove targetclas...
514
515
				}
			}
10162678   Nathanael Jourdane   Fix the infoPanel...
516
517
		};
	},
ebdc15a7   Nathanael Jourdane   remove targetclas...
518

10162678   Nathanael Jourdane   Fix the infoPanel...
519
520
521
522
523
524
525
526
527
	/**
	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...
528
			id: 'epnTapTimeSelector'
10162678   Nathanael Jourdane   Fix the infoPanel...
529
530
531
532
533
534
535
536
		};
	},

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

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

9655907c   Nathanael Jourdane   use a more extjs-...
551
552
553
554
	/************
	*** Grids ***
	************/

b185823c   Nathanael Jourdane   Use IntervalUI mo...
555
	/**
10162678   Nathanael Jourdane   Fix the infoPanel...
556
557
558
559
560
561
562
563
564
565
	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)
566
			height: 440,
10162678   Nathanael Jourdane   Fix the infoPanel...
567
568
569
570
571
572
573
574
575
576
577
578
			region: 'center',
			items: [{
				xtype: 'container',
				layout: { type: 'hbox', pack: 'start', align: 'stretch'},
				items: [
					this.createServicesGrid(),
					this.createGranulesGrid()
				]
			}]
		};
	},

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

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

9655907c   Nathanael Jourdane   use a more extjs-...
587
588
589
590
591
592
593
	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...
594
	*/
9655907c   Nathanael Jourdane   use a more extjs-...
595
	createServicesGrid: function() {
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
596
597
		return {
			xtype: 'grid',
9655907c   Nathanael Jourdane   use a more extjs-...
598
599
600
601
			id: 'epnTapServicesGrid',
			title: 'Services',
			store: Ext.data.StoreManager.lookup('servicesStore'),
			flex: 1,
9655907c   Nathanael Jourdane   use a more extjs-...
602
			columns: [
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
603
604
				{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-...
605
			],
9655907c   Nathanael Jourdane   use a more extjs-...
606
			viewConfig: {
9655907c   Nathanael Jourdane   use a more extjs-...
607
				getRowClass: function(record, index) {
49401187   Nathanael Jourdane   epntap: Do not us...
608
					var nb_res = record.get('nb_results');
3345b95b   Nathanael Jourdane   nbResults refacto...
609
					if(nb_res == 0 || nb_res == -1) {
9655907c   Nathanael Jourdane   use a more extjs-...
610
						return 'disabled_row';
3345b95b   Nathanael Jourdane   nbResults refacto...
611
612
					} else if (nb_res == -2) {
						return 'error_row';
8d5634e3   Nathanael Jourdane   Use epn-tap store...
613
					}
9655907c   Nathanael Jourdane   use a more extjs-...
614
				}
9655907c   Nathanael Jourdane   use a more extjs-...
615
			}
24fcdbc7   Nathanael Jourdane   Fix crash when ep...
616
		};
9655907c   Nathanael Jourdane   use a more extjs-...
617
	},
b185823c   Nathanael Jourdane   Use IntervalUI mo...
618

9655907c   Nathanael Jourdane   use a more extjs-...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
	/**
	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-...
641
642
	*/
	createGranulesGrid: function() {
465b7a40   Nathanael Jourdane   Escape quotes in ...
643
644
		return {
			xtype: 'grid',
9655907c   Nathanael Jourdane   use a more extjs-...
645
646
647
648
			id: 'epnTapGranulesGrid',
			title: 'Granules',
			store: Ext.data.StoreManager.lookup('granulesStore'),
			flex: 4,
016bdaae   Nathanael Jourdane   Fix bad rendering...
649
650
651
652
653
			plugins: {
				ptype: 'bufferedrenderer',
				trailingBufferZone: 20,
				leadingBufferZone: 50
			},
11f8b45b   Nathanael Jourdane   Use buffered scro...
654
			columns: []
465b7a40   Nathanael Jourdane   Escape quotes in ...
655
		};
3fc0b658   Nathanael Jourdane   Add EPN-TAP modul...
656
657
	}
});