← Back to team overview

dhis2-devs team mailing list archive

Re: [Branch ~dhis2-devs-core/dhis2/trunk] Rev 10189: (PT) Sharing implemented.

 

+ Sharing for GIS

On Wed, Mar 13, 2013 at 8:56 PM, <noreply@xxxxxxxxxxxxx> wrote:

> Merge authors:
>   Jan Henrik Øverland (janhenrik-overland)
> ------------------------------------------------------------
> revno: 10189 [merge]
> committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
> branch nick: dhis2
> timestamp: Wed 2013-03-13 20:55:13 +0100
> message:
>   (PT) Sharing implemented.
> added:
>
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png
> modified:
>
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js
>
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js
>
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css
>
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm
>
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
>
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css
>
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm
>
>
> --
> lp:dhis2
> https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
>
> Your team DHIS 2 developers is subscribed to branch lp:dhis2.
> To unsubscribe from this branch go to
> https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
>
> === added file
> 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png'
> Binary files
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png
>   1970-01-01 00:00:00 +0000 and
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png
>  2013-03-13 19:09:29 +0000 differ
> === modified file
> 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js'
> ---
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js
>        2013-03-11 15:11:59 +0000
> +++
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js
>        2013-03-13 19:53:02 +0000
> @@ -18,6 +18,7 @@
>         // Init
>
>         var gis = GIS.core.getInstance();
> +       GIS.app.instances = [gis];
>
>         GIS.app.getInits = function(r) {
>                 var init = Ext.decode(r.responseText);
> @@ -266,6 +267,30 @@
>                         window.setPosition(4,35);
>                 };
>
> +               util.gui.window.addHideOnBlurHandler = function(w) {
> +                       var el = Ext.get(Ext.query('.x-mask')[0]);
> +
> +                       el.on('click', function() {
> +                               if (w.hideOnBlur) {
> +                                       w.hide();
> +                               }
> +                       });
> +
> +                       w.hasHideOnBlurHandler = true;
> +               };
> +
> +               util.gui.window.addDestroyOnBlurHandler = function(w) {
> +                       var el = Ext.get(Ext.query('.x-mask')[0]);
> +
> +                       el.on('click', function() {
> +                               if (w.destroyOnBlur) {
> +                                       w.destroy();
> +                               }
> +                       });
> +
> +                       w.hasDestroyOnBlurHandler = true;
> +               };
> +
>                 return util;
>         };
>
> @@ -762,7 +787,7 @@
>                                                 else {
>
> layer.filterWindow.destroy();
>                                                 }
> -                                       }
> +                                       }organisationUnitLe
>
>                                         layer.filterWindow = layer.id ===
> gis.layer.facility.id ?
>
> GIS.app.FilterWindowFacility(layer) : GIS.app.FilterWindow(layer);
> @@ -1450,6 +1475,256 @@
>                 return window;
>         };
>
> +       GIS.app.SharingWindow = function(sharing) {
> +
> +               // Objects
> +               var UserGroupRow,
> +
> +               // Functions
> +                       getBody,
> +
> +               // Components
> +                       userGroupStore,
> +                       userGroupField,
> +                       userGroupButton,
> +                       userGroupRowContainer,
> +                       publicGroup,
> +                       window;
> +
> +               UserGroupRow = function(obj, isPublicAccess,
> disallowPublicAccess) {
> +                       var getData,
> +                               store,
> +                               getItems,
> +                               combo,
> +                               getAccess,
> +                               panel;
> +
> +                       getData = function() {
> +                               var data = [
> +                                       {id: 'r-------', name: 'Can
> view'}, //i18n
> +                                       {id: 'rw------', name: 'Can edit
> and view'}
> +                               ];
> +
> +                               if (isPublicAccess) {
> +                                       data.unshift({id: '-------', name:
> 'None'});
> +                               }
> +
> +                               return data;
> +                       }
> +
> +                       store = Ext.create('Ext.data.Store', {
> +                               fields: ['id', 'name'],
> +                               data: getData()
> +                       });
> +
> +                       getItems = function() {
> +                               var items = [];
> +
> +                               combo =
> Ext.create('Ext.form.field.ComboBox', {
> +                                       fieldLabel: isPublicAccess ?
> 'Public access' : obj.name, //i18n
> +                                       labelStyle: 'color:#333',
> +                                       cls: 'gis-combo',
> +                                       width: 380,
> +                                       labelWidth: 250,
> +                                       queryMode: 'local',
> +                                       valueField: 'id',
> +                                       displayField: 'name',
> +                                       labelSeparator: null,
> +                                       editable: false,
> +                                       disabled: !!disallowPublicAccess,
> +                                       value: obj.access,
> +                                       store: store
> +                               });
> +
> +                               items.push(combo);
> +
> +                               if (!isPublicAccess) {
> +                                       items.push(Ext.create('Ext.Img', {
> +                                               src:
> 'images/grid-delete_16.png',
> +                                               style: 'margin-top:2px;
> margin-left:7px',
> +                                               overCls: 'pointer',
> +                                               width: 16,
> +                                               height: 16,
> +                                               listeners: {
> +                                                       render:
> function(i) {
> +
> i.getEl().on('click', function(e) {
> +
> i.up('panel').destroy();
> +
> window.doLayout();
> +                                                               });
> +                                                       }
> +                                               }
> +                                       }));
> +                               }
> +
> +                               return items;
> +                       };
> +
> +                       getAccess = function() {
> +                               return {
> +                                       id: obj.id,
> +                                       name: obj.name,
> +                                       access: combo.getValue()
> +                               };
> +                       };
> +
> +                       panel = Ext.create('Ext.panel.Panel', {
> +                               layout: 'column',
> +                               bodyStyle: 'border:0 none',
> +                               getAccess: getAccess,
> +                               items: getItems()
> +                       });
> +
> +                       return panel;
> +               };
> +
> +               getBody = function() {
> +                       var body = {
> +                               object: {
> +                                       id: sharing.object.id,
> +                                       name: sharing.object.name,
> +                                       publicAccess:
> publicGroup.down('combobox').getValue(),
> +                                       user: {
> +                                               id: gis.init.user.id,
> +                                               name: gis.init.user.name
> +                                       }
> +                               }
> +                       };
> +
> +                       if (userGroupRowContainer.items.items.length > 1) {
> +                               body.object.userGroupAccesses = [];
> +                               for (var i = 1, item; i <
> userGroupRowContainer.items.items.length; i++) {
> +                                       item =
> userGroupRowContainer.items.items[i];
> +
> body.object.userGroupAccesses.push(item.getAccess());
> +                               }
> +                       }
> +
> +                       return body;
> +               };
> +
> +               // Initialize
> +               userGroupStore = Ext.create('Ext.data.Store', {
> +                       fields: ['id', 'name'],
> +                       proxy: {
> +                               type: 'ajax',
> +                               url: gis.baseUrl + gis.conf.url.path_api +
> 'sharing/search',
> +                               reader: {
> +                                       type: 'json',
> +                                       root: 'userGroups'
> +                               }
> +                       }
> +               });
> +
> +               userGroupField = Ext.create('Ext.form.field.ComboBox', {
> +                       valueField: 'id',
> +                       displayField: 'name',
> +                       emptyText: 'Search for user groups', //i18n
> +                       queryParam: 'key',
> +                       queryDelay: 200,
> +                       minChars: 1,
> +                       hideTrigger: true,
> +                       fieldStyle: 'height:26px; padding-left:6px;
> border-radius:1px; font-size:11px',
> +                       style: 'margin-bottom:5px',
> +                       width: 380,
> +                       store: userGroupStore,
> +                       listeners: {
> +                               beforeselect: function(cb) { //
> beforeselect instead of select, fires regardless of currently selected item
> +                                       userGroupButton.enable();
> +                               },
> +                               afterrender: function(cb) {
> +                                       cb.inputEl.on('keyup', function() {
> +                                               userGroupButton.disable();
> +                                       });
> +                               }
> +                       }
> +               });
> +
> +               userGroupButton = Ext.create('Ext.button.Button', {
> +                       text: '+',
> +                       style: 'margin-left:2px; padding-right:4px;
> padding-left:4px; border-radius:1px',
> +                       disabled: true,
> +                       height: 26,
> +                       handler: function(b) {
> +                               userGroupRowContainer.add(UserGroupRow({
> +                                       id: userGroupField.getValue(),
> +                                       name: userGroupField.getRawValue(),
> +                                       access: 'r-------'
> +                               }));
> +
> +                               userGroupField.clearValue();
> +                               b.disable();
> +                       }
> +               });
> +
> +               userGroupRowContainer =
> Ext.create('Ext.container.Container', {
> +                       bodyStyle: 'border:0 none'
> +               });
> +
> +               publicGroup = userGroupRowContainer.add(UserGroupRow({
> +                       id: sharing.object.id,
> +                       name: sharing.object.name,
> +                       access: sharing.object.publicAccess
> +               }, true, !sharing.meta.allowPublicAccess));
> +
> +               if (Ext.isArray(sharing.object.userGroupAccesses)) {
> +                       for (var i = 0, userGroupRow; i <
> sharing.object.userGroupAccesses.length; i++) {
> +                               userGroupRow =
> UserGroupRow(sharing.object.userGroupAccesses[i]);
> +                               userGroupRowContainer.add(userGroupRow);
> +                       }
> +               }
> +
> +               window = Ext.create('Ext.window.Window', {
> +                       title: 'Sharing settings',
> +                       bodyStyle: 'padding:8px 8px 3px;
> background-color:#fff',
> +                       width: 434,
> +                       resizable: false,
> +                       modal: true,
> +                       destroyOnBlur: true,
> +                       items: [
> +                               {
> +                                       html: sharing.object.name,
> +                                       bodyStyle: 'border:0 none;
> font-weight:bold; color:#333',
> +                                       style: 'margin-bottom:8px'
> +                               },
> +                               {
> +                                       xtype: 'container',
> +                                       layout: 'column',
> +                                       bodyStyle: 'border:0 none',
> +                                       items: [
> +                                               userGroupField,
> +                                               userGroupButton
> +                                       ]
> +                               },
> +                               userGroupRowContainer
> +                       ],
> +                       bbar: [
> +                               '->',
> +                               {
> +                                       text: 'Save',
> +                                       handler: function() {
> +                                               Ext.Ajax.request({
> +                                                       url: gis.baseUrl +
> gis.conf.url.path_api + 'sharing?type=map&id=' + sharing.object.id,
> +                                                       method: 'POST',
> +                                                       headers: {
> +
> 'Content-Type': 'application/json'
> +                                                       },
> +                                                       params:
> Ext.encode(getBody())
> +                                               });
> +
> +                                               window.destroy();
> +                                       }
> +                               }
> +                       ],
> +                       listeners: {
> +                               show: function(w) {
> +                                       var pos =
> gis.viewport.mapWindow.getPosition();
> +                                       w.setPosition(pos[0] + 5, pos[1] +
> 5);
> +                               }
> +                       }
> +               });
> +
> +               return window;
> +       };
> +
>      GIS.app.MapControlPanel = function(name, fn) {
>                 var button,
>                         panel;
> @@ -1487,17 +1762,31 @@
>                         tbar,
>                         bbar,
>                         info,
> -
>                         nameTextfield,
> -                       systemCheckbox,
>                         createButton,
>                         updateButton,
>                         cancelButton,
> +                       mapWindow,
>
> -                       mapWindow;
> +               // Vars
> +                       windowWidth = 500,
> +                       windowCmpWidth = windowWidth - 22;
>
>                 gis.store.maps.on('load', function(store, records) {
> -                       info.setText(records.length + ' favorite' +
> (records.length !== 1 ? 's' : '') + ' available');
> +                       var pager = store.proxy.reader.jsonData.pager;
> +
> +                       info.setText('Page ' + pager.page + ' of ' +
> pager.pageCount);
> +
> +                       prevButton.enable();
> +                       nextButton.enable();
> +
> +                       if (pager.page === 1) {
> +                               prevButton.disable();
> +                       }
> +
> +                       if (pager.page === pager.pageCount) {
> +                               nextButton.disable();
> +                       }
>                 });
>
>                 NameWindow = function(id) {
> @@ -1506,10 +1795,10 @@
>
>                         nameTextfield = Ext.create('Ext.form.field.Text', {
>                                 height: 26,
> -                               width: 300,
> -                               labelWidth: 70,
> -                               fieldStyle: 'padding-left: 6px;
> border-radius: 1px; border-color: #bbb',
> -                               fieldLabel: 'Name', //i18n
> +                               width: 250,
> +                               fieldStyle: 'padding-left: 6px;
> border-radius: 1px; border-color: #bbb; font-size:11px',
> +                               style: 'margin-bottom:0',
> +                               emptyText: 'Favorite name',
>                                 value: id ? record.data.name : '',
>                                 listeners: {
>                                         afterrender: function() {
> @@ -1518,14 +1807,6 @@
>                                 }
>                         });
>
> -                       systemCheckbox =
> Ext.create('Ext.form.field.Checkbox', {
> -                               labelWidth: 70,
> -                               fieldLabel: 'System', //i18n
> -                               style: 'margin-bottom: 0',
> -                               disabled: !gis.init.security.isAdmin,
> -                               checked: !id ? false : (record.data.user ?
> false : true)
> -                       });
> -
>                         createButton = Ext.create('Ext.button.Button', {
>                                 text: 'Create', //i18n
>                                 handler: function() {
> @@ -1557,15 +1838,12 @@
>                                                                 longitude:
> lonlat.lon,
>                                                                 latitude:
> lonlat.lat,
>                                                                 zoom:
> gis.olmap.getZoom(),
> -                                                               mapViews:
> views
> +                                                               mapViews:
> views,
> +                                                               user: {
> +
> id: 'currentUser'
> +                                                               }
>                                                         };
>
> -                                                       if (!system) {
> -                                                               map.user =
> {
> -
> id: 'currentUser'
> -                                                               };
> -                                                       }
> -
>                                                         Ext.Ajax.request({
>                                                                 url:
> gis.baseUrl + gis.conf.url.path_api + 'maps/',
>                                                                 method:
> 'POST',
> @@ -1595,11 +1873,10 @@
>                         updateButton = Ext.create('Ext.button.Button', {
>                                 text: 'Update', //i18n
>                                 handler: function() {
> -                                       var name =
> nameTextfield.getValue(),
> -                                               system =
> systemCheckbox.getValue();
> +                                       var name =
> nameTextfield.getValue();
>
>                                         Ext.Ajax.request({
> -                                               url: gis.baseUrl +
> gis.conf.url.path_gis + 'renameMap.action?id=' + id + '&name=' + name +
> '&user=' + !system,
> +                                               url: gis.baseUrl +
> gis.conf.url.path_gis + 'renameMap.action?id=' + id + '&name=' + name +
> '&user=true',
>                                                 success: function() {
>
> gis.store.maps.loadStore();
>
> @@ -1622,10 +1899,7 @@
>                                 cls: 'gis-container-default',
>                                 resizable: false,
>                                 modal: true,
> -                               items: [
> -                                       nameTextfield,
> -                                       systemCheckbox
> -                               ],
> +                               items: nameTextfield,
>                                 bbar: [
>                                         cancelButton,
>                                         '->',
> @@ -1654,9 +1928,9 @@
>                 });
>
>                 searchTextfield = Ext.create('Ext.form.field.Text', {
> -                       width: 340,
> +                       width: windowCmpWidth - addButton.width - 11,
>                         height: 26,
> -                       fieldStyle: 'padding-right: 0; padding-left: 6px;
> border-radius: 1px; border-color: #bbb',
> +                       fieldStyle: 'padding-right: 0; padding-left: 6px;
> border-radius: 1px; border-color: #bbb; font-size:11px',
>                         emptyText: 'Search for favorites', //i18n
>                         enableKeyEvents: true,
>                         currentValue: '',
> @@ -1714,7 +1988,7 @@
>                                 {
>                                         dataIndex: 'name',
>                                         sortable: false,
> -                                       width: 340,
> +                                       width: windowCmpWidth - 108,
>                                         renderer: function(value,
> metaData, record) {
>                                                 var fn = function() {
>                                                         var el = Ext.get(
> record.data.id);
> @@ -1735,25 +2009,20 @@
>                                 {
>                                         xtype: 'actioncolumn',
>                                         sortable: false,
> -                                       width: 80,
> +                                       width: 100,
>                                         items: [
>                                                 {
>                                                         iconCls:
> 'gis-grid-row-icon-edit',
>                                                         getClass:
> function(value, metaData, record) {
> -                                                               var system
> = !record.data.user,
> -
> isAdmin = gis.init.security.isAdmin;
> -
> -                                                               if
> (isAdmin || (!isAdmin && !system)) {
> +                                                               if
> (gis.init.user.isAdmin) {
>
> return 'tooltip-map-edit';
>                                                                 }
>                                                         },
>                                                         handler:
> function(grid, rowIndex, colIndex, col, event) {
>                                                                 var record
> = this.up('grid').store.getAt(rowIndex),
> -                                                                       id
> = record.data.id,
> -
> system = !record.data.user,
> -
> isAdmin = gis.init.security.isAdmin;
> +                                                                       id
> = record.data.id;
>
> -                                                               if
> (isAdmin || (!isAdmin && !system)) {
> +                                                               if
> (gis.init.user.isAdmin) {
>
> var id = this.up('grid').store.getAt(rowIndex).data.id;
>
> nameWindow = new NameWindow(id);
>
> nameWindow.show();
> @@ -1763,10 +2032,7 @@
>                                                 {
>                                                         iconCls:
> 'gis-grid-row-icon-overwrite',
>                                                         getClass:
> function(value, metaData, record) {
> -                                                               var system
> = !record.data.user,
> -
> isAdmin = gis.init.security.isAdmin;
> -
> -                                                               if
> (isAdmin || (!isAdmin && !system)) {
> +                                                               if
> (gis.init.user.isAdmin) {
>
> return 'tooltip-map-overwrite';
>                                                                 }
>                                                         },
> @@ -1824,6 +2090,30 @@
>                                                         }
>                                                 },
>                                                 {
> +                                                       iconCls:
> 'gis-grid-row-icon-sharing',
> +                                                       getClass:
> function() {
> +                                                               return
> 'tooltip-map-sharing';
> +                                                       },
> +                                                       handler:
> function(grid, rowIndex) {
> +                                                               var record
> = this.up('grid').store.getAt(rowIndex),
> +                                                                       id
> = record.data.id,
> +
> window;
> +
> +
> Ext.Ajax.request({
> +
> url: gis.baseUrl + gis.conf.url.path_api + 'sharing?type=map&id=' + id,
> +
> method: 'GET',
> +
> failure: function(r) {
> +
>       alert(r.responseText);
> +                                                                       },
> +
> success: function(r) {
> +
>       var sharing = Ext.decode(r.responseText);
> +
>       window = GIS.app.SharingWindow(sharing);
> +
>       window.show();
> +                                                                       }
> +                                                               });
> +                                                       }
> +                                               },
> +                                               {
>                                                         iconCls:
> 'gis-grid-row-icon-dashboard',
>                                                         getClass:
> function() {
>                                                                 return
> 'tooltip-map-dashboard';
> @@ -1847,10 +2137,7 @@
>                                                 {
>                                                         iconCls:
> 'gis-grid-row-icon-delete',
>                                                         getClass:
> function(value, metaData, record) {
> -                                                               var system
> = !record.data.user,
> -
> isAdmin = gis.init.security.isAdmin;
> -
> -                                                               if
> (isAdmin || (!isAdmin && !system)) {
> +                                                               if
> (gis.init.user.isAdmin) {
>
> return 'tooltip-map-delete';
>                                                                 }
>                                                         },
> @@ -1873,7 +2160,7 @@
>                                                 }
>                                         ],
>                                         renderer: function(value,
> metaData, record) {
> -                                               if
> (!gis.init.security.isAdmin && !record.data.user) {
> +                                               if (!gis.init.user.isAdmin
> && !record.data.user) {
>                                                         metaData.tdCls =
> 'gis-grid-row-icon-disabled';
>                                                 }
>                                         }
> @@ -1908,35 +2195,40 @@
>                                 },
>                                 afterrender: function() {
>                                         var fn = function() {
> -                                               var editArray =
> document.getElementsByClassName('tooltip-map-edit'),
> -                                                       overwriteArray =
> document.getElementsByClassName('tooltip-map-overwrite'),
> -                                                       dashboardArray =
> document.getElementsByClassName('tooltip-map-dashboard'),
> -                                                       deleteArray =
> document.getElementsByClassName('tooltip-map-delete'),
> +                                               var editArray =
> Ext.query('.tooltip-map-edit'),
> +                                                       overwriteArray =
> Ext.query('.tooltip-map-overwrite'),
> +                                                       sharingArray =
> Ext.query('.tooltip-map-sharing'),
> +                                                       dashboardArray =
> Ext.query('.tooltip-map-dashboard'),
> +                                                       deleteArray =
> Ext.query('.tooltip-map-delete'),
>                                                         el;
>
> -                                               for (var i = 0; i <
> deleteArray.length; i++) {
> -                                                       el = editArray[i];
> +                                               for (var i = 0; i <
> editArray.length; i++) {
> +                                                       var el =
> editArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Rename',
> +                                                               html:
> 'Rename', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
>                                                         });
> +                                               }
>
> +                                               for (var i = 0; i <
> overwriteArray.length; i++) {
>                                                         el =
> overwriteArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Overwrite',
> +                                                               html:
> 'Overwrite', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
>                                                         });
> +                                               }
>
> -                                                       el =
> deleteArray[i];
> +                                               for (var i = 0; i <
> sharingArray.length; i++) {
> +                                                       el =
> sharingArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Delete',
> +                                                               html:
> 'Share with other people', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
> @@ -1947,7 +2239,18 @@
>                                                         el =
> dashboardArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html: 'Add
> to dashboard',
> +                                                               html: 'Add
> to dashboard', //i18n
> +                                                               'anchor':
> 'bottom',
> +
> anchorOffset: -14,
> +                                                               showDelay:
> 1000
> +                                                       });
> +                                               }
> +
> +                                               for (var i = 0; i <
> deleteArray.length; i++) {
> +                                                       el =
> deleteArray[i];
> +
> Ext.create('Ext.tip.ToolTip', {
> +                                                               target: el,
> +                                                               html:
> 'Delete', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
> @@ -1977,19 +2280,18 @@
>                         bodyStyle: 'padding:5px',
>                         resizable: false,
>                         modal: true,
> -                       width: 450,
> +                       width: windowWidth,
>                         items: [
>                                 {
>                                         xtype: 'panel',
>                                         layout: 'hbox',
> -                                       width: 422,
>                                         cls: 'gis-container-inner',
>                                         items: [
>                                                 addButton,
>                                                 {
>                                                         height: 24,
>                                                         width: 1,
> -                                                       style: 'width:
> 1px; margin-left: 7px; margin-right: 7px; margin-top: 1px',
> +                                                       style: 'width:1px;
> margin-left:5px; margin-right:5px; margin-top:1px',
>                                                         bodyStyle:
> 'border-left: 1px solid #aaa'
>                                                 },
>                                                 searchTextfield
> @@ -4472,7 +4774,7 @@
>
> viewport.mapWindow.show();
>                                                         }
>                                                 });
> -                                               if
> (gis.init.security.isAdmin) {
> +                                               if (gis.init.user.isAdmin)
> {
>                                                         a.push({
>                                                                 text:
> 'Legend', //i18n
>                                                                 menu: {},
> @@ -4692,6 +4994,8 @@
>
>                 initialize = function() {
>                         gis.init = GIS.app.getInits(r);
> +                       gis.baseUrl = gis.init.contextPath;
> +
>                         gis.util = GIS.app.getUtils();
>                         gis.store = GIS.app.getStores();
>
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js'
> ---
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js
>       2013-02-05 23:26:21 +0000
> +++
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js
>       2013-03-13 19:09:29 +0000
> @@ -51,9 +51,8 @@
>                         }
>                 },
>                 url: {
> -                       base: '../../',
> -                       path_api: 'api/',
> -                       path_gis: 'dhis-web-mapping/'
> +                       path_api: '/api/',
> +                       path_gis: '/dhis-web-mapping/'
>                 },
>                 layout: {
>                         widget: {
> @@ -347,7 +346,7 @@
>  };
>
>  GIS.core.createSelectHandlers = function(gis, layer) {
> -       var isRelocate = !!GIS.app ? (gis.init.security.isAdmin ? true :
> false) : false,
> +       var isRelocate = !!GIS.app ? (gis.init.user.isAdmin ? true :
> false) : false,
>                 isInfo = !!GIS.app,
>
>                 window,
> @@ -715,7 +714,7 @@
>                         menuItems.push( Ext.create('Ext.menu.Item', {
>                                 text: GIS.i18n.relocate,
>                                 iconCls: 'gis-menu-item-icon-relocate',
> -                               disabled: !gis.init.security.isAdmin,
> +                               disabled: !gis.init.user.isAdmin,
>                                 handler: function(item) {
>                                         gis.olmap.relocate.active = true;
>                                         gis.olmap.relocate.feature =
> feature;
> @@ -1732,7 +1731,7 @@
>  GIS.core.getInstance = function(config) {
>         var gis = {};
>
> -       gis.baseUrl = config && config.baseUrl ? config.baseUrl : '../../';
> +       gis.baseUrl = config && config.baseUrl ? config.baseUrl : '../..';
>         gis.el = config && config.el ? config.el : null;
>
>         gis.conf = GIS.core.getConfigs();
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css'
> ---
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css
>      2013-03-08 11:00:41 +0000
> +++
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css
>      2013-03-13 19:53:02 +0000
> @@ -139,6 +139,46 @@
>
>  /* GIS */
>
>
> +/*----------------------------------------------------------------------------
> + * Combobox
> +
> *--------------------------------------------------------------------------*/
> +
> +       /* Combobox text position*/
> +.x-webkit .x-form-empty-field {
> +    line-height: 14px;
> +}
> +
> +       /* Combobox font size */
> +.x-form-text, textarea.x-form-field {
> +    font-size: 10px;
> +}
> +
> +       /* Combobox field label font */
> +.x-form-item-label {
> +    font-size: 11px;
> +    color: #111;
> +}
> +
> +
>
> +/*----------------------------------------------------------------------------
> + * GIS Combobox
> +
> *--------------------------------------------------------------------------*/
> +
> +       /* Combobox text position*/
> +.gis-combo .x-form-text {
> +    padding-left: 5px;
> +}
> +.gis-combo .small .x-form-field {
> +       padding-top: 2px;
> +}
> +
> +       /* Combobox border-radius */
> +.gis-combo input {
> +    border-radius: 2px 0px 0px 0px;
> +    font-size: 10px !important;
> +}
> +
> +
>  /* Panel */
>
>  .x-panel-header        { /* Panel header */
> @@ -146,6 +186,7 @@
>         padding: 7px 4px 4px 7px;
>  }
>
> +
>  /* Form */
>
>  .gis-form-subtitle,
> @@ -431,6 +472,7 @@
>
>  .gis-grid-row-icon-edit,
>  .gis-grid-row-icon-overwrite,
> +.gis-grid-row-icon-sharing,
>  .gis-grid-row-icon-dashboard,
>  .gis-grid-row-icon-delete {
>         width: 16px;
> @@ -444,6 +486,10 @@
>         background: url('../images/grid-save_16.png') no-repeat;
>         margin-left: 4px;
>  }
> +.gis-grid-row-icon-sharing {
> +       background: url('../images/grid-sharing_16.png') no-repeat;
> +       margin-left: 4px;
> +}
>  .gis-grid-row-icon-dashboard {
>         background: url('../images/grid-dashboard_16.png') no-repeat;
>         margin-left: 4px;
> @@ -461,6 +507,7 @@
>  .gis-grid-row-icon-disabled * {
>         cursor: default !important;
>  }
> +.gis-grid-row-icon-disabled img.gis-grid-row-icon-sharing,
>  .gis-grid-row-icon-disabled img.gis-grid-row-icon-dashboard {
>         cursor: pointer !important;
>  }
> @@ -544,8 +591,6 @@
>  }
>
>  /* Tooltip */
> -
> -/* Tooltip */
>  .x-tip {
>      border-radius: 2px;
>      padding: 1px 4px;
> @@ -556,6 +601,7 @@
>  .x-tip .x-tip-body {
>         font-size: 10px;
>         color: #fff;
> +       -webkit-text-stroke: 0.2px #fff;
>  }
>
>  .x-tip-anchor {
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm'
> ---
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm
> 2012-12-14 16:56:33 +0000
> +++
> dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm
> 2013-03-13 19:09:29 +0000
> @@ -25,7 +25,9 @@
>      }#if( $velocityCount < $overlaysSize ),#end
>  #end
>    ],
> -  "security": {
> +  "user": {
> +       "id":"$!currentUser.uid",
> +       "name":"$currentUser.name",
>      "isAdmin": $auth.hasAccess( "dhis-web-mapping", "deleteMapLegendSet" )
>    },
>    "rootNodes": [
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js'
> ---
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
>    2013-03-13 16:19:28 +0000
> +++
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
>    2013-03-13 19:53:02 +0000
> @@ -108,14 +108,27 @@
>                                         w.setPosition(targetx, y);
>                                 }
>                         },
> -                       addBlurHandler: function(w) {
> -                               var el = Ext.get(Ext.query('.x-mask')[0]);
> -
> -                               el.on('click', function() {
> -                                       w.hide();
> -                               });
> -
> -                               w.hasBlurHandler = true;
> +                       addHideOnBlurHandler: function(w) {
> +                               var el = Ext.get(Ext.query('.x-mask')[0]);
> +
> +                               el.on('click', function() {
> +                                       if (w.hideOnBlur) {
> +                                               w.hide();
> +                                       }
> +                               });
> +
> +                               w.hasHideOnBlurHandler = true;
> +                       },
> +                       addDestroyOnBlurHandler: function(w) {
> +                               var el = Ext.get(Ext.query('.x-mask')[0]);
> +
> +                               el.on('click', function() {
> +                                       if (w.destroyOnBlur) {
> +                                               w.destroy();
> +                                       }
> +                               });
> +
> +                               w.hasDestroyOnBlurHandler = true;
>                         }
>                 };
>
> @@ -685,6 +698,7 @@
>                         rowStore: rowStore,
>                         colStore: colStore,
>                         filterStore: filterStore,
> +                       hideOnBlur: true,
>                         items: {
>                                 layout: 'column',
>                                 bodyStyle: 'border:0 none',
> @@ -717,13 +731,12 @@
>                                         }
>                                 }
>                         ],
> -                       hasBlurHandler: false,
>                         listeners: {
>                                 show: function(w) {
>
> pt.util.window.setAnchorPosition(w, pt.viewport.layoutButton);
>
> -                                       if (!w.hasBlurHandler) {
> -
> pt.util.window.addBlurHandler(w);
> +                                       if (!w.hasHideOnBlurHandler) {
> +
> pt.util.window.addHideOnBlurHandler(w);
>                                         }
>                                 }
>                         }
> @@ -841,6 +854,7 @@
>                         autoShow: true,
>                         modal: true,
>                         resizable: false,
> +                       hideOnBlur: true,
>                         getOptions: function() {
>                                 return {
>                                         showSubTotals:
> showSubTotals.getValue(),
> @@ -883,13 +897,12 @@
>                                         }
>                                 }
>                         ],
> -                       hasBlurHandler: false,
>                         listeners: {
>                                 show: function(w) {
>
> pt.util.window.setAnchorPosition(w, pt.viewport.optionsButton);
>
> -                                       if (!w.hasBlurHandler) {
> -
> pt.util.window.addBlurHandler(w);
> +                                       if (!w.hasHideOnBlurHandler) {
> +
> pt.util.window.addHideOnBlurHandler(w);
>                                         }
>                                 }
>                         }
> @@ -1057,10 +1070,10 @@
>
>                         nameTextfield = Ext.create('Ext.form.field.Text', {
>                                 height: 26,
> -                               width: 300,
> -                               labelWidth: 70,
> -                               fieldStyle: 'padding-left: 6px;
> border-radius: 1px; border-color: #bbb',
> -                               fieldLabel: 'Name', //i18n
> +                               width: 250,
> +                               fieldStyle: 'padding-left: 6px;
> border-radius: 1px; border-color: #bbb; font-size:11px',
> +                               style: 'margin-bottom:0',
> +                               emptyText: 'Favorite name',
>                                 value: id ? record.data.name : '',
>                                 listeners: {
>                                         afterrender: function() {
> @@ -1073,10 +1086,9 @@
>                                 text: 'Create', //i18n
>                                 handler: function() {
>                                         var favorite = getBody();
> -
>                                         favorite.name =
> nameTextfield.getValue();
>
> -                                       if (favorite) {
> +                                       if (favorite && favorite.name) {
>                                                 Ext.Ajax.request({
>                                                         url: pt.baseUrl +
> '/api/reportTables/',
>                                                         method: 'POST',
> @@ -1099,9 +1111,6 @@
>                                                         }
>                                                 });
>                                         }
> -                                       else {
> -                                               alert('Please create a
> table first');
> -                                       }
>                                 }
>                         });
>
> @@ -1153,12 +1162,11 @@
>                         window = Ext.create('Ext.window.Window', {
>                                 title: id ? 'Rename favorite' : 'Create
> new favorite',
>                                 //iconCls: 'pt-window-title-icon-favorite',
> -                               bodyStyle: 'padding:8px; background:#fff',
> +                               bodyStyle: 'padding:5px; background:#fff',
>                                 resizable: false,
>                                 modal: true,
> -                               items: [
> -                                       nameTextfield
> -                               ],
> +                               items: nameTextfield,
> +                               destroyOnBlur: true,
>                                 bbar: [
>                                         cancelButton,
>                                         '->',
> @@ -1166,7 +1174,16 @@
>                                 ],
>                                 listeners: {
>                                         show: function(w) {
> -
> pt.util.window.setAnchorPosition(w, pt.viewport.favoriteButton);
> +
> pt.util.window.setAnchorPosition(w, addButton);
> +
> +                                               if
> (!w.hasDestroyBlurHandler) {
> +
> pt.util.window.addDestroyOnBlurHandler(w);
> +                                               }
> +
> +
> pt.viewport.favoriteWindow.destroyOnBlur = false;
> +                                       },
> +                                       destroy: function() {
> +
> pt.viewport.favoriteWindow.destroyOnBlur = true;
>                                         }
>                                 }
>                         });
> @@ -1180,6 +1197,7 @@
>                         height: 26,
>                         style: 'border-radius: 1px;',
>                         menu: {},
> +                       disabled: !Ext.isObject(pt.xSettings),
>                         handler: function() {
>                                 nameWindow = new NameWindow(null,
> 'create');
>                                 nameWindow.show();
> @@ -1243,8 +1261,6 @@
>                         cls: 'pt-grid',
>                         scroll: false,
>                         hideHeaders: true,
> -                       bodyStyle: 'padding-bottom:1px solid red
> !important',
> -                       style: 'padding-bottom:1px solid red !important',
>                         columns: [
>                                 {
>                                         dataIndex: 'name',
> @@ -1339,8 +1355,6 @@
>                                                                 var record
> = this.up('grid').store.getAt(rowIndex),
>                                                                         id
> = record.data.id,
>
> window;
> -
> //name = record.data.name,
> -
> //message = 'Add to dashboard?\n\n' + name;
>
>
> Ext.Ajax.request({
>
> url: pt.baseUrl + '/api/sharing?type=reportTable&id=' + id,
> @@ -1350,7 +1364,7 @@
>
>       alert(r.responseText);
>                                                                         },
>
> success: function(r) {
> -
>       sharing = Ext.decode(r.responseText);
> +
>       var sharing = Ext.decode(r.responseText);
>
>       window = PT.app.SharingWindow(sharing);
>
>       window.show();
>                                                                         }
> @@ -1421,47 +1435,29 @@
>                                 },
>                                 afterrender: function() {
>                                         var fn = function() {
> -                                               var editArray =
> document.getElementsByClassName('tooltip-favorite-edit'),
> -                                                       overwriteArray =
> document.getElementsByClassName('tooltip-favorite-overwrite'),
> -                                                       dashboardArray =
> document.getElementsByClassName('tooltip-favorite-dashboard'),
> -                                                       sharingArray =
> document.getElementsByClassName('tooltip-favorite-sharing'),
> -                                                       deleteArray =
> document.getElementsByClassName('tooltip-favorite-delete'),
> +                                               var editArray =
> Ext.query('.tooltip-favorite-edit'),
> +                                                       overwriteArray =
> Ext.query('.tooltip-favorite-overwrite'),
> +                                                       //dashboardArray =
> Ext.query('.tooltip-favorite-dashboard'),
> +                                                       sharingArray =
> Ext.query('.tooltip-favorite-sharing'),
> +                                                       deleteArray =
> Ext.query('.tooltip-favorite-delete'),
>                                                         el;
>
> -                                               for (var i = 0; i <
> deleteArray.length; i++) {
> -                                                       el = editArray[i];
> +                                               for (var i = 0; i <
> editArray.length; i++) {
> +                                                       var el =
> editArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Rename',
> +                                                               html:
> 'Rename', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
>                                                         });
> +                                               }
>
> +                                               for (var i = 0; i <
> overwriteArray.length; i++) {
>                                                         el =
> overwriteArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Overwrite',
> -                                                               'anchor':
> 'bottom',
> -
> anchorOffset: -14,
> -                                                               showDelay:
> 1000
> -                                                       });
> -
> -                                                       el =
> deleteArray[i];
> -
> Ext.create('Ext.tip.ToolTip', {
> -                                                               target: el,
> -                                                               html:
> 'Delete',
> -                                                               'anchor':
> 'bottom',
> -
> anchorOffset: -14,
> -                                                               showDelay:
> 1000
> -                                                       });
> -                                               }
> -
> -                                               for (var i = 0; i <
> dashboardArray.length; i++) {
> -                                                       el =
> dashboardArray[i];
> -
> Ext.create('Ext.tip.ToolTip', {
> -                                                               target: el,
> -                                                               html: 'Add
> to dashboard',
> +                                                               html:
> 'Overwrite', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
> @@ -1472,7 +1468,18 @@
>                                                         el =
> sharingArray[i];
>
> Ext.create('Ext.tip.ToolTip', {
>                                                                 target: el,
> -                                                               html:
> 'Share with other people',
> +                                                               html:
> 'Share with other people', //i18n
> +                                                               'anchor':
> 'bottom',
> +
> anchorOffset: -14,
> +                                                               showDelay:
> 1000
> +                                                       });
> +                                               }
> +
> +                                               for (var i = 0; i <
> deleteArray.length; i++) {
> +                                                       el =
> deleteArray[i];
> +
> Ext.create('Ext.tip.ToolTip', {
> +                                                               target: el,
> +                                                               html:
> 'Delete', //i18n
>                                                                 'anchor':
> 'bottom',
>
> anchorOffset: -14,
>                                                                 showDelay:
> 1000
> @@ -1498,10 +1505,11 @@
>                 favoriteWindow = Ext.create('Ext.window.Window', {
>                         title: 'Manage favorites',
>                         //iconCls: 'pt-window-title-icon-favorite',
> -                       bodyStyle: 'padding: 5px; background-color:#fff',
> +                       bodyStyle: 'padding:5px; background-color:#fff',
>                         resizable: false,
>                         modal: true,
>                         width: windowWidth,
> +                       destroyOnBlur: true,
>                         items: [
>                                 {
>                                         xtype: 'panel',
> @@ -1512,7 +1520,7 @@
>                                                 {
>                                                         height: 24,
>                                                         width: 1,
> -                                                       style: 'width:
> 1px; margin-left: 5px; margin-right: 5px; margin-top: 1px',
> +                                                       style: 'width:1px;
> margin-left:5px; margin-right:5px; margin-top:1px',
>                                                         bodyStyle:
> 'border-left: 1px solid #aaa'
>                                                 },
>                                                 searchTextfield
> @@ -1524,8 +1532,8 @@
>                                 show: function(w) {
>
> pt.util.window.setAnchorPosition(w, pt.viewport.favoriteButton);
>
> -                                       if (!w.hasBlurHandler) {
> -
> pt.util.window.addBlurHandler(w);
> +                                       if (!w.hasDestroyOnBlurHandler) {
> +
> pt.util.window.addDestroyOnBlurHandler(w);
>                                         }
>                                 }
>                         }
> @@ -1737,6 +1745,7 @@
>                         width: 434,
>                         resizable: false,
>                         modal: true,
> +                       destroyOnBlur: true,
>                         items: [
>                                 {
>                                         html: sharing.object.name,
> @@ -1774,7 +1783,17 @@
>                         ],
>                         listeners: {
>                                 show: function(w) {
> -                                       w.setPosition(w.getPosition()[0],
> 33);
> +                                       var pos =
> pt.viewport.favoriteWindow.getPosition();
> +                                       w.setPosition(pos[0] + 5, pos[1] +
> 5);
> +
> +                                       if (!w.hasDestroyOnBlurHandler) {
> +
> pt.util.window.addDestroyOnBlurHandler(w);
> +                                       }
> +
> +
> pt.viewport.favoriteWindow.destroyOnBlur = false;
> +                               },
> +                               destroy: function() {
> +
> pt.viewport.favoriteWindow.destroyOnBlur = true;
>                                 }
>                         }
>                 });
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css'
> ---
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css
>  2013-03-13 11:59:50 +0000
> +++
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css
>  2013-03-13 19:09:29 +0000
> @@ -512,7 +512,7 @@
>  }
>
>  .x-tip-anchor {
> -       border-bottom-color: #111;
> +       border-top-color: #111;
>  }
>
>
> @@ -542,8 +542,8 @@
>
>  .pt-grid-row-icon-edit,
>  .pt-grid-row-icon-overwrite,
> +.pt-grid-row-icon-sharing,
>  .pt-grid-row-icon-dashboard,
> -.pt-grid-row-icon-sharing,
>  .pt-grid-row-icon-delete {
>         width: 16px;
>         height: 16px;
> @@ -556,14 +556,14 @@
>         background: url('../images/grid-save_16.png') no-repeat;
>         margin-left: 4px;
>  }
> +.pt-grid-row-icon-sharing {
> +       background: url('../images/grid-sharing_16.png') no-repeat;
> +       margin-left: 4px;
> +}
>  .pt-grid-row-icon-dashboard {
>         background: url('../images/grid-dashboard_16.png') no-repeat;
>         margin-left: 4px;
>  }
> -.pt-grid-row-icon-sharing {
> -       background: url('../images/grid-sharing_16.png') no-repeat;
> -       margin-left: 4px;
> -}
>  .pt-grid-row-icon-delete {
>         background: url('../images/grid-delete_16.png') no-repeat;
>         margin-left: 4px;
> @@ -577,8 +577,8 @@
>  .pt-grid-row-icon-disabled * {
>         cursor: default !important;
>  }
> -.pt-grid-row-icon-disabled img.pt-grid-row-icon-dashboard,
> -.pt-grid-row-icon-disabled img.pt-grid-row-icon-sharing {
> +.pt-grid-row-icon-disabled img.pt-grid-row-icon-sharing,
> +.pt-grid-row-icon-disabled img.pt-grid-row-icon-dashboard {
>         cursor: pointer !important;
>  }
>
>
> === modified file
> 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm'
> ---
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm
>     2013-03-13 12:34:10 +0000
> +++
> dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm
>     2013-03-13 19:09:29 +0000
> @@ -1,6 +1,6 @@
>  #set($oucSize =
> $currentUser.getOrganisationUnit().getSortedChildren().size()){
>  "contextPath":"$!{contextPath}",
> -"user":{"id":"$!currentUser.id","name":"$currentUser.name","isAdmin":true,
>
> +"user":{"id":"$!currentUser.uid","name":"$currentUser.name","isAdmin":true,
>
>  "ou":{"id":"$currentUser.getOrganisationUnit().uid","name":"$currentUser.getOrganisationUnit().name"},
>  "ouc":[#foreach($ou in
> $currentUser.getOrganisationUnit().getSortedChildren()){"id":"$ou.uid","name":"$
> ou.name"}#if($velocityCount < $oucSize),#end#end]},
>  "rootNodes":[#foreach($node in $rootNodes){"id": "$!{node.uid}","text":
> "$!encoder.jsonEncode( ${node.name} )","level":
> 1,"hasChildrenWithCoordinates":
> $!{node.hasChildrenWithCoordinates()},"expanded":
> true}#if($velocityCount<$rootNodes.size()),#end#end],
>
>
> ...
>
> [Message clipped]

References