diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 24dd5d2313..b1dad76cf0 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -957,6 +957,8 @@ snapshot_preview=Preview webapp_current=Current Webapp Folder sandbox_no_modified_items=No modified items sandbox_no_web_forms=No Web Forms available +sandbox_my_sandbox=My Sandbox +sandbox_user=User # Website actions and dialog messages title_import_content=Web Project Bulk Import diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index 3b93fa8e99..9d07104892 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -55,6 +56,8 @@ import org.alfresco.web.bean.wcm.AVMConstants; import org.alfresco.web.bean.wcm.AVMNode; import org.alfresco.web.bean.wcm.WebProject; import org.alfresco.web.config.ClientConfigElement; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; import org.alfresco.web.forms.Form; import org.alfresco.web.ui.common.ComponentConstants; import org.alfresco.web.ui.common.ConstantMethodBinding; @@ -70,6 +73,16 @@ import org.apache.commons.logging.LogFactory; import org.springframework.web.jsf.FacesContextUtils; /** + * Component responsible for rendering the list of user sandboxes for a web project. + *

+ * The list of users attached to the supplied Web Project noderef (must be of type + * wcm:avmfolder) are iterated and the various AVM services used to provide the list + * of modified files for each user in turn. Actions are rendering with appropriate + * permission evaluators next to each item. The status of workflows in progress are + * also checked against items when building the list of actions. + *

+ * Multi-select functionality is provided for specific actions. + * * @author Kevin Roast */ public class UIUserSandboxes extends SelfRenderingComponent @@ -99,7 +112,7 @@ public class UIUserSandboxes extends SelfRenderingComponent private static final String MSG_CONTENT_FORMS = "content_forms"; private static final String MSG_SIZE = "size"; private static final String MSG_CREATED = "created_date"; - private static final String MSG_USERNAME = "username"; + private static final String MSG_USERNAME = "sandbox_user"; private static final String MSG_NAME = "name"; private static final String MSG_DESCRIPTION = "description"; private static final String MSG_MODIFIED = "modified_date"; @@ -108,6 +121,7 @@ public class UIUserSandboxes extends SelfRenderingComponent private static final String MSG_SELECTED = "selected"; private static final String MSG_NO_MODIFIED_ITEMS = "sandbox_no_modified_items"; private static final String MSG_NO_WEB_FORMS = "sandbox_no_web_forms"; + private static final String MSG_MY_SANDBOX = "sandbox_my_sandbox"; private static final String REQUEST_FORM_REF = "formref"; private static final String REQUEST_PREVIEW_REF = "prevhref"; @@ -276,18 +290,20 @@ public class UIUserSandboxes extends SelfRenderingComponent String storeRoot = (String)nodeService.getProperty(websiteRef, WCMAppModel.PROP_AVMSTORE); // find out the current user role in the web project + List userInfoRefs = nodeService.getChildAssocs( + websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); String currentUserName = Application.getCurrentUser(context).getUserName(); - String currentUserRole = getWebProjectUserRole(currentUserName, nodeService, websiteRef); + String currentUserRole = getWebProjectUserRole(nodeService, websiteRef, currentUserName, userInfoRefs); + + // sort the user list alphabetically and insert the current user at the top of the list + List userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); // get the list of users who have a sandbox in the website int index = 0; - List userInfoRefs = nodeService.getChildAssocs( - websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) + for (UserRoleWrapper wrapper : userRoleWrappers) { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + String username = wrapper.UserName; + String userrole = wrapper.UserRole; // create the lookup value of sandbox index to username this.userToRowLookup.put(index, username); @@ -328,10 +344,19 @@ public class UIUserSandboxes extends SelfRenderingComponent browseAction.setShowLink(false); Utils.encodeRecursive(context, browseAction); out.write(""); - out.write(""); - out.write(bundle.getString(MSG_USERNAME)); - out.write(": "); - out.write(username); + if (wrapper.IsCurrentUser == false) + { + out.write(""); + out.write(bundle.getString(MSG_USERNAME)); + out.write(": "); + out.write(username); + } + else + { + out.write(""); + out.write(bundle.getString(MSG_MY_SANDBOX)); + out.write(""); + } out.write(" ("); out.write(bundle.getString(userrole)); out.write(")"); @@ -440,16 +465,59 @@ public class UIUserSandboxes extends SelfRenderingComponent throw new RuntimeException(err); } } + + /** + * Build a sorted list of objects representing the users of the website. + *

+ * User role data and the current user is also stored. The current user sandbox + * is inserted at the top of the list if present. + */ + private static List buildSortedUserRoles( + NodeService nodeService, String currentUser, List userInfoRefs) + { + // build a list of wrappers to hold the fields we need for each user and role + UserRoleWrapper currentUserWrapper = null; + List wrappers = new LinkedList(); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + UserRoleWrapper wrapper = new UserRoleWrapper(username, userrole); + + if (currentUser.equals(username)) + { + wrapper.IsCurrentUser = true; + currentUserWrapper = wrapper; + } + else + { + wrappers.add(wrapper); + } + } + + // sort list by username + QuickSort sorter = new QuickSort(wrappers, "UserName", true, IDataContainer.SORT_CASEINSENSITIVE); + sorter.sort(); + + // if present, insert the current user to the top of the list + if (currentUserWrapper != null) + { + wrappers.add(0, currentUserWrapper); + } + + return wrappers; + } /** * @return the role of this user in the current Web Project, or null for no assigned role */ - private static String getWebProjectUserRole(String currentUser, NodeService nodeService, NodeRef websiteRef) + private static String getWebProjectUserRole( + NodeService nodeService, NodeRef websiteRef, String currentUser, List userInfoRefs) { String userrole = null; - List userInfoRefs = nodeService.getChildAssocs( - websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); for (ChildAssociationRef ref : userInfoRefs) { NodeRef userInfoRef = ref.getChildRef(); @@ -1136,4 +1204,34 @@ public class UIUserSandboxes extends SelfRenderingComponent return nodes; } + + + // ------------------------------------------------------------------------------ + // Inner classes + + /** + * Class representing a user of the website and their role. + */ + public static class UserRoleWrapper + { + UserRoleWrapper(String username, String userrole) + { + UserName = username; + UserRole = userrole; + } + + /** + * Public accessor to user by sorting class + * + * @return User Name + */ + public String getUserName() + { + return UserName; + } + + String UserName; + String UserRole; + boolean IsCurrentUser = false; + } }