1 /** 2 * Copyright (C) 2005-2010 Alfresco Software Limited. 3 * 4 * This file is part of Alfresco 5 * 6 * Alfresco is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Alfresco is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * Rules "Workflow" Action module. 22 * 23 * @namespace Alfresco.module 24 * @class Alfresco.module.RulesWorkflowAction 25 */ 26 (function() 27 { 28 /** 29 * YUI Library aliases 30 */ 31 var Dom = YAHOO.util.Dom, 32 KeyListener = YAHOO.util.KeyListener, 33 Selector = YAHOO.util.Selector; 34 35 /** 36 * Alfresco Slingshot aliases 37 */ 38 var $html = Alfresco.util.encodeHTML, 39 $combine = Alfresco.util.combinePaths, 40 $hasEventInterest = Alfresco.util.hasEventInterest; 41 42 Alfresco.module.RulesWorkflowAction = function(htmlId) 43 { 44 Alfresco.module.RulesWorkflowAction.superclass.constructor.call(this, "Alfresco.module.RulesWorkflowAction", htmlId, ["button", "container", "connection"]); 45 46 // Decoupled event listeners 47 if (htmlId != "null") 48 { 49 YAHOO.Bubbling.on("folderSelected", this.onDestinationSelected, this); 50 } 51 52 return this; 53 }; 54 55 /** 56 * Alias to self 57 */ 58 var RWA = Alfresco.module.RulesWorkflowAction; 59 60 /** 61 * View Mode Constants 62 */ 63 YAHOO.lang.augmentObject(RWA, 64 { 65 /** 66 * "Approval step" view mode constant. 67 * 68 * @property VIEW_MODE_APPROVAL_STEP 69 * @type string 70 * @final 71 */ 72 VIEW_MODE_APPROVAL_STEP: "approval-step", 73 74 /** 75 * "Rejection steo" view mode constant. 76 * 77 * @property VIEW_MODE_REJECTION_STEP 78 * @type string 79 * @final 80 */ 81 VIEW_MODE_REJECTION_STEP: "rejection-step" 82 }); 83 84 YAHOO.extend(Alfresco.module.RulesWorkflowAction, Alfresco.component.Base, 85 { 86 /** 87 * Object container for initialization options 88 */ 89 options: 90 { 91 /** 92 * Current siteId for site view mode. 93 * 94 * @property siteId 95 * @type string 96 */ 97 siteId: "", 98 99 /** 100 * Repository's rootNode 101 * 102 * @property rootNode 103 * @type Alfresco.util.NodeRef 104 */ 105 rootNode: null, 106 107 /** 108 * Whether the Repo Browser is in use or not 109 * 110 * @property repositoryBrowsing 111 * @type boolean 112 */ 113 repositoryBrowsing: true, 114 115 /** 116 * ContainerId representing root container in site view mode 117 * 118 * @property containerId 119 * @type string 120 * @default "documentLibrary" 121 */ 122 containerId: "documentLibrary", 123 124 /** 125 * Template URL 126 * 127 * @property templateUrl 128 * @type string 129 * @default Alfresco.constants.URL_SERVICECONTEXT + "modules/rules/actions/workflow" 130 */ 131 templateUrl: Alfresco.constants.URL_SERVICECONTEXT + "modules/rules/actions/workflow", 132 133 /** 134 * Dialog view mode: approval step or rejection steo 135 * 136 * @property viewMode 137 * @type string 138 * @default Alfresco.modules.RulesWorkflowAction.VIEW_MODE_APPROVAL_STEP 139 */ 140 viewMode: RWA.VIEW_MODE_APPROVAL_STEP, 141 142 /** 143 * Allowed dialog view modes 144 * 145 * @property allowedViewModes 146 * @type array 147 * @default [VIEW_MODE_APPROVAL_STEP, VIEW_MODE_REJECTION_STEP] 148 */ 149 allowedViewModes: 150 [ 151 RWA.VIEW_MODE_APPROVAL_STEP, 152 RWA.VIEW_MODE_REJECTION_STEP 153 ] 154 }, 155 156 157 /** 158 * Container element for template in DOM. 159 * 160 * @property containerDiv 161 * @type HTMLElement 162 */ 163 containerDiv: null, 164 165 /** 166 * Main entry point 167 * @method showDialog 168 * @param workflowConfig {object} Data to fill the form with 169 */ 170 showDialog: function RWA_showDialog(workflowConfig) 171 { 172 if (!this.containerDiv) 173 { 174 // Load the UI template from the server 175 Alfresco.util.Ajax.request( 176 { 177 url: this.options.templateUrl, 178 dataObj: 179 { 180 htmlid: this.id 181 }, 182 successCallback: 183 { 184 fn: this.onTemplateLoaded, 185 obj: workflowConfig, 186 scope: this 187 }, 188 failureMessage: "Could not load template:" + this.options.templateUrl, 189 execScripts: true 190 }); 191 } 192 else 193 { 194 // Show the dialog 195 this._showDialog(workflowConfig); 196 } 197 }, 198 199 /** 200 * Event callback when dialog template has been loaded 201 * 202 * @method onTemplateLoaded 203 * @param response {object} Server response from load template XHR request 204 * @param workflowConfig {object} Data to fill the form with 205 */ 206 onTemplateLoaded: function RWA_onTemplateLoaded(response, workflowConfig) 207 { 208 // Inject the template from the XHR request into a new DIV element 209 this.containerDiv = document.createElement("div"); 210 this.containerDiv.setAttribute("style", "display:none"); 211 this.containerDiv.innerHTML = response.serverResponse.responseText; 212 213 // The panel is created from the HTML returned in the XHR request, not the container 214 var dialogDiv = Dom.getFirstChild(this.containerDiv); 215 216 // Create and render the YUI dialog 217 this.widgets.dialog = Alfresco.util.createYUIPanel(dialogDiv); 218 219 this.widgets.destinationLocation = new Alfresco.Location(this.id + "-destinationLabel"); 220 this.widgets.destinationLocation.setOptions( 221 { 222 siteId: this.options.siteId, 223 rootNode: this.options.rootNode 224 }); 225 226 // Buttons (note: ok button's click will be handled in forms onBeforeAjaxSubmit) 227 this.widgets.selectDestinationButton = Alfresco.util.createYUIButton(this, "selectDestination-button", this.onSelectDestinationClick); 228 this.widgets.okButton = Alfresco.util.createYUIButton(this, "ok-button", null, 229 { 230 type: "submit" 231 }); 232 this.widgets.cancelButton = Alfresco.util.createYUIButton(this, "cancel-button", this.onCancelClick); 233 234 // Configure the forms runtime 235 var form = new Alfresco.forms.Form(this.id + "-form"); 236 this.widgets.form = form; 237 238 // Comment is mandatory 239 form.addValidation(this.id + "-action", Alfresco.forms.validation.mandatory, null, "keyup"); 240 form.addValidation(this.id + "-nodeRef", Alfresco.forms.validation.mandatory, null, "keyup"); 241 242 // The ok button is the submit button, and it should be enabled when the form is ready 243 form.setShowSubmitStateDynamically(true, false); 244 form.setSubmitElements(this.widgets.okButton); 245 246 // Stop the form from being submitted and fire and event from the collected information 247 form.doBeforeAjaxRequest = 248 { 249 fn: function(p_config, p_obj) 250 { 251 // Fire event so other component know 252 YAHOO.Bubbling.fire("workflowOptionsSelected", 253 { 254 options: 255 { 256 label: p_config.dataObj.label, 257 action: p_config.dataObj.action, 258 nodeRef: p_config.dataObj.nodeRef, 259 path: p_config.dataObj.path, 260 viewMode: this.options.viewMode 261 }, 262 eventGroup: this 263 }); 264 265 this.widgets.dialog.hide(); 266 267 // Return fals so the form isn't submitted 268 return false; 269 }, 270 obj: null, 271 scope: this 272 }; 273 274 // We're in a popup, so need the tabbing fix 275 form.applyTabFix(); 276 form.init(); 277 278 // Register the ESC key to close the dialog 279 var escapeListener = new KeyListener(document, 280 { 281 keys: KeyListener.KEY.ESCAPE 282 }, 283 { 284 fn: function(id, keyEvent) 285 { 286 this.onCancelClick(); 287 }, 288 scope: this, 289 correctScope: true 290 }); 291 escapeListener.enable(); 292 293 // Show the dialog 294 this._showDialog(workflowConfig); 295 }, 296 297 /** 298 * Internal show dialog function 299 * @method _showDialog 300 * @param workflowConfig {object} Data to fill the form with 301 */ 302 _showDialog: function RWA__showDialog(workflowConfig) 303 { 304 // Dialog title 305 Dom.get(this.id + "-title").innerHTML = this.msg(this.options.viewMode + ".header"); 306 307 // Display form data 308 workflowConfig = workflowConfig ? workflowConfig : {}; 309 310 // Label textfield 311 Dom.get(this.id + "-label").value = workflowConfig.label ? $html(workflowConfig.label) : this.msg(this.options.viewMode + ".label.default"); 312 313 // Action drop down 314 Alfresco.util.setSelectedIndex(Dom.get(this.id + "-action"), workflowConfig.action); 315 316 // Destination picker 317 Dom.get(this.id + "-nodeRef").value = workflowConfig.nodeRef ? workflowConfig.nodeRef.toString() : ""; 318 this.widgets.destinationLocation.displayByNodeRef(workflowConfig.nodeRef); 319 320 // Update submit elements & show the dialog 321 this.widgets.form.updateSubmitElements(); 322 this.widgets.dialog.show(); 323 }, 324 325 326 /** 327 * YUI WIDGET EVENT HANDLERS 328 * Handlers for standard events fired from YUI widgets, e.g. "click" 329 */ 330 331 /** 332 * Dialog select destination button event handler 333 * 334 * @method onSelectDestinationClick 335 * @param e {object} DomEvent 336 * @param p_obj {object} Object passed back from addListener method 337 */ 338 onSelectDestinationClick: function RCIA_onSelectDestinationClick(e, p_obj) 339 { 340 // Set up select destination dialog 341 if (!this.widgets.destinationDialog) 342 { 343 this.widgets.destinationDialog = new Alfresco.module.DoclibGlobalFolder(this.id + "-selectDestination"); 344 345 var allowedViewModes = 346 [ 347 Alfresco.module.DoclibGlobalFolder.VIEW_MODE_SITE 348 ]; 349 if (this.options.repositoryBrowsing === true) 350 { 351 allowedViewModes.push(Alfresco.module.DoclibGlobalFolder.VIEW_MODE_REPOSITORY, Alfresco.module.DoclibGlobalFolder.VIEW_MODE_USERHOME); 352 } 353 354 this.widgets.destinationDialog.setOptions( 355 { 356 allowedViewModes: allowedViewModes, 357 siteId: this.options.siteId, 358 containerId: this.options.containerId, 359 title: this.msg("title.destinationDialog"), 360 nodeRef: this.options.rootNode 361 }); 362 } 363 364 // Make sure correct path is expanded 365 var pathNodeRef = Dom.get(this.id + "-nodeRef").value; 366 this.widgets.destinationDialog.setOptions( 367 { 368 pathNodeRef: pathNodeRef ? new Alfresco.util.NodeRef(pathNodeRef) : null 369 }); 370 371 // Show dialog 372 this.widgets.destinationDialog.showDialog(); 373 }, 374 375 376 /** 377 * Folder selected in destination dialog 378 * 379 * @method onDestinationSelected 380 * @param layer {object} Event fired 381 * @param args {array} Event parameters (depends on event type) 382 */ 383 onDestinationSelected: function RWA_onDestinationSelected(layer, args) 384 { 385 // Check the event is directed towards this instance 386 if ($hasEventInterest(this.widgets.destinationDialog, args)) 387 { 388 // Save values from dialog and update submit elements 389 var obj = args[1]; 390 if (obj !== null) 391 { 392 Dom.get(this.id + "-nodeRef").value = obj.selectedFolder.nodeRef; 393 this.widgets.destinationLocation.displayByNodeRef(obj.selectedFolder.nodeRef); 394 } 395 this.widgets.form.updateSubmitElements(); 396 } 397 }, 398 399 /** 400 * Dialog Cancel button event handler 401 * 402 * @method onCancelClick 403 * @param e {object} DomEvent 404 * @param p_obj {object} Object passed back from addListener method 405 */ 406 onCancelClick: function RWA_onCancelClick(e, p_obj) 407 { 408 this.widgets.dialog.hide(); 409 } 410 }); 411 412 /* Dummy instance to load optional YUI components early */ 413 var dummyInstance = new Alfresco.module.RulesWorkflowAction("null"); 414 })(); 415