/** * 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', 'amdaUI.DescriptionField', 'amdaModel.Download', 'amdaModel.DownloadParam', 'amdaModel.RequestParamObject' ], 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; }, saveRequest: function () { var me = this; if (!this.updateObject()) { return; } var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); if (!downloadModule) { return; } if ((this.object.get('id') != '') && (downloadModule.linkedNode.get('text') == this.object.get('name'))) { this.saveProcess(false); return; } downloadModule.linkedNode.isValidName(this.fieldName.getValue(), function (res) { if (!res) { me.fieldName.validFlag = 'Error during object validation'; myDesktopApp.errorMsg(me.fieldName.validFlag); me.fieldName.validate(); return; } if (!res.valid) { if (res.error) { if (res.error.search('subtree') != -1) { Ext.MessageBox.show({ title: 'Warning', msg: res.error + '
Do you want to overwrite it?', width: 300, buttons: Ext.MessageBox.OKCANCEL, fn: function (btn) { if (btn == 'cancel') return; this.fieldName.clearInvalid(); this.saveProcess(true); }, icon: Ext.MessageBox.WARNING, scope: me }); me.fieldName.validFlag = true; } else me.fieldName.validFlag = res.error; } else { me.fieldName.validFlag = 'Invalid object name'; myDesktopApp.errorMsg(me.fieldName.validFlag); } me.fieldName.validate(); return; } me.fieldName.validFlag = true; me.fieldName.validate(); me.saveProcess(false); }); }, saveProcess: function (toRename) { var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); if (this.object.isModified('name')) { if (this.object.get('id')) { var contextNode = downloadModule.linkedNode.parentNode; downloadModule.createLinkedNode(); downloadModule.linkedNode.set('contextNode', contextNode); downloadModule.createObject(this.object.getJsonValues()); var downloadObj = downloadModule.linkedNode.get('object'); this.object = downloadObj; if (toRename) downloadModule.linkedNode.toRename = true; } downloadModule.linkedNode.create(); } else { downloadModule.linkedNode.set('contextNode', downloadModule.contextNode); downloadModule.linkedNode.update(); } }, 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(); }, addParameter: function (paramNode, updateTime) { if (this.doNotifyDrop(paramNode)) { return this.doParamDrop(paramNode); } return false; }, addParam: function (paramId, isLeaf, needArgs, components, predefined_args, info) { // 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; } if(info){ paramObj.qtip= info; } 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); }, // 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 filestructure = 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.name != 'name') && !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 && (this.object.params().count() == 0)) { myDesktopApp.warningMsg('You must define at least one parameter to download'); 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); this.object.set('filestructure', filestructure); 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 ? values.timeformatTT : amdaModel.DownloadConfig.defaultValues.timeformatTT; var compression = values.compressionTT; var fileformat = values.fileformatTT; if (this.TTGrid.getStore().count() == 0) { myDesktopApp.warningMsg('You must define at least one TimeTable or Catalog to download'); updateStatus = false; } else 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 () { // 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.paramGrid.reconfigure(this.object.params()); //this.paramGrid.getStore().loadData(this.object.params().data.items); // select "Parameters" tab var tabPanel = this.formPanel.down(); tabPanel.setActiveTab(0); }, /** * 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': (sendToSamp == true), 'clientId': 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()); } }, onTTFileFormatChange: function (combo, newValue, oldValue) { if (!this.formPanel) return; var refTimeFormatField = this.formPanel.getForm().findField('timeformatTT'); if (refTimeFormatField && newValue !== oldValue) { if (newValue === 'space') { refTimeFormatField.setValue('YYYY-MM-DDThh:mm:ss'); refTimeFormatField.setDisabled(true); } else { refTimeFormatField.setDisabled(false); } } }, 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); } }, doNotifyDrop: function (record) { if (record.get('nodeType') == 'localParam' && record.get('notyet')) { return false; } if (((record.get('nodeType') == 'localParam') || (record.get('nodeType') == 'remoteParam') || (record.get('nodeType') == 'remoteSimuParam') || (record.get('nodeType') == 'derivedParam') || (record.get('nodeType') == 'specialParam') || (record.get('nodeType') == 'myDataParam') || (record.get('nodeType') == 'alias')) && (record.isLeaf() || record.get('isParameter')) && !record.get('disable')) { return true; } return false; }, doParamDrop: function (record) { var idToSent; var components = null; var predefinedArgs = record.get('predefinedArgs'); var info = record.get('info'); switch (record.get('nodeType')) { case 'localParam': case 'remoteParam': case 'remoteSimuParam': idToSent = record.get('id'); if (record.get('alias') != "") idToSent = "#" + record.get('alias'); var component_info = record.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 = record.parentNode.get('predefinedArgs'); } if (record.get('needsArgs')) { idToSent = component_info.parentId; if (component_info.index1) { components = []; components['index1'] = component_info.index1; } } } break; case 'alias': idToSent = "#" + record.get('text'); break; case 'derivedParam': if (record.modelName == 'amdaModel.DerivedParamComponentNode') { paramId = record.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]; } } else { idToSent = "ws_" + record.get('text'); } break; case 'myDataParam': if (record.modelName == 'amdaModel.MyDataParamComponentNode') { paramId = record.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]; } } else { idToSent = "wsd_" + record.get('text'); } break; case 'specialParam': idToSent=record.get('id'); 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, record.get('leaf'), record.get('needsArgs'), components, param_info.template_args, info); }); } else { downModule.addParam(idToSent, record.get('leaf'), record.get('needsArgs'), components, null,info); return true; } } return true; }, /** * Check if changes were made before closing window * @return false */ fclose: function () { return this.object.isDirty(); }, init: function (config) { var me = this; this.timeSelector = new amdaUI.TimeSelectorUI({ id: 'downloadTimeSelector', flex: 1 }); this.fieldName = new Ext.form.field.Text({ labelAlign: 'left', labelWidth: 90, fieldLabel: 'Request Name', name: 'name', allowBlank: false, stripCharsRe: /(^\s+|\s+$)/g, validateOnChange: false, validateOnBlur: false, validFlag: false, validator: function () { return this.validFlag; } }); var downloadCont = this; 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) { meta.tdAttr = 'data-qtip="' + rec.data.qtip + '"'; 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; me.dropTarget = Ext.create('Ext.dd.DropTarget', el, { ddGroup: 'explorerTree', notifyEnter: function (ddSource, e, data) { }, notifyOver: function (ddSource, e, data) { if (!downloadCont.doNotifyDrop(data.records[0])) { this.valid = false; return this.dropNotAllowed; } this.valid = true; return this.dropAllowed; }, notifyDrop: function (ddSource, e, data) { if (!this.valid) return false; return downloadCont.doParamDrop(data.records[0]); } }); } } }); 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 storeTimeFormat = new Ext.data.ArrayStore({ fields: ['id', 'name', 'qtip'], data: amdaModel.DownloadConfig.timeformatData }); var descriptionCase = { xtype:'panel', resizable:true, height: 120, margin:'5 0 5 0', bodyStyle: {background: '#dfe8f6',padding: '1', }, border:false, layout:'fit', items:[{ xtype: 'descriptionfield', height:120, name: 'description', emptyText:'Description', fieldLabel: '' }] }; this.paramPanel = new Ext.container.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: [ this.fieldName, { xtype: 'splitter', flex: 0.05 }, this.paramGrid, descriptionCase, ] }, { 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: storeTimeFormat, listConfig: { tpl: [ '', '
  • {name}
  • ', '
    ' ] } }, { fieldLabel: 'File Structure', name: 'filestructure', store: amdaModel.DownloadConfig.filestructureData, listeners: { change: { fn: this.onFileStructureChange }, scope: this } }, { xtype: 'checkbox', boxLabel: 'Header in a separate file', boxLabelAlign: 'before', name: 'separateInfoFile', checked: false }, { xtype: 'checkbox', boxLabel: 'Sampling: use first parameter as reference', boxLabelAlign: 'before', name: 'refparamSampling', checked: false, disabled: true, listeners: { change: { fn: this.onRefParamSamplingChange }, scope: this } }, { xtype: 'numberfield', name: 'sampling', fieldLabel: 'Sampling (s.)', 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: amdaModel.DownloadConfig.fileformatData }, { fieldLabel: 'Compression', name: 'compression', store: amdaModel.DownloadConfig.filecompressData }, 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', valueField: 'id', store: storeTimeFormat, displayField: 'name', queryMode: 'local', listConfig: { tpl: [ '', '
  • {name}
  • ', '
    ' ] } }, { fieldLabel: 'File Format ', name: 'fileformatTT', store: amdaModel.DownloadConfig.fileformatTTData, listeners: { change: { fn: this.onTTFileFormatChange }, scope: this } }, { fieldLabel: 'Compression ', name: 'compressionTT', store: amdaModel.DownloadConfig.filecompressTTData }, { xtype: 'panel', html: ['
    ', '

    => Format specifications:

    ', '', '
    '].join("\n") } ] } ] }; 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 ], listeners: { tabchange: function (tabPanel, newCard, oldCard, eOpts) { var saveBtn = this.down('#save-download'); saveBtn.setDisabled(newCard != this.paramPanel); }, scope: this } }, ], 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 () { var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id); downModule.createLinkedNode(); var obj = null; downModule.createObject(obj); this.setObject(downModule.linkedNode.get('object')); } }, { text: 'Save', id: 'save-download', scope: this, handler: function () { this.saveRequest(); } }, '->', { 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)); } });