1 /**
  2  * @class Ozone.layout.CreateViewContainer
  3  * @extends Ext.form.Panel
  4  */
  5 Ext.define('Ozone.layout.CreateViewContainer', {
  6     extend: 'Ext.form.Panel',
  7     alias: [
  8         'widget.owfCreateDashboardsContainer',
  9         'widget.owfCreateViewsContainer',
 10         'widget.Ozone.layout.CreateViewContainer'
 11     ],
 12     requires: [
 13         'Ext.layout.container.Border'
 14     ],
 15     border: false,
 16     config: {},
 17     views: null,
 18     dashboardContainer: null,
 19     itemId: 'createNewDashboardPanel',
 20     cls: 'cvc-createNewDashboardContainer',
 21     afterRenderInitComplete: false,
 22     createViewContainer_FormValid: true,
 23     hideViewSelectRadio: false,
 24 
 25     initComponent: function() {
 26         this.config = this.dashboardContainer.activeDashboard.config;
 27         this.views = this.dashboardContainer.dashboards;
 28         
 29         this.addEvents('saved', 'failed');
 30         
 31         this.titleBox = {
 32             xtype: 'textfield',
 33             name: 'titleBox',
 34             cls: 'titleBox',
 35             itemId: 'titleBox', //OWF-2558
 36             fieldLabel: Ozone.util.createRequiredLabel(Ozone.ux.DashboardMgmtString.title),
 37             labelSeparator: '',
 38             labelWidth: undefined,
 39             allowBlank: false,
 40             maxLength: 200,
 41             value: '',
 42             listeners: {
 43                 blur: function(field){
 44                     // Remove leading and tailing spaces
 45                     var val = field.getValue().replace(new RegExp(Ozone.lang.regexLeadingTailingSpaceChars), '');
 46                     field.setValue(val);
 47                 }
 48             }
 49         };
 50 
 51         this.description = {
 52             xtype: 'textareafield',
 53             name: 'description',
 54             cls: 'description',
 55             itemId: 'description',
 56             fieldLabel: Ozone.ux.DashboardMgmtString.description,
 57             labelSeparator: '',
 58             labelWidth: undefined,
 59             value: '',
 60             maxLength: 255,
 61             enforceMaxLength: true
 62         };
 63 
 64         if (this.existingDashboardRecord != null) {
 65           this.titleBox.value = this.existingDashboardRecord.get('name');
 66           this.description.value = this.existingDashboardRecord.get('description');
 67         }
 68 
 69         this.existingViewRadio = { 
 70             boxLabel: Ozone.layout.CreateViewWindowString.createFromExisiting, 
 71             name: 'viewSelectRadio',
 72             inputValue: "copiedDashboard",
 73             cls:'existingViewRadio',
 74             //tabIndex: 2,
 75             listeners: {
 76                 'change': {
 77                     fn: function(radio, newValue, oldValue) {
 78                         if(newValue)
 79                         {
 80                             // var cmp = this.down('#viewCb');
 81                             // cmp.reset();
 82                             // cmp.disable();
 83 
 84                             var existViewCb = this.down('#existViewCb');
 85                             existViewCb.enable();
 86                             existViewCb.validate();
 87 
 88                             var importFileupload = this.down('#importFileupload');
 89                             importFileupload.reset();
 90                             importFileupload.disable();
 91                         }
 92                     },
 93                     scope: this
 94                 }
 95             },
 96             vtype: 'copiedDashboard',
 97             copiedDashboardField: 'existViewCb' // id of the field to validate
 98         };
 99 		
100         this.importedViewRadio = { 
101             boxLabel: Ozone.layout.CreateViewWindowString.importView, 
102             name: 'viewSelectRadio',
103             inputValue: "importedDashboard",
104             cls:'importedViewRadio',
105             //tabIndex: 3,
106             listeners: {
107                 //this listener works for both since we can use the 'isSelected' param
108                 'change': {
109                     fn: function(radio, newValue, oldValue) {
110                         if(newValue) {
111                             var existViewCb = this.down('#existViewCb');
112                             existViewCb.reset();
113                             existViewCb.disable();
114 
115                             var importFileupload = this.down('#importFileupload');
116                             importFileupload.enable();
117                             importFileupload.validate();
118                         }
119                     },
120                     scope: this
121                 }
122             },
123             vtype: 'importedDashboard',
124             importedDashboardField: 'importFileupload' // id of the field to validate
125         };
126     	
127         // Set default layout for creating a new dashboard
128         //this.newView.value = this.config.layout;
129 		
130         this.existingView = {
131             xtype: 'combo',
132             //tabIndex: 2,
133             //id: 'existViewCb',
134             itemId: 'existViewCb',
135             store: this.dashboardContainer.dashboardStore,
136             valueField:'guid',
137             displayField:'name',
138             hideLabel: true,
139             typeAhead: true,
140             queryMode: 'local',
141             value: null,
142             triggerAction: 'all',
143             editable: true,
144             selectOnFocus:true,
145             allowBlank:true,
146             forceSelection: true,
147             disabled: true,
148             width: 400
149         };
150         this.existingView.value = this.views[0].guid;
151 
152         this.importedView = {
153             xtype: 'filefield',
154             //tabIndex: 3,
155             //id: 'importFileupload',
156             itemId: 'importFileupload',
157             cls: 'importFileupload',
158             name: 'importFileupload',
159             hideLabel: true,
160             label: '',
161             width: 400,
162             emptyText: Ozone.ux.DashboardMgmtString.uploadConfig,
163             allowBlank: true,
164             disabled: true,
165             buttonText:Ozone.ux.DashboardMgmtString.browse,
166     //        buttonConfig: {
167     //            ui: 'button'
168     //        },
169             listeners: {
170                 afterrender: function (cmp) {
171                     cmp.setupFocus = function() {
172                         /*
173                          * We need to have the file input be focusable, but
174                          * have it appear that the button is what actually has focus
175                          */
176 
177                         var btnEl = this.button.getEl();
178                         var innerBtnEl = this.button.btnEl;
179                         var fileInputEl = this.fileInputEl;
180                         var allowFocus = true;
181 
182                         //set the <button> element and the text field to not be focusable
183                         innerBtnEl.dom.tabIndex = -1;
184                         cmp.inputEl.dom.tabIndex = -1;
185 
186                         fileInputEl.dom.tabIndex = 0;
187                         fileInputEl.dom.hideFocus = true;
188                         fileInputEl.dom.style.outlineStyle = 'none';
189 
190                         cmp.mon(fileInputEl, 'focus', function() {
191                             this.addCls('x-focus');
192                         }, btnEl);
193 
194                         cmp.mon(fileInputEl,'blur', function() {
195                             this.removeCls('x-focus');
196                         }, btnEl);
197 
198                         function enableBorder() {
199                             allowFocus = true;
200                         }
201 
202                         cmp.mon(fileInputEl, {
203                             mouseup: enableBorder,
204                             mouseout: enableBorder
205                         });
206                     };
207 
208                     cmp.setupFocus();
209 
210                     //override the reset function
211                     cmp._reset = cmp.reset;
212                     cmp.reset = function() {
213                         this._reset.apply(this, arguments);
214 
215                         this.setupFocus();
216                     }
217                 }
218             }
219         };
220 
221 
222         //RadioGroup and CheckboxGroup does not properly validate other form fields that are not radio/checkboxes
223         //when mixed with radio/checkbox fields because it assumes if any radio/checkbox is checked it can assume the
224         //entire group is valid
225         this.viewSelectRadio = {
226             layout: {
227                 type: 'hbox',
228                 align: 'stretchmax'
229             },
230             cls: 'createSelector',
231             region: 'center',
232             allowBlank: false,
233             hideLabel: true,
234             hidden: this.hideViewSelectRadio,
235             items: [
236                 [
237                     {
238                         xtype: 'radiogroup',
239                         flex: 1,
240                         cls: 'viewSelect',
241                         itemId: "viewSelect", //OWF-2558
242                         layout: {
243                             type: 'vbox',
244                             align: 'stretch'
245                         },
246                         defaults: {
247                             flex: 1
248                         },
249                         items: [
250                             this.existingViewRadio,
251                             this.importedViewRadio
252                         ]
253                     },
254                     {
255                         layout: {
256                             type: 'vbox',
257                             align: 'stretch'
258                         },
259                         cls: 'viewSelectBoxes',
260                         flex: 1,
261                         defaults: {
262                             flex: 1
263                         },
264                         items: [
265                             this.existingView,
266                             this.importedView
267                         ]
268                     }
269                 ]
270             ]
271         };
272 
273         this.layout = {
274             type: 'vbox',
275             align: 'stretch'
276         };
277         this.items = [
278             this.titleBox,
279             this.description,
280             this.viewSelectRadio
281         ];
282 
283         this.dockedItems = [{
284             xtype: 'toolbar',
285             dock: 'bottom',
286             defaults: {
287                 minWidth: this.minButtonWidth
288             },
289             items: [{
290                 xtype: 'tbfill'
291             },{
292                 xtype:'button',
293                 scale: 'small',
294                 text: Ozone.layout.DialogMessages.ok,
295                 itemId: 'saveButton',
296                 //iconCls: 'okSaveBtnIcon',
297                 //tabIndex: 4,
298                 handler: function (button, event) {
299                     if (this.getForm().isValid() && this.createViewContainer_FormValid) {
300                         Ozone.util.formField.removeLeadingTrailingSpaces(this.getComponent('titleBox'));
301                         //make sure name is unique
302                         Ext.getCmp('mainPanel').saveActiveDashboardToServer();
303 
304                         var title = this.getComponent('titleBox').getValue();
305                         var desc = this.getComponent('description').getValue();
306 
307                         //edit an existing dashboard if a record was passed in
308                         if (this.existingDashboardRecord != null) {
309                             this.existingDashboardRecord.set('name',title);
310                             this.existingDashboardRecord.set('description',desc);
311                             this.dashboardContainer.editDashboard(this.existingDashboardRecord);
312                             this.close();
313                         }
314                         //else create a new one
315                         else {
316 
317                             var radioSelection = this.down('#viewSelect').getValue().viewSelectRadio;
318                             var isCreateFromExisting = (radioSelection == "copiedDashboard") ? true : false;
319                             var isImport = (radioSelection == "importedDashboard") ? true : false;
320 
321                             //create new from existing
322                             if (isCreateFromExisting) {
323                                 var existingViewSelected = this.down('#existViewCb').getValue();
324 
325                                 if (Ext.isEmpty(existingViewSelected)) {
326                                     this.down('#existViewCb').markInvalid("This field cannot be blank.");
327                                     Ozone.Msg.alert(Ozone.util.ErrorMessageString.invalidForm, Ozone.util.ErrorMessageString.invalidFormMsg, function () {
328                                             this.focusTitleBox();
329                                         }, this, null, this.dashboardContainer.floatingWindowManager);
330                                     return;
331                                 }
332 
333                                 var existingViewToDuplicate = this.dashboardContainer.dashboardStore.getById(existingViewSelected).data;
334                                 existingViewToDuplicate = Ozone.util.cloneDashboard(existingViewToDuplicate, true);
335                                 
336                                 existingViewToDuplicate.name = title;
337                                 existingViewToDuplicate.description = desc;
338                                 existingViewToDuplicate.isdefault = false;
339 
340                                 Ext.getCmp('mainPanel').createDashboard(
341                                         Ext.create('Ozone.data.Dashboard', existingViewToDuplicate)
342                                 );
343 
344                                 this.close();
345                             }
346                             //create new from import
347                             else if (isImport) {
348                                 //check if the fileupload field was actually set
349                                 var importFileupload = this.down('#importFileupload');
350                                 if (!Ext.isEmpty("importFileupload")) {
351                                     //create a new view based on imported file
352                                     this.getForm().submit({
353                                         url: Ozone.util.contextPath() + '/servlet/FileServlet',
354                                         waitMsg: 'Uploading config file...',
355                                         success: Ext.bind(function (fp, action) {
356                                             var dashboardJson = Ozone.util.parseJson(action.response.responseText).value;
357 
358                                             // Reset title
359                                             dashboardJson.name = title;
360                                             dashboardJson.description = desc;
361 
362                                             // make sure the right type of json is being imported
363                                             if (!Ozone.util.validateDashboardJSON(dashboardJson)) {
364                                                 Ozone.Msg.alert(Ozone.util.ErrorMessageString.dashboardConfig, "Invalid " + dashboardJson.layout + " configuration file.", function () {
365                                                     this.focusTitleBox();
366                                                 }, this, null, this.dashboardContainer.floatingWindowManager);
367                                             }
368                                             else {
369                                                 delete dashboardJson.state;
370 
371                                                 Ext.getCmp('mainPanel').createDashboard(
372                                                         Ext.create('Ozone.data.Dashboard', Ozone.util.cloneDashboard(dashboardJson, true))
373                                                 );
374                                                 this.close();
375                                             }
376                                         }, this),
377                                         failure: Ext.bind(function (form, action) {
378                                             Ozone.Msg.alert(Ozone.util.ErrorMessageString.dashboardConfig, "Invalid configuration file.", function () {
379                                                 this.focusTitleBox();
380                                             }, this, null, this.dashboardContainer.floatingWindowManager);
381                                         }, this)
382                                     });
383                                 }
384                                 else {
385                                     Ozone.Msg.alert(Ozone.util.ErrorMessageString.invalidForm, Ozone.util.ErrorMessageString.invalidFormMsg, function () {
386                                         this.focusTitleBox();
387                                     }, this, null, this.dashboardContainer.floatingWindowManager);
388                                 }
389                             }
390                             //create new using name, and description
391                             else {
392                                 Ext.getCmp('mainPanel').createDashboard(
393                                         Ext.create('Ozone.data.Dashboard', {
394                                             "name": title,
395                                             "description": desc
396                                         })
397                                 );
398                                 this.close();
399                             }
400                         }
401                     }
402                     else {
403                         Ozone.Msg.alert(Ozone.util.ErrorMessageString.invalidForm, Ozone.util.ErrorMessageString.invalidFormMsg, function () {
404                             this.focusTitleBox();
405                         }, this, null, this.dashboardContainer.floatingWindowManager);
406                     }
407                 },
408                 scope: this,
409                 listeners: {
410                     afterrender: function(button) {
411                         button.getEl().on('keydown', function(e) {
412                             e.stopPropagation(); //prevent keydown from bubbling up to the toolbar
413                         });
414                     }
415                 }
416             },{
417                 xtype:'button',
418                 scale: 'small',
419                 text: 'Cancel',
420                 itemId: 'cancelBtn',
421 //                iconCls: 'cancelBtnIcon',
422                 scope: this,
423                 handler: this.close
424             }]
425         }];
426 		
427         //Need this to get rid of destory errors with ExtJS
428         this.on('beforedestroy', function(cmp){
429             cmp.dockedItems = null;
430         });
431 
432         //        this.on("afterrender", function(cmp) {
433         //        	cmp.focusTitleBox();
434         //        });
435 
436         this.callParent();
437     },
438 
439     refreshData: function(){
440         this.config = this.dashboardContainer.activeDashboard.config;
441         this.views = this.dashboardContainer.dashboards;
442 
443         // Reset fields
444         var txtTitle = this.getComponent('titleBox');
445         if (txtTitle) {
446             txtTitle.setRawValue('');
447         }
448 
449         var txtDescription = this.getComponent('description');
450         if (txtDescription) {
451             txtDescription.setRawValue('');
452         }
453 
454         var txtImportFile = this.down('#importFileupload');
455         if (txtImportFile) {
456             txtImportFile.setRawValue('');
457         }
458 
459         var cboViewSelect = this.getComponent('viewSelect');
460         if (cboViewSelect) {
461             cboViewSelect.reset();
462         }
463 
464         var existingView = this.down('#existViewCb');
465         existingView.setValue(this.views[0].guid);
466     },
467 
468     focusTitleBox: function() {
469         /*
470          * Have to defer this so that it happens after a focus that Ext does 
471          * internally that is also deffered
472          */
473         Ext.defer(function() {
474             this.getComponent('titleBox').focus();
475         }, 500, this);
476     },
477 
478     close: function() {
479         Ext.getCmp(this.winId).close();
480     }
481 });