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  * Data Lists: Toolbar component.
 22  * 
 23  * Displays a list of Toolbar
 24  * 
 25  * @namespace Alfresco
 26  * @class Alfresco.component.DataListToolbar
 27  */
 28 (function()
 29 {
 30    /**
 31     * YUI Library aliases
 32     */
 33    var Dom = YAHOO.util.Dom,
 34       Event = YAHOO.util.Event;
 35 
 36    /**
 37     * Toolbar constructor.
 38     * 
 39     * @param htmlId {String} The HTML id of the parent element
 40     * @return {Alfresco.component.DataListToolbar} The new Toolbar instance
 41     * @constructor
 42     */
 43    Alfresco.component.DataListToolbar = function(htmlId)
 44    {
 45       Alfresco.component.DataListToolbar.superclass.constructor.call(this, "Alfresco.component.DataListToolbar", htmlId, ["button", "container"]);
 46 
 47       // Decoupled event listeners
 48       YAHOO.Bubbling.on("selectedItemsChanged", this.onSelectedItemsChanged, this);
 49       YAHOO.Bubbling.on("userAccess", this.onUserAccess, this);
 50       
 51       return this;
 52    };
 53    
 54    /**
 55     * Extend from Alfresco.component.Base
 56     */
 57    YAHOO.extend(Alfresco.component.DataListToolbar, Alfresco.component.Base)
 58    
 59    /**
 60     * Augment prototype with Common Actions module
 61     */
 62    YAHOO.lang.augmentProto(Alfresco.component.DataListToolbar, Alfresco.service.DataListActions);
 63    
 64    /**
 65     * Augment prototype with main class implementation, ensuring overwrite is enabled
 66     */
 67    YAHOO.lang.augmentObject(Alfresco.component.DataListToolbar.prototype,
 68    {
 69       /**
 70        * Object container for initialization options
 71        *
 72        * @property options
 73        * @type object
 74        */
 75       options:
 76       {
 77          /**
 78            * Current siteId.
 79            * 
 80            * @property siteId
 81            * @type string
 82            * @default ""
 83            */
 84           siteId: ""
 85       },
 86 
 87       /**
 88        * Fired by YUI when parent element is available for scripting.
 89        *
 90        * @method onReady
 91        */
 92       onReady: function DataListToolbar_onReady()
 93       {
 94          this.widgets.newRowButton = Alfresco.util.createYUIButton(this, "newRowButton", this.onNewRow,
 95          {
 96             disabled: true,
 97             value: "create"
 98          });
 99 
100          // Selected Items menu button
101          this.widgets.selectedItems = Alfresco.util.createYUIButton(this, "selectedItems-button", this.onSelectedItems,
102          {
103             type: "menu", 
104             menu: "selectedItems-menu",
105             lazyloadmenu: false,
106             disabled: true
107          });
108 
109          this.widgets.printButton = Alfresco.util.createYUIButton(this, "printButton",
110          {
111             disabled: true
112          });
113          this.widgets.rssFeedButton = Alfresco.util.createYUIButton(this, "rssFeedButton",
114          {
115             disabled: true
116          });
117 
118          // DataList Actions module
119          this.modules.actions = new Alfresco.module.DataListActions();
120 
121          // Reference to Data Grid component
122          this.modules.dataGrid = Alfresco.util.ComponentManager.findFirst("Alfresco.component.DataGrid");
123 
124          // Finally show the component body here to prevent UI artifacts on YUI button decoration
125          Dom.setStyle(this.id + "-body", "visibility", "visible");
126       },
127       
128       /**
129        * New Row button click handler
130        *
131        * @method onNewRow
132        * @param e {object} DomEvent
133        * @param p_obj {object} Object passed back from addListener method
134        */
135       onNewRow: function DataListToolbar_onNewRow(e, p_obj)
136       {
137          var datalistMeta = this.modules.dataGrid.datalistMeta,
138             destination = datalistMeta.nodeRef,
139             itemType = datalistMeta.itemType;
140 
141          // Intercept before dialog show
142          var doBeforeDialogShow = function DataListToolbar_onNewRow_doBeforeDialogShow(p_form, p_dialog)
143          {
144             Alfresco.util.populateHTML(
145                [ p_dialog.id + "-dialogTitle", this.msg("label.new-row.title") ],
146                [ p_dialog.id + "-dialogHeader", this.msg("label.new-row.header") ]
147             );
148          };
149          
150          var templateUrl = YAHOO.lang.substitute(Alfresco.constants.URL_SERVICECONTEXT + "components/form?itemKind={itemKind}&itemId={itemId}&destination={destination}&mode={mode}&submitType={submitType}&showCancelButton=true",
151          {
152             itemKind: "type",
153             itemId: itemType,
154             destination: destination,
155             mode: "create",
156             submitType: "json"
157          });
158 
159          // Using Forms Service, so always create new instance
160          var createRow = new Alfresco.module.SimpleDialog(this.id + "-createRow");
161 
162          createRow.setOptions(
163          {
164             width: "33em",
165             templateUrl: templateUrl,
166             actionUrl: null,
167             destroyOnHide: true,
168             doBeforeDialogShow:
169             {
170                fn: doBeforeDialogShow,
171                scope: this
172             },
173             onSuccess:
174             {
175                fn: function DataListToolbar_onNewRow_success(response)
176                {
177                   YAHOO.Bubbling.fire("dataItemCreated",
178                   {
179                      nodeRef: response.json.persistedObject
180                   });
181 
182                   Alfresco.util.PopupManager.displayMessage(
183                   {
184                      text: this.msg("message.new-row.success")
185                   });
186                },
187                scope: this
188             },
189             onFailure:
190             {
191                fn: function DataListToolbar_onNewRow_failure(response)
192                {
193                   Alfresco.util.PopupManager.displayMessage(
194                   {
195                      text: this.msg("message.new-row.failure")
196                   });
197                },
198                scope: this
199             }
200          }).show();
201       },
202 
203       /**
204        * Selected Items button click handler
205        *
206        * @method onSelectedItems
207        * @param sType {string} Event type, e.g. "click"
208        * @param aArgs {array} Arguments array, [0] = DomEvent, [1] = EventTarget
209        * @param p_obj {object} Object passed back from subscribe method
210        */
211       onSelectedItems: function DataListToolbar_onSelectedItems(sType, aArgs, p_obj)
212       {
213          var domEvent = aArgs[0],
214             eventTarget = aArgs[1];
215 
216          // Check mandatory docList module is present
217          if (this.modules.dataGrid)
218          {
219             // Get the function related to the clicked item
220             var fn = Alfresco.util.findEventClass(eventTarget);
221             if (fn && (typeof this[fn] == "function"))
222             {
223                this[fn].call(this, this.modules.dataGrid.getSelectedItems());
224             }
225          }
226 
227          Event.preventDefault(domEvent);
228       },
229 
230       /**
231        * Deselect currectly selected assets.
232        *
233        * @method onActionDeselectAll
234        */
235       onActionDeselectAll: function DataListToolbar_onActionDeselectAll()
236       {
237          this.modules.dataGrid.selectItems("selectNone");
238       },
239 
240       /**
241        * User Access event handler
242        *
243        * @method onUserAccess
244        * @param layer {object} Event fired
245        * @param args {array} Event parameters (depends on event type)
246        */
247       onUserAccess: function DataListToolbar_onUserAccess(layer, args)
248       {
249          var obj = args[1];
250          if (obj && obj.userAccess)
251          {
252             var widget, widgetPermissions, index, orPermissions, orMatch;
253             for (index in this.widgets)
254             {
255                if (this.widgets.hasOwnProperty(index))
256                {
257                   widget = this.widgets[index];
258                   // Skip if this action specifies "no-access-check"
259                   if (widget.get("srcelement").className != "no-access-check")
260                   {
261                      // Default to disabled: must be enabled via permission
262                      widget.set("disabled", false);
263                      if (typeof widget.get("value") == "string")
264                      {
265                         // Comma-separation indicates "AND"
266                         widgetPermissions = widget.get("value").split(",");
267                         for (var i = 0, ii = widgetPermissions.length; i < ii; i++)
268                         {
269                            // Pipe-separation is a special case and indicates an "OR" match. The matched permission is stored in "activePermission" on the widget.
270                            if (widgetPermissions[i].indexOf("|") !== -1)
271                            {
272                               orMatch = false;
273                               orPermissions = widgetPermissions[i].split("|");
274                               for (var j = 0, jj = orPermissions.length; j < jj; j++)
275                               {
276                                  if (obj.userAccess[orPermissions[j]])
277                                  {
278                                     orMatch = true;
279                                     widget.set("activePermission", orPermissions[j], true);
280                                     break;
281                                  }
282                               }
283                               if (!orMatch)
284                               {
285                                  widget.set("disabled", true);
286                                  break;
287                               }
288                            }
289                            else if (!obj.userAccess[widgetPermissions[i]])
290                            {
291                               widget.set("disabled", true);
292                               break;
293                            }
294                         }
295                      }
296                   }
297                }
298             }
299          }
300       },
301 
302       /**
303        * Selected Items Changed event handler.
304        * Determines whether to enable or disable the multi-item action drop-down
305        *
306        * @method onSelectedItemsChanged
307        * @param layer {object} Event fired
308        * @param args {array} Event parameters (depends on event type)
309        */
310       onSelectedItemsChanged: function DataListToolbar_onSelectedItemsChanged(layer, args)
311       {
312          if (this.modules.dataGrid)
313          {
314             var items = this.modules.dataGrid.getSelectedItems(), item,
315                userAccess = {}, itemAccess, index,
316                menuItems = this.widgets.selectedItems.getMenu().getItems(), menuItem,
317                actionPermissions, disabled,
318                i, ii;
319             
320             // Check each item for user permissions
321             for (i = 0, ii = items.length; i < ii; i++)
322             {
323                item = items[i];
324                
325                // Required user access level - logical AND of each item's permissions
326                itemAccess = item.permissions.userAccess;
327                for (index in itemAccess)
328                {
329                   if (itemAccess.hasOwnProperty(index))
330                   {
331                      userAccess[index] = (userAccess[index] === undefined ? itemAccess[index] : userAccess[index] && itemAccess[index]);
332                   }
333                }
334             }
335 
336             // Now go through the menu items, setting the disabled flag appropriately
337             for (index in menuItems)
338             {
339                if (menuItems.hasOwnProperty(index))
340                {
341                   // Defaulting to enabled
342                   menuItem = menuItems[index];
343                   disabled = false;
344 
345                   if (menuItem.element.firstChild)
346                   {
347                      // Check permissions required - stored in "rel" attribute in the DOM
348                      if (menuItem.element.firstChild.rel && menuItem.element.firstChild.rel !== "")
349                      {
350                         // Comma-separated indicates and "AND" match
351                         actionPermissions = menuItem.element.firstChild.rel.split(",");
352                         for (i = 0, ii = actionPermissions.length; i < ii; i++)
353                         {
354                            // Disable if the user doesn't have ALL the permissions
355                            if (!userAccess[actionPermissions[i]])
356                            {
357                               disabled = true;
358                               break;
359                            }
360                         }
361                      }
362 
363                      menuItem.cfg.setProperty("disabled", disabled);
364                   }
365                }
366             }
367             this.widgets.selectedItems.set("disabled", (items.length === 0));
368          }
369       }
370    }, true);
371 })();