diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties
index 93804fbe05..a118262766 100644
--- a/config/alfresco/messages/webclient.properties
+++ b/config/alfresco/messages/webclient.properties
@@ -853,9 +853,9 @@ create_website_finish_instruction=To close this wizard and create your web proje
create_website_summary_users=Users and Roles
# Invite web users wizard messages
-invite_website_users=Invite Website Users
-invite_webusers_title=Invite Website Users
-invite_webusers_desc=Invite new users and create sandboxes for the web project.
+invite_website_users=Invite Web Project Users
+invite_webusers_title=Invite Web Project Users
+invite_webusers_desc=Invite new users and create sandboxes for the Web Project.
invite_webusers_step1_title=Step One - Invite Users
invite_webusers_step1_desc=Select users and their roles.
invite_webusers_step2_title=Step Two - Notify Users
@@ -883,6 +883,7 @@ sandbox_revertselected=Undo Selected
sandbox_icon=Browse Website
sandbox_snapshot=Create Snapshot
sandbox_snapshot_info=Create a snaphost of this sandbox.
+sandbox_remove=Delete Sandbox
import_website_content=Import Website Content
title_browse_sandbox=Browse Sandbox
sandbox_info=Use this view to browse the files and folders within the sandbox for a web project.
@@ -944,6 +945,9 @@ snapshot_success=Snapshot ''{0}'' created for sandbox: {1}
snapshot_failure=Snapshot not created - the sandbox has not been modified since the last snapshot.
title_website_details=Web Project Details
websitedetails_description=View the details of the web project.
+delete_sandbox=Delete Sandbox
+delete_sandbox_info=To remove this sandbox and the user from the Web Project, click OK.
+delete_sandbox_confirm=Are you sure you want to remove the user sandbox \"{0}\" from the Web Project?
# New User Wizard messages
new_user_title=New User Wizard
@@ -1314,6 +1318,7 @@ error_search=Search failed due to system error: {0}
error_exists=A Space or File with that name already exists: {0}
error_delete_space=Unable to delete Space due to system error:
error_delete_file=Unable to delete File due to system error:
+error_delete_sandbox=Unable to delete Sandbox due to system error:
error_checkout=Unable to check out Content Node due to system error:
error_update=Unable to update Content Node due to system error:
error_cancel_checkout=Unable to cancel check out of Content Node due to system error:
diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml
index 3e5cbfa2e5..a843b4f4e4 100644
--- a/config/alfresco/web-client-config-dialogs.xml
+++ b/config/alfresco/web-client-config-dialogs.xml
@@ -122,6 +122,10 @@
icon="/images/icons/create_snapshot_large.gif" title-id="sandbox_snapshot"
description-id="sandbox_snapshot_info" />
+
+
@@ -141,7 +145,7 @@
-
+
diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
index b1569139ef..1a635c9945 100644
--- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
+++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
@@ -62,6 +62,7 @@ import org.alfresco.web.bean.BrowseBean;
import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
+import org.alfresco.web.bean.repository.User;
import org.alfresco.web.bean.wizard.WizardManager;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.ui.common.Utils;
@@ -538,21 +539,29 @@ public class AVMBrowseBean implements IContextListener
{
boolean isManager = false;
- String currentUser = Application.getCurrentUser(FacesContext.getCurrentInstance()).getUserName();
- Node websiteNode = this.navigator.getCurrentNode();
- List userInfoRefs = this.nodeService.getChildAssocs(
- websiteNode.getNodeRef(), ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
- for (ChildAssociationRef ref : userInfoRefs)
+ User user = Application.getCurrentUser(FacesContext.getCurrentInstance());
+ if (user.isAdmin() == false)
{
- NodeRef userInfoRef = ref.getChildRef();
- String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME);
- String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE);
- if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole))
+ String currentUser = user.getUserName();
+ Node websiteNode = this.navigator.getCurrentNode();
+ List userInfoRefs = this.nodeService.getChildAssocs(
+ websiteNode.getNodeRef(), ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef ref : userInfoRefs)
{
- isManager = true;
- break;
+ NodeRef userInfoRef = ref.getChildRef();
+ String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME);
+ String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE);
+ if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole))
+ {
+ isManager = true;
+ break;
+ }
}
}
+ else
+ {
+ isManager = true;
+ }
return isManager;
}
diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java
new file mode 100644
index 0000000000..8b96d8470a
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java
@@ -0,0 +1,134 @@
+package org.alfresco.web.bean.wcm;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.web.app.AlfrescoNavigationHandler;
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.dialog.BaseDialogBean;
+import org.alfresco.web.bean.repository.Node;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Bean implementation for the AVM "Delete Sandbox" dialog
+ *
+ * @author kevinr
+ */
+public class DeleteSandboxDialog extends BaseDialogBean
+{
+ private static final Log logger = LogFactory.getLog(DeleteSandboxDialog.class);
+
+ protected AVMService avmService;
+ protected AVMBrowseBean avmBrowseBean;
+
+
+ /**
+ * @param avmBrowseBean The avmBrowseBean to set.
+ */
+ public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
+ {
+ this.avmBrowseBean = avmBrowseBean;
+ }
+
+ /**
+ * @param avmService The avmService to set.
+ */
+ public void setAvmService(AVMService avmService)
+ {
+ this.avmService = avmService;
+ }
+
+
+ // ------------------------------------------------------------------------------
+ // Dialog implementation
+
+ @Override
+ protected String finishImpl(FacesContext context, String outcome)
+ throws Exception
+ {
+ // the username for the sandbox to delete
+ String username = this.avmBrowseBean.getUsername();
+ if (username != null)
+ {
+ Node website = this.avmBrowseBean.getWebsite();
+
+ // remove the store reference from the website folder meta-data
+ List userInfoRefs = this.nodeService.getChildAssocs(
+ website.getNodeRef(),
+ ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef ref : userInfoRefs)
+ {
+ NodeRef userInfoRef = ref.getChildRef();
+ String user = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME);
+ String role = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE);
+
+ if (username.equals(user))
+ {
+ // found the sandbox to remove
+ String storeRoot = (String)website.getProperties().get(ContentModel.PROP_AVMSTORE);
+
+ // TODO: would it be better to use the .sandbox-id. property to delete all sandboxes?
+
+ // purge the user main sandbox store from the system
+ String sandbox = AVMConstants.buildAVMUserMainStoreName(storeRoot, username);
+ this.avmService.purgeAVMStore(sandbox);
+
+ // purge the user preview sandbox store from the system
+ sandbox = AVMConstants.buildAVMUserPreviewStoreName(storeRoot, username);
+ this.avmService.purgeAVMStore(sandbox);
+
+ // remove the association to this web project user meta-data
+ this.nodeService.removeChild(website.getNodeRef(), ref.getChildRef());
+
+ break;
+ }
+ }
+ }
+
+ return outcome;
+ }
+
+ @Override
+ protected String doPostCommitProcessing(FacesContext context, String outcome)
+ {
+ return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
+ }
+
+ @Override
+ protected String getErrorMessageId()
+ {
+ return "error_delete_sandbox";
+ }
+
+ @Override
+ public boolean getFinishButtonDisabled()
+ {
+ return false;
+ }
+
+
+ // ------------------------------------------------------------------------------
+ // Bean Getters and Setters
+
+ /**
+ * Returns the confirmation to display to the user before deleting the user sandbox.
+ *
+ * @return The formatted message to display
+ */
+ public String getConfirmMessage()
+ {
+ String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
+ "delete_sandbox_confirm");
+
+ return MessageFormat.format(fileConfirmMsg,
+ new Object[] {this.avmBrowseBean.getUsername()});
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java
index b3c6ec0dc7..eb37440258 100644
--- a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java
+++ b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java
@@ -67,6 +67,8 @@ public abstract class InviteUsersWizard extends BaseWizardBean
private static final String MSG_INVITED_TO = "invited_to";
private static final String MSG_INVITED_ROLE = "invite_role";
+ protected static final String STEP_NOTIFY = "notify";
+
private static final String NOTIFY_YES = "yes";
/** NamespaceService bean reference */
@@ -234,6 +236,23 @@ public abstract class InviteUsersWizard extends BaseWizardBean
return outcome;
}
+ /**
+ * @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled()
+ */
+ @Override
+ public boolean getFinishButtonDisabled()
+ {
+ boolean disabled = true;
+
+ String stepName = Application.getWizardManager().getCurrentStepName();
+ if (STEP_NOTIFY.equals(stepName))
+ {
+ disabled = false;
+ }
+
+ return disabled;
+ }
+
/**
* Returns the properties for current user-roles JSF DataModel
*
@@ -462,7 +481,7 @@ public abstract class InviteUsersWizard extends BaseWizardBean
{
String stepName = Application.getWizardManager().getCurrentStepName();
- if (stepName.equals("notify"))
+ if (STEP_NOTIFY.equals(stepName))
{
FacesContext context = FacesContext.getCurrentInstance();
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 87fc0d48c6..5095429841 100644
--- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
+++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
@@ -81,6 +81,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
private static final String ACT_SANDBOX_SUBMITALL = "sandbox_submitall";
private static final String ACT_SANDBOX_PREVIEW = "sandbox_preview";
private static final String ACT_SANDBOX_ICON = "sandbox_icon";
+ private static final String ACT_REMOVE_SANDBOX = "sandbox_remove";
private static final String ACTIONS_FILE = "avm_file_modified";
private static final String ACTIONS_FOLDER = "avm_folder_modified";
@@ -103,12 +104,26 @@ public class UIUserSandboxes extends SelfRenderingComponent
private static final String MSG_DELETED_ITEM = "avm_node_deleted";
private static final String MSG_SELECTED = "selected";
+ /** Content Manager role name */
+ private static final String ROLE_CONTENT_MANAGER = "ContentManager";
+
private static final String REQUEST_FORM_REF = "formref";
private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif";
public static final String PARAM_FORM_ID = "form-id";
+ private static final String SCRIPT_MULTISELECT =
+ "";
+
/** website to show sandboxes for */
private NodeRef value;
@@ -253,8 +268,10 @@ public class UIUserSandboxes extends SelfRenderingComponent
}
String storeRoot = (String)nodeService.getProperty(websiteRef, ContentModel.PROP_AVMSTORE);
+ // find out if this user is a Content Manager
+ boolean isManager = isManagerRole(context, nodeService, websiteRef);
+
// get the list of users who have a sandbox in the website
- String currentUser = Application.getCurrentUser(context).getUserName();
int index = 0;
List userInfoRefs = nodeService.getChildAssocs(
websiteRef, ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
@@ -285,15 +302,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
logger.debug("Building sandbox view for user store: " + mainStore);
// output a javascript function we need for multi-select functionality
- out.write("");
+ out.write(SCRIPT_MULTISELECT);
// for each user sandbox, generate an outer panel table
PanelGenerator.generatePanelStart(out,
@@ -334,6 +343,14 @@ public class UIUserSandboxes extends SelfRenderingComponent
"#{AVMBrowseBean.revertAll}", null));
out.write(" ");
+ if (isManager)
+ {
+ Utils.encodeRecursive(context, aquireAction(
+ context, mainStore, username, ACT_REMOVE_SANDBOX, "/images/icons/delete_sandbox.gif",
+ "#{AVMBrowseBean.setupSandboxAction}", "dialog:deleteSandbox"));
+ out.write(" ");
+ }
+
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, ACT_SANDBOX_BROWSE, "/images/icons/space_small.gif",
"#{AVMBrowseBean.setupSandboxAction}", "browseSandbox"));
@@ -403,6 +420,29 @@ public class UIUserSandboxes extends SelfRenderingComponent
throw new RuntimeException(err);
}
}
+
+ /**
+ * @return true if the current user is a Content Manager, false otherwise
+ */
+ private static boolean isManagerRole(FacesContext context, NodeService nodeService, NodeRef websiteRef)
+ {
+ boolean isManager = false;
+ String currentUser = Application.getCurrentUser(context).getUserName();
+ List userInfoRefs = nodeService.getChildAssocs(
+ websiteRef, ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef ref : userInfoRefs)
+ {
+ NodeRef userInfoRef = ref.getChildRef();
+ String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME);
+ String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE);
+ if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole))
+ {
+ isManager = true;
+ break;
+ }
+ }
+ return isManager;
+ }
/**
* Render the list of user modified files/folders in the layered sandbox area.
diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml
index b932cb7971..e26e48bdfe 100644
--- a/source/web/WEB-INF/faces-config-beans.xml
+++ b/source/web/WEB-INF/faces-config-beans.xml
@@ -2379,6 +2379,27 @@
+
+
+ The bean that backs up the Delete User Sandbox Dialog
+
+ DeleteSandboxDialog
+ org.alfresco.web.bean.wcm.DeleteSandboxDialog
+ session
+
+ avmService
+ #{AVMService}
+
+
+ avmBrowseBean
+ #{AVMBrowseBean}
+
+
+ nodeService
+ #{NodeService}
+
+
+
The bean that backs up the Create AVM Folder Dialog
diff --git a/source/web/images/icons/delete_sandbox.gif b/source/web/images/icons/delete_sandbox.gif
new file mode 100644
index 0000000000..4ee6ccfce4
Binary files /dev/null and b/source/web/images/icons/delete_sandbox.gif differ
diff --git a/source/web/images/icons/delete_sandbox_large.gif b/source/web/images/icons/delete_sandbox_large.gif
new file mode 100644
index 0000000000..cfe75d348b
Binary files /dev/null and b/source/web/images/icons/delete_sandbox_large.gif differ