Commit 428eb66e9a862ce84908e6bc08a0d11403d813ae
1 parent
80d30e39
Exists in
master
and in
111 other branches
Use JS standard coding convention
Showing
2 changed files
with
758 additions
and
758 deletions
Show diff stats
js/app/controllers/EpnTapModule.js
1 | 1 | /** |
2 | 2 | * Project : AMDA-NG |
3 | - * Name : EpnTapModule.js | |
3 | + * Name : EpnTapModule.js | |
4 | 4 | * @class amdaDesktop.EpnTapModule |
5 | 5 | * @extends amdaDesktop.AmdaModule |
6 | 6 | * @brief EpnTap Module controller definition |
... | ... | @@ -9,175 +9,175 @@ |
9 | 9 | |
10 | 10 | Ext.define('amdaDesktop.EpnTapModule', { |
11 | 11 | |
12 | - extend: 'amdaDesktop.AmdaModule', | |
13 | - requires: ['amdaUI.EpnTapUI'], | |
14 | - contentId : 'EpnTapUI', | |
15 | - | |
16 | - /** The alias name of the module view. */ | |
17 | - // uiType: 'panelEpnTap', | |
18 | - uiType : 'panelEpnTap', | |
19 | - | |
20 | - /** The text displayed on the *help button* tooltip. */ | |
21 | - helpTitle: 'Help on EPN-TAP Module', | |
22 | - | |
23 | - /** The name of the documentation file related to the module. */ | |
24 | - helpFile : 'epnTapHelp', | |
25 | - | |
26 | - /** | |
27 | - Module initialisation. Called the first time that the user open the epnTap module. | |
28 | - */ | |
29 | - init: function() { | |
30 | - this.launcher = { | |
31 | - text: this.title, | |
32 | - iconCls: this.icon, | |
33 | - handler: this.createWindow, | |
34 | - scope: this | |
35 | - }; | |
36 | - }, | |
37 | - | |
38 | - /** | |
39 | - Called each time the epntap module is loaded. | |
40 | - - `target`: an array of 3 values: [target_name, dataproduct_type]; or null. | |
41 | - */ | |
42 | - loadTarget: function(filter) { | |
43 | - this.aquireElements(); | |
44 | - this.addListeners(); | |
45 | - | |
46 | - this.servicesStore.each(function(record) { | |
47 | - record.set('nb_results', -1); | |
48 | - }, this); | |
49 | - this.granulesStore.removeAll(); | |
50 | - | |
51 | - if(filter) { | |
52 | - this.targetNameCB.setRawValue(filter['targetName']); | |
53 | - this.productTypeCB.select(filter['productType']); | |
54 | - this.getServices(); | |
55 | - } | |
56 | - }, | |
57 | - | |
58 | - aquireElements: function() { | |
59 | - // UI elements | |
60 | - this.servicesGrid = Ext.getCmp('epnTapServicesGrid'); | |
61 | - this.granulesGrid = Ext.getCmp('epnTapGranulesGrid'); | |
62 | - this.productTypeCB = Ext.getCmp('epnTapProductTypeCB'); | |
63 | - this.targetNameCB = Ext.getCmp('epnTapTargetNameCB'); | |
64 | - this.timeSelector = Ext.getCmp('epnTapTimeSelector'); | |
65 | - this.getBtn = Ext.getCmp('epnTapGetBtn'); | |
66 | - | |
67 | - // stores elements | |
68 | - this.servicesStore = Ext.data.StoreManager.lookup('servicesStore'); | |
69 | - this.granulesStore = Ext.data.StoreManager.lookup('granulesStore'); | |
70 | - this.productTypesStore = Ext.data.StoreManager.lookup('productTypesStore'); | |
71 | - this.targetNamesStore = Ext.data.StoreManager.lookup('targetNamesStore'); | |
72 | - }, | |
73 | - | |
74 | - addListeners: function() { | |
75 | - this.targetNameCB.on('change', function() { | |
76 | - this.updateGetBtnStatus(); | |
77 | - }, this); | |
78 | - | |
79 | - this.productTypeCB.on('change', function() { | |
80 | - this.updateGetBtnStatus(); | |
81 | - }, this); | |
82 | - | |
83 | - this.servicesGrid.on('cellclick', function(grid, td, cellIndex, record) { | |
84 | - this.onServiceSelected(record); | |
85 | - }, this); | |
86 | - | |
87 | - this.getBtn.on('click', function() { | |
88 | - this.getServices(); | |
89 | - }, this); | |
90 | - }, | |
91 | - | |
92 | - /********************** | |
93 | - *** Utils functions *** | |
94 | - **********************/ | |
95 | - | |
96 | - updateGetBtnStatus: function() { | |
97 | - var shouldEnabled = this.targetNameCB.rawValue.length > 0 && this.productTypeCB.rawValue.length > 0; | |
98 | - if(shouldEnabled) { | |
99 | - this.getBtn.enable(); | |
100 | - } else { | |
101 | - this.getBtn.disable(); | |
102 | - } | |
103 | - }, | |
104 | - | |
105 | - /************* | |
106 | - *** Events *** | |
107 | - *************/ | |
108 | - | |
109 | - /** | |
110 | - Trigerred when the 'Get results' button is clicked. | |
111 | - */ | |
112 | - getServices: function() { | |
113 | - this.granulesStore.removeAll(); | |
114 | - var targetName = this.targetNameCB.rawValue; | |
115 | - var productTypes = this.productTypeCB.value.join(';'); | |
116 | - var timeMin = Ext.Date.format(this.timeSelector.getStartTime(), 'd/m/Y H:i:s'); // start time | |
117 | - var timeMax = Ext.Date.format(this.timeSelector.getStopTime(), 'd/m/Y H:i:s'); // stop time | |
118 | - | |
119 | - loadMask.show(); | |
120 | - this.servicesStore.each(function(record) { | |
121 | - // TODO: use store.load() method instead and add 'success' and 'enable' columns in the store | |
122 | - Ext.Ajax.request({ | |
123 | - url: 'php/epntap.php', | |
124 | - method: 'GET', | |
125 | - headers: {'Content-Type': 'application/json'}, | |
126 | - params: { | |
127 | - 'action': 'getNbResults', | |
128 | - 'serviceId': record.data['id'], | |
129 | - 'url': record.data['access_url'], | |
130 | - 'tableName': record.data['table_name'], | |
131 | - 'targetNames': targetName, | |
132 | - 'productTypes': productTypes, | |
133 | - 'timeMin': timeMin, | |
134 | - 'timeMax': timeMax | |
135 | - }, | |
136 | - // timeout: 3000, | |
137 | - success: function(response, options) { | |
138 | - var record = this.servicesStore.getById(options.params['serviceId']); | |
139 | - var responseObj = Ext.decode(response.responseText); | |
140 | - this.updateService(record, responseObj['success'] ? responseObj['data'] : -2, responseObj['msg']); | |
141 | - }, | |
142 | - failure: function(response, options) { | |
143 | - var record = this.servicesStore.getById(options.params['serviceId']); | |
144 | - this.updateService(record, -1, response.statusText); | |
145 | - }, | |
146 | - scope: this | |
147 | - }); | |
148 | - }, this); | |
149 | - }, | |
150 | - | |
151 | - /** | |
152 | - Update the nb_result field of the services store (see `EpnTapUI.servicesStore`), according to the field values in `serviceFilterPanel`. | |
153 | - */ | |
154 | - updateService: function(record, nbRes, info) { | |
155 | - record.set('nb_results', nbRes); | |
156 | - record.set('info', info); | |
157 | - this.servicesStore.sort(); | |
158 | - loadMask.hide(); | |
159 | - }, | |
160 | - | |
161 | - /** | |
162 | - Trigerred when a row is clicked in `servicesGrid` table (see `EpnTapUI.createServicesGrid()`). Among other things, | |
163 | - send a new query and fill `granulesGrid`. | |
164 | - */ | |
165 | - onServiceSelected: function(record) { | |
166 | - this.granulesStore.selectedService = record.data.id; | |
167 | - Ext.Ajax.suspendEvent('requestexception'); | |
168 | - Ext.Ajax.abortAll(); | |
169 | - | |
170 | - if(record.get('nb_results') > 0) { | |
171 | - this.granulesStore.removeAll(); | |
172 | - this.granulesStore.load({ | |
173 | - callback: function (records, operation, success) { | |
174 | - Ext.Ajax.resumeEvents('requestexception'); | |
175 | - // console.log(Ext.decode(operation.response.responseText)); | |
176 | - }, | |
177 | - start: 0, | |
178 | - limit: this.granulesStore.pageSize, | |
179 | - scope: this | |
180 | - }); | |
181 | - } | |
182 | - } | |
183 | -}); | |
12 | + extend: 'amdaDesktop.AmdaModule', | |
13 | + requires: ['amdaUI.EpnTapUI'], | |
14 | + contentId: 'EpnTapUI', | |
15 | + | |
16 | + /** The alias name of the module view. */ | |
17 | + // uiType: 'panelEpnTap', | |
18 | + uiType: 'panelEpnTap', | |
19 | + | |
20 | + /** The text displayed on the *help button* tooltip. */ | |
21 | + helpTitle: 'Help on EPN-TAP Module', | |
22 | + | |
23 | + /** The name of the documentation file related to the module. */ | |
24 | + helpFile: 'epnTapHelp', | |
25 | + | |
26 | + /** | |
27 | + Module initialisation. Called the first time that the user open the epnTap module. | |
28 | + */ | |
29 | + init: function () { | |
30 | + this.launcher = { | |
31 | + text: this.title, | |
32 | + iconCls: this.icon, | |
33 | + handler: this.createWindow, | |
34 | + scope: this | |
35 | + } | |
36 | + }, | |
37 | + | |
38 | + /** | |
39 | + Called each time the epntap module is loaded. | |
40 | + - `target`: an array of 3 values: [target_name, dataproduct_type]; or null. | |
41 | + */ | |
42 | + loadTarget: function (filter) { | |
43 | + this.aquireElements() | |
44 | + this.addListeners() | |
45 | + | |
46 | + this.servicesStore.each(function (record) { | |
47 | + record.set('nb_results', -1) | |
48 | + }, this) | |
49 | + this.granulesStore.removeAll() | |
50 | + | |
51 | + if (filter) { | |
52 | + this.targetNameCB.setRawValue(filter['targetName']) | |
53 | + this.productTypeCB.select(filter['productType']) | |
54 | + this.getServices() | |
55 | + } | |
56 | + }, | |
57 | + | |
58 | + aquireElements: function () { | |
59 | + // UI elements | |
60 | + this.servicesGrid = Ext.getCmp('epnTapServicesGrid') | |
61 | + this.granulesGrid = Ext.getCmp('epnTapGranulesGrid') | |
62 | + this.productTypeCB = Ext.getCmp('epnTapProductTypeCB') | |
63 | + this.targetNameCB = Ext.getCmp('epnTapTargetNameCB') | |
64 | + this.timeSelector = Ext.getCmp('epnTapTimeSelector') | |
65 | + this.getBtn = Ext.getCmp('epnTapGetBtn') | |
66 | + | |
67 | + // stores elements | |
68 | + this.servicesStore = Ext.data.StoreManager.lookup('servicesStore') | |
69 | + this.granulesStore = Ext.data.StoreManager.lookup('granulesStore') | |
70 | + this.productTypesStore = Ext.data.StoreManager.lookup('productTypesStore') | |
71 | + this.targetNamesStore = Ext.data.StoreManager.lookup('targetNamesStore') | |
72 | + }, | |
73 | + | |
74 | + addListeners: function () { | |
75 | + this.targetNameCB.on('change', function () { | |
76 | + this.updateGetBtnStatus() | |
77 | + }, this) | |
78 | + | |
79 | + this.productTypeCB.on('change', function () { | |
80 | + this.updateGetBtnStatus() | |
81 | + }, this) | |
82 | + | |
83 | + this.servicesGrid.on('cellclick', function (grid, td, cellIndex, record) { | |
84 | + this.onServiceSelected(record) | |
85 | + }, this) | |
86 | + | |
87 | + this.getBtn.on('click', function () { | |
88 | + this.getServices() | |
89 | + }, this) | |
90 | + }, | |
91 | + | |
92 | + /********************** | |
93 | + *** Utils functions *** | |
94 | + **********************/ | |
95 | + | |
96 | + updateGetBtnStatus: function () { | |
97 | + var shouldEnabled = this.targetNameCB.rawValue.length > 0 && this.productTypeCB.rawValue.length > 0 | |
98 | + if (shouldEnabled) { | |
99 | + this.getBtn.enable() | |
100 | + } else { | |
101 | + this.getBtn.disable() | |
102 | + } | |
103 | + }, | |
104 | + | |
105 | + /************* | |
106 | + *** Events *** | |
107 | + *************/ | |
108 | + | |
109 | + /** | |
110 | + Trigerred when the 'Get results' button is clicked. | |
111 | + */ | |
112 | + getServices: function () { | |
113 | + this.granulesStore.removeAll() | |
114 | + var targetName = this.targetNameCB.rawValue | |
115 | + var productTypes = this.productTypeCB.value.join(';') | |
116 | + var timeMin = Ext.Date.format(this.timeSelector.getStartTime(), 'd/m/Y H:i:s') // start time | |
117 | + var timeMax = Ext.Date.format(this.timeSelector.getStopTime(), 'd/m/Y H:i:s') // stop time | |
118 | + | |
119 | + loadMask.show() | |
120 | + this.servicesStore.each(function (record) { | |
121 | + // TODO: use store.load() method instead and add 'success' and 'enable' columns in the store | |
122 | + Ext.Ajax.request({ | |
123 | + url: 'php/epntap.php', | |
124 | + method: 'GET', | |
125 | + headers: {'Content-Type': 'application/json'}, | |
126 | + params: { | |
127 | + 'action': 'getNbResults', | |
128 | + 'serviceId': record.data['id'], | |
129 | + 'url': record.data['access_url'], | |
130 | + 'tableName': record.data['table_name'], | |
131 | + 'targetNames': targetName, | |
132 | + 'productTypes': productTypes, | |
133 | + 'timeMin': timeMin, | |
134 | + 'timeMax': timeMax | |
135 | + }, | |
136 | + // timeout: 3000, | |
137 | + success: function (response, options) { | |
138 | + var record = this.servicesStore.getById(options.params['serviceId']) | |
139 | + var responseObj = Ext.decode(response.responseText) | |
140 | + this.updateService(record, responseObj['success'] ? responseObj['data'] : -2, responseObj['msg']) | |
141 | + }, | |
142 | + failure: function (response, options) { | |
143 | + var record = this.servicesStore.getById(options.params['serviceId']) | |
144 | + this.updateService(record, -1, response.statusText) | |
145 | + }, | |
146 | + scope: this | |
147 | + }) | |
148 | + }, this) | |
149 | + }, | |
150 | + | |
151 | + /** | |
152 | + Update the nb_result field of the services store (see `EpnTapUI.servicesStore`), according to the field values in `serviceFilterPanel`. | |
153 | + */ | |
154 | + updateService: function (record, nbRes, info) { | |
155 | + record.set('nb_results', nbRes) | |
156 | + record.set('info', info) | |
157 | + this.servicesStore.sort() | |
158 | + loadMask.hide() | |
159 | + }, | |
160 | + | |
161 | + /** | |
162 | + Trigerred when a row is clicked in `servicesGrid` table (see `EpnTapUI.createServicesGrid()`). Among other things, | |
163 | + send a new query and fill `granulesGrid`. | |
164 | + */ | |
165 | + onServiceSelected: function (record) { | |
166 | + this.granulesStore.selectedService = record.data.id | |
167 | + Ext.Ajax.suspendEvent('requestexception') | |
168 | + Ext.Ajax.abortAll() | |
169 | + | |
170 | + if (record.get('nb_results') > 0) { | |
171 | + this.granulesStore.removeAll() | |
172 | + this.granulesStore.load({ | |
173 | + callback: function (records, operation, success) { | |
174 | + Ext.Ajax.resumeEvents('requestexception') | |
175 | + // console.log(Ext.decode(operation.response.responseText)); | |
176 | + }, | |
177 | + start: 0, | |
178 | + limit: this.granulesStore.pageSize, | |
179 | + scope: this | |
180 | + }) | |
181 | + } | |
182 | + } | |
183 | +}) | |
... | ... |
js/app/views/EpnTapUI.js
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | * 24/10/2016: file creation |
8 | 8 | */ |
9 | 9 | |
10 | -Ext.require(['Ext.grid.plugin.BufferedRenderer']); | |
10 | +Ext.require(['Ext.grid.plugin.BufferedRenderer']) | |
11 | 11 | /** |
12 | 12 | `productTypesStore`: An ExtJS Store containing the list of the different data product types defined on all granules, on |
13 | 13 | all available EPN-TAP services (defined in `generic_data/EpnTapData/metadata.json`, updated periodically with a cron |
... | ... | @@ -16,7 +16,7 @@ script). |
16 | 16 | This list is used to fill the `productTypeCB` combo box, which is initilized in `EpnTapModule` at the panel creation. |
17 | 17 | |
18 | 18 | - `id`: the data product type IDs, according to the EPN-TAP specification (see |
19 | - https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=1148225); | |
19 | + https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=1148225); | |
20 | 20 | - `name`: the data product name, according to the EPN-TAP specification (ibid). |
21 | 21 | |
22 | 22 | These IDs and names are hard-defined in the JSon file `generic_data/EpnTapData/dataproduct_types.json`. |
... | ... | @@ -28,26 +28,26 @@ in this store and an information message is displayed on the JavaScript console |
28 | 28 | store. |
29 | 29 | */ |
30 | 30 | Ext.create('Ext.data.Store', { |
31 | - storeId: 'productTypesStore', | |
32 | - autoLoad: true, | |
33 | - fields: ['id', 'name', 'desc'], | |
34 | - data: [ | |
35 | - {'id': 'all', 'name': '--All--', 'desc': 'Select all produt types.'}, | |
36 | - {'id': 'clear', 'name': '--Clear--', 'desc': 'Clear the selection.'}, | |
37 | - {'id': 'im', 'name': 'Image', 'desc': '2D series of values depending on 2 spatial axes, with measured parameters.'}, | |
38 | - {'id': 'ma', 'name': 'Map', 'desc': '2D series of values depending on 2 spatial axes, with derived parameters.'}, | |
39 | - {'id': 'sp', 'name': 'Spectrum', 'desc': '1D series of values depending on a spectral axis (or Frequency, Energy, Mass,...).'}, | |
40 | - {'id': 'ds', 'name': 'Dynamic spectrum', 'desc': '2D series of values depending on time and on a spectral axis (Frequency, Energy, Mass,...), FoV is homogeneous.'}, | |
41 | - {'id': 'sc', 'name': 'Spectral cube', 'desc': '3D series of values depending on 2 spatial axes and on a spectral axis (Frequency, Energy, Mass,..).'}, | |
42 | - {'id': 'pr', 'name': 'Profile', 'desc': '1D series of values depending on a spatial axis.'}, | |
43 | - {'id': 'vo', 'name': 'Volume', 'desc': '3D series of values depending on 3 spatial axes (spatial coordinates or tabulated values in a volumic grid).'}, | |
44 | - {'id': 'mo', 'name': 'Movie', 'desc': '3D series of values depending on 2 spatial axes and on time.'}, | |
45 | - // {'id': 'cu', 'name': 'Cube', 'desc': '.'}, | |
46 | - {'id': 'ts', 'name': 'Time series', 'desc': '1D series of values depending on time.'}, | |
47 | - {'id': 'ca', 'name': 'Catalogue', 'desc': '1D list of elements.'}, | |
48 | - {'id': 'ci', 'name': 'Catalogue item', 'desc': '0D list of elements.'} | |
49 | - ] | |
50 | -}); | |
31 | + storeId: 'productTypesStore', | |
32 | + autoLoad: true, | |
33 | + fields: ['id', 'name', 'desc'], | |
34 | + data: [ | |
35 | + {'id': 'all', 'name': '--All--', 'desc': 'Select all produt types.'}, | |
36 | + {'id': 'clear', 'name': '--Clear--', 'desc': 'Clear the selection.'}, | |
37 | + {'id': 'im', 'name': 'Image', 'desc': '2D series of values depending on 2 spatial axes, with measured parameters.'}, | |
38 | + {'id': 'ma', 'name': 'Map', 'desc': '2D series of values depending on 2 spatial axes, with derived parameters.'}, | |
39 | + {'id': 'sp', 'name': 'Spectrum', 'desc': '1D series of values depending on a spectral axis (or Frequency, Energy, Mass,...).'}, | |
40 | + {'id': 'ds', 'name': 'Dynamic spectrum', 'desc': '2D series of values depending on time and on a spectral axis (Frequency, Energy, Mass,...), FoV is homogeneous.'}, | |
41 | + {'id': 'sc', 'name': 'Spectral cube', 'desc': '3D series of values depending on 2 spatial axes and on a spectral axis (Frequency, Energy, Mass,..).'}, | |
42 | + {'id': 'pr', 'name': 'Profile', 'desc': '1D series of values depending on a spatial axis.'}, | |
43 | + {'id': 'vo', 'name': 'Volume', 'desc': '3D series of values depending on 3 spatial axes (spatial coordinates or tabulated values in a volumic grid).'}, | |
44 | + {'id': 'mo', 'name': 'Movie', 'desc': '3D series of values depending on 2 spatial axes and on time.'}, | |
45 | + // {'id': 'cu', 'name': 'Cube', 'desc': '.'}, | |
46 | + {'id': 'ts', 'name': 'Time series', 'desc': '1D series of values depending on time.'}, | |
47 | + {'id': 'ca', 'name': 'Catalogue', 'desc': '1D list of elements.'}, | |
48 | + {'id': 'ci', 'name': 'Catalogue item', 'desc': '0D list of elements.'} | |
49 | + ] | |
50 | +}) | |
51 | 51 | |
52 | 52 | /** |
53 | 53 | `targetNamesStore`: An ExtJS Store containing the list of the different target names defined on all granules, on |
... | ... | @@ -61,23 +61,23 @@ This list is used to fill the `targetNameCB` combo box, which is updated by `Epn |
61 | 61 | - `name`: the target name, capitalized with spaces between each word (done `EpnTapModule.prettify()`). |
62 | 62 | */ |
63 | 63 | Ext.create('Ext.data.Store', { |
64 | - storeId: 'targetNamesStore', | |
65 | - fields: ['id', 'text', 'name', 'type', 'parent', 'aliases'], | |
66 | - proxy: { | |
67 | - type: 'ajax', | |
68 | - url: 'php/epntap.php', | |
69 | - extraParams: { action: 'resolver' } | |
70 | - }, | |
71 | - errorDisplayed: false, | |
72 | - listeners: { | |
73 | - load: function(store, records, successful) { | |
74 | - if(!successful && !store.errorDisplayed) { | |
75 | - Ext.Msg.alert('Error', 'Can not load results from the resolver. Please enter target names manually.'); | |
76 | - store.errorDisplayed = true; | |
77 | - } | |
78 | - } | |
79 | - } | |
80 | -}); | |
64 | + storeId: 'targetNamesStore', | |
65 | + fields: ['id', 'text', 'name', 'type', 'parent', 'aliases'], | |
66 | + proxy: { | |
67 | + type: 'ajax', | |
68 | + url: 'php/epntap.php', | |
69 | + extraParams: { action: 'resolver' } | |
70 | + }, | |
71 | + errorDisplayed: false, | |
72 | + listeners: { | |
73 | + load: function (store, records, successful) { | |
74 | + if (!successful && !store.errorDisplayed) { | |
75 | + Ext.Msg.alert('Error', 'Can not load results from the resolver. Please enter target names manually.') | |
76 | + store.errorDisplayed = true | |
77 | + } | |
78 | + } | |
79 | + } | |
80 | +}) | |
81 | 81 | |
82 | 82 | /** |
83 | 83 | `servicesStore`: An ExtJS Store containing the list of the EPN-TAP services (defined in |
... | ... | @@ -88,51 +88,51 @@ This list is used to fill the `servicesGrid` table, which is updated by `EpnTapM |
88 | 88 | (or, by transitivity, target class or product type) is selected. |
89 | 89 | |
90 | 90 | - `id`: the database name of the service, according to the `table_name` column from the `rr.res_table` in the |
91 | - registry database; | |
91 | + registry database; | |
92 | 92 | - `nbResults`: the number of granules matching with the granules filter for this service; |
93 | 93 | - `shortName`: the service short name, according to the `short_name` column from the `rr.resource` table in the registry |
94 | - database; | |
94 | + database; | |
95 | 95 | - `title`: the service title, according to the `res_title` column from the `rr.resource` table in the registry database; |
96 | 96 | - `accessURL`: the service access URL, according to the `access_url` column from the `rr.interface` table in the |
97 | - registry database. | |
97 | + registry database. | |
98 | 98 | */ |
99 | 99 | Ext.create('Ext.data.Store', { |
100 | - storeId: 'servicesStore', | |
101 | - autoLoad: true, | |
102 | - fields: [ | |
103 | - {name: 'id', type: 'string'}, | |
104 | - {name: 'short_name', type: 'string'}, | |
105 | - {name: 'res_title', type: 'string'}, | |
106 | - {name: 'ivoid', type: 'string'}, | |
107 | - {name: 'access_url', type: 'string'}, | |
108 | - {name: 'table_name', type: 'string'}, | |
109 | - {name: 'content_type', type: 'string'}, | |
110 | - {name: 'creator_seq', type: 'string'}, | |
111 | - {name: 'content_level', type: 'string'}, | |
112 | - {name: 'reference_url', type: 'string'}, | |
113 | - {name: 'created', type: 'date', dateFormat: 'c'}, | |
114 | - {name: 'updated', type: 'date', dateFormat: 'c'}, | |
115 | - {name: 'nb_results', type: 'integer'}, | |
116 | - {name: 'info', type: 'string'} | |
117 | - ], | |
118 | - proxy: { | |
119 | - type: 'ajax', | |
120 | - url: 'php/epntap.php', | |
121 | - extraParams : {action: 'getServices'} | |
122 | - }, | |
123 | - sorters: [ | |
124 | - {property: 'nb_results', direction: 'DESC'}, | |
125 | - {property: 'short_name', direction: 'ASC'} | |
126 | - ], | |
127 | - listeners: { | |
128 | - // beforeload: function(s, operation) { console.log(operation); }, | |
129 | - load: function(store, records, successful) { | |
130 | - if(!successful) { | |
131 | - Ext.Msg.alert('Error', 'Can not get epntap services from registries.'); | |
132 | - } | |
133 | - } | |
134 | - } | |
135 | -}); | |
100 | + storeId: 'servicesStore', | |
101 | + autoLoad: true, | |
102 | + fields: [ | |
103 | + {name: 'id', type: 'string'}, | |
104 | + {name: 'short_name', type: 'string'}, | |
105 | + {name: 'res_title', type: 'string'}, | |
106 | + {name: 'ivoid', type: 'string'}, | |
107 | + {name: 'access_url', type: 'string'}, | |
108 | + {name: 'table_name', type: 'string'}, | |
109 | + {name: 'content_type', type: 'string'}, | |
110 | + {name: 'creator_seq', type: 'string'}, | |
111 | + {name: 'content_level', type: 'string'}, | |
112 | + {name: 'reference_url', type: 'string'}, | |
113 | + {name: 'created', type: 'date', dateFormat: 'c'}, | |
114 | + {name: 'updated', type: 'date', dateFormat: 'c'}, | |
115 | + {name: 'nb_results', type: 'integer'}, | |
116 | + {name: 'info', type: 'string'} | |
117 | + ], | |
118 | + proxy: { | |
119 | + type: 'ajax', | |
120 | + url: 'php/epntap.php', | |
121 | + extraParams: {action: 'getServices'} | |
122 | + }, | |
123 | + sorters: [ | |
124 | + {property: 'nb_results', direction: 'DESC'}, | |
125 | + {property: 'short_name', direction: 'ASC'} | |
126 | + ], | |
127 | + listeners: { | |
128 | + // beforeload: function(s, operation) { console.log(operation); }, | |
129 | + load: function (store, records, successful) { | |
130 | + if (!successful) { | |
131 | + Ext.Msg.alert('Error', 'Can not get epntap services from registries.') | |
132 | + } | |
133 | + } | |
134 | + } | |
135 | +}) | |
136 | 136 | |
137 | 137 | /** |
138 | 138 | `granulesStore`: An ExtJS Store containing the list of granules of the selected service (on `servicesGrid`), which match |
... | ... | @@ -143,7 +143,7 @@ selected. |
143 | 143 | |
144 | 144 | - `num`: the line number, according to the order of the query response and the current page (see `currentPageLb`); |
145 | 145 | - `dataproduct_type`: the dataproduct_type EPN-TAP parameter, as defined in |
146 | - https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters. | |
146 | + https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters. | |
147 | 147 | - `target_name`: the target_name EPN-TAP parameter (ibid); |
148 | 148 | - `time_min`: the time_min EPN-TAP parameter (ibid); |
149 | 149 | - `time_max`: the time_max EPN-TAP parameter (ibid); |
... | ... | @@ -156,224 +156,224 @@ selected. |
156 | 156 | // TODO: Add granules filter (see http://docs.sencha.com/extjs/4.0.7/#!/example/grid-filtering/grid-filter-local.html) |
157 | 157 | |
158 | 158 | Ext.define('GranulesModel', { |
159 | - extend: 'Ext.data.Model' | |
160 | - // columns are created dynamically | |
161 | -}); | |
159 | + extend: 'Ext.data.Model' | |
160 | + // columns are created dynamically | |
161 | +}) | |
162 | 162 | |
163 | 163 | Ext.create('Ext.data.Store', { |
164 | - storeId: 'granulesStore', | |
165 | - model: 'GranulesModel', | |
166 | - buffered: true, | |
167 | - autoload: false, | |
168 | - pageSize: 500, | |
169 | - leadingBufferZone: 0, | |
170 | - proxy: { | |
171 | - type: 'ajax', | |
172 | - url: 'php/epntap.php', | |
173 | - reader: { type: 'json', root: 'data'}, | |
174 | - simpleSortMode: true | |
175 | - }, | |
176 | - listeners: { | |
177 | - 'beforeprefetch': function(store, operation) { | |
178 | - var service = Ext.data.StoreManager.lookup('servicesStore').getById(store.selectedService).data; | |
179 | - store.getProxy().extraParams = { | |
180 | - 'action': 'getGranules', | |
181 | - 'url': service['access_url'], | |
182 | - 'tableName': service['table_name'], | |
183 | - 'targetNames': Ext.getCmp('epnTapTargetNameCB').rawValue, | |
184 | - 'productTypes': Ext.getCmp('epnTapProductTypeCB').value.join(';'), | |
185 | - 'timeMin': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStartTime(), 'd/m/Y H:i:s'), | |
186 | - 'timeMax': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStopTime(), 'd/m/Y H:i:s'), | |
187 | - 'nbRes': service['nb_results'] | |
188 | - }; | |
189 | - }, | |
190 | - 'prefetch': function(store, records, successful, operation) { | |
191 | - // console.log('(prefetch) operation ' + (successful ? 'success' : 'failed') + ': ', operation); | |
192 | - // console.log(operation.params); | |
193 | - // console.log(Ext.decode(operation.response.responseText)); | |
194 | - }, | |
195 | - 'metachange': function(store, meta) { | |
196 | - if(meta.metaHash != store.metaHash) { | |
197 | - Ext.getCmp('epnTapGranulesGrid').reconfigure(store, meta.columns); | |
198 | - store.metaHash = meta.metaHash; | |
199 | - } | |
200 | - } | |
201 | - } | |
202 | -}); | |
164 | + storeId: 'granulesStore', | |
165 | + model: 'GranulesModel', | |
166 | + buffered: true, | |
167 | + autoload: false, | |
168 | + pageSize: 500, | |
169 | + leadingBufferZone: 0, | |
170 | + proxy: { | |
171 | + type: 'ajax', | |
172 | + url: 'php/epntap.php', | |
173 | + reader: { type: 'json', root: 'data'}, | |
174 | + simpleSortMode: true | |
175 | + }, | |
176 | + listeners: { | |
177 | + 'beforeprefetch': function (store, operation) { | |
178 | + var service = Ext.data.StoreManager.lookup('servicesStore').getById(store.selectedService).data | |
179 | + store.getProxy().extraParams = { | |
180 | + 'action': 'getGranules', | |
181 | + 'url': service['access_url'], | |
182 | + 'tableName': service['table_name'], | |
183 | + 'targetNames': Ext.getCmp('epnTapTargetNameCB').rawValue, | |
184 | + 'productTypes': Ext.getCmp('epnTapProductTypeCB').value.join(';'), | |
185 | + 'timeMin': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStartTime(), 'd/m/Y H:i:s'), | |
186 | + 'timeMax': Ext.Date.format(Ext.getCmp('epnTapTimeSelector').getStopTime(), 'd/m/Y H:i:s'), | |
187 | + 'nbRes': service['nb_results'] | |
188 | + } | |
189 | + }, | |
190 | + 'prefetch': function (store, records, successful, operation) { | |
191 | + // console.log('(prefetch) operation ' + (successful ? 'success' : 'failed') + ': ', operation); | |
192 | + // console.log(operation.params); | |
193 | + // console.log(Ext.decode(operation.response.responseText)); | |
194 | + }, | |
195 | + 'metachange': function (store, meta) { | |
196 | + if (meta.metaHash != store.metaHash) { | |
197 | + Ext.getCmp('epnTapGranulesGrid').reconfigure(store, meta.columns) | |
198 | + store.metaHash = meta.metaHash | |
199 | + } | |
200 | + } | |
201 | + } | |
202 | +}) | |
203 | 203 | |
204 | 204 | /** |
205 | 205 | Error are not displayed here, use try/catch each time it's necessary. |
206 | 206 | */ |
207 | 207 | Ext.define('App.util.Format', { |
208 | - override: 'Ext.util.Format', | |
209 | - | |
210 | - // Utils | |
211 | - | |
212 | - 'prettify': function(data) { | |
213 | - return data.charAt(0).toUpperCase() + data.replace(/_/g, ' ').substr(1).toLowerCase(); | |
214 | - }, | |
215 | - 'url': function(data) { | |
216 | - var url_pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol | |
217 | - '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name | |
218 | - '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address | |
219 | - '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path | |
220 | - '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string | |
221 | - '(\\#[-a-z\\d_]*)?$','i'); // fragment locator | |
222 | - return url_pattern.test(data) ? data : null; | |
223 | - }, | |
224 | - 'cell': function(content, tooltip, tooltipTitle) { | |
225 | - var ttAttr = ""; | |
226 | - if(tooltip !== '') { | |
227 | - var ttTitle = tooltipTitle ? " data-qtitle='" + tooltipTitle + "'" : ""; | |
228 | - ttAttr = ttTitle + "' data-qtip='" + (tooltip ? tooltip : (content ? content : 'No value.')) + "'"; | |
229 | - } | |
230 | - return "<div class=epntap_cell " + ttAttr + ">" + (content ? content : '-') + "</div>"; | |
231 | - }, | |
232 | - | |
233 | - // Services grid | |
234 | - | |
235 | - 'serviceTooltip': function(data) { | |
236 | - for (var key in data) { | |
237 | - if(typeof data[key] == 'string' && data[key] != '') { | |
238 | - data[key] = data[key].replace(/'/g, ''').replace(/"/g, '"'); | |
239 | - } | |
240 | - } | |
241 | - var infoColor = data.nb_results == -2 ? 'IndianRed' : 'green'; | |
242 | - var info = data.info.length > 0 ? '<p style="color:' + infoColor + '">' + data.info + '</p>' : ''; | |
243 | - | |
244 | - var colums = ['res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated']; | |
245 | - var details = ''; | |
246 | - for (var key in colums) { | |
247 | - if(data[colums[key]] !== '') { | |
248 | - var val = colums[key] === 'content_level' ? data[colums[key]].replace(/#/g, ', ') : data[colums[key]]; | |
249 | - details += '<li><b>' + Ext.util.Format.prettify(colums[key]) + '</b>: ' + val + '</li>'; | |
250 | - } | |
251 | - } | |
252 | - return info + '<ul>' + details + '</ul>'; | |
253 | - }, | |
254 | - 'service.text': function(data, metadata, record) { | |
255 | - return Ext.util.Format.cell(data, Ext.util.Format.serviceTooltip(record.data), data); | |
256 | - }, | |
257 | - 'service.number': function(data, metadata, record) { | |
258 | - value = '' + data; | |
259 | - if(data < 0) { | |
260 | - value = '-'; | |
261 | - } else if(data >= 1000*1000) { | |
262 | - value = (data/(1000*1000)).toPrecision(3) + 'm'; | |
263 | - } else if(data >= 1000) { | |
264 | - value = (data/1000).toPrecision(3) + 'k'; | |
265 | - } | |
266 | - return Ext.util.Format.cell(value, Ext.util.Format.serviceTooltip(record.data), record.data.short_name); | |
267 | - }, | |
268 | - | |
269 | - // Granules grid | |
270 | - | |
271 | - 'granule.text': function(data, metadata, record) { | |
272 | - return Ext.util.Format.cell(data); | |
273 | - }, | |
274 | - 'granule.link': function(data, metadata, record) { | |
275 | - var icon_b64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxMDI0IiB3aWR0aD0iNzY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik02NDAgNzY4SDEyOFYyNTcuOTA1OTk5OTk5OTk5OTVMMjU2IDI1NlYxMjhIMHY3NjhoNzY4VjU3Nkg2NDBWNzY4ek0zODQgMTI4bDEyOCAxMjhMMzIwIDQ0OGwxMjggMTI4IDE5Mi0xOTIgMTI4IDEyOFYxMjhIMzg0eiIvPjwvc3ZnPg=='; | |
276 | - var icon = '<img style="width:15px;" alt="link" src="' + icon_b64 + '">'; | |
277 | - url = Ext.util.Format.url(data); | |
278 | - if(url) { | |
279 | - txt = '<a style="font-size:150%" target="_blank" href="' + url + '">' + icon + '</a>'; | |
280 | - } | |
281 | - return Ext.util.Format.cell(txt, url); | |
282 | - }, | |
283 | - 'granule.img': function(data, metadata, record) { | |
284 | - img_url = Ext.util.Format.url(data); | |
285 | - if(img_url) { | |
286 | - icon = '<img style="max-width:100%; max-height:100%" alt="-" src="' + img_url + '">'; | |
287 | - img = '<img style="max-width:200px; max-height:200px" src="' + img_url + '">'; | |
288 | - } | |
289 | - return Ext.util.Format.cell(icon, img); | |
290 | - }, | |
291 | - 'granule.type': function(data, metadata, record) { | |
292 | - var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map; | |
293 | - return Ext.util.Format.cell(productTypeDict[data].data.name); | |
294 | - }, | |
295 | - 'granule.size': function(data, metadata, record) { | |
296 | - var size = parseInt(data); | |
297 | - if (isNaN(size)) { | |
298 | - } else if (size >= 1024*1024) { | |
299 | - txt = (size/(1024*1024)).toPrecision(3) + 'Go'; | |
300 | - } else if (size >= 1024) { | |
301 | - txt = (size/1024).toPrecision(3) + 'Mo'; | |
302 | - } else { | |
303 | - txt = size + 'Ko'; | |
304 | - } | |
305 | - return Ext.util.Format.cell(txt); | |
306 | - }, | |
307 | - 'granule.proc_lvl': function(data, metadata, record) { | |
308 | - var levels = {1: 'Raw', 2: 'Edited', 3: 'Calibrated', 4: 'Resampled', 5: 'Derived', 6: 'Ancillary'}; | |
309 | - return Ext.util.Format.cell((data in levels) ? levels[data] : '<em>' + data + '</em>'); | |
310 | - }, | |
311 | - 'granule.date': function(data, metadata, record) { | |
312 | - if(isNaN(data)) { | |
313 | - return ''; | |
314 | - } | |
315 | - var f = Number(data) + 1401 + Math.floor((Math.floor((4 * Number(data) + 274277) / 146097) * 3) / 4) - 38; | |
316 | - var e = 4 * f + 3; | |
317 | - var g = Math.floor((e % 1461) / 4); | |
318 | - var h = 5 * g + 2; | |
319 | - var D = Math.floor((h % 153) / 5) + 1; | |
320 | - var M = ((Math.floor(h / 153) + 2) % 12) + 1; | |
321 | - var Y = Math.floor(e / 1461) - 4716 + Math.floor((12 + 2 - M) / 12); | |
322 | - var date = new Date(Y, M-1, D); | |
323 | - return Ext.util.Format.cell(Ext.Date.format(date, 'Y/m/d'), Ext.Date.format(date, 'F j, Y, g:i a')); | |
324 | - }, | |
325 | - 'granule.format': function(data, metadata, record) { | |
326 | - var mimetypeDict = { | |
327 | - 'application/fits': 'fits', | |
328 | - 'application/x-pds': 'pds', | |
329 | - 'image/x-pds': 'pds', | |
330 | - 'application/gml+xml': 'gml', | |
331 | - 'application/json': 'json', | |
332 | - 'application/octet-stream': 'bin, idl, envi or matlab', | |
333 | - 'application/pdf': 'pdf', | |
334 | - 'application/postscript': 'ps', | |
335 | - 'application/vnd.geo+json': 'geojson', | |
336 | - 'application/vnd.google-earth.kml+xml': 'kml', | |
337 | - 'application/vnd.google-earth.kmz': 'kmz', | |
338 | - 'application/vnd.ms-excel': 'xls', | |
339 | - 'application/x-asdm': 'asdm', | |
340 | - 'application/x-cdf': 'cdf', | |
341 | - 'application/x-cdf-istp': 'cdf', | |
342 | - 'application/x-cdf-pds4': 'cdf', | |
343 | - 'application/x-cef1': 'cef1', | |
344 | - 'application/x-cef2': 'cef2', | |
345 | - 'application/x-directory': 'dir', | |
346 | - 'application/x-fits-bintable': 'bintable', | |
347 | - 'application/x-fits-euro3d': 'euro3d', | |
348 | - 'application/x-fits-mef': 'mef', | |
349 | - 'application/x-geotiff': 'geotiff', | |
350 | - 'application/x-hdf': 'hdf', | |
351 | - 'application/x-netcdf': 'nc', | |
352 | - 'application/x-netcdf4': 'nc', | |
353 | - 'application/x-tar': 'tar', | |
354 | - 'application/x-tar-gzip': 'gtar', | |
355 | - 'application/x-votable+xml': 'votable', | |
356 | - 'application/x-votable+xml;content=datalink': 'votable', | |
357 | - 'application/zip': 'zip', | |
358 | - 'image/fits': 'fits', | |
359 | - 'image/gif': 'gif', | |
360 | - 'image/jpeg': 'jpeg', | |
361 | - 'image/png': 'png', | |
362 | - 'image/tiff': 'tiff', | |
363 | - 'image/x-fits-gzip': 'fits', | |
364 | - 'image/x-fits-hcompress': 'fits', | |
365 | - 'text/csv': 'csv', | |
366 | - 'text/html': 'html', | |
367 | - 'text/plain': 'txt', | |
368 | - 'text/tab-separated-values': 'tsv', | |
369 | - 'text/xml': 'xml', | |
370 | - 'video/mpeg': 'mpeg', | |
371 | - 'video/quicktime': 'mov', | |
372 | - 'video/x-msvideo': 'avi' | |
373 | - }; | |
374 | - return Ext.util.Format.cell((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>'); | |
375 | - } | |
376 | -}); | |
208 | + override: 'Ext.util.Format', | |
209 | + | |
210 | + // Utils | |
211 | + | |
212 | + 'prettify': function (data) { | |
213 | + return data.charAt(0).toUpperCase() + data.replace(/_/g, ' ').substr(1).toLowerCase() | |
214 | + }, | |
215 | + 'url': function (data) { | |
216 | + var url_pattern = new RegExp('^(https?:\\/\\/)?' + // protocol | |
217 | + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name | |
218 | + '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address | |
219 | + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path | |
220 | + '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string | |
221 | + '(\\#[-a-z\\d_]*)?$', 'i') // fragment locator | |
222 | + return url_pattern.test(data) ? data : null | |
223 | + }, | |
224 | + 'cell': function (content, tooltip, tooltipTitle) { | |
225 | + var ttAttr = '' | |
226 | + if (tooltip !== '') { | |
227 | + var ttTitle = tooltipTitle ? " data-qtitle='" + tooltipTitle + "'" : '' | |
228 | + ttAttr = ttTitle + "' data-qtip='" + (tooltip || (content || 'No value.')) + "'" | |
229 | + } | |
230 | + return '<div class=epntap_cell ' + ttAttr + '>' + (content || '-') + '</div>' | |
231 | + }, | |
232 | + | |
233 | + // Services grid | |
234 | + | |
235 | + 'serviceTooltip': function (data) { | |
236 | + for (var key in data) { | |
237 | + if (typeof data[key] === 'string' && data[key] != '') { | |
238 | + data[key] = data[key].replace(/'/g, ''').replace(/"/g, '"') | |
239 | + } | |
240 | + } | |
241 | + var infoColor = data.nb_results == -2 ? 'IndianRed' : 'green' | |
242 | + var info = data.info.length > 0 ? '<p style="color:' + infoColor + '">' + data.info + '</p>' : '' | |
243 | + | |
244 | + var colums = ['res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated'] | |
245 | + var details = '' | |
246 | + for (var key in colums) { | |
247 | + if (data[colums[key]] !== '') { | |
248 | + var val = colums[key] === 'content_level' ? data[colums[key]].replace(/#/g, ', ') : data[colums[key]] | |
249 | + details += '<li><b>' + Ext.util.Format.prettify(colums[key]) + '</b>: ' + val + '</li>' | |
250 | + } | |
251 | + } | |
252 | + return info + '<ul>' + details + '</ul>' | |
253 | + }, | |
254 | + 'service.text': function (data, metadata, record) { | |
255 | + return Ext.util.Format.cell(data, Ext.util.Format.serviceTooltip(record.data), data) | |
256 | + }, | |
257 | + 'service.number': function (data, metadata, record) { | |
258 | + value = '' + data | |
259 | + if (data < 0) { | |
260 | + value = '-' | |
261 | + } else if (data >= 1000 * 1000) { | |
262 | + value = (data / (1000 * 1000)).toPrecision(3) + 'm' | |
263 | + } else if (data >= 1000) { | |
264 | + value = (data / 1000).toPrecision(3) + 'k' | |
265 | + } | |
266 | + return Ext.util.Format.cell(value, Ext.util.Format.serviceTooltip(record.data), record.data.short_name) | |
267 | + }, | |
268 | + | |
269 | + // Granules grid | |
270 | + | |
271 | + 'granule.text': function (data, metadata, record) { | |
272 | + return Ext.util.Format.cell(data) | |
273 | + }, | |
274 | + 'granule.link': function (data, metadata, record) { | |
275 | + var icon_b64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxMDI0IiB3aWR0aD0iNzY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik02NDAgNzY4SDEyOFYyNTcuOTA1OTk5OTk5OTk5OTVMMjU2IDI1NlYxMjhIMHY3NjhoNzY4VjU3Nkg2NDBWNzY4ek0zODQgMTI4bDEyOCAxMjhMMzIwIDQ0OGwxMjggMTI4IDE5Mi0xOTIgMTI4IDEyOFYxMjhIMzg0eiIvPjwvc3ZnPg==' | |
276 | + var icon = '<img style="width:15px;" alt="link" src="' + icon_b64 + '">' | |
277 | + url = Ext.util.Format.url(data) | |
278 | + if (url) { | |
279 | + txt = '<a style="font-size:150%" target="_blank" href="' + url + '">' + icon + '</a>' | |
280 | + } | |
281 | + return Ext.util.Format.cell(txt, url) | |
282 | + }, | |
283 | + 'granule.img': function (data, metadata, record) { | |
284 | + img_url = Ext.util.Format.url(data) | |
285 | + if (img_url) { | |
286 | + icon = '<img style="max-width:100%; max-height:100%" alt="-" src="' + img_url + '">' | |
287 | + img = '<img style="max-width:200px; max-height:200px" src="' + img_url + '">' | |
288 | + } | |
289 | + return Ext.util.Format.cell(icon, img) | |
290 | + }, | |
291 | + 'granule.type': function (data, metadata, record) { | |
292 | + var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map | |
293 | + return Ext.util.Format.cell(productTypeDict[data].data.name) | |
294 | + }, | |
295 | + 'granule.size': function (data, metadata, record) { | |
296 | + var size = parseInt(data) | |
297 | + if (isNaN(size)) { | |
298 | + } else if (size >= 1024 * 1024) { | |
299 | + txt = (size / (1024 * 1024)).toPrecision(3) + 'Go' | |
300 | + } else if (size >= 1024) { | |
301 | + txt = (size / 1024).toPrecision(3) + 'Mo' | |
302 | + } else { | |
303 | + txt = size + 'Ko' | |
304 | + } | |
305 | + return Ext.util.Format.cell(txt) | |
306 | + }, | |
307 | + 'granule.proc_lvl': function (data, metadata, record) { | |
308 | + var levels = {1: 'Raw', 2: 'Edited', 3: 'Calibrated', 4: 'Resampled', 5: 'Derived', 6: 'Ancillary'} | |
309 | + return Ext.util.Format.cell((data in levels) ? levels[data] : '<em>' + data + '</em>') | |
310 | + }, | |
311 | + 'granule.date': function (data, metadata, record) { | |
312 | + if (isNaN(data)) { | |
313 | + return '' | |
314 | + } | |
315 | + var f = Number(data) + 1401 + Math.floor((Math.floor((4 * Number(data) + 274277) / 146097) * 3) / 4) - 38 | |
316 | + var e = 4 * f + 3 | |
317 | + var g = Math.floor((e % 1461) / 4) | |
318 | + var h = 5 * g + 2 | |
319 | + var D = Math.floor((h % 153) / 5) + 1 | |
320 | + var M = ((Math.floor(h / 153) + 2) % 12) + 1 | |
321 | + var Y = Math.floor(e / 1461) - 4716 + Math.floor((12 + 2 - M) / 12) | |
322 | + var date = new Date(Y, M - 1, D) | |
323 | + return Ext.util.Format.cell(Ext.Date.format(date, 'Y/m/d'), Ext.Date.format(date, 'F j, Y, g:i a')) | |
324 | + }, | |
325 | + 'granule.format': function (data, metadata, record) { | |
326 | + var mimetypeDict = { | |
327 | + 'application/fits': 'fits', | |
328 | + 'application/x-pds': 'pds', | |
329 | + 'image/x-pds': 'pds', | |
330 | + 'application/gml+xml': 'gml', | |
331 | + 'application/json': 'json', | |
332 | + 'application/octet-stream': 'bin, idl, envi or matlab', | |
333 | + 'application/pdf': 'pdf', | |
334 | + 'application/postscript': 'ps', | |
335 | + 'application/vnd.geo+json': 'geojson', | |
336 | + 'application/vnd.google-earth.kml+xml': 'kml', | |
337 | + 'application/vnd.google-earth.kmz': 'kmz', | |
338 | + 'application/vnd.ms-excel': 'xls', | |
339 | + 'application/x-asdm': 'asdm', | |
340 | + 'application/x-cdf': 'cdf', | |
341 | + 'application/x-cdf-istp': 'cdf', | |
342 | + 'application/x-cdf-pds4': 'cdf', | |
343 | + 'application/x-cef1': 'cef1', | |
344 | + 'application/x-cef2': 'cef2', | |
345 | + 'application/x-directory': 'dir', | |
346 | + 'application/x-fits-bintable': 'bintable', | |
347 | + 'application/x-fits-euro3d': 'euro3d', | |
348 | + 'application/x-fits-mef': 'mef', | |
349 | + 'application/x-geotiff': 'geotiff', | |
350 | + 'application/x-hdf': 'hdf', | |
351 | + 'application/x-netcdf': 'nc', | |
352 | + 'application/x-netcdf4': 'nc', | |
353 | + 'application/x-tar': 'tar', | |
354 | + 'application/x-tar-gzip': 'gtar', | |
355 | + 'application/x-votable+xml': 'votable', | |
356 | + 'application/x-votable+xml;content=datalink': 'votable', | |
357 | + 'application/zip': 'zip', | |
358 | + 'image/fits': 'fits', | |
359 | + 'image/gif': 'gif', | |
360 | + 'image/jpeg': 'jpeg', | |
361 | + 'image/png': 'png', | |
362 | + 'image/tiff': 'tiff', | |
363 | + 'image/x-fits-gzip': 'fits', | |
364 | + 'image/x-fits-hcompress': 'fits', | |
365 | + 'text/csv': 'csv', | |
366 | + 'text/html': 'html', | |
367 | + 'text/plain': 'txt', | |
368 | + 'text/tab-separated-values': 'tsv', | |
369 | + 'text/xml': 'xml', | |
370 | + 'video/mpeg': 'mpeg', | |
371 | + 'video/quicktime': 'mov', | |
372 | + 'video/x-msvideo': 'avi' | |
373 | + } | |
374 | + return Ext.util.Format.cell((data in mimetypeDict) ? '<p>' + mimetypeDict[data] + '</p>' : '<em>' + data + '</em>') | |
375 | + } | |
376 | +}) | |
377 | 377 | |
378 | 378 | /** |
379 | 379 | `EpnTapUI`: The view of the AMDA EPN-TAP module, allowing the user to query and display granules information from |
... | ... | @@ -382,298 +382,298 @@ EPN-TAP services. |
382 | 382 | Note: The controller part of this module is defined in `js/app/controller/EpnTapModule`. |
383 | 383 | */ |
384 | 384 | Ext.define('amdaUI.EpnTapUI', { |
385 | - extend: 'Ext.panel.Panel', | |
386 | - alias: 'widget.panelEpnTap', | |
387 | - requires: ['amdaUI.IntervalUI'], | |
388 | - | |
389 | - /** | |
390 | - Method constructor, which basically call the `init()` method to create the EpnTap panel. | |
391 | - */ | |
392 | - constructor: function(config) { | |
393 | - this.init(config); | |
394 | - this.callParent(arguments); | |
395 | - }, | |
396 | - | |
397 | - /** | |
398 | - Create all the EpnTapPanel UI elements, and apply the AMDA module `config` (which includes the created items). | |
399 | - | |
400 | - When the panel is correctly rendered, the panel triggers `EpnTapModule.onWindowLoaded()`. | |
401 | - | |
402 | - Note: All the UI elements creation are defined as functions in this init method and not as methods in order to make | |
403 | - them private (ie. to avoid `EpnTapUI.createServicesGrid();`, which doesn't make sense). | |
404 | - */ | |
405 | - init: function(config) { | |
406 | - var myConf = { | |
407 | - id: 'epntapTab', | |
408 | - title: 'EPN-TAP', | |
409 | - items: [{ | |
410 | - xtype: 'container', | |
411 | - layout: { type: 'vbox', pack: 'start', align: 'stretch'}, | |
412 | - items: [ | |
413 | - this.createServiceFilterPanel(), | |
414 | - this.createGridsPanel() | |
415 | - ] | |
416 | - }] | |
417 | - }; | |
418 | - Ext.apply(this, Ext.apply(arguments, myConf)); | |
419 | - }, | |
420 | - | |
421 | - /*************************** | |
422 | - *** Service filter panel *** | |
423 | - ***************************/ | |
424 | - | |
425 | - /** | |
426 | - Create `epnTapServiceFilterPanel`, an ExtJS Panel containing two containers: | |
427 | - - the left container, containing the combo boxes (for product type, target class and target name) | |
428 | - and the navigation panel; | |
429 | - - the right container, containing the time selector. | |
430 | - */ | |
431 | - createServiceFilterPanel: function() { | |
432 | - return { | |
433 | - xtype: 'form', | |
434 | - id: 'epnTapServiceFilterPanel', | |
435 | - layout: { type: 'hbox', pack: 'start', align: 'stretch' }, | |
436 | - region: 'north', | |
437 | - defaults: { margin: '5 0 5 5'}, | |
438 | - items: [{ // Left part | |
439 | - xtype : 'container', | |
440 | - flex: 1, | |
441 | - items: [ | |
442 | - this.createTargetNameCB(), | |
443 | - this.createProductTypeCB() | |
444 | - ] | |
445 | - }, { // Middle part | |
446 | - xtype : 'container', | |
447 | - flex: 1, | |
448 | - items: [ | |
449 | - this.createTimeSelector() | |
450 | - ] | |
451 | - }, { // Right part | |
452 | - xtype : 'container', | |
453 | - items: [ | |
454 | - this.createSendButton() | |
455 | - ] | |
456 | - | |
457 | - }] | |
458 | - }; | |
459 | - }, | |
460 | - | |
461 | - /** | |
462 | - Create `epnTapTargetNameCB`, an ExtJS ComboBox, containing a list of target names corresponding to the selected | |
463 | - target class, as defined in `targetNamesStore`, which is initilized by `EpnTapModule`. | |
464 | - | |
465 | - The selection of a target name triggers `EpnTapModule.onTargetNameCBChanged()`, which basically updates | |
466 | - `granulesGrid`. | |
467 | - */ | |
468 | - createTargetNameCB: function() { | |
469 | - return { | |
470 | - xtype: 'combobox', | |
471 | - id: 'epnTapTargetNameCB', | |
472 | - fieldLabel: 'Target name', | |
473 | - emptyText: 'Earth, Saturn, 67P, ...', | |
474 | - tooltip: 'Start to type a text, then select a target name (required). Several values are allowed, separated by a semicolon.', | |
475 | - store: Ext.data.StoreManager.lookup('targetNamesStore'), | |
476 | - queryMode: 'remote', | |
477 | - queryParam: 'input', | |
478 | - displayField: 'text', | |
479 | - valueField: 'id', | |
480 | - margin: '15 0 5 0', | |
481 | - labelWidth: 71, | |
482 | - minWidth: 20, | |
483 | - minChars: 2, | |
484 | - hideTrigger: true, | |
485 | - listConfig: { | |
486 | - getInnerTpl: function() { | |
487 | - return '<div data-qtitle="{name}" data-qtip="<p>type: {type}</p><p>parent: {parent}</p><p>aliases:</p><ul>{aliases}</ul>">{name}</div>'; | |
488 | - } | |
489 | - }, | |
490 | - listeners: { | |
491 | - render: function(cb) { | |
492 | - new Ext.ToolTip({ target: cb.getEl(), html: '<div style="width:200px">' + cb.tooltip + '</div>'}); | |
493 | - } | |
494 | - } | |
495 | - }; | |
496 | - }, | |
497 | - | |
498 | - /** | |
499 | - Create `epnTapProductTypeCB`, an ExtJS ComboBox, containing a list of product types as defined in | |
500 | - `epnTapProductTypesStore`, which is initilized by `EpnTapModule`. | |
501 | - | |
502 | - The selection of a produt type triggers `EpnTapModule.onProductTypeCBChanged()`, which basically update | |
503 | - `epnTapGranulesGrid`. | |
504 | - */ | |
505 | - createProductTypeCB: function() { | |
506 | - return { | |
507 | - xtype: 'combobox', | |
508 | - id: 'epnTapProductTypeCB', | |
509 | - fieldLabel: 'Product type', | |
510 | - emptyText: 'Image, Time series, ...', | |
511 | - tooltip: 'Select one or several data product types (required).', | |
512 | - store: Ext.data.StoreManager.lookup('productTypesStore'), | |
513 | - queryMode: 'local', | |
514 | - valueField: 'id', | |
515 | - multiSelect: true, | |
516 | - displayField: 'name', | |
517 | - labelWidth: 71, | |
518 | - editable: false, | |
519 | - listConfig: { | |
520 | - getInnerTpl: function() { | |
521 | - return '<div data-qtitle="{name}" data-qwidth=200 data-qtip="<p>{desc}</p>">{name}</div>'; | |
522 | - } | |
523 | - }, | |
524 | - listeners: { | |
525 | - change: function(cb, records) { | |
526 | - var val = cb.value[cb.value.length - 1]; | |
527 | - if(val === 'all') { | |
528 | - cb.select(cb.store.getRange().slice(2)); | |
529 | - } else if (val === 'clear') { | |
530 | - cb.reset(); | |
531 | - } | |
532 | - }, | |
533 | - render: function(cb) { | |
534 | - new Ext.ToolTip({ target: cb.getEl(), html: '<div style="width:200px">' + cb.tooltip + '</div>'}); | |
535 | - } | |
536 | - } | |
537 | - }; | |
538 | - }, | |
539 | - | |
540 | - /** | |
541 | - Create `epnTapTimeSelector`, an IntervalUI object, allowing the user to select a time interval (by filling two | |
542 | - dates and/or a duration). | |
543 | - | |
544 | - See `js/app/views/IntervalUI.js` for more information about this component. | |
545 | - */ | |
546 | - createTimeSelector: function() { | |
547 | - return { | |
548 | - xtype: 'intervalSelector', | |
549 | - id: 'epnTapTimeSelector' | |
550 | - }; | |
551 | - }, | |
552 | - | |
553 | - /*********************** | |
554 | - *** Navigation panel *** | |
555 | - ***********************/ | |
556 | - | |
557 | - /** | |
558 | - The button used to send the query. | |
559 | - */ | |
560 | - createSendButton: function() { | |
561 | - return { | |
562 | - xtype: 'button', | |
563 | - id: 'epnTapGetBtn', | |
564 | - text: 'Get services', | |
565 | - disabled: true, | |
566 | - width: 140, | |
567 | - height: 50, | |
568 | - margin: 10 | |
569 | - } | |
570 | - }, | |
571 | - | |
572 | - /************ | |
573 | - *** Grids *** | |
574 | - ************/ | |
575 | - | |
576 | - /** | |
577 | - Create `epnTapGridsPanel`, an ExtJS Panel, containing `epnTapServicesGrid` and `epnTapGranulesGrid`. | |
578 | - | |
579 | - After the rendering of the grids, it triggers `epnTapModule.onWindowLoaded()`, which basically fill | |
580 | - `epnTapServicesGrid` for the first time. | |
581 | - */ | |
582 | - createGridsPanel: function() { | |
583 | - return { | |
584 | - xtype: 'panel', | |
585 | - id: 'epnTapGridsPanel', | |
586 | - layout: 'fit', | |
587 | - flex: 1, | |
588 | - items: [{ | |
589 | - xtype: 'container', | |
590 | - layout: { type: 'hbox', pack: 'start', align: 'stretch'}, | |
591 | - items: [ | |
592 | - this.createServicesGrid(), | |
593 | - this.createGranulesGrid() | |
594 | - ] | |
595 | - }] | |
596 | - }; | |
597 | - }, | |
598 | - | |
599 | - /** | |
600 | - Create `epnTapServicesGrid`, an ExtJS grid containing the EPN-TAP services matching with the filter form | |
601 | - (`serviceFilterPanel`). | |
602 | - | |
603 | - For each service, this grid displays: | |
604 | - - the service name; | |
605 | - - the number of granules matching with the filter. | |
606 | - | |
607 | - Other informations are available through an ExtJS Tooltip, on each row: | |
608 | - - short name; | |
609 | - - title; | |
610 | - - access URL. | |
611 | - | |
612 | - A click on a service triggers `EpnTapModule.onServiceSelected()`, which basically fills `GranulesGrid` by the | |
613 | - service granules. | |
614 | - */ | |
615 | - createServicesGrid: function() { | |
616 | - return { | |
617 | - xtype: 'grid', | |
618 | - cls: 'epntap_grid', | |
619 | - id: 'epnTapServicesGrid', | |
620 | - title: 'Services', | |
621 | - store: Ext.data.StoreManager.lookup('servicesStore'), | |
622 | - flex: 1, | |
623 | - columns: [ | |
624 | - {text: 'Name', dataIndex: 'short_name', flex: 1, renderer: 'service.text'}, | |
625 | - {text: 'Nb res.', dataIndex: 'nb_results', width: 50, renderer: 'service.number'} | |
626 | - ], | |
627 | - viewConfig: { | |
628 | - getRowClass: function(record, index) { | |
629 | - var nb_res = record.get('nb_results'); | |
630 | - if(nb_res == 0 || nb_res == -1) { | |
631 | - return 'disabled_row'; | |
632 | - } else if (nb_res == -2) { | |
633 | - return 'error_row'; | |
634 | - } | |
635 | - } | |
636 | - } | |
637 | - }; | |
638 | - }, | |
639 | - | |
640 | - /** | |
641 | - Create `epnTapGranulesGrid`, an ExtJS grid containing the granules of the selected service in | |
642 | - `epnTapServicesGrid`. | |
643 | - | |
644 | - For each granule, this grid displays: | |
645 | - - the row number; | |
646 | - - the dataproduct type; | |
647 | - - the target name; | |
648 | - - the min and max times; | |
649 | - - the format; | |
650 | - - the UID (granule identifier); | |
651 | - - the estimated size; | |
652 | - - the URL; | |
653 | - - the thumbnail. | |
654 | - | |
655 | - Each of these information are displayed in a specific rendering to improve user experience. | |
656 | - For more information about these parameters, see https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters. | |
657 | - | |
658 | - Other informations are available through an ExtJS Tooltip on each row: | |
659 | - - currently only the granule thumbnail, in full size. | |
660 | - | |
661 | - A click on a granule triggers `EpnTapModule.onGranuleSelected()`. | |
662 | - */ | |
663 | - createGranulesGrid: function() { | |
664 | - return { | |
665 | - xtype: 'grid', | |
666 | - cls: 'epntap_grid', | |
667 | - id: 'epnTapGranulesGrid', | |
668 | - title: 'Granules', | |
669 | - store: Ext.data.StoreManager.lookup('granulesStore'), | |
670 | - flex: 4, | |
671 | - plugins: { | |
672 | - ptype: 'bufferedrenderer', | |
673 | - trailingBufferZone: 20, | |
674 | - leadingBufferZone: 50 | |
675 | - }, | |
676 | - columns: [] | |
677 | - }; | |
678 | - } | |
679 | -}); | |
385 | + extend: 'Ext.panel.Panel', | |
386 | + alias: 'widget.panelEpnTap', | |
387 | + requires: ['amdaUI.IntervalUI'], | |
388 | + | |
389 | + /** | |
390 | + Method constructor, which basically call the `init()` method to create the EpnTap panel. | |
391 | + */ | |
392 | + constructor: function (config) { | |
393 | + this.init(config) | |
394 | + this.callParent(arguments) | |
395 | + }, | |
396 | + | |
397 | + /** | |
398 | + Create all the EpnTapPanel UI elements, and apply the AMDA module `config` (which includes the created items). | |
399 | + | |
400 | + When the panel is correctly rendered, the panel triggers `EpnTapModule.onWindowLoaded()`. | |
401 | + | |
402 | + Note: All the UI elements creation are defined as functions in this init method and not as methods in order to make | |
403 | + them private (ie. to avoid `EpnTapUI.createServicesGrid();`, which doesn't make sense). | |
404 | + */ | |
405 | + init: function (config) { | |
406 | + var myConf = { | |
407 | + id: 'epntapTab', | |
408 | + title: 'EPN-TAP', | |
409 | + items: [{ | |
410 | + xtype: 'container', | |
411 | + layout: { type: 'vbox', pack: 'start', align: 'stretch'}, | |
412 | + items: [ | |
413 | + this.createServiceFilterPanel(), | |
414 | + this.createGridsPanel() | |
415 | + ] | |
416 | + }] | |
417 | + } | |
418 | + Ext.apply(this, Ext.apply(arguments, myConf)) | |
419 | + }, | |
420 | + | |
421 | + /*************************** | |
422 | + *** Service filter panel *** | |
423 | + ***************************/ | |
424 | + | |
425 | + /** | |
426 | + Create `epnTapServiceFilterPanel`, an ExtJS Panel containing two containers: | |
427 | + - the left container, containing the combo boxes (for product type, target class and target name) | |
428 | + and the navigation panel; | |
429 | + - the right container, containing the time selector. | |
430 | + */ | |
431 | + createServiceFilterPanel: function () { | |
432 | + return { | |
433 | + xtype: 'form', | |
434 | + id: 'epnTapServiceFilterPanel', | |
435 | + layout: { type: 'hbox', pack: 'start', align: 'stretch' }, | |
436 | + region: 'north', | |
437 | + defaults: { margin: '5 0 5 5'}, | |
438 | + items: [{ // Left part | |
439 | + xtype: 'container', | |
440 | + flex: 1, | |
441 | + items: [ | |
442 | + this.createTargetNameCB(), | |
443 | + this.createProductTypeCB() | |
444 | + ] | |
445 | + }, { // Middle part | |
446 | + xtype: 'container', | |
447 | + flex: 1, | |
448 | + items: [ | |
449 | + this.createTimeSelector() | |
450 | + ] | |
451 | + }, { // Right part | |
452 | + xtype: 'container', | |
453 | + items: [ | |
454 | + this.createSendButton() | |
455 | + ] | |
456 | + | |
457 | + }] | |
458 | + } | |
459 | + }, | |
460 | + | |
461 | + /** | |
462 | + Create `epnTapTargetNameCB`, an ExtJS ComboBox, containing a list of target names corresponding to the selected | |
463 | + target class, as defined in `targetNamesStore`, which is initilized by `EpnTapModule`. | |
464 | + | |
465 | + The selection of a target name triggers `EpnTapModule.onTargetNameCBChanged()`, which basically updates | |
466 | + `granulesGrid`. | |
467 | + */ | |
468 | + createTargetNameCB: function () { | |
469 | + return { | |
470 | + xtype: 'combobox', | |
471 | + id: 'epnTapTargetNameCB', | |
472 | + fieldLabel: 'Target name', | |
473 | + emptyText: 'Earth, Saturn, 67P, ...', | |
474 | + tooltip: 'Start to type a text, then select a target name (required). Several values are allowed, separated by a semicolon.', | |
475 | + store: Ext.data.StoreManager.lookup('targetNamesStore'), | |
476 | + queryMode: 'remote', | |
477 | + queryParam: 'input', | |
478 | + displayField: 'text', | |
479 | + valueField: 'id', | |
480 | + margin: '15 0 5 0', | |
481 | + labelWidth: 71, | |
482 | + minWidth: 20, | |
483 | + minChars: 2, | |
484 | + hideTrigger: true, | |
485 | + listConfig: { | |
486 | + getInnerTpl: function () { | |
487 | + return '<div data-qtitle="{name}" data-qtip="<p>type: {type}</p><p>parent: {parent}</p><p>aliases:</p><ul>{aliases}</ul>">{name}</div>' | |
488 | + } | |
489 | + }, | |
490 | + listeners: { | |
491 | + render: function (cb) { | |
492 | + new Ext.ToolTip({ target: cb.getEl(), html: '<div style="width:200px">' + cb.tooltip + '</div>'}) | |
493 | + } | |
494 | + } | |
495 | + } | |
496 | + }, | |
497 | + | |
498 | + /** | |
499 | + Create `epnTapProductTypeCB`, an ExtJS ComboBox, containing a list of product types as defined in | |
500 | + `epnTapProductTypesStore`, which is initilized by `EpnTapModule`. | |
501 | + | |
502 | + The selection of a produt type triggers `EpnTapModule.onProductTypeCBChanged()`, which basically update | |
503 | + `epnTapGranulesGrid`. | |
504 | + */ | |
505 | + createProductTypeCB: function () { | |
506 | + return { | |
507 | + xtype: 'combobox', | |
508 | + id: 'epnTapProductTypeCB', | |
509 | + fieldLabel: 'Product type', | |
510 | + emptyText: 'Image, Time series, ...', | |
511 | + tooltip: 'Select one or several data product types (required).', | |
512 | + store: Ext.data.StoreManager.lookup('productTypesStore'), | |
513 | + queryMode: 'local', | |
514 | + valueField: 'id', | |
515 | + multiSelect: true, | |
516 | + displayField: 'name', | |
517 | + labelWidth: 71, | |
518 | + editable: false, | |
519 | + listConfig: { | |
520 | + getInnerTpl: function () { | |
521 | + return '<div data-qtitle="{name}" data-qwidth=200 data-qtip="<p>{desc}</p>">{name}</div>' | |
522 | + } | |
523 | + }, | |
524 | + listeners: { | |
525 | + change: function (cb, records) { | |
526 | + var val = cb.value[cb.value.length - 1] | |
527 | + if (val === 'all') { | |
528 | + cb.select(cb.store.getRange().slice(2)) | |
529 | + } else if (val === 'clear') { | |
530 | + cb.reset() | |
531 | + } | |
532 | + }, | |
533 | + render: function (cb) { | |
534 | + new Ext.ToolTip({ target: cb.getEl(), html: '<div style="width:200px">' + cb.tooltip + '</div>'}) | |
535 | + } | |
536 | + } | |
537 | + } | |
538 | + }, | |
539 | + | |
540 | + /** | |
541 | + Create `epnTapTimeSelector`, an IntervalUI object, allowing the user to select a time interval (by filling two | |
542 | + dates and/or a duration). | |
543 | + | |
544 | + See `js/app/views/IntervalUI.js` for more information about this component. | |
545 | + */ | |
546 | + createTimeSelector: function () { | |
547 | + return { | |
548 | + xtype: 'intervalSelector', | |
549 | + id: 'epnTapTimeSelector' | |
550 | + } | |
551 | + }, | |
552 | + | |
553 | + /*********************** | |
554 | + *** Navigation panel *** | |
555 | + ***********************/ | |
556 | + | |
557 | + /** | |
558 | + The button used to send the query. | |
559 | + */ | |
560 | + createSendButton: function () { | |
561 | + return { | |
562 | + xtype: 'button', | |
563 | + id: 'epnTapGetBtn', | |
564 | + text: 'Get services', | |
565 | + disabled: true, | |
566 | + width: 140, | |
567 | + height: 50, | |
568 | + margin: 10 | |
569 | + } | |
570 | + }, | |
571 | + | |
572 | + /************ | |
573 | + *** Grids *** | |
574 | + ************/ | |
575 | + | |
576 | + /** | |
577 | + Create `epnTapGridsPanel`, an ExtJS Panel, containing `epnTapServicesGrid` and `epnTapGranulesGrid`. | |
578 | + | |
579 | + After the rendering of the grids, it triggers `epnTapModule.onWindowLoaded()`, which basically fill | |
580 | + `epnTapServicesGrid` for the first time. | |
581 | + */ | |
582 | + createGridsPanel: function () { | |
583 | + return { | |
584 | + xtype: 'panel', | |
585 | + id: 'epnTapGridsPanel', | |
586 | + layout: 'fit', | |
587 | + flex: 1, | |
588 | + items: [{ | |
589 | + xtype: 'container', | |
590 | + layout: { type: 'hbox', pack: 'start', align: 'stretch'}, | |
591 | + items: [ | |
592 | + this.createServicesGrid(), | |
593 | + this.createGranulesGrid() | |
594 | + ] | |
595 | + }] | |
596 | + } | |
597 | + }, | |
598 | + | |
599 | + /** | |
600 | + Create `epnTapServicesGrid`, an ExtJS grid containing the EPN-TAP services matching with the filter form | |
601 | + (`serviceFilterPanel`). | |
602 | + | |
603 | + For each service, this grid displays: | |
604 | + - the service name; | |
605 | + - the number of granules matching with the filter. | |
606 | + | |
607 | + Other informations are available through an ExtJS Tooltip, on each row: | |
608 | + - short name; | |
609 | + - title; | |
610 | + - access URL. | |
611 | + | |
612 | + A click on a service triggers `EpnTapModule.onServiceSelected()`, which basically fills `GranulesGrid` by the | |
613 | + service granules. | |
614 | + */ | |
615 | + createServicesGrid: function () { | |
616 | + return { | |
617 | + xtype: 'grid', | |
618 | + cls: 'epntap_grid', | |
619 | + id: 'epnTapServicesGrid', | |
620 | + title: 'Services', | |
621 | + store: Ext.data.StoreManager.lookup('servicesStore'), | |
622 | + flex: 1, | |
623 | + columns: [ | |
624 | + {text: 'Name', dataIndex: 'short_name', flex: 1, renderer: 'service.text'}, | |
625 | + {text: 'Nb res.', dataIndex: 'nb_results', width: 50, renderer: 'service.number'} | |
626 | + ], | |
627 | + viewConfig: { | |
628 | + getRowClass: function (record, index) { | |
629 | + var nb_res = record.get('nb_results') | |
630 | + if (nb_res == 0 || nb_res == -1) { | |
631 | + return 'disabled_row' | |
632 | + } else if (nb_res == -2) { | |
633 | + return 'error_row' | |
634 | + } | |
635 | + } | |
636 | + } | |
637 | + } | |
638 | + }, | |
639 | + | |
640 | + /** | |
641 | + Create `epnTapGranulesGrid`, an ExtJS grid containing the granules of the selected service in | |
642 | + `epnTapServicesGrid`. | |
643 | + | |
644 | + For each granule, this grid displays: | |
645 | + - the row number; | |
646 | + - the dataproduct type; | |
647 | + - the target name; | |
648 | + - the min and max times; | |
649 | + - the format; | |
650 | + - the UID (granule identifier); | |
651 | + - the estimated size; | |
652 | + - the URL; | |
653 | + - the thumbnail. | |
654 | + | |
655 | + Each of these information are displayed in a specific rendering to improve user experience. | |
656 | + For more information about these parameters, see https://voparis-confluence.obspm.fr/display/VES/EPN-TAP+V2.0+parameters. | |
657 | + | |
658 | + Other informations are available through an ExtJS Tooltip on each row: | |
659 | + - currently only the granule thumbnail, in full size. | |
660 | + | |
661 | + A click on a granule triggers `EpnTapModule.onGranuleSelected()`. | |
662 | + */ | |
663 | + createGranulesGrid: function () { | |
664 | + return { | |
665 | + xtype: 'grid', | |
666 | + cls: 'epntap_grid', | |
667 | + id: 'epnTapGranulesGrid', | |
668 | + title: 'Granules', | |
669 | + store: Ext.data.StoreManager.lookup('granulesStore'), | |
670 | + flex: 4, | |
671 | + plugins: { | |
672 | + ptype: 'bufferedrenderer', | |
673 | + trailingBufferZone: 20, | |
674 | + leadingBufferZone: 50 | |
675 | + }, | |
676 | + columns: [] | |
677 | + } | |
678 | + } | |
679 | +}) | |
... | ... |