/** * Project  : AMDA-NG * Name : ParamsMgrUI.js * @class amdaUI.ParamsMgrUI * @extends Ext.Panel.Panel * @brief * @author Elena */ Ext.define('amdaUI.ParamsMgrUI',{ extend: 'Ext.panel.Panel', alias: 'widget.paramsMgrPanel', baseId : null, srcTree : null, destTree : null, //TODO where keep this (==baseId) description ? Global variable? basesNames : ['CDAWEB', 'THEMIS', 'MAPSKP'], bases : [], configSrc : {title: 'source', enableDrag : true, enableDrop: false}, configDest : {title: 'destination', enableDrag : false, enableDrop:true}, constructor: function(config){ this.init(config); this.callParent(arguments); }, /* * Load new data bases trees : source & destination */ loadTrees : function(button, pressed){ if (pressed) { this.baseId = button.text; this.loadTree('source'); this.loadTree('destination'); } }, /* * Real Load data base tree */ loadTree : function(type){ var title = this.baseId; if (type == 'source'){ var store = this.srcTree.getStore(); } else { var store = this.destTree.getStore(); title = 'My '+ this.baseId; } // sort alphabetically store.sort([ { sorterFn: function(o1, o2){ return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1; } } ]); // or RELOAD? var root = store.getRootNode(); store.load({ node: root, params: { nodeType: type, baseId: this.baseId } }); root.set('text', title); }, /* * Store and tree creation */ initTree: function(config){ if (this.baseId){ var title = config.title == 'source' ? this.baseId : 'My '+ this.baseId; } else var title = config.title; var selMode = config.title == 'source' ? {mode: 'SIMPLE'} : {mode: 'SINGLE'}; var store = Ext.create('Ext.data.TreeStore', { model: 'amdaModel.AmdaNode', root: { text: title, nodeType : 'remoteParam', expanded: true }, listeners: { scope : this, beforeload: function(store, operation){ store.proxy.extraParams = { nodeType: config.title, baseId: this.baseId } }} }); var menu = new Ext.menu.Menu({ items: [{ text: 'Delete Data' }], listeners: { scope : this, click : this.deleteMulti } }); var tree = Ext.create('Ext.tree.Panel', { store: store, id : config.title, flex: 1, height: 500, selModel: selMode, //{mode: 'SIMPLE'}, viewConfig: { plugins:{ ptype: 'treeviewdragdrop', allowContainerDrops : true, enableDrag: config.enableDrag, enableDrop: config.enableDrop, //TODO dataset drag/drop by parameters SELECTION dragText : "{0} selected parameter{1}", expandDelay : 100, ddGroup : "RemoteTreeDD", isValidDropPoint : function(){ return true; }, onContainerOver : function() { return this.dropAllowed; }, onNodeOver : function() { return this.dropAllowed; }, onNodeDrop : function(nodeData, dd, e, data){ if (!data.records) return false; Ext.Array.each(data.records, this.onDrop, this); // deselect source tree selection data.view.getSelectionModel().deselectAll(); return true; }, onContainerDrop : function(dd, e, data){ if (!data.records) return false; Ext.Array.each(data.records, this.onDrop, this); // deselect source tree selection data.view.getSelectionModel().deselectAll(); return true; }, onDrop : function(record) { var root = tree.getRootNode(); var srcNode = record; var id = srcNode.get('id'); // Check if node exists already at destination var idToCheck = id.toLowerCase().replace(":", "_", "gi"); // TODO check at sever side if (root.findChild('id',idToCheck, true)) { myDesktopApp.infoMsg('This parameter exists already in your treee'); return; } var ddNode = srcNode; // Array of parent nodes description var Arr = []; while (!ddNode.isRoot()) { ddNode = ddNode.parentNode; Arr.push(ddNode); } // start with the highest node Arr.reverse(); // create parent nodes if they do not exist var parentNode = root; Ext.Array.each(Arr,function(srcNode, index) { if (index > 0) { var nodeId = srcNode.get('id'); var node = root.findChild('id',nodeId, true); if (!node) { node = srcNode.copy(); parentNode.appendChild(node); parentNode.expand(); node.setDirty(); } parentNode = node; } }); // Add new node to correct location parentNode.expand(!this.isDataSet, function(res){ var newNode = srcNode.copy(); parentNode.appendChild(newNode); //to sync treeStore newNode.setDirty(); //expand the whole subtree of added node tree.selectPath(newNode.getPath( 'id', '|'), 'id', '|'); }); return true; }, onViewRender : function(view){ var me = this; if (me.enableDrag){ me.dragZone = Ext.create('Ext.tree.ViewDragZone', { view: view, ddGroup: me.dragGroup || me.ddGroup, dragText: me.dragText }); } if (me.enableDrop){ me.dropZone = Ext.create('Ext.tree.ViewDropZone', { view: view, ddGroup: me.dropGroup || me.ddGroup, allowContainerDrops: me.allowContainerDrops, expandDelay: me.expandDelay, isValidDropPoint : me.isValidDropPoint, onContainerDrop : me.onContainerDrop, onNodeDrop : me.onNodeDrop, onContainerOver : me.onContainerOver, onNodeOver : me.onNodeOver, onDrop : me.onDrop, onSimpleDrop : me.onSimpleDrop }); } } } }, listeners: { afterrender: function(comp) { var view = comp.getView(); view.tip = Ext.create('Ext.tip.ToolTip', { // The overall target element. target: view.el, // Each grid row causes its own seperate show and hide. delegate: view.itemSelector, // Moving within the row should not hide the tip. trackMouse: true, autoRender: true, listeners: { // Change content dynamically depending on which element triggered the show. beforeshow: function updateTipBody(tip) { var trigger = view.getRecord(tip.triggerElement); if (trigger) { var info = trigger.get('info'); if (!info || info == '') { tip.addCls('hide'); } else { tip.removeCls('hide'); tip.update(info); } } } } }); }, itemmouseenter: function(view, record, item){ if(record.get('allowDrag') && view.ownerCt.id == 'source'){ var el = Ext.get(item), td = el.down('td > div'); td.setStyle('cursor', 'crosshair'); } }, beforeselect: function(selmodel, record, index) { if (!(record.get('isRemoteDataSet') || record.get('isParameter')) && tree.id == 'source') return false; }, select: function(selmodel, record, index){ if (record.get('isRemoteDataSet') && tree.id == 'source' && record.isExpanded()) { var toSelect = selmodel.getCount() !== record.childNodes.length + 1; var alreadySelected = selmodel.isSelected(record.firstChild); selmodel.deselectAll(); if (toSelect && !alreadySelected) selmodel.select(record.childNodes); } }, itemcontextmenu: function(view, rec, item, index, e) { e.preventDefault();//stopEvent(); if (tree.id == 'destination' && rec.getDepth() > 0) menu.showAt(e.getXY()); } } }); return tree; }, // for the moment SINGLE! deleteMulti: function(){ var selected = this.destTree.getSelectionModel().getSelection(); Ext.Array.each(selected, function(rec){ rec.deleteData(); }); // reload destination tree and expand created nodes var store = this.destTree.getStore(); var root = store.getRootNode(); store.load({ node : root, params : { nodeType: 'destination', baseId : this.baseId } }); }, successCallBack : function(batch, options) { loadMask.hide(); // Check Errors var res = batch.operations[0].response.result; if (res.err) { myDesktopApp.errorMsg(res.err); this.loadTree('destination'); } else { var createdNodes = options.operations.create; // define Pathes to the created nodes Arr = []; Ext.Array.each(createdNodes,function(item){ if (item.get('isParameter')){ // parameter level Arr.push(item.getPath('id', '|')); } }); // reload destination tree and expand created nodes var panel = this.destTree; var store = this.destTree.getStore(); var root = store.getRootNode(); store.load({ node : root, params : { nodeType: 'destination', baseId : this.baseId }, scope : this, callback : function(){ for (var i = 0; i < Arr.length; i++){ panel.selectPath(Arr[i], 'id', '|'); } } }); this.updateUserTree(); } }, failureCallBack : function(batch, options) { myDesktopApp.errorMsg('Error while saving modifs'); loadMask.hide(); this.loadTree('destination'); }, /* * Update User Tree in Explorer after the the modifs */ updateUserTree : function() { // reload RemoteParam Tree in explorer var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); if (explorerTree) { var explorerTreeStore = explorerTree.getStore(); var explorerRoot = explorerTreeStore.getRootNode(); var explorerPath = '/root/parameters-treeBase/myRemoteData-treeRootNode/'; explorerTreeStore.load( { node : explorerRoot, params : { nodeType: 'resources'}, callback : function(){ explorerTree.selectPath(explorerPath); } }); } myDesktopApp.infoMsg('Parameter Tree has been updated'); }, /* * Panel Trees generation */ init: function(config) { if (config.baseId && config.baseId != 'root') this.baseId = config.baseId; this.srcTree = this.initTree(this.configSrc); this.destTree = this.initTree(this.configDest); // synchron load of destination tree if the corresponding node exists this.srcTree.on('itemexpand', function(node) { var root = this.destTree.getRootNode(); var destNode = root.findChild('id',node.get('id'),true); if (destNode) destNode.expand(); }, this); // toolbar Ext.Array.each(this.basesNames, function(baseName,index){ var isTheBase = false; if (this.baseId && baseName == this.baseId) var isTheBase = true; this.bases[index] = {text: baseName, toggleGroup: 'remoteBases', pressed: isTheBase, scope : this, toggleHandler: this.loadTrees} }, this); var myConf = { id : 'rb_tab_panel', title : 'Remote Data Base', items: [ this.srcTree, this.destTree ], tbar: this.bases, fbar: [ { text: 'Save Modifs', scope : this, handler: function(){ var store = this.destTree.getStore(); var new_nodes = store.getNewRecords(); var removed_nodes = store.getRemovedRecords(); // if only removed: no sync - already removed at Server by node.delete if ( new_nodes.length === 0 && removed_nodes.length > 0) this.updateUserTree(); if ( new_nodes.length > 0 ){ loadMask.show(); store.sync({ success : this.successCallBack, failure: this.failureCallBack, scope : this}); } } } ] }; Ext.apply(this, Ext.apply(arguments, myConf)); } });