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 });