← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 14691: Impl UI for selection of data capture org units and data analysis org units for add/edit user. Th...

 

------------------------------------------------------------
revno: 14691
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Sat 2014-04-05 22:08:37 +0200
message:
  Impl UI for selection of data capture org units and data analysis org units for add/edit user. This allows for setting data input/output org units separately for users.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/User.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/css/widgets.css
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/DefaultSelectionTreeManager.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/SelectionTreeManager.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/DefaultOrganisationUnitSelectionManager.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/OrganisationUnitSelectionManager.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/RestrictOrganisationUnitsAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/SetupTreeAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/addUserForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/updateUserForm.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
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/User.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/User.java	2014-04-02 10:51:13 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/User.java	2014-04-05 20:08:37 +0000
@@ -103,12 +103,15 @@
     private Set<UserGroup> groups = new HashSet<UserGroup>();
 
     /**
-     * All OrgUnits where the user could belong <p/> TODO This should have been
-     * put in UserCredentials
+     * Organisation units for data input and data capture / write operations.
+     * TODO move to UserCredentials.
      */
     @Scanned
     private Set<OrganisationUnit> organisationUnits = new HashSet<OrganisationUnit>();
     
+    /**
+     * Organisation units for data output and data analysis / read operations.
+     */
     @Scanned
     private Set<OrganisationUnit> dataViewOrganisationUnits = new HashSet<OrganisationUnit>();
 
@@ -117,6 +120,9 @@
      */
     private Set<AttributeValue> attributeValues = new HashSet<AttributeValue>();
 
+    /**
+     * Ordered favorite apps.
+     */
     private List<String> apps = new ArrayList<String>();
     
     // -------------------------------------------------------------------------
@@ -150,7 +156,7 @@
             addOrganisationUnit( unit );
         }
     }
-
+            
     /**
      * Returns the concatenated first name and surname.
      */

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/css/widgets.css'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/css/widgets.css	2014-04-05 17:55:31 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/css/widgets.css	2014-04-05 20:08:37 +0000
@@ -217,7 +217,7 @@
   background-color: white;
   overflow: auto;
   width: 235px;
-  height: 298px;
+  height: 300px;
   border-top: 1px solid #e3e3e3;
   border-bottom: 1px solid #e3e3e3;
 }
@@ -238,7 +238,7 @@
   list-style-type: none;
   white-space: nowrap;
   margin-top: 0;
-  padding: 1px 0 1px 15px;
+  padding: 0 0 1px 15px;
   background-color: transparent;
   background-image: url('../../images/treeview-gray-line.gif');
   background-repeat: no-repeat;
@@ -272,7 +272,6 @@
 {
   color: #000;
   font-family: LiberationSansBold, arial;
-  font-size: 13px;
 }
 
 /*----------------------------------------------------------------------------*/
@@ -287,7 +286,7 @@
   width: 493px;  
   overflow: auto;
   border: 1px solid #ccc;   
-  padding: 2px 0 0 5px;
+  padding: 4px 0 0 5px;
 }
 
 div#selectionTree ul 

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/DefaultSelectionTreeManager.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/DefaultSelectionTreeManager.java	2014-04-05 17:55:31 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/DefaultSelectionTreeManager.java	2014-04-05 20:08:37 +0000
@@ -41,8 +41,6 @@
 import java.util.Set;
 
 /**
- * The selection tree is used for data output and analysis.
- * 
  * @author Torgeir Lorange Ostby
  */
 public class DefaultSelectionTreeManager
@@ -206,6 +204,7 @@
         setSelectedOrganisationUnits( set );
     }
 
+    //TODO remove?
     public boolean setCurrentUserOrganisationUnitAsSelected()
     {
         User user = currentUserService.getCurrentUser();

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/SelectionTreeManager.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/SelectionTreeManager.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/oust/manager/SelectionTreeManager.java	2014-04-05 20:08:37 +0000
@@ -33,8 +33,9 @@
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 
 /**
+ * The selection tree is used for data output and analysis.
+ * 
  * @author Torgeir Lorange Ostby
- * @version $Id: SelectionTreeManager.java 5549 2008-08-20 05:23:35Z abyot $
  */
 public interface SelectionTreeManager
 {

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/DefaultOrganisationUnitSelectionManager.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/DefaultOrganisationUnitSelectionManager.java	2014-04-05 17:55:31 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/DefaultOrganisationUnitSelectionManager.java	2014-04-05 20:08:37 +0000
@@ -40,8 +40,6 @@
 import com.opensymphony.xwork2.ActionContext;
 
 /**
- * The web tree is used for data input and data capture/write operations.
- * 
  * @author Torgeir Lorange Ostby
  */
 public class DefaultOrganisationUnitSelectionManager

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/OrganisationUnitSelectionManager.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/OrganisationUnitSelectionManager.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/ouwt/manager/OrganisationUnitSelectionManager.java	2014-04-05 20:08:37 +0000
@@ -33,8 +33,9 @@
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 
 /**
+ * The web tree is used for data input and data capture.
+ * 
  * @author Torgeir Lorange Ostby
- * @version $Id: OrganisationUnitSelectionManager.java 5549 2008-08-20 05:23:35Z abyot $
  */
 public interface OrganisationUnitSelectionManager
 {

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/RestrictOrganisationUnitsAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/RestrictOrganisationUnitsAction.java	2014-03-18 08:10:10 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/action/RestrictOrganisationUnitsAction.java	2014-04-05 20:08:37 +0000
@@ -85,26 +85,23 @@
             // Initialize ouwt and selection tree
             // -----------------------------------------------------------------
 
-            Set<OrganisationUnit> orgUnits = user.getOrganisationUnits();
+            Set<OrganisationUnit> dataCaptureOrgUnits = user.getOrganisationUnits();
+            Set<OrganisationUnit> dataViewOrgUnits = user.getDataViewOrganisationUnits();
 
-            if ( orgUnits.size() > 0 )
+            if ( dataCaptureOrgUnits.size() > 0 )
             {
-                selectionManager.setRootOrganisationUnits( orgUnits );
-
-                selectionManager.setSelectedOrganisationUnits( orgUnits );
-                
-                selectionTreeManager.setRootOrganisationUnits( orgUnits );
-                
-                selectionTreeManager.setSelectedOrganisationUnits( orgUnits );
+                selectionManager.setRootOrganisationUnits( dataCaptureOrgUnits );
+                selectionManager.setSelectedOrganisationUnits( dataCaptureOrgUnits );
+                
+                selectionTreeManager.setRootOrganisationUnits( dataViewOrgUnits );                
+                selectionTreeManager.setSelectedOrganisationUnits( dataViewOrgUnits );
             }
             else
             {
                 selectionManager.resetRootOrganisationUnits();
-
                 selectionManager.clearSelectedOrganisationUnits();
                 
-                selectionTreeManager.resetRootOrganisationUnits();
-                
+                selectionTreeManager.resetRootOrganisationUnits();                
                 selectionTreeManager.clearSelectedOrganisationUnits();
             }
         }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java	2014-04-05 06:00:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java	2014-04-05 20:08:37 +0000
@@ -28,8 +28,12 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.google.common.collect.Lists;
-import com.opensymphony.xwork2.Action;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.struts2.ServletActionContext;
 import org.hisp.dhis.api.utils.ContextUtils;
 import org.hisp.dhis.attribute.AttributeService;
@@ -52,12 +56,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 
-import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import com.google.common.collect.Lists;
+import com.opensymphony.xwork2.Action;
 
 /**
  * @author Torgeir Lorange Ostby
@@ -244,10 +244,6 @@
     public String execute()
         throws Exception
     {
-        // ---------------------------------------------------------------------
-        // Prepare values
-        // ---------------------------------------------------------------------
-
         if ( email != null && email.trim().length() == 0 )
         {
             email = null;
@@ -258,11 +254,9 @@
         inviteEmail = inviteEmail.trim();
 
         // ---------------------------------------------------------------------
-        // Create userCredentials and user
+        // User credentials and user
         // ---------------------------------------------------------------------
 
-        Collection<OrganisationUnit> orgUnits = selectionTreeManager.getReloadedSelectedOrganisationUnits();
-
         UserCredentials userCredentials = new UserCredentials();
         User user = new User();
 
@@ -293,7 +287,25 @@
             userCredentials.setPassword( passwordManager.encodePassword( username, rawPassword ) );
         }
 
-        user.updateOrganisationUnits( new HashSet<OrganisationUnit>( orgUnits ) );
+        if ( jsonAttributeValues != null )
+        {
+            AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues,
+                attributeService );
+        }
+
+        // ---------------------------------------------------------------------
+        // Organisation units
+        // ---------------------------------------------------------------------
+
+        Set<OrganisationUnit> dataCaptureOrgUnits = new HashSet<OrganisationUnit>( selectionManager.getSelectedOrganisationUnits() );
+        user.updateOrganisationUnits( dataCaptureOrgUnits );        
+        
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>( selectionTreeManager.getReloadedSelectedOrganisationUnits() );
+        user.setDataViewOrganisationUnits( dataViewOrgUnits );
+
+        // ---------------------------------------------------------------------
+        // User roles
+        // ---------------------------------------------------------------------
 
         Set<UserAuthorityGroup> userAuthorityGroups = new HashSet<UserAuthorityGroup>();
 
@@ -306,19 +318,12 @@
 
         userCredentials.setUserAuthorityGroups( userAuthorityGroups );
 
-        if ( jsonAttributeValues != null )
-        {
-            AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues,
-                attributeService );
-        }
-
         userService.addUser( user );
         userService.addUserCredentials( userCredentials );
 
-        if ( orgUnits.size() > 0 )
-        {
-            selectionManager.setSelectedOrganisationUnits( orgUnits );
-        }
+        // ---------------------------------------------------------------------
+        // User settings
+        // ---------------------------------------------------------------------
 
         userService.addUserSetting( new UserSetting( user, UserSettingService.KEY_UI_LOCALE, LocaleUtils.getLocale( localeUi ) ) );
         userService.addUserSetting( new UserSetting( user, UserSettingService.KEY_DB_LOCALE, LocaleUtils.getLocale( localeDb ) ) );
@@ -330,15 +335,15 @@
             securityService.sendRestoreMessage( userCredentials, getRootPath(), restoreOptions );
         }
 
+        // ---------------------------------------------------------------------
+        // User groups
+        // ---------------------------------------------------------------------
+
         for ( String id : ugSelected )
         {
             UserGroup userGroup = userGroupService.getUserGroup( id );
-
-            if ( userGroup != null )
-            {
-                userGroup.addUser( user );
-                userGroupService.updateUserGroup( userGroup );
-            }
+            userGroup.addUser( user );
+            userGroupService.updateUserGroup( userGroup );
         }
 
         return SUCCESS;
@@ -346,8 +351,6 @@
 
     private String getRootPath()
     {
-        HttpServletRequest request = ServletActionContext.getRequest();
-
-        return ContextUtils.getContextPath( request );
+        return ContextUtils.getContextPath( ServletActionContext.getRequest() );
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/SetupTreeAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/SetupTreeAction.java	2014-04-05 06:00:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/SetupTreeAction.java	2014-04-05 20:08:37 +0000
@@ -208,11 +208,16 @@
         {
             user = userService.getUser( id );
 
-            if ( user.getOrganisationUnits().size() > 0 )
-            {
-                selectionTreeManager.setSelectedOrganisationUnits( user.getOrganisationUnits() );
-            }
-
+            if ( user.hasOrganisationUnit() )
+            {
+                selectionManager.setSelectedOrganisationUnits( user.getOrganisationUnits() );
+            }
+            
+            if ( user.hasDataViewOrganisationUnit() )
+            {
+                selectionTreeManager.setSelectedOrganisationUnits( user.getDataViewOrganisationUnits() );
+            }
+            
             userCredentials = userService.getUserCredentials( userService.getUser( id ) );
 
             userAuthorityGroups.removeAll( userCredentials.getUserAuthorityGroups() );
@@ -224,12 +229,7 @@
             currentLocaleDb = (Locale) userService.getUserSettingValue( user, KEY_DB_LOCALE, null );
         }
         else
-        {
-            if ( selectionManager.getSelectedOrganisationUnits().size() > 0 )
-            {
-                selectionTreeManager.setSelectedOrganisationUnits( selectionManager.getSelectedOrganisationUnits() );
-            }
-            
+        {            
             currentLocale = LocaleManager.DHIS_STANDARD_LOCALE;
         }
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java	2014-04-05 06:00:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java	2014-04-05 20:08:37 +0000
@@ -28,9 +28,12 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.opensymphony.xwork2.Action;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import org.hisp.dhis.attribute.AttributeService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.oust.manager.SelectionTreeManager;
@@ -50,11 +53,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import com.google.common.collect.Lists;
+import com.opensymphony.xwork2.Action;
 
 /**
  * @author Torgeir Lorange Ostby
@@ -206,10 +206,6 @@
     public String execute()
         throws Exception
     {
-        // ---------------------------------------------------------------------
-        // Prepare values
-        // ---------------------------------------------------------------------
-
         if ( email != null && email.trim().length() == 0 )
         {
             email = null;
@@ -221,17 +217,14 @@
         }
 
         // ---------------------------------------------------------------------
-        // Update userCredentials and user
+        // User credentials and user
         // ---------------------------------------------------------------------
 
-        Collection<OrganisationUnit> units = selectionTreeManager.getReloadedSelectedOrganisationUnits();
-
         User user = userService.getUser( id );
         user.setSurname( surname );
         user.setFirstName( firstName );
         user.setEmail( email );
         user.setPhoneNumber( phoneNumber );
-        user.updateOrganisationUnits( new HashSet<OrganisationUnit>( units ) );
 
         UserCredentials userCredentials = userService.getUserCredentials( user );
 
@@ -244,6 +237,31 @@
             userCredentials.setOpenId( null );
         }
 
+        if ( rawPassword != null )
+        {
+            userCredentials.setPassword( passwordManager.encodePassword( userCredentials.getUsername(), rawPassword ) );
+        }
+
+        if ( jsonAttributeValues != null )
+        {
+            AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues,
+                attributeService );
+        }
+
+        // ---------------------------------------------------------------------
+        // Organisation units
+        // ---------------------------------------------------------------------
+
+        Set<OrganisationUnit> dataCaptureOrgUnits = new HashSet<OrganisationUnit>( selectionManager.getSelectedOrganisationUnits() );
+        user.updateOrganisationUnits( dataCaptureOrgUnits );        
+        
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>( selectionTreeManager.getReloadedSelectedOrganisationUnits() );
+        user.setDataViewOrganisationUnits( dataViewOrgUnits );
+
+        // ---------------------------------------------------------------------
+        // User roles
+        // ---------------------------------------------------------------------
+
         Set<UserAuthorityGroup> userAuthorityGroups = new HashSet<UserAuthorityGroup>();
 
         for ( String id : selectedList )
@@ -255,50 +273,41 @@
 
         userCredentials.setUserAuthorityGroups( userAuthorityGroups );
 
-        if ( rawPassword != null )
-        {
-            userCredentials.setPassword( passwordManager.encodePassword( userCredentials.getUsername(), rawPassword ) );
-        }
-
-        if ( jsonAttributeValues != null )
-        {
-            AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues,
-                attributeService );
-        }
-
         userService.updateUserCredentials( userCredentials );
         userService.updateUser( user );
 
-        if ( currentUserService.getCurrentUser() == user )
-        {
-            selectionManager.setRootOrganisationUnits( units );
-            selectionManager.setSelectedOrganisationUnits( units );
-
-            selectionTreeManager.setRootOrganisationUnits( units );
-            selectionTreeManager.setSelectedOrganisationUnits( units );
-        }
-
-        if ( units.size() > 0 )
-        {
-            selectionManager.setSelectedOrganisationUnits( units );
-        }
+        // ---------------------------------------------------------------------
+        // Organisation unit trees
+        // ---------------------------------------------------------------------
+
+        if ( user.equals( currentUserService.getCurrentUser() ) )
+        {
+            selectionManager.setRootOrganisationUnits( dataCaptureOrgUnits );
+            selectionManager.setSelectedOrganisationUnits( dataCaptureOrgUnits );
+
+            selectionTreeManager.setRootOrganisationUnits( dataViewOrgUnits );
+            selectionTreeManager.setSelectedOrganisationUnits( dataViewOrgUnits );
+        }
+
+        // ---------------------------------------------------------------------
+        // User settings
+        // ---------------------------------------------------------------------
 
         userService.addOrUpdateUserSetting( new UserSetting( user, UserSettingService.KEY_UI_LOCALE, LocaleUtils.getLocale( localeUi ) ) );
         userService.addOrUpdateUserSetting( new UserSetting( user, UserSettingService.KEY_DB_LOCALE, LocaleUtils.getLocale( localeDb ) ) );
 
-        Set<UserGroup> userGroups = Sets.newHashSet();
+        // ---------------------------------------------------------------------
+        // User groups
+        // ---------------------------------------------------------------------
+
+        Set<UserGroup> userGroups = new HashSet<UserGroup>();
 
         for ( String id : ugSelected )
         {
-            UserGroup userGroup = userGroupService.getUserGroup( id );
-
-            if ( userGroup != null )
-            {
-                userGroups.add( userGroup );
-            }
+            userGroups.add( userGroupService.getUserGroup( id ) );
         }
 
-        for ( UserGroup userGroup : Sets.newHashSet( user.getGroups() ) )
+        for ( UserGroup userGroup : new HashSet<UserGroup>( user.getGroups() ) )
         {
             if ( !userGroups.contains( userGroup ) )
             {

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties	2014-04-05 06:00:20 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties	2014-04-05 20:08:37 +0000
@@ -327,3 +327,5 @@
 disabled=Disabled
 disable=Disable
 enable=Enable
+data_capture_maintenance_org_units=Data capture and maintenance organisation units
+data_output_analysis_org_units=Data output and analysis organisation units
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/struts.xml	2014-03-24 19:11:38 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/struts.xml	2014-04-05 20:08:37 +0000
@@ -48,7 +48,7 @@
     <action name="showAddUserForm" class="org.hisp.dhis.user.action.SetupTreeAction">
       <result name="success" type="velocity">/main.vm</result>
       <param name="page">/dhis-web-maintenance-user/addUserForm.vm</param>
-      <param name="javascripts">javascript/user.js</param>
+      <param name="javascripts">../dhis-web-commons/oust/oust.js,../dhis-web-commons/ouwt/ouwt.js,javascript/user.js</param>
       <param name="requiredAuthorities">F_USER_ADD</param>
     </action>
 
@@ -62,7 +62,7 @@
     <action name="showUpdateUserForm" class="org.hisp.dhis.user.action.SetupTreeAction">
       <result name="success" type="velocity">/main.vm</result>
       <param name="page">/dhis-web-maintenance-user/updateUserForm.vm</param>
-      <param name="javascripts">javascript/user.js</param>
+      <param name="javascripts">../dhis-web-commons/oust/oust.js,../dhis-web-commons/ouwt/ouwt.js,javascript/user.js</param>
       <param name="requiredAuthorities">F_USER_ADD</param>
     </action>
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/addUserForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/addUserForm.vm	2014-04-05 06:47:56 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/addUserForm.vm	2014-04-05 20:08:37 +0000
@@ -44,6 +44,14 @@
 	});
 </script>
 
+<style type="text/css">
+div#orgUnitTree
+{
+  width: 495px;
+  border: 1px solid #ccc;
+}
+</style>
+
 <h3>$i18n.getString( "create_new_user" )</h3>
 <form id="addUserForm" action="addUser.action" method="post" class="inputForm">
 
@@ -174,7 +182,7 @@
     </tr>
 </table>
 
-<table>
+<table style="margin-bottom: 20px">
 <colgroup>
   <col style="width: 500px;"/>
   <col/>
@@ -212,10 +220,18 @@
 
 <table>
 	<tr>
-		<td colspan="3">
-			#organisationUnitSelectionTree( true, true, false )
-		</td>
-
+		<th>$i18n.getString( "data_capture_maintenance_org_units" )</th>
+		<th></th>
+		<th>$i18n.getString( "data_output_analysis_org_units" )</th>
+	</tr>
+	<tr>
+		<td>			
+            #parse( "/dhis-web-commons/ouwt/orgunittree.vm" )
+		</td>
+		<td style="width: 26px"></td>
+		<td>
+            #parse( "/dhis-web-commons/oust/selectionTree.vm" )
+		</td>
 	</tr>
 </table>
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/updateUserForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/updateUserForm.vm	2014-04-05 06:47:56 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/webapp/dhis-web-maintenance-user/updateUserForm.vm	2014-04-05 20:08:37 +0000
@@ -44,9 +44,20 @@
 				return option;
 			}
 		});
+		
+        selectionTreeSelection.setMultipleSelectionAllowed(true);
+        selectionTree.buildSelectionTree();
 	});
 </script>
 
+<style type="text/css">
+div#orgUnitTree
+{
+  width: 495px;
+  border: 1px solid #ccc;
+}
+</style>
+
 <h3>$i18n.getString( "edit_user" )</h3>
 
 <form id="updateUserForm" action="updateUser.action" method="post" class="inputForm">
@@ -169,7 +180,7 @@
 </tr>
 </table>
 
-<table>
+<table style="margin-bottom: 20px">
 <colgroup>
 <col style="width: 500px;"/>
 <col/>
@@ -210,11 +221,20 @@
 </table>
 
 <table>
-	<tr>
-		<td colspan="3">
-			#organisationUnitSelectionTree( false, true, false )
-		</td>
-	</tr>
+    <tr>
+        <th>$i18n.getString( "data_capture_maintenance_org_units" )</th>
+        <th></th>
+        <th>$i18n.getString( "data_output_analysis_org_units" )</th>
+    </tr>
+    <tr>
+        <td>            
+            #parse( "/dhis-web-commons/ouwt/orgunittree.vm" )
+        </td>
+        <td style="width: 26px"></td>
+        <td>
+            <div id="selectionTree"></div>
+        </td>
+    </tr>
 </table>
 
 <p>