Commit a8a12768e39334cae8c451eaff18604699a42063

Authored by Nathanael Jourdane
1 parent 081d9db8

Create the grid model dynamically

js/app/controllers/EpnTapModule.js
... ... @@ -58,7 +58,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
58 58 this.targetNamesStore = Ext.data.StoreManager.lookup('targetNamesStore');
59 59 },
60 60  
61   - addUIListeners: function() {
  61 + addListeners: function() {
62 62 this.targetNameCB.on('change', function() {
63 63 this.updateGetBtnStatus();
64 64 }, this);
... ... @@ -101,7 +101,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
101 101 loadTarget: function(target) {
102 102 this.target = target;
103 103 this.aquireElements();
104   - this.addUIListeners();
  104 + this.addListeners();
105 105  
106 106 // this.servicesStore.clearFilter();
107 107 this.granulesStore.removeAll();
... ... @@ -145,6 +145,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
145 145 'timeMin': timeMin,
146 146 'timeMax': timeMax
147 147 },
  148 + // timeout: 3000,
148 149 success: this.updateNbResults,
149 150 failure: this.updateNbResultsFail,
150 151 scope: this
... ... @@ -191,30 +192,22 @@ Ext.define('amdaDesktop.EpnTapModule', {
191 192 },
192 193  
193 194 onPageChanged: function() {
194   - var myProxy = this.granulesStore.getProxy();
195   - myProxy.params = this.getGranuleParams();
196   - myProxy.extraParams = this.getGranuleParams();
197   - // //--- Set value to your parameter ----//
198   - // myProxy.setExtraParam('url', this.selectedService.data['access_url']);
199   - // myProxy.setExtraParam('MENU_DETAIL', '555555');
  195 + this.granulesStore.getProxy().extraParams = this.getGranuleParams();
200 196 },
  197 +
201 198 /**
202 199 Trigerred when a row is clicked in `servicesGrid` table (see `EpnTapUI.createServicesGrid()`). Among other things,
203 200 send a new query and fill `granulesGrid`.
204 201 */
205 202 onServiceSelected: function(record) {
  203 + // Ext.Ajax.abortAll();
206 204 this.selectedService = record;
207 205 var nbRes = this.selectedService.get('nb_results');
208 206 if(nbRes > 0 && !isNaN(nbRes)) {
209   - loadMask.show();
210 207 this.granulesStore.load({
211 208 params: this.getGranuleParams(),
212 209 start: 0,
213 210 limit: this.granulesStore.pageSize,
214   - callback: function(records, operation, success) {
215   - console.log(records, operation);
216   - loadMask.hide();
217   - },
218 211 scope: this
219 212 });
220 213 }
... ...
js/app/views/EpnTapUI.js
... ... @@ -113,7 +113,10 @@ Ext.create('Ext.data.Store', {
113 113 sorters: [
114 114 {property: 'nb_results', direction: 'DESC'},
115 115 {property: 'short_name', direction: 'ASC'}
116   - ]
  116 + ],
  117 + listeners: {
  118 + // load: function(record) { console.log(record); }
  119 + }
117 120 });
118 121  
119 122 /**
... ... @@ -136,21 +139,22 @@ selected.
136 139 - `thumbnail_url`: the thumbnail_url EPN-TAP parameter (ibid).
137 140 */
138 141 Ext.create('Ext.data.Store', {
139   - storeId:'granulesStore',
140   - pageSize: 25,
  142 + id: 'granulesStore',
  143 + model: 'granulesModel',
141 144 autoload: false,
142   - fields:['num', 'dataproduct_type', 'target_name', 'time_min', 'time_max', 'access_format', 'granule_uid', 'access_estsize', 'access_url', 'thumbnail_url'],
  145 + pageSize: 25,
143 146 proxy: {
144 147 type: 'ajax',
145 148 url: 'php/epntap.php',
146 149 reader: {
147 150 type: 'json',
148   - root: 'rows'
  151 + root: 'data'
149 152 }
150   - },
151   - sorters: [
152   - {property: 'num', direction: 'ASC'}
153   - ]
  153 + }, listeners: {
  154 + 'metachange': function(store, meta) {
  155 + Ext.getCmp('epnTapGranulesGrid').reconfigure(store, meta.columns);
  156 + }
  157 + }
154 158 });
155 159  
156 160 /**
... ... @@ -385,7 +389,6 @@ Ext.define('amdaUI.EpnTapUI', {
385 389 };
386 390 },
387 391  
388   -
389 392 /**
390 393 Create `epnTapServicesGrid`, an ExtJS grid containing the EPN-TAP services matching with the filter form
391 394 (`serviceFilterPanel`).
... ... @@ -472,7 +475,6 @@ Ext.define('amdaUI.EpnTapUI', {
472 475 }
473 476 }
474 477 });
475   -
476 478 return epnTapServicesGrid;
477 479 },
478 480  
... ... @@ -498,6 +500,7 @@ Ext.define('amdaUI.EpnTapUI', {
498 500 - currently only the granule thumbnail, in full size.
499 501  
500 502 A click on a granule triggers `EpnTapModule.onGranuleSelected()`.
  503 + TODO: infinite scroll! http://docs.sencha.com/extjs/4.2.3/extjs-build/examples/grid/infinite-scroll-with-filter.html
501 504 */
502 505 createGranulesGrid: function() {
503 506 var txtRender = function(val) {
... ... @@ -510,9 +513,8 @@ Ext.define('amdaUI.EpnTapUI', {
510 513 return '<img width="40px height="40px" src="' + val + '">';
511 514 };
512 515 var dptRender = function(val) {
513   - console.log(Ext.data.StoreManager.lookup('productTypesStore'));
514   - return val;
515   - // (val in productTypeDict) ? '<p style="white-space: normal;">' + productTypeDict[val] + '</p>' : '<em>' + val + '</em>';
  516 + var productTypeDict = Ext.data.StoreManager.lookup('productTypesStore').data.map;
  517 + return productTypeDict[val].data.name;
516 518 };
517 519 var formatRender = function(val) {
518 520 // A dictionnary used to associate the mimetype (i.e "application/fits") to a pretty printed word (i.e "fits").
... ... @@ -585,16 +587,16 @@ Ext.define(&#39;amdaUI.EpnTapUI&#39;, {
585 587 store: Ext.data.StoreManager.lookup('granulesStore'),
586 588 flex: 4,
587 589 columns: [
588   - { text: 'Num', dataIndex: 'num', flex: 1, renderer: txtRender },
  590 + // { text: 'Num', dataIndex: 'num', flex: 1, renderer: txtRender, hidden: true },
589 591 // { text: 'Type', dataIndex: 'dataproduct_type', flex: 2, renderer: dptRender },
590   - { text: 'Target', dataIndex: 'target_name', flex: 2, renderer: txtRender },
591   - { text: 'Time min', dataIndex: 'time_min', flex: 2, renderer: txtRender },
592   - { text: 'Time max', dataIndex: 'time_max', flex: 2, renderer: txtRender },
  592 + // { text: 'Target', dataIndex: 'target_name', flex: 2, renderer: txtRender, hidden: true },
  593 + // { text: 'Time min', dataIndex: 'time_min', flex: 2, renderer: txtRender },
  594 + // { text: 'Time max', dataIndex: 'time_max', flex: 2, renderer: txtRender },
593 595 // { text: 'Format', dataIndex: 'access_format', flex: 2, renderer: formatRender },
594   - { text: 'uid', dataIndex: 'granule_uid', flex: 2, renderer: txtRender },
595   - { text: 'Size', dataIndex: 'access_estsize', flex: 1, renderer: sizeRender },
596   - { text: 'URL', dataIndex: 'access_url', flex: 1, renderer: linkRender },
597   - { text: 'Thumb.', dataIndex: 'thumbnail_url', flex: 1, renderer: imgRender}
  596 + // { text: 'uid', dataIndex: 'granule_uid', flex: 2, renderer: txtRender },
  597 + // { text: 'Size', dataIndex: 'access_estsize', flex: 1, renderer: sizeRender },
  598 + // { text: 'URL', dataIndex: 'access_url', flex: 1, renderer: linkRender },
  599 + // { text: 'Thumb.', dataIndex: 'thumbnail_url', flex: 1, renderer: imgRender}
598 600 ],
599 601 dockedItems: [{
600 602 xtype: 'pagingtoolbar',
... ...
php/epntap.php
... ... @@ -8,20 +8,23 @@ $action = preg_replace(&quot;/[^a-zA-Z]+/&quot;, &quot;&quot;, filter_var($_GET[&#39;action&#39;], FILTER_SA
8 8  
9 9 switch ($action) {
10 10 case 'resolver':
11   - echo json_encode(resolver());
  11 + $response = json_encode(resolver());
12 12 break;
13 13 case 'getServices':
14   - echo json_encode(getServices());
  14 + $response = json_encode(getServices());
15 15 break;
16 16 case 'getNbResults':
17   - echo getNbResults();
  17 + $response = getNbResults();
18 18 break;
19 19 case 'getGranules':
20   - echo json_encode(getGranules());
  20 + $response = json_encode(getGranules());
21 21 break;
22 22 default:
23   - echo 'unknown action';
  23 + $response = 'unknown action';
  24 + break;
24 25 }
  26 +// error_log('epntap response: ' . $response);
  27 +echo $response;
25 28  
26 29 function resolver() {
27 30 $input = filter_var($_GET['input'], FILTER_SANITIZE_URL);
... ... @@ -41,13 +44,14 @@ function resolver() {
41 44 function getServices() {
42 45 $registriesURL = ["http://registry.euro-vo.org/regtap/tap", "http://dc.zah.uni-heidelberg.de/tap", "http://gavo.aip.de/tap", "http://reg.g-vo.org/tap"];
43 46 $columns = ['short_name', 'res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated'];
44   - $getServicesQuery = "SELECT DISTINCT " . implode(', ', $columns) . " FROM rr.resource
  47 + $query = "SELECT DISTINCT " . implode(', ', $columns) . " FROM rr.resource
45 48 NATURAL JOIN rr.res_schema NATURAL JOIN rr.res_table NATURAL JOIN rr.interface NATURAL JOIN rr.res_detail NATURAL JOIN rr.capability
46 49 WHERE standard_id='ivo://ivoa.net/std/tap' AND intf_type='vs:paramhttp' AND detail_xpath='/capability/dataModel/@ivo-id'
47 50 AND 1=ivo_nocasematch(detail_value, 'ivo://vopdc.obspm/std/EpnCore%') AND table_name LIKE '%.epn_core' ORDER BY short_name, table_name";
  51 + // error_log('getServices query: ' . $query);
48 52  
49 53 for($i=0; $i<count($registriesURL); $i++) {
50   - $services = request($registriesURL[$i], $getServicesQuery);
  54 + $services = request($registriesURL[$i], $query);
51 55 if(! array_key_exists("error", $services)) {
52 56 for($j=0; $j<count($services); $j++) {
53 57 $services[$j]['id'] = generateServiceId($services[$j]);
... ... @@ -78,6 +82,7 @@ function getNbResults() {
78 82 $timeMax = filter_var($_GET['timeMax'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
79 83  
80 84 $query = "SELECT COUNT(*) AS nb_rows FROM $tableName" . createFilter($targetName, $productTypes, $timeMin, $timeMax);
  85 + // error_log('getNbResults query: ' . $query);
81 86 $result = request($url, $query);
82 87 if(count($result) < 1) {
83 88 return 'Too few returned raws.';
... ... @@ -97,7 +102,7 @@ function getNbResults() {
97 102 }
98 103  
99 104 function getGranules() {
100   - error_log(json_encode($_GET));
  105 + // error_log('getGranules GET: ' . json_encode($_GET));
101 106 $url = filter_var($_GET['url'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
102 107 $tableName = filter_var($_GET['tableName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
103 108 $targetName = filter_var($_GET['targetName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
... ... @@ -108,13 +113,20 @@ function getGranules() {
108 113 $limit = filter_var($_GET['limit'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
109 114 $nbRes = filter_var($_GET['nbRes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
110 115  
111   - // TODO find a way to handle 'non existing key errors' (and then add access_format)
112   - $columns = "dataproduct_type, target_name, time_min, time_max, granule_uid, access_estsize, access_url, thumbnail_url";
113 116 $filter = createFilter($targetName, $productTypes, $timeMin, $timeMax);
114   - $query = "SELECT TOP $limit $columns FROM $tableName $filter OFFSET $start";
  117 + $query = "SELECT TOP $limit * FROM $tableName $filter OFFSET $start";
  118 + // error_log('getGranules query: ' . $query);
115 119 $rows = request($url, $query);
116   - return ['success' => true, 'total' => $nbRes, 'rows' => $rows];
117   - // return $rows;
  120 +
  121 + $fields = array();
  122 + $columns = array();
  123 + foreach($rows[0] as $key => $value) {
  124 + $fields[] = ['name' => $key, 'type' => 'string'];
  125 + $columns[] = ['text' => ucfirst(str_replace('_', ' ', $key)), 'dataIndex' => $key];
  126 + }
  127 +
  128 + $metadata = ['fields' => $fields, 'columns' => $columns, 'root' => 'data'];
  129 + return ['data' => $rows, 'total' => $nbRes, 'metaData' => $metadata];
118 130 }
119 131  
120 132 // ----- utils -----
... ...