      1 /**
      2  * @class Ozone.layout.ManageWidgetsContainer
      3  * @extends Ext.form.Panel
      4  */
      5 Ext.define('Ozone.layout.ManageWidgetsContainer', {
      6     extend: 'Ext.form.Panel', /** @lends Ozone.layout.ManageWidgetsContainer */
      7     alias: ['widget.owfManageWidgetsContainer', 'widget.Ozone.layout.ManageWidgetsContainer'],
      8     requires: [
      9         'Ext.layout.container.VBox'
     10     ],
     11
     12     layout: {
     13       type: 'vbox',
     14       align: 'stretch'
     15     },
     16
     17     border: false,
     18
     19     cls: 'mwc-manageWidgetsContainer',
     20
     21     mixins: {
     22         focus: 'Ozone.components.focusable.CircularFocus'
     23     },
     24
     25     loadGridData: function(){
     26     this.setLoading(true);
     27     var existingWidgetStore = this.dashboardContainer.widgetStore;
     28
     29         // Add removed flag for delete column
     30         var storeData = [];
     31         for (var i = 0; i < existingWidgetStore.getCount(); i++) {
     32             var widget = existingWidgetStore.getAt(i).data;
     33             widget["removed"] = false;
     34             if (widget.definitionVisible && widget.widgetTypes != null) {
     35               //loop through widget types and find 'standard'
     36               var widgetTypes = widget.widgetTypes;
     37               var isStandard = false;
     38               for (var j = 0 ; j < widgetTypes.length ; j++) {
     39                 var widgetType = widgetTypes[j];
     40                 if (widgetType != null && widgetType.name == 'standard') {
     41                   isStandard = true;
     42                   break;
     43                 }
     44               }
     45
     46               //only show standard and visible widgetdefs
     47               if (isStandard) {
     48                 storeData.push(widget);
     49               }
     50             }
     51         }
     52
     53         this.store.loadData(storeData);
     54         this.setLoading(false);
     55     },
     56
     57     refreshOriginalWidgetNames: function(params) {
     58         this.setLoading(true);
     59         var scope = this;
     60         Ozone.pref.PrefServer.findWidgets({
     61           onSuccess: function(records) {
     62                 // Update originalWidgetNames
     63                 for (var i = 0; i < records.length; i++) {
     64                     scope.dashboardContainer.originalWidgetNames[records[i].path] = records[i].value.namespace;
     65                 }
     66
     67                 if (params.reloadGrid == true) {
     68                     scope.loadGridData();
     69                 } else {
     70                     scope.setLoading(false);
     71                 }
     72                 params.callback();
     73             },
     74
     75             onFailure: function() {
     76                 scope.setLoading(false);
     77                 params.callback();
     78             }
     79         });
     80     },
     81     initComponent: function() {
     82         var scope = this;
     83
     84           // Set up a model to use in our Store
     85         var widgetJsonModel = Ext.define('widgetJsonModel', {
     86             extend: 'Ext.data.Model',
     87             fields: ['widgetGuid', {name:'name', sortType:Ext.data.SortTypes.asUCString}, 'visible', 'removed', 'headerIcon','tags', 'editable', '_tags','_editable']
     88         });
     89
     90           // Create data store
     91         this.store = Ext.create('Ext.data.JsonStore', {
     92             model:'widgetJsonModel',
     93             sorters: [{
     94                 property : 'name',
     95                 direction: 'ASC' // or 'DESC' (case sensitive for local sorting)
     96             }],
     97             listeners : {
     98                 datachanged : {
     99                     fn : function(s) {
    100                         //preprocess store
    101                         var store = s;
    102                         store.suspendEvents();
    103                         for (var i = 0 ; i < store.getCount() ; i++) {
    104                             var rec = store.getAt(i);
    105                             var recData = rec.data;
    106                             if (Ext.isArray(recData.tags) && recData.tags.length > 0) {
    107                                 var _tags = '';
    108                                 var editable = true;
    109                                 for (var j = 0 ; j < recData.tags.length ; j++) {
    110                                     _tags +=recData.tags[j].name;
    111                                     if (j < recData.tags.length -1) {
    112                                         _tags+=', ';
    113                                     }
    114                                     if (recData.tags[j].editable === false) {
    115                                         editable = false;
    116                                     }
    117                                 }
    118                                 rec.set('_tags',_tags);
    119                                 rec.set('_editable',editable);
    120                                 rec.commit();
    121                             }
    122                             else {
    123                                 rec.set('_tags','');
    124                                 rec.set('_editable',true);
    125                                 rec.commit();
    126                             }
    127                         }
    128                         store.resumeEvents();
    129                     },
    130                     scope : this
    131                 }
    132             }
    133         });
    134
    135         // Create editable Dashboard Name field
    136         this.nameField = Ext.create('Ext.form.field.Text', {
    137             maxLength: 200,
    138             allowBlank: false,
    139             blankText: Ozone.layout.DialogMessages.view_dashboardNameField_blankText,
    140             validator: function(value) {
    141                 if (this.value) {
    142                     if (this.value.toUpperCase() != value.toUpperCase()) {
    143                         for (var i = 0; i < store.data.items.length; i++) {
    144                             if(value.charAt(0) === ' ' || value.charAt(value.length-1) === ' ') {
    145                                 return Ozone.util.ErrorMessageString.invalidDashboardNameMsg;
    146                             }
    147                         }
    148                     }
    149                     else {
    150                         if(this.value.charAt(0) === ' ' || this.value.charAt(this.value.length-1) === ' ') {
    151                             return Ozone.util.ErrorMessageString.invalidDashboardNameMsg;
    152                         }
    153                     }
    154                     return true;
    155                 }
    156                 return true;
    157             }
    158         });
    159
    160         this.tagsField = Ext.create('Ext.form.field.Text', {
    161             allowBlank: true,
    162             validator: function(val) {
    163                 if (val.match(Ozone.config.carousel.restrictedTagGroupsRegex) != null) {
    164                 return '"'+val+'"'+Ozone.util.ErrorMessageString.restrictedTagError;
    165                 }
    166                 else {
    167                 return true;
    168                 }
    169             }
    170         });
    171
    172         var resetTitleAction = Ext.create('Ext.Action', {
    173             text: 'Reset Title',
    174             handler: function(widget, event) {
    175                 var rec = scope.widgetGrid.getSelectionModel().getSelection()[0];
    176                 if (rec) {
    177                     scope.refreshOriginalWidgetNames({
    178                         reloadGrid: false,
    179                         callback: function() {
    180                             var originalName = rec.get('originalName');
    181                             rec.set('name', originalName);
    182                         }
    183                     });
    184                 }
    185             }
    186         });
    187         var resetAllTitlesAction = Ext.create('Ext.Action', {
    188             text: 'Reset All Titles',
    189             handler: function(widget, event) {
    190                 var records = scope.widgetGrid.getStore().getRange();
    191                 scope.refreshOriginalWidgetNames({
    192                     reloadGrid: false,
    193                     callback: function() {
    194                         for (var i = 0; i < records.length; i++) {
    195                             if (records[i].data.editable) {
    196                                 // Reset titles
    197                                 var originalName = records[i].get('originalName');
    198                                 records[i].data.name = originalName;
    199
    200                                 // Update tags
    201                                 var tags = [];
    202                                 if (records[i].data._tags.length > 0 && records[i].data._tags != '') {
    203                                     var splits = records[i].data._tags.split(',');
    204                                     for (var j = 0 ; j < splits.length ; j++) {
    205                                         var name = Ext.String.trim(splits[j]);
    206                                         if (name != '') {
    207                                             tags.push({
    208                                                 name: name,
    209                                                 visible: true,
    210
    211                                                 //todo use position to order groups for now just set to -1
    212                                                 position: -1,
    213                                                 editable: records[i].data._editable
    214                                             });
    215                                         }
    216                                     }
    217                                 }
    218                                 records[i].data.tags = tags;
    219                             }
    220                         }
    221                         scope.store.loadRecords(records, {
    222                             addRecords: false
    223                         });
    224                     }
    225                 });
    226             }
    227         });
    228
    229         var contextMenu = Ext.create('Ext.menu.Menu', {
    230             items: [
    231                 resetTitleAction,
    232                 resetAllTitlesAction
    233             ]
    234         });
    235
    236         this.widgetGrid = Ext.create('Ext.grid.GridPanel', {
    237             ddGroup: 'ddWidgets',
    238             cls:'mwc-widgetGridPanel',
    239             store: this.store,
    240             autoScroll: true,
    241             scroll: true,
    242             viewConfig: {
    243                 listeners: {
    244                     itemcontextmenu: {
    245                         fn: function (view, rec, node, index, e) {
    246                             e.stopEvent();
    247                             this.dashboardContainer.floatingWindowManager.register(contextMenu);
    248                             contextMenu.showAt(e.getXY());
    249                             this.dashboardContainer.floatingWindowManager.bringToFront(contextMenu);
    250                             return false;
    251                         },
    252                         scope: this
    253                     },
    254                     itemkeydown: {
    255                         fn: function (view, record, item, index, evt) {
    256                             switch (evt.getKey()) {
    257                                 case Ext.EventObject.S:
    258                                     record.set('visible', !record.get('visible'));
    259                                     view.refreshNode(index);
    260                                     break;
    261
    262                                 case Ext.EventObject.D:
    263                                     record.set('removed', !record.get('removed'));
    264                                     view.refreshNode(index);
    265                                     break;
    266
    267                                 case Ext.EventObject.R:
    268                                     if(!Ext.EventObject.hasModifier()) {
    269                                         //Get the 3rd cell (in the Tags column) of the selected row to get starting point
    270                                         //for XY coordinates to place the context menu inside the selected row appropriately.
    271                                         var thirdCellInSelectedRow = Ext.select('tr[class*=x-grid-row-focused]:first td').item(2);
    272                                         var coordinates = thirdCellInSelectedRow.getXY();
    273                                         coordinates[0] -= 5;
    274                                         coordinates[1] += 10; // Approximates a good location for the context menu to appear
    275                                         contextMenu.showAt(coordinates);
    276
    277                                         //Add a listener to the context menu so that when it is closed with ESC it will
    278                                         //move focus back to the widget grid
    279                                         contextMenu.addListener('hide', function(view, record, item) {
    280                                             //Set on a defer to wait until focus is moved to the banner, then pulls focus back
    281                                             Ext.defer(function() {
    282                                                 //Set focus on the widget grid, which is 3 levels down from the manageWidgetsWindow
    283                                                 Ext.getCmp("manageWidgetsWindowId").getComponent(0).getComponent(0).getComponent(0).focus();
    284                                             }, 100, this);
    285
    286                                             //Remove this listener after the context menu is hidden
    287                                             contextMenu.removeListener('hide', arguments.callee);
    288                                         });
    289                                     }
    290                                     break;
    291
    292                                 case Ext.EventObject.ENTER:
    293                                     var header = view.headerCt.getHeaderAtIndex(1);
    294                                     view.editingPlugin.startEdit(record, header);
    295                             }
    296                         },
    297                         scope: this
    298                     },
    299                     afterrender: function (cmp) {
    300                         cmp.getEl().on('keyup', function(evt) {
    301                             //prevent ESC key from escaping to the
    302                             //body.  Since ESC keydown is stopped
    303                             //internally to the grid, we need to to
    304                             //stop the keyup as well
    305                             if (evt.getKey() === evt.ESC)
    306                                 evt.stopPropagation();
    307                         });
    308                     }
    309                 }
    310             },
    311             columns: [
    312                 {
    313                     xtype: 'gridcolumn',
    314                     text: '<span class="gridHdr">Icon</span>',
    315                     dataIndex: 'headerIcon',
    316                     width: 36,
    317                     sortable: false,
    318                     resizable: false,
    319                     menuDisabled: true,
    320                     renderer: function (val, metaData, record, rowIndex, colIndex, store) {
    321                         if (record.get('editable') == false) {
    322                             metaData.attr = 'ext:qtip="This widget belongs to a Group and may not be edited or deleted"';
    323                             metaData.tdCls += ' x-item-disabled';
    324                         }
    325
    326                         var retVal = '<div><img width=\"24px\" height=\"24px\" src="'+val+'">';
    327                         retVal += '</div>';
    328
    329                         return  retVal;
    330                     }
    331                 },
    332                 {
    333                     xtype: 'textcolumn',
    334                     text: '<span class="gridHdr">Widget</span>',
    335                     dataIndex: 'name',
    336                     field: this.nameField,
    337                     width: 176,
    338                     resizable: false,
    339                     menuDisabled: true,
    340                     renderer: function(value, metaData, record, rowIndex, colIndex, store) {
    341                         if(record.get('editable') != false && record.get('_editable')!= false) {
    342                             metaData.tdCls += ' manage-editable';
    343                         }
    344                         if (record.get('editable') == false) {
    345                             metaData.tdAttr = 'data-qtip="This widget belongs to a Group and may not be edited or deleted"';
    346                             metaData.tdCls += ' x-item-disabled';
    347                         }
    348                         return Ext.util.Format.htmlEncode(value);
    349                     }
    350                 },
    351                 {
    352                     xtype:'textcolumn',
    353                     menuDisabled: true,
    354                     text: '<span class="gridHdr">Tags</span>',
    355                     field : this.tagsField,
    356                     dataIndex: '_tags',
    357                     width: 170,
    358                     resizable: false,
    359                     renderer: function(value, metaData, record, rowIndex, colIndex, store) {
    360                         metaData.tdCls = 'hd-tags';
    361                         if (record.get('_editable') == false) {
    362                             metaData.tdCls += ' x-item-disabled';
    363                         }
    364                         if (record.get('editable') == false) {
    365                             metaData.tdAttr = 'data-qtip="This widget belongs to a Group and may not be edited or deleted"';
    366                             metaData.tdCls += ' x-item-disabled';
    367                         }
    368                         if(record.get('editable') != false && record.get('_editable')!= false)
    369                         {
    370                             metaData.tdCls += ' manage-editable';
    371                             var encValue = Ext.util.Format.htmlEncode(value);
    372                             //work-around to html-encode html tags - can't just directly htmlEncode stuff
    373                             //so we inject an XTemplate to handle it
    374                             metaData.tdAttr = 'data-qtip="'+new Ext.XTemplate('{foo:htmlEncode}').apply({
    375                                 foo:encValue
    376                             })+'"';
    377                         }
    378                         return Ext.util.Format.htmlEncode(value);
    379                     }
    380                 },
    381                 {
    382                     xtype:'checkcolumn',
    383                     text: '<span class="gridHdrShow"><span class="x-grid-column-checkbox-off"></span><span class="underline">S</span>how</span>',
    384                     dataIndex: 'visible',
    385                     width: 90,
    386                     menuDisabled: true,
    387                     sortable: false,
    388                     resizable: false,
    389                     tdCls:'gridCellShowWidgets-chkbox',
    390                     cellDisabled: function(record) {
    391                         return record.data['removed'] || record.get('editable') === false;
    392                     },
    393                     renderer : function(value, metaData, record, rowIndex, colIndex, store) {
    394                         var thisColumn = this.columns[colIndex];
    395                         var cls = [thisColumn._checkBoxCls];
    396                         if (!value || 'false' == value) {
    397                             cls.push(thisColumn._checkBoxClsOff);
    398                         } else {
    399                             cls.push(thisColumn._checkBoxClsOn);
    400                         }
    401                         if (record.get('editable') == false) {
    402                             metaData.tdAttr = 'data-qtip="This widget belongs to a Group and may not be edited or deleted"';
    403                             metaData.tdCls += ' x-item-disabled';
    404                         }
    405                         return '<div class="' + cls.join(' ') + '"> </div>';
    406                     }
    407                 },
    408                 {
    409                     xtype:'checkcolumn',
    410                     text: '<span class="gridHdrDelete"><span class="x-grid-column-checkbox-off"></span><span class="underline">D</span>elete</span>',
    411                     dataIndex: 'removed',
    412                     width: 90,
    413                     menuDisabled: true,
    414                     sortable: false,
    415                     resizable: false,
    416                     tdCls:'gridCellDeleteWidgets-chkbox',
    417                     cellDisabled : function(record) {
    418                         if (record.get('_editable') === false || record.get('editable') === false) {
    419                             return true;
    420                         }
    421                         else {
    422                             return false;
    423                         }
    424                     },
    425                     onChecked: function(view, record) {
    426                         view.addRowCls(record.index, "x-item-disabled");
    427                     },
    428                     onUnchecked: function(view, record) {
    429                         view.removeRowCls(record.index, "x-item-disabled");
    430                     },
    431                     renderer : function(value, metaData, record, rowIndex, colIndex, store) {
    432                         var thisColumn = this.columns[colIndex];
    433                         var cls = [thisColumn._checkBoxCls];
    434                         if (!value || 'false' == value) {
    435                             cls.push(thisColumn._checkBoxClsOff);
    436                         } else {
    437                             cls.push(thisColumn._checkBoxClsOn);
    438                         }
    439                         if (record.get('editable') == false) {
    440                             metaData.tdAttr = 'data-qtip="This widget belongs to a Group and may not be edited or deleted"';
    441                             metaData.tdCls += ' x-item-disabled';
    442                         }
    443                         return '<div class="' + cls.join(' ') + '"> </div>';
    444                     }
    445                 }
    446             ],
    447             selType:'rowmodel',
    448             frame: false,
    449             enableDragDrop: true,
    450             enableHdMenu: false,
    451             enableColumnResize: false,
    452             plugins: [
    453                 Ext.create('Ext.grid.plugin.CellEditing', {
    454                     clicksToEdit: 1
    455                 }),
    456                 new Ozone.components.focusable.FocusableGridPanel()
    457             ],
    458             flex: 1,
    459             listeners: {
    460                 //Handle Before Edit has taken place
    461                 beforeedit: function(e) {
    462                     var isCellEditable = function(record) {
    463                         if (record.get('removed') || record.get('_editable') === false ||  record.get('editable') === false) {
    464                             return false;
    465                         }
    466                         return true;
    467                     };
    468                     return isCellEditable(e.record);
    469                 },
    470                 //Handle After Edit has taken place
    471                 edit: function(editor, e) {
    472                     if(editor.editors.items[e.column.id]) {
    473                         e.record.set('_tags',editor.editors.items[e.column.id].field.value.toLowerCase());
    474                     }
    475                 }
    476             }
    477         });
    478
    479         this.items = [
    480             this.widgetGrid
    481         ];
    482
    483         /***
    484          * IMPLEMENT HEADER CLICKED.
    485          */
    486         this.widgetGrid.headerCt.on('headerclick', function(ct, column, evt, htmlElem) {
    487                 if(typeof column.onGridHeaderCtClick == 'function') {
    488                     column.onGridHeaderCtClick(this.widgetGrid, evt, htmlElem);
    489                 }
    490             },
    491             this
    492         );
    493
    494         this.keys = [];
    495         this.keys.push({
    496             key: Ext.EventObject.ENTER,
    497             fn: function (k,e) {
    498                 var button = this.getFooterToolbar().getComponent('saveButton');
    499                 if (button) {
    500                     e.button = 0;
    501                     button.onClick(e);
    502                 }
    503             },
    504             scope: this
    505         });
    506
    507         this.dockedItems = [{
    508             xtype: 'toolbar',
    509             dock: 'bottom',
    510             defaults: {
    511                 minWidth: this.minButtonWidth
    512             },
    513             layout: {
    514                 type: 'hbox',
    515                 pack: 'end'
    516             },
    517             items: [
    518                 {
    519                     xtype:'button',
    520                     scale: 'small',
    521                     text: Ozone.layout.MessageBoxButtonText.ok,
    522                     itemId: 'saveButton',
    523                     //                iconCls: 'okSaveBtnIcon',
    524                     handler: function() {
    525                         scope.onSaveClick();
    526                     },
    527                     listeners: {
    528                         // afterrender: function(button) {
    529                         //     button.getEl().on('keydown', function(e) {
    530                         //         e.stopPropagation();
    531                         //     });
    532                         // }
    533                     }
    534                 },
    535                 {
    536                     xtype:'button',
    537                     scale: 'small',
    538                     itemId: 'cancelBtn',
    539                     text: Ozone.layout.MessageBoxButtonText.cancel,
    540                     // iconCls: 'cancelBtnIcon',
    541                     handler: function() {
    542                         Ext.getCmp(scope.winId).close();
    543                     }
    544                 }
    545             ]
    546         }];
    547
    548         //Need this to get rid of destory errors with ExtJS
    549         this.on('beforedestroy', function(cmp) {
    550             cmp.dockedItems = null;
    551         });
    552
    553         this.on({
    554             afterrender: {
    555                 fn: function(cmp) {
    556                     var winCmp = Ext.getCmp(cmp.winId);
    557
    558                     winCmp.on('show', function() {
    559                         cmp.loadGridData();
    560                     });
    561
    562                     winCmp.setupFocus(cmp.widgetGrid.getView().getEl(),
    563                     cmp.down('#cancelBtn').getFocusEl());
    564
    565                 },
    566                 scope: this
    567             }
    568         });
    569
    570         //Ensure the shadow follows the window in IE
    571         this.on('resize', function() {
    572             this.syncShadow();
    573         });
    574
    575         this.callParent();
    576     },
    577
    578     onSaveClick: function() {
    579         // Create array of widgets
    580         var gridData = this.widgetGrid.store.data.items;
    581         var widgetsToUpdate = [];
    582         var widgetsToDelete = [];
    583         var widgetGuidsToDelete = [];
    584         //this.dashboardContainer.widgetNames = {};
    585         for (var i = 0; i < gridData.length; i++) {
    586
    587             if (gridData[i].data.editable) {
    588                 if (!gridData[i].data.removed) {
    589                     var recData = gridData[i].data;
    590                     var tags = [];
    591                     if (recData._tags.length > 0 && recData._tags != '') {
    592                         var splits = recData._tags.split(',');
    593                         for (var j = 0 ; j < splits.length ; j++) {
    594                             var name = Ext.String.trim(splits[j]);
    595                             if (name != '') {
    596                                 tags.push({
    597                                     name: name,
    598                                     visible: true,
    599
    600                                     //todo use position to order groups for now just set to -1
    601                                     position: -1,
    602                                     editable: recData._editable
    603                                 });
    604                             }
    605                         }
    606                     }
    607
    608                     var widget = {
    609                         guid: gridData[i].data.widgetGuid,
    610                         visible: gridData[i].data.visible,
    611                         tags: tags
    612                     };
    613                     var originalName = gridData[i].data.originalName;
    614                     if (gridData[i].data.name !== originalName) {
    615                         widget.name = gridData[i].data.name;
    616                     }
    617                     widgetsToUpdate.push(widget);
    618
    619                 } else {
    620                     widgetGuidsToDelete.push(gridData[i].data.widgetGuid);
    621                     widgetsToDelete.push({
    622                         guid: gridData[i].data.widgetGuid,
    623                         name: gridData[i].data.name,
    624                         headerIcon: gridData[i].data.headerIcon,
    625                         image: gridData[i].data.image
    626                     });
    627                 }
    628             }
    629         }
    630
    631         var scope = this;
    632         function onSuccess() {
    633             //Call method to refresh the 'widget launch menu' widgets.
    634             scope.dashboardContainer.retrieveUpdatedWidgets();
    635         }
    636
    637         function onFailure() {
    638             Ozone.Msg.alert(Ozone.util.ErrorMessageString.saveUpdatedWidgets, Ozone.util.ErrorMessageString.saveUpdatedWidgetsMsg,
    639                 null, null, null, scope.dashboardContainer.floatingWindowManager);
    640         }
    641
    642         Ext.getCmp(this.winId).close();
    643         Ozone.pref.PrefServer.updateAndDeleteWidgets({
    644             widgetsToUpdate:widgetsToUpdate,
    645             widgetGuidsToDelete:[],
    646             updateOrder:false,
    647             onSuccess:onSuccess,
    648             onFailure:onFailure
    649         });
    650
    651         if (widgetGuidsToDelete.length > 0) {
    652
    653             Ext.create('Ext.window.Window', {
    654                 title: 'Deleting Widgets',
    655                 cls: 'delete-widgets-window',
    656                 height: 550,
    657                 ownerCt: scope.dashboardContainer,
    658                 dashboardContainer: scope.dashboardContainer,
    659                 constrain: Ext.isIE,
    660                 constrainHeader: true,
    661                 width: 600,
    662                 layout: 'fit',
    663                 resizable: false,
    664                 modal: true,
    665                 items: {
    666                     xtype: 'deletewidgetspanel',
    667                     delWidgets: widgetsToDelete,
    668                     dashboardContainer: scope.dashboardContainer
    669                 },
    670                 listeners: {
    671                     show: function (cmp) {
    672                         //Ensure its on top
    673                         cmp.dashboardContainer.floatingWindowManager.register(cmp);
    674                         cmp.dashboardContainer.floatingWindowManager.bringToFront(cmp);
    675
    676                         /*
    677                          * Needs to be deferred or it will happen before the
    678                          * window close in IE
    679                          */
    680                         Ext.defer(function() {
    681                             this.focus();
    682                         }, 100, cmp.getComponent('topdeletepanel').okBtn);
    683                     }
    684                 }
    685             }).show();
    686
    687         }
    688     }
    689 });