diff --git a/js/app/controllers/EpnTapModule.js b/js/app/controllers/EpnTapModule.js index 13ec051..e875f47 100644 --- a/js/app/controllers/EpnTapModule.js +++ b/js/app/controllers/EpnTapModule.js @@ -27,8 +27,7 @@ Ext.define('amdaDesktop.EpnTapModule', { Module initialisation. Called the first time that the user open the epnTap module. */ init: function() { - this.filter = Array(); - this.selectedServiceId = null; + this.selectedService = null; this.launcher = { text: this.title, @@ -38,18 +37,6 @@ Ext.define('amdaDesktop.EpnTapModule', { }; this.aquireElements(); - - // create productTypeDict based on productTypesStore - this.productTypesStore.on({ - load: function(store) { - this.productTypeDict = {}; - for (var key in store.data.map) { - this.productTypeDict[key] = store.data.map[key].data.name; - } - }, - scope: this - }); - this.servicesStore.load(); this.productTypesStore.load(); }, @@ -60,20 +47,13 @@ Ext.define('amdaDesktop.EpnTapModule', { this.granulesGrid = Ext.getCmp('epnTapGranulesGrid'); this.productTypeCB = Ext.getCmp('epnTapProductTypeCB'); this.targetNameCB = Ext.getCmp('epnTapTargetNameCB'); + this.pagingTB = Ext.getCmp('epnTapPagingTB'); this.timeSelector = Ext.getCmp('epnTapTimeSelector'); - this.rowsPerPageNf = Ext.getCmp('epnTapRowsPerPageNf'); - this.currentPageLb = Ext.getCmp('epnTapCurrentPageLb'); - this.totalPagesLb = Ext.getCmp('epnTapTotalPagesLb'); - this.firstPageBtn = Ext.getCmp('epnTapFirstPageBtn'); - this.previousPageBtn = Ext.getCmp('epnTapPreviousPageBtn'); - this.nextPageBtn = Ext.getCmp('epnTapNextPageBtn'); - this.lastPageBtn = Ext.getCmp('epnTapLastPageBtn'); this.getBtn = Ext.getCmp('epnTapGetBtn'); // stores elements this.servicesStore = Ext.data.StoreManager.lookup('servicesStore'); this.granulesStore = Ext.data.StoreManager.lookup('granulesStore'); - // this.metadataStore = Ext.data.StoreManager.lookup('metadataStore') this.productTypesStore = Ext.data.StoreManager.lookup('productTypesStore'); this.targetNamesStore = Ext.data.StoreManager.lookup('targetNamesStore'); }, @@ -91,24 +71,8 @@ Ext.define('amdaDesktop.EpnTapModule', { this.onServiceSelected(record); }, this); - this.granulesGrid.on('cellclick', function(grid, td, cellIndex, record) { - this.onGranuleSelected(record.data['id']); - }, this); - - this.firstPageBtn.on('click', function() { - this.onFirstPageBtnClicked(); - }, this); - - this.previousPageBtn.on('click', function() { - this.onPreviousPageBtnClicked(); - }, this); - - this.nextPageBtn.on('click', function() { - this.onNextPageBtnClicked(); - }, this); - - this.lastPageBtn.on('click', function() { - this.onLastPageBtnClicked(); + this.pagingTB.on('beforechange', function(grid, td, cellIndex, record) { + this.onPageChanged(); }, this); this.getBtn.on('click', function() { @@ -120,43 +84,6 @@ Ext.define('amdaDesktop.EpnTapModule', { *** Utils functions *** **********************/ - /** - Capitalize a name and replace underscores with spaces. - - `name`: The string to make pretty. - */ - prettify: function(name) { - return name.charAt(0).toUpperCase() + name.replace(/_/g, ' ').substr(1).toLowerCase(); - }, - - /** - Capitalize a name, replace underscores with spaces, and write it in a plurial form. - - `name`: The string to make pretty. - */ - allPrettify: function(name) { - return 'All ' + (name[name.length-1] == 's' ? name : name + 's').replace(/_/g, ' ').toLowerCase(); - }, - - isDate: function(date) { - if (date === null) { - return false; - } - var dateArr = date.split('/'); - if (dateArr.length != 3 || isNaN(parseInt(dateArr[0])) || isNaN(parseInt(dateArr[1])) || isNaN(parseInt(dateArr[2])) ) { - return false; - } - return true; - }, - - /** - Disable or enable the navigation buttons (see `EpnTapUI.createNavigationPanel()`). - */ - disableNavBtns: function(firt, previous, next, last) { - this.firstPageBtn.setDisabled(firt); - this.previousPageBtn.setDisabled(previous); - this.nextPageBtn.setDisabled(next); - this.lastPageBtn.setDisabled(last); - }, - updateGetBtnStatus: function() { var shouldEnabled = this.targetNameCB.rawValue.length > 0 && this.productTypeCB.rawValue.length > 0; if(shouldEnabled) { @@ -167,10 +94,6 @@ Ext.define('amdaDesktop.EpnTapModule', { }, - /**************************** - *** Service filter events *** - ****************************/ - /** Called each time the epntap module is loaded. - `target`: an array of 3 values: [target_name, dataproduct_type]; or null. @@ -184,82 +107,17 @@ Ext.define('amdaDesktop.EpnTapModule', { this.granulesStore.removeAll(); if(target) { - this.targetNameCB.getStore().add({'id': target[0], 'name': this.prettify(target[0])}); + var name = target[0].charAt(0).toUpperCase() + target[0].replace(/_/g, ' ').substr(1).toLowerCase(); + this.targetNameCB.getStore().add({'id': target[0], 'name': name}); this.targetNameCB.select(target[0]); this.productTypeCB.select(target[1]); this.updateNbResults(); } }, - /********************* - *** Buttons events *** - *********************/ - - /** - Trigerred when the `firstPageBtn` button is clicked (see `EpnTapUI.createNavigationPanel()`). Among other things, - send a new query and fill `granulesGrid`. - */ - onFirstPageBtnClicked: function() { - var newPageNumber = 1; - var limit = Number(this.rowsPerPageNf.value); - var offset = 0; - var selectedService = this.servicesStore.findRecord('id', this.selectedServiceId).data; - - this.disableNavBtns(true, true, false, false); - this.currentPageLb.setText('' + newPageNumber); - loadMask.show(); - AmdaAction.epnTapGetGranules(selectedService['table_name'], selectedService['access_url'], this.filter, limit, offset, this.fillGranules); - }, - - /** - Trigerred when the `previousPageBtn` button is clicked (see `EpnTapUI.createNavigationPanel()`). Among other things, - send a new query and fill `granulesGrid`. - */ - onPreviousPageBtnClicked: function() { - var newPageNumber = Number(this.currentPageLb.text) - 1; - var limit = Number(this.rowsPerPageNf.value); - var offset = (newPageNumber-1) * limit; - var selectedService = this.servicesStore.findRecord('id', this.selectedServiceId).data; - - this.currentPageLb.setText('' + newPageNumber); - var isFirstPage = this.currentPageLb.text === '1'; - this.disableNavBtns(isFirstPage, isFirstPage, false, false); - loadMask.show(); - AmdaAction.epnTapGetGranules(selectedService['table_name'], selectedService['access_url'], this.filter, limit, offset, this.fillGranules); - }, - - /** - Trigerred when the `nextPageBtn` button is clicked (see `EpnTapUI.createNavigationPanel()`). Among other things, - send a new query and fill `granulesGrid`. - */ - onNextPageBtnClicked: function() { - var newPageNumber = Number(this.currentPageLb.text) + 1; - var limit = Number(this.rowsPerPageNf.value); - var offset = (newPageNumber-1) * limit; - var selectedService = this.servicesStore.findRecord('id', this.selectedServiceId).data; - - this.currentPageLb.setText('' + newPageNumber); - var isLastPage = this.currentPageLb.text == this.totalPagesLb.text; - this.disableNavBtns(false, false, isLastPage, isLastPage); - loadMask.show(); - AmdaAction.epnTapGetGranules(selectedService['table_name'], selectedService['access_url'], this.filter, limit, offset, this.fillGranules); - }, - - /** - Trigerred when the `lastPageBtn` button is clicked (see `EpnTapUI.createNavigationPanel()`). Among other things, - send a new query and fill `granulesGrid`. - */ - onLastPageBtnClicked: function() { - var newPageNumber = Number(this.totalPagesLb.text); - var limit = Number(this.rowsPerPageNf.value); - var offset = (newPageNumber-1) * limit; - var selectedService = this.servicesStore.findRecord('id', this.selectedServiceId).data; - - this.currentPageLb.setText('' + newPageNumber); - this.disableNavBtns(false, false, true, true); - loadMask.show(); - AmdaAction.epnTapGetGranules(selectedService['table_name'], selectedService['access_url'], this.filter, limit, offset, this.fillGranules); - }, + /************* + *** Events *** + *************/ /** Trigerred when the 'Get results' button is clicked. @@ -272,6 +130,7 @@ Ext.define('amdaDesktop.EpnTapModule', { loadMask.show(); this.servicesStore.each(function(record) { + // TODO: use store.load() method instead. Ext.Ajax.request({ url: 'php/epntap.php', method: 'GET', @@ -318,114 +177,46 @@ Ext.define('amdaDesktop.EpnTapModule', { loadMask.hide(); }, - /******************* - *** Grids events *** - *******************/ - - /** - Trigerred when a row is clicked in `servicesGrid` table (see `EpnTapUI.createServicesGrid()`). Among other things, - send a new query and fill `granulesGrid`. - */ - onServiceSelected: function(record) { - var nbRes = record.get('nb_results'); - if(nbRes <= 0 || isNaN(nbRes)) { - return; + getGranuleParams: function() { + return { + 'action': 'getGranules', + 'url': this.selectedService.data['access_url'], + 'tableName': this.selectedService.data['table_name'], + 'targetName': this.targetNameCB.rawValue, + 'productTypes': this.productTypeCB.value.join(';'), + 'timeMin': Ext.Date.format(this.timeSelector.getStartTime(), 'd/m/Y H:i:s'), + 'timeMax': Ext.Date.format(this.timeSelector.getStopTime(), 'd/m/Y H:i:s'), + 'nbRes': this.selectedService.get('nb_results') } - var targetName = this.targetNameCB.rawValue; - var productTypes = this.productTypeCB.value.join(';'); - var timeMin = Ext.Date.format(this.timeSelector.getStartTime(), 'd/m/Y H:i:s'); // start time - var timeMax = Ext.Date.format(this.timeSelector.getStopTime(), 'd/m/Y H:i:s'); // stop time - - loadMask.show(); - Ext.Ajax.request({ - url: 'php/epntap.php', - method: 'GET', - headers: {'Content-Type': 'application/json'}, - // waitTitle: 'Connecting', - // waitMsg: 'Sending data...', - params: { - 'action': 'getGranules', - 'url': record.data['access_url'], - 'tableName': record.data['table_name'], - 'targetName': targetName, - 'productTypes': productTypes, - 'timeMin': timeMin, - 'timeMax': timeMax, - 'top': this.rowsPerPageNf.value, - 'offset': 0 - }, - success: this.updateGranules, - failure: this.updateGranulesFail, - scope: this - }); }, - updateGranules: function(response) { - try { - granules = JSON.parse(response.responseText); - } catch (e) { - response.responseText = 'Can not decode the returned Json.' - this.updateGranulesFail(response); - } - this.granulesStore.add(granules); - loadMask.hide(); + onPageChanged: function() { + var myProxy = this.granulesStore.getProxy(); + myProxy.params = this.getGranuleParams(); + myProxy.extraParams = this.getGranuleParams(); + // //--- Set value to your parameter ----// + // myProxy.setExtraParam('url', this.selectedService.data['access_url']); + // myProxy.setExtraParam('MENU_DETAIL', '555555'); }, - /** - Trigerred when a row is clicked in `granulesGrid` table (see `EpnTapUI.createGranulesGrid()`). - */ - updateGranulesFail: function(granule) { - var reason = response.status === 200 ? response.responseText : response.statusText; - Ext.Msg.alert('Can not display granules: ' + reason); - loadMask.hide(); - // console.log('selected granule: ', granule); - }, - - /********************** - *** Other functions *** - **********************/ - - /** - Callback function, called from the PHP script when the query result is received, when a service is selected. - - Among other things, update the `epnTapCurrentPageLb` label (see `EpnTapUI.createNavigationPanel()`). - */ - updateNbRows: function(nb_results) { - var totalPages = Math.ceil(Number(nb_results) / Ext.getCmp('epnTapRowsPerPageNf').value); - - Ext.getCmp('epnTapCurrentPageLb').setText(totalPages == 0 ? '-' : '1'); - Ext.getCmp('epnTapTotalPagesLb').setText(totalPages == 0 ? '-' : totalPages); - - Ext.getCmp('epnTapPreviousPageBtn').setDisabled(true); - Ext.getCmp('epnTapFirstPageBtn').setDisabled(true); - Ext.getCmp('epnTapNextPageBtn').setDisabled(totalPages <= 1); - Ext.getCmp('epnTapLastPageBtn').setDisabled(totalPages <= 1); - }, - - /** - Callback function, called from the PHP script when the query result is received, when a service is selected or a - navigation button is clicked. - - Among other things, fill the `epnTapGranulesGrid` table (see `EpnTapUI.granulesStore`). + Trigerred when a row is clicked in `servicesGrid` table (see `EpnTapUI.createServicesGrid()`). Among other things, + send a new query and fill `granulesGrid`. */ - fillGranules: function(granules) { - loadMask.hide(); - - if (granules["error"] != null) { - console.log('Can not get request response:', granules["error"]); - if(granules["error"] == "no result") { - Ext.Msg.alert('There is no result for this query.'); - } else { - Ext.Msg.alert('Can not display granules due to an error from the selected epn-tap service.'); - } - } else { - try { - Ext.getCmp('epnTapGranulesGrid').getStore().removeAll(); - Ext.getCmp('epnTapGranulesGrid').getStore().add(granules); - } catch( e ) { - console.log('Can not add granules: ' + e); - Ext.Msg.alert('Can not display granules due to an error from the selected epn-tap service.'); - } + onServiceSelected: function(record) { + this.selectedService = record; + var nbRes = this.selectedService.get('nb_results'); + if(nbRes > 0 && !isNaN(nbRes)) { + loadMask.show(); + this.granulesStore.load({ + params: this.getGranuleParams(), + start: 0, + limit: this.granulesStore.pageSize, + callback: function(records, operation, success) { + console.log(records, operation); + loadMask.hide(); + }, + scope: this + }); } } }); diff --git a/js/app/views/EpnTapUI.js b/js/app/views/EpnTapUI.js index 3021a93..337da87 100644 --- a/js/app/views/EpnTapUI.js +++ b/js/app/views/EpnTapUI.js @@ -137,7 +137,20 @@ selected. */ Ext.create('Ext.data.Store', { storeId:'granulesStore', - fields:['num', 'dataproduct_type', 'target_name', 'time_min', 'time_max', 'access_format', 'granule_uid', 'access_estsize', 'access_url', 'thumbnail_url'] + pageSize: 25, + autoload: false, + fields:['num', 'dataproduct_type', 'target_name', 'time_min', 'time_max', 'access_format', 'granule_uid', 'access_estsize', 'access_url', 'thumbnail_url'], + proxy: { + type: 'ajax', + url: 'php/epntap.php', + reader: { + type: 'json', + root: 'rows' + } + }, + sorters: [ + {property: 'num', direction: 'ASC'} + ] }); /** @@ -217,8 +230,6 @@ Ext.define('amdaUI.EpnTapUI', { }, { // Right part xtype : 'container', items: [ - this.createRowPerPageNf(), - this.createNavigationPanel(), this.createSendButton() ] @@ -332,92 +343,6 @@ Ext.define('amdaUI.EpnTapUI', { ***********************/ /** - Create `epnTapRowsPerPageNf`, a ExtJS Number field, allowing the user to select the number of rows to display in - `epnTapGranulesGrid`. - - When a new number is entered, it triggers `EpnTapModule.onRowsPerPageChanged()`. - */ - createRowPerPageNf: function() { - return { - xtype: 'numberfield', - id: 'epnTapRowsPerPageNf', - fieldLabel: 'Rows per page', - labelWidth: 85, - margin: '4 0 4 0', - width: 140, - height: 20, - value: 20, - minValue: 1, - maxValue: 2000 - }; - }, - - /** - Create `epnTapNavigationPanel`, an ExtJSPanel containing several elements in order to navigate through the - different pages of the query result. If the number of results is highter than the `epnTapRowsPerPageNf` field - value, the result appears to be displayed in different pages. This panel is used to select and display the page - number, mainly with these following elements: - - `epnTapFirstPageBtn`: an ExtJS Button, used to come back to the first page of result, - handling `EpnTapModule.onFirstPageBtnClicked()`; - - `epnTapPreviousPageBtn`: an ExtJS Button, used to come back to the previous page of result, - handling `EpnTapModule.onPreviousPageBtnClicked()`; - - `epnTapCurrentPageLb`: an ExtJS Label, displaying the actual current page; TODO: use a Number field instead! - - `epnTapTotalPagesLb`: an ExtJS Label, displaying the total page number of results (according to the - `epnTapRowsPerPageNf` field value); - - `epnTapNextPageBtn`: an ExtJS Button, used to go to the next page of result, - handling `EpnTapModule.onNextPageBtnClicked()`; - - `epnTapLastPageBtn`: an ExtJS Button, used to come back to the last page of result, - handling `EpnTapModule.onLastPageBtnClicked()`. - - Note: Pages are not actually a "graphical filter": when the user navigate through the pages, a new query is send - to the server with the corresponding range, which improves the response time on large requests. - */ - createNavigationPanel: function() { - return { - xtype: 'container', - width: 145, - defaults: {margin: '0 5 0 0', xtype: 'button', disabled: true}, - items: [{ - id: 'epnTapFirstPageBtn', - text: '|<', - width: 26, - tooltip: 'First page' - }, { - id: 'epnTapPreviousPageBtn', - text: '<', - width: 26, - tooltip: 'Previous page' - }, { - xtype: 'label', - id: 'epnTapCurrentPageLb', - tooltip: 'Current page', - text: '0', - margin: 0 - }, { - xtype: 'label', - text: '/', - margin: 0 - }, { - xtype: 'label', - id: 'epnTapTotalPagesLb', - tooltip: 'Total pages', - text: '0', - }, { - id: 'epnTapNextPageBtn', - text: '>', - width: 26, - tooltip: 'Next page' - }, { - id: 'epnTapLastPageBtn', - text: '>|', - width: 26, - margin: 0, - tooltip: 'Last page' - }] - }; - }, - - /** The button used to send the query. */ createSendButton: function() { @@ -427,7 +352,8 @@ Ext.define('amdaUI.EpnTapUI', { text: 'Get results', disabled: true, width: 140, - margin: '5 0 0 0' + height: 50, + margin: 10 } }, @@ -670,6 +596,30 @@ Ext.define('amdaUI.EpnTapUI', { { text: 'URL', dataIndex: 'access_url', flex: 1, renderer: linkRender }, { text: 'Thumb.', dataIndex: 'thumbnail_url', flex: 1, renderer: imgRender} ], + dockedItems: [{ + xtype: 'pagingtoolbar', + id: 'epnTapPagingTB', + store: Ext.data.StoreManager.lookup('granulesStore'), + dock: 'bottom', + displayInfo: true, + items: [{ + xtype: 'tbseparator' + }, { + xtype: 'numberfield', + id: 'epnTapRowsPerPageNf', + fieldLabel: 'Rows per page', + labelWidth: 78, + width: 150, + value: Ext.data.StoreManager.lookup('granulesStore').pageSize, + minValue: 1, + maxValue: 2000, + listeners: { + change: function(newValue, oldValue) { + Ext.data.StoreManager.lookup('granulesStore').pageSize = newValue; + } + } + }] + }], renderTo: Ext.getBody() }); diff --git a/php/epntap.php b/php/epntap.php index 4cf1c3f..82b2fb0 100644 --- a/php/epntap.php +++ b/php/epntap.php @@ -80,6 +80,8 @@ function getNbResults() { return 'Too few returned raws.'; } else if(count($result) > 1) { return 'Too many returned raws.'; + } else if(!array_key_exists(0, $result)) { + return 'cant find raw item 0'; } else if(is_null($result[0])) { return 'The returned raw is null.'; } else if(!array_key_exists("nb_rows", $result[0])) { @@ -92,21 +94,24 @@ function getNbResults() { } function getGranules() { + error_log(json_encode($_GET)); $url = filter_var($_GET['url'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); $tableName = filter_var($_GET['tableName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); $targetName = filter_var($_GET['targetName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); $productTypes = filter_var($_GET['productTypes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); $timeMin = filter_var($_GET['timeMin'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); $timeMax = filter_var($_GET['timeMax'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); - $top = filter_var($_GET['top'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); - $offset = filter_var($_GET['offset'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + $start = filter_var($_GET['start'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + $limit = filter_var($_GET['limit'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + $nbRes = filter_var($_GET['nbRes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); // TODO find a way to handle 'non existing key errors' (and then add access_format) $columns = "dataproduct_type, target_name, time_min, time_max, granule_uid, access_estsize, access_url, thumbnail_url"; $filter = createFilter($targetName, $productTypes, $timeMin, $timeMax); - $query = "SELECT TOP $top $columns FROM $tableName $filter OFFSET $offset"; - $result = request($url, $query); - return $result; + $query = "SELECT TOP $limit $columns FROM $tableName $filter OFFSET $start"; + $rows = request($url, $query); + return ['success' => true, 'total' => $nbRes, 'rows' => $rows]; + // return $rows; } // ----- utils ----- -- libgit2 0.21.2