/** * Project  : AMDA-NG * Name : DownloadUI.js * @class amdaUI.DownloadUI * @extends Ext.container.Container * @brief Download Module UI definition (View) * @author Myriam * @version $Id: DownloadUI.js 2622 2014-11-07 14:50:09Z elena $ */ Ext.define('amdaUI.DownloadUI', { extend: 'Ext.container.Container', alias: 'widget.panelDownload', requires: [ 'amdaUI.TimeSelectorUI', 'amdaUI.ParamArgumentsPlug', 'amdaUI.SendToSampButtonUI', 'amdaModel.DownloadParam' ], //Old kernel time formats //timeformatData : [['Y-m-dTH:i:s', 'YYYY-MM-DDThh:mm:ss'], ['Y m d H i s', 'YYYY MM DD hh mm ss'], ['d m Y H i s', 'DD MM YYYY hh mm ss'], ['Y z H i s', 'YYYY DDD hh mm ss']], //New kernel time formats timeformatData: [['YYYY-MM-DDThh:mm:ss', 'YYYY-MM-DDThh:mm:ss.ms', 'ISO format with msecs'], ['DD Time', 'YYYYDOYhhmmssms', 'Day-Of-Year, 1 Jan : DOY = 0'], ['Timestamp', 'Seconds from 1970', 'Total of seconds from the Unix Epoch on January 1st, 1970 at UTC.'], ['YYYY MM DD hh mm ss', 'YYYY MM DD hh mm ss ms', 'date with spaces'], ['Timestamp-with-milliseconds', 'Seconds from 1970 with ms', 'Total of seconds from the Unix Epoch with milliseconds.']], timeformatTTData: [['Y-m-dTH:i:s', 'YYYY-MM-DDThh:mm:ss']], fileformatData: [['ASCII', 'ASCII'], ['vot', 'VOTable'], ['cdf', 'CDF'], ['json', 'JSON']], fileformatTTData: [['text', 'plain text'], ['vot', 'VOTable']], filecompressData: [['zip', 'zip'], ['tar+gzip', 'tar+gzip']], filecompressTT: [['zip', 'zip'], ['tar+gzip', 'tar+gzip'], ['none', 'none']], filestructureData: [['0', 'All In One File'], ['1', 'One File Per Time Interval'], ['2', 'One File Per Param/Interval']], constructor: function (config) { this.init(config); this.callParent(arguments); // load object into view if (this.object) this.loadObject(); // var paramArgsPlug = this.getPlugin('download-param-arguments-plugin'); if (paramArgsPlug) paramArgsPlug.onApply = this.onApplyParameterArgs; }, addTT: function (newTTName, newTTid) { var tabPanel = this.formPanel.down(); var downloadSrc = tabPanel.items.indexOf(tabPanel.getActiveTab()); if (downloadSrc === 0) { this.timeSelector.addTT(newTTName, newTTid); } else { // search for an existing record in store with this unique name var existingIndex = this.TTGrid.store.findExact('name', newTTName); // if no corresponding TT found if (existingIndex == -1) { // adding the time table to the TTGrid of TT download var r = Ext.create('amdaModel.TTobject', {id: newTTid, name: newTTName}); this.TTGrid.store.insert(this.TTGrid.store.getCount(), r); } } }, addTTs: function (TTarray) { // set TTTab this.timeSelector.setTTTab(TTarray); }, // Add TT in download TT module addTTdownload: function (newTTName, newTTid) { var tabPanel = this.formPanel.down(); tabPanel.setActiveTab(1); this.addTT(newTTName, newTTid); }, /** * Set Start-Stop from parameter info (Local & MyData) */ setTimeFromData: function (obj) { if (!obj.start || !obj.stop) return; var dateStart = new Date(obj.start.replace(/[T|Z]/g, ' ').replace(/\-/g, '\/')); var dateStop = new Date(obj.stop.replace(/[T|Z]/g, ' ').replace(/\-/g, '\/')); this.down('form').getForm().setValues({startDate: dateStart, stopDate: dateStop}); this.timeSelector.intervalSel.updateDuration(); }, addParam: function (paramId, isLeaf, needArgs, components, predefined_args) { // adding the parameter to the paramGrid var paramObj = amdaModel.RequestParamObject.getEmptyObj(); paramObj.paramid = paramId; if (components) { if (components['index1']) { paramObj['dim1-index'] = components['index1']; ++paramObj['type']; } if (components['index2']) { paramObj['dim2-index'] = components['index2']; ++paramObj['type']; } } if (predefined_args) { paramObj.template_args = predefined_args; } var r = Ext.create('amdaModel.DownloadParam', paramObj); var pos = this.paramGrid.store.getCount(); this.paramGrid.store.insert(pos, r); this.paramGrid.getView().refresh(); if (needArgs) this.editParameterArgs(r); }, addParams: function (arrayParams) { var arrayRec = new Array(); var index = 1; if (arrayParams) { Ext.Array.each(arrayParams, function (item) { if (Ext.isObject(item)) { // handel case of derived parameters var patt_ws = new RegExp("ws_"); var patt_wsd = new RegExp("wsd_"); if (typeof paramId !== 'undefined' && ! patt_ws.test(item.paramid) && ! patt_wsd.test(item.paramid)) { // for Parameter Name in Download Module var paramObj = amdaModel.RequestParamObject.getEmptyObj(); paramObj.paramid = paramId; paramObj['dim1-index'] = item.get('dim1'); paramObj['dim2-index'] = item.get('dim2'); var r = Ext.create('amdaModel.DownloadParam', paramObj); } else { //for download from get Data in Plot module var r = Ext.create('amdaModel.DownloadParam', item); } } else { // for Download By Request in Operations menu //TODO BRE - Components selection var r = Ext.create('amdaModel.DownloadParam', {paramid: item}); } arrayRec.push(r); }); } this.paramGrid.getStore().loadData(arrayRec); }, // parameter name -> alias updateConstruct: function (oldval, newval) { var index = this.paramGrid.store.findExact('name', oldval); if (index != -1) { this.paramGrid.getStore().getAt(index).set('name', newval); this.paramGrid.getStore().getAt(index).set('text', newval); } }, setObject: function (obj) { this.object = obj; this.loadObject(); }, /** * update this.object from form */ updateObject: function () { // get the basic form var tabPanel = this.formPanel.down(); var downloadSrc = tabPanel.items.indexOf(tabPanel.getActiveTab()); var basicForm = this.formPanel.getForm(); var updateStatus = true; var values = basicForm.getValues(); // data download if (downloadSrc === 0) { var timeformat = values.timeformat; var timeSource = this.timeSelector.getActiveTimeSource(); var structure = values.filestructure; var sampling = values.sampling ? values.sampling : 600; var refparamSampling = values.refparamsampling == 'on'; var fileprefix = values.fileprefix ? values.fileprefix : ''; var fileformat = values.fileformat; var compression = values.compression; var fieldsWithoutName = basicForm.getFields().items; Ext.Array.each(fieldsWithoutName, function (item, index, allItems) { if (!item.isValid()) { if ((timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) && ((item.name == 'startDate') || (item.name == 'stopDate') || (item.name == 'duration'))) { updateStatus = true; } else { // set update isn't allowed updateStatus = false; return false; } } }, this); if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0] // timeSource 'TimeTable' && this.timeSelector.TTGrid.getStore().count() == 0) { myDesktopApp.warningMsg('You\'ve chosen Time Selection `by TimeTable` but no timeTable was added!' + '
You must add one or choose Time Selection `by Interval`'); updateStatus = false; } if (updateStatus) { /// real object update // update TimeTable object with the content of form basicForm.updateRecord(this.object); this.object.set('timesrc', timeSource); // set valid intervals into TimeTable object if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) this.object.set('timeTables', this.timeSelector.TTGrid.getStore().data.items); // set parameters this.object.set('list', this.paramGrid.getStore().data.items); this.object.set('structure', structure); this.object.set('refparamSampling', refparamSampling); this.object.set('sampling', sampling); this.object.set('fileprefix', fileprefix); this.object.set('timeformat', timeformat); this.object.set('fileformat', fileformat); this.object.set('compression', compression); } } //TT download else { var timeformat = values.timeformatTT; var compression = values.compressionTT; var fileformat = values.fileformatTT; if (compression === 'none' && this.TTGrid.getStore().count() > 1) { myDesktopApp.warningMsg('You are going to download several time tables - select the Compression please'); updateStatus = false; } this.object.set('timeTables', this.TTGrid.getStore().data.items); this.object.set('timeformatTT', timeformat); this.object.set('fileformatTT', fileformat); this.object.set('compressionTT', compression); } this.object.set('downloadSrc', downloadSrc); // return the update status return updateStatus; }, /** * load this.object into form */ loadObject: function () { if (!this.object.get('timeformat')) this.object.set('timeformat', this.timeformatData[0][0]); if (!this.object.get('timeformatTT')) this.object.set('timeformatTT', this.timeformatTTData[0][0]); if (!this.object.get('fileformat')) this.object.set('fileformat', this.fileformatData[0][0]); if (!this.object.get('fileformatTT')) this.object.set('fileformatTT', this.fileformatTTData[0][0]); if (!this.object.get('compression')) this.object.set('compression', this.filecompressData[1][0]); if (!this.object.get('compressionTT')) this.object.set('compressionTT', this.filecompressData[1][0]); // load object into form this.formPanel.getForm().loadRecord(this.object); // set object's TTs into the timeselector this.addTTs(this.object.get('timeTables')); // set parameters this.addParams(this.object.get('list')); }, /** * download method called by 'Download' button to launch the download process */ doDownload: function (sendToSamp, clientId) { var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); if (downloadModule) downloadModule.linkedNode.execute(sendToSamp, clientId); }, actionItem: function (grid, cell, cellIndex, record, row, recordIndex, e) { var isTimeTable = record instanceof amdaModel.TTobject; if (cellIndex == 3 || (cellIndex == 2 && isTimeTable)) grid.getStore().remove(record); else if (cellIndex == 2) { this.paramGrid.getView().select(row); this.editParameterArgs(record); } }, editParameterArgs: function (record) { var paramArgsPlug = this.getPlugin('download-param-arguments-plugin'); if (paramArgsPlug) paramArgsPlug.show('download-param-arguments-plugin', record); }, onApplyParameterArgs: function (parentUI, paramObject) { parentUI.paramGrid.getView().refresh(); }, onFileStructureChange: function (combo, newValue, oldValue) { if (!this.formPanel) return; var refParamCheck = this.formPanel.getForm().findField('refparamsampling'); var samplingField = this.formPanel.getForm().findField('sampling'); if (samplingField && newValue !== oldValue) { refParamCheck.setDisabled(newValue == 2); samplingField.setDisabled((newValue == 2) || refParamCheck.getValue()); } }, onRefParamSamplingChange: function (check, newValue, oldValue) { if (!this.formPanel) return; var samplingField = this.formPanel.getForm().findField('sampling'); var structureCombo = this.formPanel.getForm().findField('filestructure'); if (samplingField && newValue !== oldValue) samplingField.setDisabled((structureCombo.getValue() == 2) || check.getValue()); }, onSendVOTableToSamp: function (clientId, sendOpt) { var me = sendOpt.scope; if (me.updateObject()) { me.doDownload(true, clientId); } }, /** * Check if changes were made before closing window * @return false */ fclose: function () { return false; }, init: function (config) { var me = this; this.timeSelector = new amdaUI.TimeSelectorUI({id: 'downloadTimeSelector', flex: 1}); this.paramGrid = Ext.create('Ext.grid.Panel', { flex: 2, store: Ext.create('Ext.data.Store', {model: 'amdaModel.DownloadParam'}), columns: [ {xtype: 'rownumberer', width: 20}, { header: "Parameter Name", dataIndex: 'name', flex: 1, sortable: false, menuDisabled: true, renderer: function (val, meta, rec) { return rec.getParamFullName(); } }, { menuDisabled: true, width: 30, renderer: function () { return'
'; } }, { menuDisabled: true, width: 30, renderer: function () { return'
'; } } ], //TODO - BRE - Wait the fix for drag&drop issue listeners: { render: function (o, op) { var me = this; var el = me.body.dom; var dropTarget = Ext.create('Ext.dd.DropTarget', el, { ddGroup: 'explorerTree', notifyEnter: function (ddSource, e, data) { }, notifyOver: function (ddSource, e, data) { if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet')) { this.valid = false; return this.dropNotAllowed; } if (((data.records[0].data.nodeType == 'localParam') || (data.records[0].data.nodeType == 'remoteParam') || (data.records[0].data.nodeType == 'remoteSimuParam') || (data.records[0].data.nodeType == 'derivedParam') || (data.records[0].data.nodeType == 'myDataParam') || (data.records[0].data.nodeType == 'alias')) && (data.records[0].isLeaf() || data.records[0].data.isParameter) && !data.records[0].data.disable) { this.valid = true; return this.dropAllowed; } this.valid = false; return this.dropNotAllowed; }, notifyDrop: function (ddSource, e, data) { if (!this.valid) return false; var idToSent; var components = null; var predefinedArgs = data.records[0].get('predefinedArgs'); switch (data.records[0].data.nodeType) { case 'localParam' : case 'remoteParam': case 'remoteSimuParam': idToSent = data.records[0].get('id'); if (data.records[0].get('alias') != "") idToSent = "#" + data.records[0].get('alias'); var component_info = data.records[0].get('component_info'); if (component_info && component_info.parentId) { if (component_info.index1 || component_info.index2) { idToSent = component_info.parentId; components = []; if (component_info.index1) components['index1'] = component_info.index1; if (component_info.index2) components['index2'] = component_info.index2; predefinedArgs = data.records[0].parentNode.get('predefinedArgs'); } if (data.records[0].get('needsArgs')) { idToSent = component_info.parentId; if (component_info.index1) { components = []; components['index1'] = component_info.index1; } } } break; case 'alias' : idToSent = "#" + data.records[0].get('text'); break; case 'derivedParam' : if (data.records[0].modelName == 'amdaModel.DerivedParamComponentNode') { paramId = data.records[0].get('text'); var parentId = paramId.substr(0, paramId.length - 3); idToSent = "ws_" + parentId; var regExp = /\(([\d]+)\)/; var component_index = regExp.exec(paramId); if (component_index) { components = []; components['index1'] = component_index[1]; } break; } else { idToSent = "ws_" + data.records[0].get('text'); } break; case 'myDataParam' : if (data.records[0].modelName == 'amdaModel.MyDataParamComponentNode') { paramId = data.records[0].get('text'); var parentId = paramId.substr(0, paramId.length - 3); idToSent = "wsd_" + parentId; var regExp = /\(([\d]+)\)/; var component_index = regExp.exec(paramId); if (component_index) { components = []; components['index1'] = component_index[1]; } break; } else{ idToSent = "wsd_" + data.records[0].get('text'); } break; default : return false; } var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); if (downModule) { if (predefinedArgs) { downModule.parseTemplatedParam(idToSent, function(param_info) { downModule.addParam(param_info.paramid, data.records[0].get('leaf'), data.records[0].get('needsArgs'), components, param_info.template_args); }); } else { downModule.addParam(idToSent, data.records[0].get('leaf'), data.records[0].get('needsArgs'), components); return true; } } return true; } }); } } }); this.paramGrid.on('cellclick', this.actionItem, this); this.TTGrid = Ext.create('Ext.grid.Panel', { flex: 2, store: Ext.create('Ext.data.Store', {model: 'amdaModel.TTobject'}), columns: [ {xtype: 'rownumberer', width: 20}, {header: "TimeTable/Catalog Name", dataIndex: 'name', flex: 1, sortable: false, menuDisabled: true}, { menuDisabled: true, width: 30, renderer: function () { return '
'; } } ], listeners: { render: function (o, op) { var me = this; var el = me.body.dom; var dropTarget = Ext.create('Ext.dd.DropTarget', el, { ddGroup: 'explorerTree', notifyEnter: function (ddSource, e, data) { }, notifyOver: function (ddSource, e, data) { var nodeType = data.records[0].get('nodeType'); if ((nodeType == 'timeTable' || nodeType == 'sharedtimeTable') || (nodeType == 'catalog' || nodeType == 'sharedcatalog') && (data.records[0].get('leaf'))) { this.valid = true; return this.dropAllowed; } this.valid = false; return this.dropNotAllowed; }, notifyDrop: function (ddSource, e, data) { if (!this.valid) return false; var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); if (downModule) downModule.getUiContent().addTTdownload(data.records[0].get('text'), data.records[0].get('id')); return true; } }); } } }); this.TTGrid.on('cellclick', this.actionItem, this); var store = new Ext.data.ArrayStore({ fields: ['id', 'name', 'qtip'], data: this.timeformatData }); this.paramPanel = { xtype: 'container', title: 'Parameters', layout: { type: 'hbox', align: 'stretch', defaultMargins: {top: 10, left: 10, bottom: 5, right: 10} }, items: [ { xtype: 'container', flex: 2, layout: { type: 'vbox', align: 'stretch' }, items: [ { xtype: 'textfield', fieldLabel: 'Request Name', disabled: true, name: 'name' }, { xtype: 'splitter', flex: 0.05 }, this.paramGrid ] }, { xtype: 'container', flex: 2, defaults: { xtype: 'combo', labelWidth: 90, queryMode: 'local', editable: false }, layout: { type: 'vbox', align: 'stretch' }, items: [ { fieldLabel: 'Time Format', name: 'timeformat', valueField: 'id', displayField: 'name', queryMode: 'local', store: store, listConfig: { tpl: [ '', '
  • {name}
  • ', '
    ' ] }, value: store.first() }, { fieldLabel: 'File Structure', name: 'filestructure', store: this.filestructureData, value: this.filestructureData[2], listeners: { change: {fn: this.onFileStructureChange}, scope: this } }, { xtype: 'checkbox', boxLabel: 'Header in a separate file', boxLabelAlign: 'before', name: 'separateInfoFile', checked: false }, { xtype: 'checkbox', boxLabel: 'Use first param. as reference for sampling', boxLabelAlign: 'before', name: 'refparamsampling', checked: false, disabled: true, listeners: { change: {fn: this.onRefParamSamplingChange}, scope: this } }, { xtype: 'numberfield', name: 'sampling', fieldLabel: 'Sampling Time', value: 600, hideTrigger: true, editable: true, disabled: true }, { xtype: 'checkbox', boxLabel: 'Scientific floating-point formatting', boxLabelAlign: 'before', name: 'scientificformat', checked: false }, { xtype: 'textfield', name: 'fileprefix', fieldLabel: 'File Prefix', disabled: false, editable: true }, { fieldLabel: 'File Format', name: 'fileformat', store: this.fileformatData, value: this.fileformatData[0] }, { fieldLabel: 'Compression', name: 'compression', store: this.filecompressData, value: this.filecompressData[0] }, this.timeSelector ] } ]}; this.ttPanel = { xtype: 'container', title: 'Time Tables / Catalogs', layout: { type: 'hbox', align: 'stretch', defaultMargins: {top: 10, left: 10, bottom: 5, right: 10} }, items: [ this.TTGrid, { xtype: 'container', flex: 2, defaults: { xtype: 'combo', labelWidth: 90, queryMode: 'local', editable: false }, layout: { type: 'vbox', align: 'stretch' }, items: [{ fieldLabel: 'Time Format', name: 'timeformatTT', store: this.timeformatTTData, value: this.timeformatTTData[0] }, { fieldLabel: 'File Format ', name: 'fileformatTT', store: this.fileformatTTData, value: this.fileformatTTData[0] }, { fieldLabel: 'Compression ', name: 'compressionTT', store: this.filecompressTT, value: this.filecompressTT[0] } ]} ] }; this.formPanel = new Ext.form.Panel({ layout: 'fit', region: 'center', bodyStyle: {background: '#dfe8f6'}, buttonAlign: 'left', trackResetOnLoad: true, //reset to the last loaded record defaults: { border: false }, items: [{ xtype: 'tabpanel', activeTab: 0, bodyStyle: {background: '#dfe8f6'}, items: [ this.paramPanel, this.ttPanel ] }], fbar: [ { text: 'Download', scope: this, handler: function (button) { // if the return is true (object had been updated) if (this.updateObject()) { // launch the download process this.doDownload(); } } }, { text: 'Reset', scope: this, handler: function () { this.formPanel.getForm().reset(); var tabPanel = this.formPanel.down(); var downloadSrc = tabPanel.items.indexOf(tabPanel.getActiveTab()); if (downloadSrc === 0) { // reset parameters and Time Tables in Get Data this.paramGrid.store.removeAll(); this.timeSelector.TTGrid.store.removeAll(); } else { // reset Time Tables in Get time Table this.TTGrid.store.removeAll(); } } }, '->', { xtype: 'sendToSampButton', type: 'votable', onSendToSamp: this.onSendVOTableToSamp, sendOpt: {scope: this} }] }); var myConf = { layout: 'border', items: [ this.formPanel, { xtype: 'panel', region: 'south', title: 'Information', collapsible: true, collapseMode: 'header', height: 100, autoHide: false, bodyStyle: 'padding:5px', iconCls: 'icon-information', loader: { autoLoad: true, url: helpDir + 'downloadHOWTO' } } ], plugins: [{ptype: 'paramArgumentsPlugin', pluginId: 'download-param-arguments-plugin'}] }; Ext.apply(this, Ext.apply(arguments, myConf)); } });