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  * EditSite module
 22  *
 23  * A dialog for creating sites
 24  *
 25  * @namespace Alfresco.module
 26  * @class Alfresco.module.EditSite
 27  */
 28 (function()
 29 {
 30    
 31    var Dom = YAHOO.util.Dom,
 32       Element = YAHOO.util.Element;
 33    
 34    /**
 35     * EditSite constructor.
 36     *
 37     * @param htmlId {string} A unique id for this component
 38     * @return {Alfresco.EditSite} The new DocumentList instance
 39     * @constructor
 40     */
 41    Alfresco.module.EditSite = function(containerId)
 42    {
 43       this.name = "Alfresco.module.EditSite";
 44       this.id = containerId;
 45 
 46       var instance = Alfresco.util.ComponentManager.get(this.id);
 47       if (instance !== null)
 48       {
 49          throw new Error("An instance of Alfresco.module.EditSite already exists.");
 50       }
 51 
 52       // Set protype variables
 53       this.editPanelActive = false;
 54 
 55       // Register this component
 56       Alfresco.util.ComponentManager.register(this);
 57 
 58       // Load YUI Components
 59       Alfresco.util.YUILoaderHelper.require(["button", "container", "connection", "selector", "json", "event"], this.onComponentsLoaded, this);
 60 
 61       return this;
 62    };
 63 
 64    Alfresco.module.EditSite.prototype =
 65    {
 66 
 67       /**
 68        * True if the delete prompt is shown
 69        *
 70        * @property: visible
 71        * @type: boolean
 72        */
 73       editPanelActive: false,
 74 
 75       /**
 76        * Object container for storing YUI widget instances.
 77        * 
 78        * @property widgets
 79        * @type object
 80        */
 81        widgets: {},
 82 
 83       /**
 84        * Set messages for this module.
 85        *
 86        * @method setMessages
 87        * @param obj {object} Object literal specifying a set of messages
 88        * @return {Alfresco.module.EditSite} returns 'this' for method chaining
 89        */
 90       setMessages: function CS_setMessages(obj)
 91       {
 92          Alfresco.util.addMessages(obj, this.name);
 93          return this;
 94       },
 95 
 96       /**
 97        * Fired by YUILoaderHelper when required component script files have
 98        * been loaded into the browser.
 99        *
100        * @method onComponentsLoaded
101        */
102       onComponentsLoaded: function CS_onComponentsLoaded()
103       {
104          if (this.id === null)
105          {
106             return;
107          }
108       },
109 
110 
111       /**
112        * The default config for the gui state for edit site.
113        *
114        * @property defaultShowConfig
115        * @type object
116        */
117       defaultShowConfig:
118       {
119       },
120 
121       /**
122        * The merged result of the defaultShowConfig and the config passed in
123        * to the show method.
124        *
125        * @property defaultShowConfig
126        * @type object
127        */
128       showConfig: {},
129 
130       /**
131        * Shows the CreteSite dialog to the user.
132        *
133        * @method show
134        */
135       show: function CS_show(config)
136       {
137          if (!this.editPanelActive)
138          {
139             // Set editPanelActive to true so we don't open multiple dialogs
140             this.editPanelActive = true;
141 
142             // Merge the supplied config with default config and check mandatory properties
143             this.showConfig = YAHOO.lang.merge(this.defaultShowConfig, config);
144             if (this.showConfig.shortName === undefined)
145             {
146                this.editPanelActive = false;
147                throw new Error("A shortName must be provided");
148             }
149 
150             if (this.widgets.panel)
151             {
152                this.widgets.panel.destroy();
153                this.widgets = {};
154             }
155 
156             /**
157              * Load the gui and site info from the server and let the templateLoaded() method
158              * handle the rest.
159              */
160             Alfresco.util.Ajax.request(
161             {
162                url: Alfresco.constants.URL_SERVICECONTEXT + "modules/edit-site",
163                dataObj:
164                {
165                   htmlid: this.id,
166                   shortName: this.showConfig.shortName
167                },
168                successCallback:
169                {
170                   fn: this.onTemplateLoaded,
171                   scope: this
172                },
173                execScripts: true,
174                failureMessage: "Could not load edit site template"
175             });
176          }
177       },
178 
179       /**
180        * Called when the EditSite html template has been returned from the server.
181        * Creates the YUI gui objects such as buttons and a panel and shows it.
182        *
183        * @method onTemplateLoaded
184        * @param response {object} a Alfresco.util.Ajax.request response object 
185        */
186       onTemplateLoaded: function CS_onTemplateLoaded(response)
187       {
188          // Inject the template from the XHR request into a new DIV element
189          var containerDiv = document.createElement("div");
190          containerDiv.innerHTML = response.serverResponse.responseText;
191 
192          // The panel is created from the HTML returned in the XHR request, not the container
193          var panelDiv = YAHOO.util.Dom.getFirstChild(containerDiv);
194 
195          this.widgets.panel = Alfresco.util.createYUIPanel(panelDiv,
196          {
197             close: false
198          });
199 
200          // Create the cancel button
201          this.widgets.cancelButton = Alfresco.util.createYUIButton(this, "cancel-button", this.onCancelButtonClick);
202 
203          // Create the ok button, the forms runtime will handle when its clicked
204          this.widgets.okButton = Alfresco.util.createYUIButton(this, "ok-button", null,
205          {
206             type: "submit"
207          });
208 
209          // Configure the forms runtime
210          var editSiteForm = new Alfresco.forms.Form(this.id + "-form");
211 
212          // Title is mandatory
213          editSiteForm.addValidation(this.id + "-title", Alfresco.forms.validation.mandatory, null, "keyup");
214          // ...and has a maximum length
215          editSiteForm.addValidation(this.id + "-title", Alfresco.forms.validation.length,
216          {
217             max: 256,
218             crop: true
219          }, "keyup");
220 
221          // Description kept to a reasonable length
222          editSiteForm.addValidation(this.id + "-description", Alfresco.forms.validation.length,
223          {
224             max: 512,
225             crop: true
226          }, "keyup");
227 
228          // The ok button is the submit button, and it should be enabled when the form is ready
229          editSiteForm.setShowSubmitStateDynamically(true, false);
230          editSiteForm.setSubmitElements(this.widgets.okButton);
231          editSiteForm.doBeforeFormSubmit =
232          {
233             fn: function()
234             {
235                var formEl = YAHOO.util.Dom.get(this.id + "-form");
236                formEl.attributes.action.nodeValue = Alfresco.constants.PROXY_URI + "api/sites/" + this.showConfig.shortName; 
237 
238                // Site access
239                var siteVisibility = "PUBLIC";
240                if (this.widgets.isPublic.checked)
241                {
242                   if (this.widgets.isModerated.checked)
243                   {
244                      siteVisibility = "MODERATED";
245                   }
246                }
247                else
248                {
249                   siteVisibility = "PRIVATE";
250                }
251                this.widgets.siteVisibility.value = siteVisibility;
252 
253                this.widgets.okButton.set("disabled", true);
254                this.widgets.cancelButton.set("disabled", true);
255                this.widgets.panel.hide();
256                this.widgets.feedbackMessage = Alfresco.util.PopupManager.displayMessage(
257                {
258                   text: Alfresco.util.message("message.saving", this.name),
259                   spanClass: "wait",
260                   displayTime: 0
261                });
262             },
263             obj: null,
264             scope: this
265          };
266 
267          // Submit as an ajax submit (not leave the page), in json format
268          editSiteForm.setAJAXSubmit(true,
269          {
270             successCallback:
271             {
272                fn: this.onEditSiteSuccess,
273                scope: this               
274             },
275             failureCallback:
276             {
277                fn: this.onEditSiteFailure,
278                scope: this
279             }
280          });
281          editSiteForm.setSubmitAsJSON(true);
282          editSiteForm.setAjaxSubmitMethod("PUT");
283          // We're in a popup, so need the tabbing fix
284          editSiteForm.applyTabFix();
285          editSiteForm.init();
286 
287          this.widgets.siteVisibility = Dom.get(this.id + "-visibility");
288          this.widgets.isPublic = Dom.get(this.id + "-isPublic");
289          this.widgets.isModerated = Dom.get(this.id + "-isModerated");
290          this.widgets.isPrivate = Dom.get(this.id + "-isPrivate");
291 
292          // Make sure we disable moderated if public isn't selected
293          YAHOO.util.Event.addListener(this.widgets.isPublic, "change", this.onVisibilityChange, this, true);
294          YAHOO.util.Event.addListener(this.widgets.isPrivate, "change", this.onVisibilityChange, this, true);
295 
296          // Show the panel
297          this._showPanel();
298       },
299 
300 
301       /**
302        * Called when user clicks on the isPublic checkbox.
303        *
304        * @method onVisibilityChange
305        * @param type
306        * @param args
307        */
308       onVisibilityChange: function CS_onVisibilityChange(type, args)
309       {
310          new Element(this.widgets.isModerated).set("disabled", !new Element(this.widgets.isPublic).get("checked"));
311       },
312 
313       /**
314        * Called when user clicks on the cancel button.
315        * Closes the EditSite panel.
316        *
317        * @method onCancelButtonClick
318        * @param type
319        * @param args
320        */
321       onCancelButtonClick: function CS_onCancelButtonClick(type, args)
322       {
323          this.widgets.panel.hide();
324          this.editPanelActive = false;
325       },
326 
327       /**
328        * Called when a site has been succesfully created on the server.
329        * Redirects the user to the new site.
330        *
331        * @method onEditSiteSuccess
332        * @param response
333        */
334       onEditSiteSuccess: function CS_onEditSiteSuccess(response)
335       {
336          if (response.json !== undefined && response.json.shortName)
337          {
338             // The site has been successfully created, redirect the user to it.
339             document.location.href = Alfresco.constants.URL_PAGECONTEXT + "site/" + response.json.shortName + "/dashboard";
340          }
341          else
342          {
343             this._adjustGUIAfterFailure(response);
344          }
345       },
346 
347       /**
348        * Called when a site failed to be created.
349        *
350        * @method onEditSiteFailure
351        * @param response
352        */
353       onEditSiteFailure: function CS_onEditSiteFailure(response)
354       {
355          this._adjustGUIAfterFailure(response);
356       },
357 
358       /**
359        * Helper method that restores the gui and displays an error message.
360        *
361        * @method _adjustGUIAfterFailure
362        * @param response
363        */
364       _adjustGUIAfterFailure: function CS__adjustGUIAfterFailure(response)
365       {
366          this.widgets.feedbackMessage.destroy();
367          this.widgets.okButton.set("disabled", false);
368          this.widgets.cancelButton.set("disabled", false);
369          this.widgets.panel.show();
370          var text = Alfresco.util.message("message.failure", this.name);
371          if (response.json.message)
372          {
373             var tmp = Alfresco.util.message(response.json.message, this.name);
374             text = tmp ? tmp : text;
375          }
376          Alfresco.util.PopupManager.displayPrompt(
377          {
378             text: text
379          });
380       },
381 
382       /**
383        * Prepares the gui and shows the panel.
384        *
385        * @method _showPanel
386        * @private
387        */
388       _showPanel: function CS__showPanel()
389       {
390          // Show the upload panel
391          this.widgets.panel.show();
392 
393          // Firefox insertion caret fix
394          Alfresco.util.caretFix(this.id + "-form");
395 
396          // Register the ESC key to close the dialog
397          var escapeListener = new YAHOO.util.KeyListener(document,
398          {
399             keys: YAHOO.util.KeyListener.KEY.ESCAPE
400          },
401          {
402             fn: function(id, keyEvent)
403             {
404                this.onCancelButtonClick();
405             },
406             scope: this,
407             correctScope: true
408          });
409          escapeListener.enable();
410 
411          // Set the focus on the first field
412          YAHOO.util.Dom.get(this.id + "-title").focus();
413       }
414 
415    };
416 })();
417 
418 Alfresco.module.getEditSiteInstance = function()
419 {
420    var instanceId = "alfresco-editSite-instance";
421    return Alfresco.util.ComponentManager.get(instanceId) || new Alfresco.module.EditSite(instanceId);
422 }