/** * Project AMDA-NG * Name CatalogUI.js * @class amdaUI.catalogUI * @extends Ext.container.Container * @brief Catalog Module UI definition (View) * @author elena */ Ext.define('amdaUI.CatalogUI', { extend: 'Ext.container.Container', alias: 'widget.panelCatalog', requires: [ 'Ext.ux.grid.menu.RangeMenu', 'Ext.ux.grid.FiltersFeature', 'Ext.ux.grid.filter.DateFilter', 'Ext.ux.grid.filter.NumericFilter', 'Ext.ux.grid.filter.StringFilter', 'amdaUI.OperationsTT', 'amdaUI.DescriptionField', 'Ext.grid.plugin.BufferedRenderer', 'amdaUI.StatusGrid', 'amdaUI.StatisticalPlug', 'amdaDesktop.AmdaStateProvider', 'Ext.grid.plugin.CellEditing' ], isCatalog: true, activeField : null, statusGrid:null, statics: { COL_TO_HIDE_DURATION: 'colToHideDuration' }, constructor: function (config) { this.init(config); this.callParent(arguments); this.toReconfigure = true; if (this.object) { this.loadObject(); } }, setObject: function (object, toReconfigure) { if (toReconfigure) this.toReconfigure = true; // set object this.object = object; // load object into view this.loadObject(); // show the default duration column this.TTGrid.headerCt.getGridColumns(); Ext.Array.each(this.TTGrid.headerCt.getGridColumns(), function (item, index, all) { // if item is the default duration column if (item.id == amdaUI.CatalogUI.COL_TO_HIDE_DURATION + Ext.state.Manager.getProvider().get('cat_duration').toString()) { // show this column item.show(); } }); // fire the refresh event (to statistical plugin) this.fireEvent("refresh"); // global event myDesktopApp.EventManager.fireEvent("refresh"); }, /** * set params description into this.object */ setParamInfo: function (parameters) { var params = []; Ext.Array.each(parameters, function (item, index) { params[index] = item; }, this); this.object.set('parameters', params); this.object.set('nbParameters', params.length); }, /** * update this.object from form */ updateObject: function () { // get the basic form var basicForm = this.formPanel.getForm(); var updateStatus = true; var fieldsWithoutName = basicForm.getFields().items; Ext.Array.each(fieldsWithoutName, function (item, index, allItems) { if (item !== this.fieldName) { if (!item.isValid()) { // set update isn't allowed updateStatus = false; } } }, this); // if the update is allowed if (updateStatus) { /// real object update // update TimeTable object with the content of form basicForm.updateRecord(this.object); } // return the update status return updateStatus; }, addInterval: function (start, stop) { var row = this.TTGrid.getStore().getTotalCount(); var me = this; this.TTGrid.getSelectionModel().deselectAll(); AmdaAction.addCacheInterval({'start': start, 'stop': stop, 'index': row, 'isCatalog': true}, function (result, e) { this.status = result.status; if (!this.TTGrid.getStore().loading) { this.TTGrid.getStore().reload({ callback: function (records, options, success) { me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function () { me.TTGrid.getView().select(row); }, me); } }); } }, this); }, updateCount: function () { this.object.set('nbIntervals', this.TTGrid.getStore().getTotalCount()); this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals')); }, generateTT: function () { if (this.fclose()) { Ext.Msg.confirm('Generate TT', 'Current Catalog has been modified.\nDo you want to save it to include these changes in the generated Time Table ?', function (btn, text) { if (btn == 'yes') { var me = this; // mark this.closed as true before the call to close() as that will fire the beforeclose event again if (this.object.get('id') == "") { // case of creation of catalog this.saveCatalog(function () { me.createTT(me.object.get('id')); }, true); } else { // casse existing catalog this.saveProcess(false, function () { me.createTT(me.object.get('id')); }, true); } return; } }, this); } else { this.createTT(this.object.get('id')); return; } }, updateSurveyDates : function(res){ if (this.TTGrid.getStore().getTotalCount() <= 0) return; if(! this.object.get('surveyStart') ){ this.object.set('surveyStart', res['minStart']); this.status.isModified = true; } if(! this.object.get('surveyStop') ){ this.object.set('surveyStop', res['maxStop']); this.status.isModified = true; } }, createTT: function (catId) { var ttObj = Ext.create('amdaModel.TimeTable'); var timeTabNode = Ext.create('amdaModel.TimeTableNode', {leaf: true}); ttObj.set('relatedCatalogId', catId) creatDate = new Date(this.object.get('created')); date = Ext.Date.format(creatDate, 'Y-m-d\\TH:i:s.u'); descr = 'Generated by CDPP/Amda Catalog Module \n' + 'From Catalog: ' + this.object.get('name') + '\nOn: ' + date + '\n'; ttObj.set('description', descr + this.object.get('description')); ttObj.set('contact', this.object.get('contact')); timeTabNode.set('object', ttObj); var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); var ttRootNode = explorerTree.getRootNode().findChild('id', 'timeTable-treeRootNode', true); amdaModel.InteractiveNode.preloadNodes(ttRootNode.getRootNode(), function () { // edit newNode into Parameter Module with node as contextNode timeTabNode.editInModule(); }); }, // Convert UTC date to client local date convertUTCDateToLocalDate: function (date) { if (date == null) { return date; } ; var newDate = new Date(date.getTime() + date.getTimezoneOffset() * 60 * 1000); var offset = date.getTimezoneOffset() / 60; var hours = date.getHours(); newDate.setHours(hours - offset); return newDate; }, onAfterInit: function (result, e) { var me = this; if (!result) { myDesktopApp.errorMsg(e.message); Ext.defer(function () { Ext.Msg.toFront() }, 10); return; } else if (!result.success) { if (result.message) myDesktopApp.errorMsg(result.message); else myDesktopApp.errorMsg('Unknown error during catalog cache initialisation'); Ext.defer(function () { Ext.Msg.toFront() }, 10); return; } if (me.toReconfigure) { // clear filters if (me.TTGrid.filters) { me.TTGrid.getStore().clearFilter(true); me.TTGrid.filters.clearFilters(); me.TTGrid.filters.destroy(); } var fieldsConfig = [ { name: 'start', type: 'date', dateFormat: 'Y-m-d\\TH:i:s.u', convert: function (value, rec) { if (!Ext.isDate(value)) { return new Date(value); } return value; } }, { name: 'stop', type: 'date', dateFormat: 'Y-m-d\\TH:i:s.u', convert: function (value, rec) { if (!Ext.isDate(value)) { return new Date(value); } return value; } }, { name: 'durationDay', type: 'float', convert: function (value, rec) { if (rec.get('stop') && rec.get('start') && (rec.get('stop') - rec.get('start')) >= 0) { return (rec.get('stop') - rec.get('start')) / 3600000.0/24.0; } }, persist: false }, { name: 'durationHour', type: 'float', convert: function (value, rec) { if (rec.get('stop') && rec.get('start') && (rec.get('stop') - rec.get('start')) >= 0) { return (rec.get('stop') - rec.get('start')) / 3600000.0; } }, persist: false }, { name: 'durationMin', type: 'float', convert: function (value, rec) { if (rec.get('stop') && rec.get('start') && (rec.get('stop') - rec.get('start')) >= 0) { return (rec.get('stop') - rec.get('start')) / 60000.0; } }, persist: false }, { name: 'durationSec', type: 'float', convert: function (value, rec) { if (rec.get('stop') && rec.get('start') && (rec.get('stop') - rec.get('start')) >= 0) { return (rec.get('stop') - rec.get('start')) / 1000.0; } }, persist: false }, {name: 'cacheId', type: 'int'}, {name: 'isNew', type: 'boolean', defaultValue: false}, {name: 'isModified', type: 'boolean', defaultValue: false} ]; var updateDurationColumnsVisibility = function (columns, visibleId) { Ext.Array.each(columns, function (item, index) { // if item is a column to hide automatically if (Ext.util.Format.substr(item.id, 0, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length) == amdaUI.CatalogUI.COL_TO_HIDE_DURATION) { // if item isn't the column which is being declared and is not hidden if (item.id != visibleId && !item.isHidden()) { // hide this column item.hide(); } } }); }; var columnsConfig = [ { xtype: 'rownumberer', width: 50, minWidth: 50, renderer: function (value, metaData, record) { var msg = record.index + 1; if (record.get('isNew') || record.get('isModified')) { msg += ' *'; metaData.style = 'font-weight: bold' } return msg; } }, { header: 'Start Time', dataIndex: 'start', width: 145, editor: {xtype: 'datefield', allowBlank: false, hideTrigger: true, format: 'Y-m-d\\TH:i:s.u'}, renderer: function (value) { if (value != null) { if (Ext.isDate(value)) { return Ext.Date.format(value, 'Y-m-d\\TH:i:s.u'); } else { return Ext.Date.format(new Date(value), 'Y-m-d\\TH:i:s.u'); } } else { return value; } } }, { header: 'Stop Time', dataIndex: 'stop', width: 145, editor: {xtype: 'datefield', allowBlank: false, hideTrigger: true, format: 'Y-m-d\\TH:i:s.u'}, renderer: function (value) { if (value != null) { if (Ext.isDate(value)) { return Ext.Date.format(value, 'Y-m-d\\TH:i:s.u'); } else { return Ext.Date.format(new Date(value), 'Y-m-d\\TH:i:s.u'); } } else { return value; } } }, { xtype: 'gridcolumn', text: 'Duration (day)', sortable: true, dataIndex: 'durationDay', width: 120, minWidth: 50, menuDisabled: false, hidden: Ext.state.Manager.getProvider().get('cat_duration') != 1 ? true : false, id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '1', renderer: function (value) { return this.dateToString(value); }, listeners: { beforeshow: function () { updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '1'); } }, filter: {type: 'numeric'} }, { xtype: 'gridcolumn', text: 'Duration (hour)', sortable: true, dataIndex: 'durationHour', width: 120, minWidth: 50, menuDisabled: false, hidden: Ext.state.Manager.getProvider().get('cat_duration') != 2 ? true : false, id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '2', renderer: function (value) { return this.dateToString(value); }, listeners: { beforeshow: function () { updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '2'); } }, filter: {type: 'numeric'} }, { xtype: 'gridcolumn', text: 'Duration (Min)', sortable: true, dataIndex: 'durationMin', width: 120, minWidth: 50, menuDisabled: false, hidden: Ext.state.Manager.getProvider().get('cat_duration') != 3 ? true : false, id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '3', renderer: function (value) { return this.dateToString(value); }, listeners: { beforeshow: function () { updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '3'); } }, filter: {type: 'numeric'} }, { xtype: 'gridcolumn', text: 'Duration (Sec)', sortable: true, dataIndex: 'durationSec', width: 120, minWidth: 50, menuDisabled: false, hidden: Ext.state.Manager.getProvider().get('cat_duration') != 4 ? true : false, id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '4', renderer: function (value) { return Ext.util.Format.number(value, '0.000'); }, listeners: { beforeshow: function () { updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '4'); } }, filter: {type: 'numeric'} } ]; var pramColumnWidth = 120 * (1 - 0.7 * (1 - 1 / result.parameters.length)); Ext.Array.each(result.parameters, function (obj, index) { var field = { name: obj.id }; var column = { text: obj.name, sortable: true, dataIndex: obj.id, menuDisabled: false, minWidth: 50, paramColumn: true }; switch (obj.type) { case 0: //double field = Ext.apply({}, field, { type: 'string' }); column = Ext.apply({}, column, { xtype: 'gridcolumn', width: pramColumnWidth * parseInt(obj.size), editor: 'textfield', filter: {type: 'numeric', menuItemCfgs: {decimalPrecision: 10}}, renderer :function(value){ return (value == "NAN") ? "nan": value; }, }); break; case 1: //dateTime field = Ext.apply({}, field, { type: 'date', dateFormat: 'Y-m-d\\TH:i:s.u', convert: function (value, rec) { if (!Ext.isDate(value)) { return new Date(value); } return value; } }); column = Ext.apply({}, column, { xtype: 'datecolumn', width: 120, editor: { xtype: 'datefield', allowBlank: false, hideTrigger: true, format: 'Y-m-d\\TH:i:s.u' }, filter: {type: 'date', dateFormat: 'Y-m-d'}, renderer: function (value) { if (value != null) { if (Ext.isDate(value)) { return Ext.Date.format(value, 'Y-m-d\\TH:i:s.u'); } else { return Ext.Date.format(new Date(value), 'Y-m-d\\TH:i:s.u'); } } else { return value; } } }); break; case 2: //string field = Ext.apply({}, field, { type: 'string' }); column = Ext.apply({}, column, { xtype: 'gridcolumn', width: pramColumnWidth * parseInt(obj.size), editor: 'textfield', renderer :function(value){ var renderedVal = value; if(value.toLowerCase().startsWith("http://") ||value.toLowerCase().startsWith("https://")) { renderedVal = '' + value +''; } return renderedVal; }, filter: {type: 'string'} }); break; case 3: //int field = Ext.apply({}, field, { type: 'string' }); column = Ext.apply({}, column, { xtype: 'gridcolumn', width: pramColumnWidth * parseInt(obj.size), editor: 'textfield', filter: {type: 'numeric'} }); break; default: field = Ext.apply({}, field, { type: 'string' }); column = Ext.apply({}, column, { xtype: 'gridcolumn', width: pramColumnWidth * parseInt(obj.size), editor: 'textfield', filter: {type: 'string'} }); } fieldsConfig.push(field); columnsConfig.push(column); }); var store = Ext.create('Ext.data.Store', { fields: fieldsConfig, autoDestroy: false, pageSize: 200, buffered: true, purgePageCount: 0, remoteSort: true, proxy: { type: 'direct', api: {read: AmdaAction.readCacheIntervals}, // remplir automatiquement tt, sharedtt , catalog, shared catalog extraParams: {'typeTT': 'catalog'}, reader: { type: 'json', root: 'intervals', totalProperty: 'totalCount' } }, listeners: { scope: me, load: function (store, records) { // myDesktopApp.EventManager.fireEvent('refresh'); me.TTGrid.getView().refresh(); me.TTGrid.getSelectionModel().refresh(); me.updateCount(); //Statistical plugin this.fireEvent("refresh"); }, prefetch: function (store, records, successful, operation, eOpts) { if (operation && (operation.action == 'read')) { if (operation.response && operation.response.result && operation.response.result.success) me.status = operation.response.result.status; } } } }); me.TTGrid.reconfigure(store, columnsConfig); if (me.TTGrid.filters) { me.TTGrid.filters.bindStore(store); } } me.TTGrid.getSelectionModel().deselectAll(); // // // clear filters if (me.TTGrid.filters) { me.TTGrid.getStore().clearFilter(true); me.TTGrid.filters.clearFilters(); } // // clear sort me.TTGrid.getStore().sorters.clear(); //me.TTGrid.getStore().sorters = new Ext.util.MixedCollection(); //set cache token to the Catalog object me.object.set('cacheToken', result.token); me.setParamInfo(result.parameters); me.TTGrid.getStore().load(); me.status = result.status; //Statistical plugin me.fireEvent("refresh"); }, /** * load object catalog into this view */ loadObject: function () { // load object into form this.object.set('created', this.convertUTCDateToLocalDate(this.object.get('created'))); this.formPanel.getForm().loadRecord(this.object); this.status = null; if (this.object.get('fromPlugin') && (this.object.get('objName') != '')) { if (this.object.get('objFormat') && this.object.get('objFormat') != '') { //From uploaded file AmdaAction.initObjectCacheFromUploadedFile(this.object.get('objName'), this.object.get('objFormat'), this.isCatalog, this.onAfterInit, this); } else { //From tmp object (ie Statistics result) AmdaAction.initObjectCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, this.onAfterInit, this); } } else { var typeTT = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id).linkedNode.data.nodeType; if (this.object.get('id') == '' && this.object.get('relatedTimeTableId') == '') { // creating new catalog AmdaAction.initObjectCache(this.isCatalog, this.object.get('nbParameters'), this.onAfterInit, this); } else if (this.object.get('relatedTimeTableId') != '') { // Generate Catalog from Time Table var pathern = this.object.get('relatedTimeTableId').split('_')[0]; if (pathern == 'sharedtimeTable') typeTT='sharedtimeTable'; AmdaAction.initObjectCacheFromTimeTable(this.object.get('relatedTimeTableId'), typeTT, this.object.get('nbParameters'), this.onAfterInit, this); } else { //From existing TT file AmdaAction.initObjectCacheFromObject(this.object.get('id'), typeTT, this.onAfterInit, this); } } //Statistical plugin this.fireEvent("refresh"); }, checkIntervalsStatusForSave: function (onStatusOk) { if (this.status == null) return; if (this.status.nbValid <= 0) { myDesktopApp.errorMsg('Your catalog is invalid,
you must have at least one valid interval'); return; } var msg = ''; if (this.status.nbInvalid > 0) msg += 'There are some invalid intervals. Only valid intervals will be saved!
'; if (this.status.nbFiltered > 0) msg += 'There are some filtered intervals. Filtered intervals will not be saved!
'; if (msg != '') { msg += 'Do you want to continue?'; Ext.Msg.show({ title: 'Warning!', msg: msg, buttons: Ext.Msg.OKCANCEL, fn: function (btnId) { if (btnId === 'cancel') { // cancel the save action } else { onStatusOk(); } }, scope: this, icon: Ext.Msg.WARNING }); return; } onStatusOk(); }, /* * save method called by Save button */ saveProcess: function (toRename, onAfterSave, notDisplayMsg) { var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); // store / columns are the same - not needed to reconfigure grid this.toReconfigure = false; // if save shared catalog if (module.contextNode && (module.contextNode.get('id') == 'sharedcatalog-treeRootNode')) { module.linkedNode = null; module.createLinkedNode(); module.createObject(this.object.getJsonValues()); var obj = module.linkedNode.get('object'); // synchronisation of objects this.object = obj; module.linkedNode.create({notDisplayMsg: notDisplayMsg, callback: function (type,res) { this.updateSurveyDates(res); if (onAfterSave) onAfterSave(); }, scope: this}); } // if the name has been modified this is a creation else if (this.fclose() || this.status) { if (this.object.isModified('name') || this.object.get('fromPlugin')) { // if object already has an id : it's a 'rename' of an existing if (this.object.get('id')) { // the context Node is the parent node of current edited one var contextNode = module.linkedNode.parentNode; // link a new node to the TimeTableModule module.createLinkedNode(); // set the contextNode module.linkedNode.set('contextNode', contextNode); // create a new object linked module.createObject(this.object.getJsonValues()); var obj = module.linkedNode.get('object'); // synchronisation of objects this.object = obj; if (toRename) module.linkedNode.toRename = true; } module.linkedNode.create({callback: function () { module.linkedNode.update({notDisplayMsg: notDisplayMsg, callback: function (type,res) { this.updateSurveyDates(res); if (onAfterSave) onAfterSave(); }, scope: this}, "", notDisplayMsg); }, scope: this}); } else { //update module.linkedNode.update({notDisplayMsg: notDisplayMsg, callback: function (type,res) { this.updateSurveyDates(res); if (onAfterSave) onAfterSave(); }, scope: this}); } } }, saveCatalog: function (onAfterSave, notDisplayMsg) { if (this.updateObject()) { var basicForm = this.formPanel.getForm(); // update TimeTable object which the content of form basicForm.updateRecord(this.object); var me = this; this.checkIntervalsStatusForSave(function () { //Name validation var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); if (!module) return; module.linkedNode.isValidName(me.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: me.overwriteProcess, 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, onAfterSave, notDisplayMsg); }); }); } }, /** * overwrite metod called by Save button */ overwriteProcess: function (btn) { if (btn == 'cancel') return; this.fieldName.clearInvalid(); this.saveProcess(true); }, /** * Check if changes were made before closing window * @return true if changes */ fclose: function () { if (this.status == null) return false; var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0); return isDirty; }, onChangeStartField: function(field, newValue, oldValue){ if (field.isValid()) { if (field.isValid() && this.activeField == 'surveyStart') { // launch the update of duration fields var form = this.findParentByType('form').getForm(); var stop = form.findField('surveyStop').setMinValue(newValue); var start = form.findField('surveyStart').getValue(); var stop = form.findField('surveyStop').getValue(); if (stop <= start) { form.findField('surveyStart').markInvalid('Start Time must be before Stop Time'); } } } }, onChangeStopField: function(field, newValue, oldValue) { if (field.isValid() && this.activeField =='surveyStop' ) { // launch the update of duration fields var form = this.findParentByType('form').getForm(); var start = form.findField('surveyStart').getValue(); var stop =form.findField('surveyStop').getValue(); if ( stop <= start ) { field.markInvalid('Stop Time must be after Start Time'); } } }, columnForm: function(isNew, self, me , columnInfo = null){ this.statusGrid = Ext.create('amdaUI.StatusGrid',{type:'cat',status : (columnInfo != null) ? columnInfo.status : null }); var me = this; // Different avaible types var types = Ext.create('Ext.data.Store', { fields: ['type', 'name'], data : [ {"type":2, "name":"String"}, {"type":3, "name":"Integer"}, {"type":0, "name":"Float"}, {"type":1,"name":"TIme"} ] }); // Window for the creation of the new Column var window = Ext.create('Ext.window.Window', { title: (isNew) ? 'New Column' : 'Edit Column', width: 480, height: 210, closable:false, modal:true, resizable: false, items: [ { xtype: 'form', renderTo: Ext.getBody(), fieldDefaults: { labelAlign: 'right', msgTarget: 'side' }, defaults: { xtype: 'panel', bodyStyle: {background: '#dfe8f6'}, border:false, layout: 'anchor' }, layout:'hbox', id: 'simpleForm', frame: true, items: [{ flex:6, items:[{ // Name xtype:'textfield', fieldLabel: 'Column Name', name: 'nameColumn', value: (isNew) ? null : columnInfo.name, allowBlank: false, tooltip: 'Enter the name of the column you want to create' },{ // Type xtype: 'combobox', fieldLabel: 'Data Type', name:'typeColumn', store:types, allowBlank: false, value : (isNew) ? null : columnInfo.type, queryMode: 'local', displayField: 'name', valueField: 'type', editable: false, tooltip: 'Enter the type of data you want to put in this column' }, { // Size xtype:'numberfield', fieldLabel: 'Size', name: 'sizeColumn', value: (isNew) ? 1 : columnInfo.size, maxValue: 3, minValue: 1, allowBlank: false, tooltip: 'For exemple: 1 for scalar type or 3 for a vector' }, { // Name xtype:'textarea', fieldLabel: 'Description', name: 'descriptionColumn', height:50, value: (isNew) ? null : columnInfo.description, allowBlank: true, }] }, { flex:4, margin:'0 8 0 -5', items:[this.statusGrid], }], buttons: [{ text: 'Save', handler: function() { // If the form is correctly filled, we continue if(this.up('form').getForm().isValid()){ if(isNew){ var newColumnPrefix='added_param_id_'; var nbAddedColumn= 0; Ext.each(self.TTGrid.headerCt.getGridColumns(), function(column){ if(column.dataIndex.substr(0, 15) == newColumnPrefix){ nbAddedColumn++; } }); AmdaAction.addColumn(newColumnPrefix+nbAddedColumn, this.up('form').getForm().findField('nameColumn').getValue(), this.up('form').getForm().findField('typeColumn').getValue(), this.up('form').getForm().findField('sizeColumn').getValue(), this.up('form').getForm().findField('descriptionColumn').getValue(), me.statusGrid.getStatusString(), function(result, e){ if(result){ me.toReconfigure = true; me.onAfterInit(result); window.close(); } }); } else{ var newName = null; var newType = null; var newSize = null; var newDescription = null; var newStatus = null; // Check if there is modifications if(this.up('form').getForm().findField('nameColumn').getValue() != columnInfo.name){ newName = this.up('form').getForm().findField('nameColumn').getValue(); } if(this.up('form').getForm().findField('typeColumn').getValue() != columnInfo.type){ newType = this.up('form').getForm().findField('typeColumn').getValue(); } if(this.up('form').getForm().findField('sizeColumn').getValue() != columnInfo.size){ newSize = this.up('form').getForm().findField('sizeColumn').getValue(); } if(this.up('form').getForm().findField('descriptionColumn').getValue() != columnInfo.description){ newDescription = this.up('form').getForm().findField('descriptionColumn').getValue(); } if(me.statusGrid.getStatusString() != columnInfo.status){ newStatus = me.statusGrid.getStatusString(); } if(newName != null || newType != null || newSize != null || newDescription != null || newStatus != null) { AmdaAction.editColumn(columnInfo.id, newName, newType, newSize, newDescription, newStatus, function(result, e){ if(result){ me.toReconfigure = true; me.onAfterInit(result); me.statusGrid.clearStore(); window.close(); } }); } else{ window.close(); } } } }, }, { // to reset the form text: 'Reset', handler: function() { this.up('form').getForm().reset(); me.statusGrid.clearStore(); me.statusGrid.parseStatus(columnInfo.status); } }, { // To quit the window text: 'Cancel', handler: function() { me.statusGrid.clearStore(); window.close(); } }] } ] }).show(); }, init: function (config) { var me = this; this.object = config.object; this.fieldName = new Ext.form.field.Text({ fieldLabel: 'Name', allowBlank: false, stripCharsRe: /(^\s+|\s+$)/g, emptyText: 'Please no spaces!', name: 'name', validateOnChange: false, validateOnBlur: false, validFlag: false, validator: function () { return this.validFlag; } }); var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', { // clicksToEdit: 2, onEditComplete: function (ed, value, startValue) { var me = this, activeColumn = me.getActiveColumn(), context = me.context, record; if (activeColumn) { record = context.record; me.setActiveEditor(null); me.setActiveColumn(null); me.setActiveRecord(null); context.value = value; if (!me.validateEdit()) { me.editing = false; return; } // Only update the record if the new value is different than the // startValue. When the view refreshes its el will gain focus if (!record.isEqual(value, startValue)) { var obj = { 'cacheId': record.get('cacheId'), 'isCatalog': true, 'data': {} }; if(activeColumn.dataIndex == "start" || activeColumn.dataIndex == "stop") obj['data'][activeColumn.dataIndex] = Ext.Date.format(value, 'Y-m-d\\TH:i:s.u'); else obj['data'][activeColumn.dataIndex] = value; //Interval is modified on the server side me.editing = true; AmdaAction.modifyCacheInterval(obj, function (result, e) { var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); if (module) module.getUiContent().status = result.status; if (!context.store.loading) { context.grid.getSelectionModel().deselectAll(); context.store.reload({ callback: function (records, options, success) { context.view.bufferedRenderer.scrollTo(context.rowIdx, true, function () { me.fireEvent('edit', me, context); me.editing = false; }, me); } }); } else { me.editing = false; } }, this); } else me.editing = false; } } }); var filters = { ftype: 'filters', encode: true, // json encode the filter query local: false, filters: [ ] }; const self = this; this.TTGrid = Ext.create('Ext.grid.Panel', { height: 530, features: [filters], columns: [], frame: true, columnLines: true, selModel: {pruneRemoved: false}, countDecimals: function (value) { if (Math.floor(value) === value) return 0; return value.toString().split(".")[1].length || 0; }, dateToString: function (value) { ndegits = this.countDecimals(value); if (ndegits <= 3) { return Ext.util.Format.number(value, '0.000'); } else if (value < 0.1) { return value.toExponential(3); } else { return Ext.util.Format.number(value, '0.000000'); } }, // selType: 'cellmodel', plugins: [cellEditing, {ptype: 'bufferedrenderer'}], listeners: { afterrender: function ( ) { this.TTGrid.headerCt.resizer.tracker.gridBugFix = true; // Adding "Delete Column" in the menu var menu = this.TTGrid.headerCt.getMenu(); menu.on('beforeshow',function(){ var deleteName='delete_column'; var editName= 'edit_column'; var isDeleteinMenu = false; var isEditInMenu = false; // Is there already the delete or edit item in the menu Ext.each(menu.items.items, function(items){ if(items.name == deleteName){ isDeleteinMenu = true; } if(items.name == editName){ isEditInMenu = true; } }); // Computing the number of parameters in the catalog var nbParamColumns=0; Ext.each(this.TTGrid.headerCt.getGridColumns(), function(column){ if(column.paramColumn){ nbParamColumns++ } }); // Adding the "Edit Column" if conditions satisfied if(!isEditInMenu){ menu.add({ text: 'Edit Column', iconCls: 'icon-parameters', name: editName, handler: function(item,e) { AmdaAction.getCatColumnInfo(menu.activeHeader.dataIndex,function(result, e){ if(result){ me.columnForm(false, self,me, result); } }); } }); } // Adding the "Delete Column" if conditions satisfied if(!isDeleteinMenu){ menu.add({ text: 'Delete Column', iconCls: 'icon-delete', disabled:false, name: deleteName, handler: function(item,e) { AmdaAction.deleteColumn(menu.activeHeader.dataIndex,function(result, e){ me.toReconfigure = true; me.onAfterInit(result); }); } }); } Ext.each(menu.items.items, function(item){ if(item.name == deleteName){ item.setDisabled(!menu.activeHeader.paramColumn || nbParamColumns <= 1); } if(item.name == editName){ item.setDisabled(!menu.activeHeader.paramColumn); } }); }, this); }, scope: this, columnschanged:function(ct,eOpts){ // Takes into count the duration changes Ext.Array.each(ct.getGridColumns(), function (item, index, all) { if (Ext.util.Format.substr(item.id, 0, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length) == amdaUI.CatalogUI.COL_TO_HIDE_DURATION && !item.isHidden()) { var durationNumber = parseInt(Ext.util.Format.substr(item.id, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length+1)); Ext.state.Manager.getProvider().set('cat_duration', durationNumber); } }); } }, dockedItems: [{ xtype: 'toolbar', items: [{ iconCls: 'icon-add', text:'New line', scope: this, handler: function () { cellEditing.cancelEdit(); var store = this.TTGrid.getStore(); var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0]; var row = 0; if (selection) row = store.indexOf(selection) + 1; this.TTGrid.getSelectionModel().deselectAll(); var me = this; AmdaAction.addCacheInterval({'index': row, 'isCatalog': true}, function (result, e) { this.status = result.status; if (!this.TTGrid.getStore().loading) { this.TTGrid.getStore().reload({ callback: function (records, options, success) { me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function () { me.TTGrid.getView().select(row); cellEditing.startEditByPosition({row: row, column: 1}); }, me); } }); } }, this); } }, { iconCls: 'icon-delete', disabled: true, text:'Delete Line', itemId: 'delete', scope: this, handler: function () { var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0]; if (selection) { var rowId = selection.get('cacheId'); this.TTGrid.getSelectionModel().deselectAll(); AmdaAction.removeTTCacheIntervalFromId(rowId, this.isCatalog, function (result, e) { this.status = result.status; if (!this.TTGrid.getStore().loading) { this.TTGrid.getStore().reload(); } }, this); } } }, '-',{ iconCls: 'icon-add', text:'New Column(s)', itemId: 'column_add', scope: this, handler: function () { me.columnForm(true, self,me); } }, '->', { text: 'Clear Filters', scope: this, handler: function () { this.TTGrid.getStore().clearFilter(true); this.TTGrid.filters.clearFilters(); } }] }] }); this.codeDescripton = Ext.create('amdaUI.DescriptionField',{ xtype: 'descriptionfield', height:150, align:'stretch', name: 'description', }); this.formPanel = Ext.create('Ext.form.Panel', { region: 'center', me:this, layout: 'hbox', model: 'amdaModel.Catalog', trackResetOnLoad: true, // reset to the last loaded record bodyStyle: {background: '#dfe8f6'}, defaults: {border: false, align: 'stretch', bodyStyle: {background: '#dfe8f6'}, padding: '3'}, fieldDefaults: {labelWidth: 80, labelAlign: 'top'}, items: [{ xtype:'panel', overflowY:true, height:530, layout:'hbox', defaults: {border: false, align: 'stretch',bodyStyle: {background: '#dfe8f6',padding: '1'}}, flex: 1, items:[{ xtype: 'form', flex: 1, buttonAlign: 'left', // title : 'Information', layout: {type: 'vbox', pack:'start',align: 'stretch'}, items: [ this.fieldName, { xtype: 'fieldcontainer', layout: 'hbox', items: [{ xtype: 'datefield', fieldLabel: 'Creation date', name: 'created', disabled: true, hideTrigger: true, format: 'Y/m/d H:i:s' }, {xtype: 'splitter'}, {xtype: 'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true} ] }, { xtype:'fieldset', columnWidth: 0.5, title: 'Survey Period', collapsible: true, defaultType: 'datefield', defaults: {anchor: '100%'}, layout: 'anchor', items :[{ fieldLabel: 'Start Time', name: 'surveyStart', emptyText: 'YYYY/MM/DDThh:mm:ss.fff', format: 'Y-m-d\\TH:i:s.u', enforceMaxLength: true, disabled: true, hideTrigger: true, maxLength: 25, labelWidth: 60, labelAlign: 'left', renderer: function (value) { if (value != null) { if (Ext.isDate(value)) { return Ext.Date.format(value, 'Y-m-d\\TH:i:s.u'); } else { return Ext.Date.format(new Date(value), 'Y-m-d\\TH:i:s.u'); } } else { return value; } }, }, { fieldLabel: 'Stop Time', name: 'surveyStop', emptyText: 'YYYY/MM/DDThh:mm:ss.fff', format: 'Y-m-d\\TH:i:s.u', labelAlign: 'left', enforceMaxLength: true, disabled: true, hideTrigger: true, maxLength: 25, labelWidth: 60, align: 'left', }] }, { xtype: 'textarea', name: 'contact', fieldLabel: 'Contact', height:50 }, { xtype:'panel', resizable:true, height: 165, bodyStyle: {background: '#dfe8f6',padding: '1'}, border:false, layout:'fit', items:[ this.codeDescripton ], listeners:{ resize:function(a,b,height){ if(this.codeDescripton.codeMirror) this.codeDescripton.codeMirror.setSize(null, height-20); }, scope:this }, }, { xtype: 'operationsTT', margin:'5 0 0 0', collapsible: true, collapsed:false, parent: this, isCat:true, id: 'operationCat' }, ], }], }, { xtype: 'form', bodyStyle: {background: '#dfe8f6'}, //padding: '3', flex: 2, items: [this.TTGrid] } ], dockedItems: [ { xtype: 'toolbar', dock: 'bottom', ui: 'footer', height: 35, items: [ { type: 'button', text: 'Save', width: 50, scope: this, handler: function () { this.saveCatalog(); } }, { type: 'button', text: 'Reset', width: 50, scope: this, handler: function () { var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); // module.createLinkedNode(); // module.createObject(); this.setObject(module.getLinkedNode().get('object'), true); } }, { type: 'button', text: 'Create New Catalog', width: 120, scope: this, handler: function () { var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); if (!module) return; module.createLinkedNode(); module.createObject(); var obj = module.linkedNode.get('object'); var me = this; Ext.Msg.prompt('Create catalog', 'Enter the number of columns:', function (btn, text) { if (btn == 'ok') { module.createLinkedNode(); module.createObject(); var obj = module.linkedNode.get('object'); var nbParam = parseInt(text); if ((nbParam <= 0) || (nbParam > 100)) { nbParam = 1; } obj.set('nbParameters', nbParam); me.setObject(obj, true); } }, this); } }, //statistical info { xtype: 'toolbar', dock: 'bottom', ui: 'footer', items: [{ xtype: 'button', text: 'Statistical info', scope: this, //dock: 'bottom', //ui: 'footer', handler: function () { this.fireEvent('info', 'catalogUI'); } }, { type: 'button', text: 'Visualize', scope: this, handler: function () { var me = this; myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.visu.id, true, function (module) { module.visualize(me.object); }); } }, ] }, { xtype: 'toolbar', dock: 'bottom', ui: 'footer', items: [{ xtype: 'button', text: 'Generate Time Table', scope: this, //dock: 'bottom', //ui: 'footer', handler: function () { this.generateTT(this.object.get('id')); } }] },] }, ], }); this.TTGrid.getSelectionModel().on('selectionchange', function (selModel, selections) { this.TTGrid.down('#delete').setDisabled(selections.length === 0); }, 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 + 'catalogHOWTO' } } ], plugins: [{ptype: 'statisticalPlugin'}] }; Ext.apply(this, Ext.apply(arguments, myConf)); } });