diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties
index e1a6e570b9..200aa08023 100644
--- a/config/alfresco/messages/webclient.properties
+++ b/config/alfresco/messages/webclient.properties
@@ -953,6 +953,14 @@ 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?
+submit_submission_info=Submission Info
+submit_comment=Comment
+submit_snapshotlabel=Snapshot Label
+submit_workflow_selection=Use the following workflow to submit all modified items
+submit_not_submit_warning=The following items will not be submitted
+submit_submit_info=The following items will be submitted
+submit_items_title=Submit Items
+submit_items_desc=This page helps you to submit modified items for publishing on the website.
# New User Wizard messages
new_user_title=New User Wizard
diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml
index ca7717e5b1..69d2802cc0 100644
--- a/config/alfresco/web-client-config-dialogs.xml
+++ b/config/alfresco/web-client-config-dialogs.xml
@@ -177,6 +177,10 @@
+
+
diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
index ca1f3d9a72..d955a5cc2f 100644
--- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
+++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java
@@ -116,6 +116,7 @@ public class AVMBrowseBean implements IContextListener
private String sandboxTitle = null;
private String currentPath = null;
private AVMNode currentPathNode = null;
+ private boolean submitAll = false;
/* component references */
private UIRichList foldersRichList;
@@ -686,6 +687,21 @@ public class AVMBrowseBean implements IContextListener
}
}
+ /**
+ * Return the list of selected items for the current user sandbox view
+ *
+ * @return List of AVMNodeDescriptor objects representing selected items
+ */
+ public List getSelectedSandboxItems()
+ {
+ return this.userSandboxes.getSelectedNodes(this.username);
+ }
+
+ public boolean getSubmitAll()
+ {
+ return this.submitAll;
+ }
+
// ------------------------------------------------------------------------------
// Action event handlers
@@ -740,6 +756,14 @@ public class AVMBrowseBean implements IContextListener
// update UI state ready for return to the previous screen
this.location = null;
setCurrentPath(null);
+
+ this.submitAll = false;
+ }
+
+ public void setupSubmitAllAction(ActionEvent event)
+ {
+ setupSandboxAction(event);
+ this.submitAll = true;
}
/**
diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
index 0accf66438..a98fdb36cd 100644
--- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
+++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
@@ -313,7 +313,7 @@ public class CreateWebsiteWizard extends BaseWizardBean
* @param params Serializable workflow params
* @param workflowRef The noderef to write the property too
*/
- private void serializeWorkflowParams(Serializable params, NodeRef workflowRef)
+ public static void serializeWorkflowParams(Serializable params, NodeRef workflowRef)
{
try
{
diff --git a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java
index 808ac81cb5..32c29b5fca 100644
--- a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java
+++ b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java
@@ -215,13 +215,13 @@ public class EditWebsiteWizard extends CreateWebsiteWizard
}
/**
- * Deserialize the workflow params from a content stream
+ * Deserialize the default workflow params from a content stream
*
* @param workflowRef The noderef to write the property too
*
* @return Serializable workflow params
*/
- private Serializable deserializeWorkflowParams(NodeRef workflowRef)
+ public static Serializable deserializeWorkflowParams(NodeRef workflowRef)
{
try
{
diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java
new file mode 100644
index 0000000000..308fc55a43
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.bean.wcm;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.model.ContentModel;
+import org.alfresco.model.WCMAppModel;
+import org.alfresco.repo.avm.AVMNodeConverter;
+import org.alfresco.repo.workflow.WorkflowModel;
+import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avmsync.AVMDifference;
+import org.alfresco.service.cmr.avmsync.AVMSyncService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.workflow.WorkflowDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowPath;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.cmr.workflow.WorkflowTaskState;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.util.GUID;
+import org.alfresco.util.ISO8601DateFormat;
+import org.alfresco.web.app.servlet.DownloadContentServlet;
+import org.alfresco.web.bean.dialog.BaseDialogBean;
+import org.alfresco.web.ui.common.Utils;
+import org.alfresco.web.ui.common.component.UIListItem;
+import org.alfresco.web.ui.wcm.WebResources;
+
+/**
+ * @author Kevin Roast
+ */
+public class SubmitDialog extends BaseDialogBean
+{
+ private String comment;
+ private String label;
+ private String[] workflowSelectedValue;
+
+ private List submitItems;
+ private List warningItems;
+ private HashSet workflows;
+ private Map formWorkflowMap;
+ private List workflowItems;
+
+ protected AVMService avmService;
+ protected AVMBrowseBean avmBrowseBean;
+ protected WorkflowService workflowService;
+ protected AVMSyncService avmSyncService;
+
+ /**
+ * @param avmService The AVM Service to set.
+ */
+ public void setAvmService(AVMService avmService)
+ {
+ this.avmService = avmService;
+ }
+
+ /**
+ * @param avmSyncService The AVMSyncService to set.
+ */
+ public void setAvmSyncService(AVMSyncService avmSyncService)
+ {
+ this.avmSyncService = avmSyncService;
+ }
+
+ /**
+ * @param avmBrowseBean The AVM BrowseBean to set
+ */
+ public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
+ {
+ this.avmBrowseBean = avmBrowseBean;
+ }
+
+ /**
+ * @param workflowService The WorkflowService to set.
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /**
+ * @see org.alfresco.web.bean.dialog.BaseDialogBean#init(java.util.Map)
+ */
+ @Override
+ public void init(Map parameters)
+ {
+ super.init(parameters);
+
+ this.comment = null;
+ this.label = null;
+ this.submitItems = null;
+ this.warningItems = null;
+ this.workflowItems = null;
+ this.workflows = new HashSet(4);
+
+ // walk all the web forms attached the website, and lookup the workflow defaults for each
+ NodeRef websiteRef = this.avmBrowseBean.getWebsite().getNodeRef();
+ List webFormRefs = this.nodeService.getChildAssocs(
+ websiteRef, WCMAppModel.ASSOC_WEBFORM, RegexQNamePattern.MATCH_ALL);
+ this.formWorkflowMap = new HashMap(webFormRefs.size(), 1.0f);
+ for (ChildAssociationRef ref : webFormRefs)
+ {
+ NodeRef webFormRef = ref.getChildRef();
+ String form = (String)this.nodeService.getProperty(webFormRef, WCMAppModel.PROP_FORMNAME);
+ List wfRefs = this.nodeService.getChildAssocs(
+ webFormRef, WCMAppModel.TYPE_WORKFLOWDEFAULTS, RegexQNamePattern.MATCH_ALL);
+ if (wfRefs.size() == 1)
+ {
+ NodeRef wfDefaultsRef = wfRefs.get(0).getChildRef();
+ String wfName = (String)this.nodeService.getProperty(wfDefaultsRef, WCMAppModel.PROP_WORKFLOW_NAME);
+ Map params = (Map)EditWebsiteWizard.deserializeWorkflowParams(
+ wfDefaultsRef);
+ this.formWorkflowMap.put(form, new FormWorkflowWrapper(wfName, params));
+ }
+ }
+ }
+
+ /**
+ * @see org.alfresco.web.bean.dialog.BaseDialogBean#finishImpl(javax.faces.context.FacesContext, java.lang.String)
+ */
+ @Override
+ protected String finishImpl(FacesContext context, String outcome) throws Exception
+ {
+ // get the defaults from the workflow configuration attached to the selected workflow
+ Map params = null;
+ String workflowName = this.workflowSelectedValue[0];
+ for (FormWorkflowWrapper wrapper : this.workflows)
+ {
+ if (wrapper.Name.equals(workflowName))
+ {
+ params = wrapper.Params;
+ }
+ }
+
+ if (params != null)
+ {
+ // create container for our avm workflow package
+ NodeRef workflowPackage = createWorkflowPackage();
+ params.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage);
+
+ // start the workflow to get access to the start task
+ WorkflowDefinition wfDef = workflowService.getDefinitionByName("jbpm$" + workflowName);
+ WorkflowPath path = this.workflowService.startWorkflow(wfDef.id, params);
+ if (path != null)
+ {
+ // extract the start task
+ List tasks = this.workflowService.getTasksForWorkflowPath(path.id);
+ if (tasks.size() == 1)
+ {
+ WorkflowTask startTask = tasks.get(0);
+
+ if (startTask.state == WorkflowTaskState.IN_PROGRESS)
+ {
+ // end the start task to trigger the first 'proper' task in the workflow
+ this.workflowService.endTask(startTask.id, null);
+ }
+ }
+ }
+ }
+ else
+ {
+ // TODO: jump to dialog and allow user to finish wf properties config!
+ throw new AlfrescoRuntimeException("Workflow has not been configured correctly, cannot submit items.");
+ }
+
+ return outcome;
+ }
+
+ /**
+ * @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled()
+ */
+ @Override
+ public boolean getFinishButtonDisabled()
+ {
+ return (getWorkflowSelectedValue() == null || getSubmitItemsSize() == 0);
+ }
+
+ /**
+ * @return Returns the workflow comment.
+ */
+ public String getComment()
+ {
+ return this.comment;
+ }
+
+ /**
+ * @param comment The workflow comment to set.
+ */
+ public void setComment(String comment)
+ {
+ this.comment = comment;
+ }
+
+ /**
+ * @return Returns the snapshot label.
+ */
+ public String getLabel()
+ {
+ return this.label;
+ }
+
+ /**
+ * @param label The snapshot label to set.
+ */
+ public void setLabel(String label)
+ {
+ this.label = label;
+ }
+
+ /**
+ * @return Returns the workflow Selected Value.
+ */
+ public String[] getWorkflowSelectedValue()
+ {
+ // TODO: select default!
+ return this.workflowSelectedValue;
+ }
+
+ /**
+ * @param workflowSelectedValue The workflow Selected Value to set.
+ */
+ public void setWorkflowSelectedValue(String[] workflowSelectedValue)
+ {
+ this.workflowSelectedValue = workflowSelectedValue;
+ }
+
+ /**
+ * @return List of UIListItem object representing the available workflows for the website
+ */
+ public List getWorkflowList()
+ {
+ if (this.workflowItems == null)
+ {
+ // ensure all workflows have been collected from any form generated assets
+ calculateSubmitItems();
+
+ // add the list of workflows for the website itself to the set
+ NodeRef websiteRef = this.avmBrowseBean.getWebsite().getNodeRef();
+ List webWorkflowRefs = this.nodeService.getChildAssocs(
+ websiteRef, WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef ref : webWorkflowRefs)
+ {
+ NodeRef wfDefaultsRef = ref.getChildRef();
+ String wfName = (String)this.nodeService.getProperty(wfDefaultsRef, WCMAppModel.PROP_WORKFLOW_NAME);
+ Map params = (Map)EditWebsiteWizard.deserializeWorkflowParams(
+ wfDefaultsRef);
+ this.workflows.add(new FormWorkflowWrapper(wfName, params));
+ }
+
+ // build a UI item for each available workflow
+ List items = new ArrayList(this.workflows.size());
+ for (FormWorkflowWrapper wrapper : this.workflows)
+ {
+ WorkflowDefinition workflowDef = this.workflowService.getDefinitionByName("jbpm$" + wrapper.Name);
+ UIListItem item = new UIListItem();
+ item.setValue(workflowDef.getName());
+ item.setLabel(workflowDef.getTitle());
+ item.setDescription(workflowDef.getDescription());
+ item.setImage(WebResources.IMAGE_WORKFLOW_32);
+ items.add(item);
+ // add first as default TODO: what is correct here?
+ if (workflowSelectedValue == null)
+ {
+ workflowSelectedValue = new String[]{workflowDef.getName()};
+ }
+ }
+ this.workflowItems = items;
+ }
+
+ return this.workflowItems;
+ }
+
+ public List getSubmitItems()
+ {
+ if (this.submitItems == null)
+ {
+ // this method builds all submit and warning item data structures
+ calculateSubmitItems();
+ }
+ return this.submitItems;
+ }
+
+ public int getSubmitItemsSize()
+ {
+ return getSubmitItems().size();
+ }
+
+ public List getWarningItems()
+ {
+ if (this.warningItems == null)
+ {
+ // this method builds all submit and warning item data structures
+ calculateSubmitItems();
+ }
+ return this.warningItems;
+ }
+
+ public int getWarningItemsSize()
+ {
+ return this.getWarningItems().size();
+ }
+
+ private void calculateSubmitItems()
+ {
+ // TODO: start txn here?
+ List selected;
+ if (this.avmBrowseBean.getSubmitAll())
+ {
+ String userStore = this.avmBrowseBean.getSandbox() + ":/";
+ String stagingStore = this.avmBrowseBean.getStagingStore() + ":/";
+ List diffs = avmSyncService.compare(-1, userStore, -1, stagingStore);
+ selected = new ArrayList(diffs.size());
+ for (AVMDifference diff : diffs)
+ {
+ AVMNodeDescriptor node = this.avmService.lookup(-1, diff.getSourcePath());
+ selected.add(node);
+ }
+ }
+ else
+ {
+ selected = this.avmBrowseBean.getSelectedSandboxItems();
+ }
+ if (selected != null)
+ {
+ this.submitItems = new ArrayList(selected.size());
+ this.warningItems = new ArrayList(selected.size() >> 1);
+ for (AVMNodeDescriptor node : selected)
+ {
+ if (hasAssociatedWorkflow(AVMNodeConverter.ToNodeRef(-1, node.getPath())) == false)
+ {
+ // TODO: lookup if this item was created via a FORM - then need to lookup the workflow defaults
+ // for that form (and associated artifacts!) and then save that in list of workflows
+ NodeRef ref = AVMNodeConverter.ToNodeRef(-1, node.getPath());
+ if (this.nodeService.hasAspect(ref, WCMAppModel.ASPECT_FORM_INSTANCE_DATA))
+ {
+ // found an XML form instance data file
+ String formName = (String)this.nodeService.getProperty(ref, WCMAppModel.PROP_PARENT_FORM_NAME);
+ FormWorkflowWrapper wrapper = this.formWorkflowMap.get(formName);
+ if (wrapper.Params != null)
+ {
+ // found a workflow with params attached to the form
+ this.workflows.add(wrapper);
+ }
+ }
+ this.submitItems.add(new ItemWrapper(node));
+ }
+ else
+ {
+ this.warningItems.add(new ItemWrapper(node));
+ }
+ }
+ }
+ else
+ {
+ this.submitItems = Collections.emptyList();
+ this.warningItems = Collections.emptyList();
+ }
+ }
+
+ private boolean hasAssociatedWorkflow(NodeRef ref)
+ {
+ // TODO: does not appear to work for AVM - need a specific impl instead
+ return (this.workflowService.getWorkflowsForContent(ref, true).size() != 0);
+ }
+
+ /**
+ * Construct a workflow package as a layered directory over the users sandbox. The items for
+ * submission are pushed into the layer and the package constructed around it.
+ *
+ * @return Reference to the package
+ */
+ private NodeRef createWorkflowPackage()
+ {
+ // TODO: add to common util class for all AVM workflows
+ String packagesRoot = "workflow-system:/packages";
+ AVMNodeDescriptor packagesDesc = avmService.lookup(-1, packagesRoot);
+ if (packagesDesc == null)
+ {
+ avmService.createAVMStore("workflow-system");
+ avmService.createDirectory("workflow-system:/", "packages");
+ }
+
+ List items = getSubmitItems();
+
+ // create package paths (layered to user sandbox area as target)
+ String sandboxPath = AVMConstants.buildAVMStoreRootPath(avmBrowseBean.getSandbox());
+ String packageName = GUID.generate();
+ String packagesPath = packagesRoot + "/" + packageName;
+ avmService.createLayeredDirectory(sandboxPath, packagesRoot, packageName);
+
+ // construct diffs for selected items
+ List diffs = new ArrayList(this.submitItems.size());
+ for (ItemWrapper wrapper : this.submitItems)
+ {
+ String srcPath = sandboxPath + wrapper.getPath();
+ String destPath = packagesPath + wrapper.getPath();
+ AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER);
+ diffs.add(diff);
+ }
+
+ // write changes to layer so files are marked as modified
+ avmSyncService.update(diffs, true, true, false, false, null, null);
+
+ // convert package to workflow package
+ AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath);
+ NodeRef packageNodeRef = workflowService.createPackage(AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath()));
+ nodeService.setProperty(packageNodeRef, WorkflowModel.PROP_IS_SYSTEM_PACKAGE, true);
+
+ return packageNodeRef;
+ }
+
+
+ /**
+ * Simple structure class to wrap form workflow name and default parameter values
+ */
+ private static class FormWorkflowWrapper
+ {
+ public String Name;
+ public Map Params;
+
+ FormWorkflowWrapper(String name, Map params)
+ {
+ this.Name = name;
+ this.Params = params;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return this.Name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof FormWorkflowWrapper)
+ {
+ return this.Name.equals( ((FormWorkflowWrapper)obj).Name );
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Wrapper class to provide UI RichList component getters for an AVM node descriptor
+ */
+ public class ItemWrapper
+ {
+ private static final String rootPath = '/' + AVMConstants.DIR_WEBAPPS;
+ private AVMNodeDescriptor descriptor;
+
+ public ItemWrapper(AVMNodeDescriptor descriptor)
+ {
+ this.descriptor = descriptor;
+ }
+
+ public String getName()
+ {
+ return descriptor.getName();
+ }
+
+ public String getModifiedDate()
+ {
+ return ISO8601DateFormat.format(new Date(descriptor.getModDate()));
+ }
+
+ public String getDescription()
+ {
+ return (String)nodeService.getProperty(
+ AVMNodeConverter.ToNodeRef(-1, descriptor.getPath()), ContentModel.PROP_DESCRIPTION);
+ }
+
+ public String getPath()
+ {
+ return descriptor.getPath().substring(descriptor.getPath().indexOf(rootPath) + rootPath.length());
+ }
+
+ public String getUrl()
+ {
+ return DownloadContentServlet.generateBrowserURL(
+ AVMNodeConverter.ToNodeRef(-1, descriptor.getPath()), descriptor.getName());
+ }
+
+ public String getIcon()
+ {
+ return Utils.getFileTypeImage(descriptor.getName(), true);
+ }
+ }
+}
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 16fa398920..04447848e3 100644
--- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
+++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
@@ -337,7 +337,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, ACT_SANDBOX_SUBMITALL, "/images/icons/submit_all.gif",
- "#{AVMBrowseBean.submitAll}", null));
+ "#{AVMBrowseBean.setupSubmitAllAction}", "dialog:submitSandboxItems"));
out.write(" ");
Utils.encodeRecursive(context, aquireAction(
@@ -663,7 +663,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
out.write(": ");
Utils.encodeRecursive(fc, aquireAction(
fc, userStorePrefix, username, ACT_SANDBOX_SUBMITSELECTED, "/images/icons/submit_all.gif",
- "#{AVMBrowseBean.submitSelected}", null));
+ "#{AVMBrowseBean.setupSandboxAction}", "dialog:submitSandboxItems"));
out.write(" ");
Utils.encodeRecursive(fc, aquireAction(
fc, userStorePrefix, username, ACT_SANDBOX_REVERTSELECTED, "/images/icons/revert_all.gif",
@@ -1048,7 +1048,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
{
List nodes = null;
- if (username != null)
+ if (username != null && this.checkedItems != null)
{
List paths = this.userNodes.get(username);
if (paths != null)
diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml
index a42d32fa47..1495fd5f69 100644
--- a/source/web/WEB-INF/faces-config-beans.xml
+++ b/source/web/WEB-INF/faces-config-beans.xml
@@ -2726,6 +2726,35 @@
+
+
+ The bean that backs up the Submit dialog
+
+ SubmitDialog
+ org.alfresco.web.bean.wcm.SubmitDialog
+ session
+
+ avmService
+ #{AVMService}
+
+
+ avmSyncService
+ #{AVMSyncService}
+
+
+ avmBrowseBean
+ #{AVMBrowseBean}
+
+
+ workflowService
+ #{WorkflowService}
+
+
+ nodeService
+ #{NodeService}
+
+
+
diff --git a/source/web/images/icons/error.gif b/source/web/images/icons/error.gif
new file mode 100644
index 0000000000..eb841a8a88
Binary files /dev/null and b/source/web/images/icons/error.gif differ
diff --git a/source/web/images/icons/error_large.gif b/source/web/images/icons/error_large.gif
new file mode 100644
index 0000000000..12b6d3ecac
Binary files /dev/null and b/source/web/images/icons/error_large.gif differ
diff --git a/source/web/images/icons/info_icon_large.gif b/source/web/images/icons/info_icon_large.gif
new file mode 100644
index 0000000000..e59c3ca3b2
Binary files /dev/null and b/source/web/images/icons/info_icon_large.gif differ
diff --git a/source/web/images/icons/warning.gif b/source/web/images/icons/warning.gif
new file mode 100644
index 0000000000..e6ebb31230
Binary files /dev/null and b/source/web/images/icons/warning.gif differ
diff --git a/source/web/images/icons/warning_large.gif b/source/web/images/icons/warning_large.gif
new file mode 100644
index 0000000000..2deba21196
Binary files /dev/null and b/source/web/images/icons/warning_large.gif differ
diff --git a/source/web/jsp/wcm/browse-sandbox.jsp b/source/web/jsp/wcm/browse-sandbox.jsp
index 3391dbecc0..15c9a9d9e4 100644
--- a/source/web/jsp/wcm/browse-sandbox.jsp
+++ b/source/web/jsp/wcm/browse-sandbox.jsp
@@ -217,7 +217,6 @@
-
<%-- Description column --%>
diff --git a/source/web/jsp/wcm/submit-dialog.jsp b/source/web/jsp/wcm/submit-dialog.jsp
new file mode 100644
index 0000000000..0a0152d974
--- /dev/null
+++ b/source/web/jsp/wcm/submit-dialog.jsp
@@ -0,0 +1,163 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
+<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
+<%@ page isELIgnored="false" %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
+
+
+
+
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
+
+
+
+ <%-- Primary column for details view mode --%>
+
+
+
+
+
+
+
+
+
+
+ <%-- Description columns --%>
+
+
+
+
+
+
+
+ <%-- Description columns --%>
+
+
+
+
+
+
+
+ <%-- Modified Date column --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
+
+
+
+
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
+
+
+
+ <%-- Primary column for details view mode --%>
+
+
+
+
+
+
+
+
+
+
+ <%-- Description columns --%>
+
+
+
+
+
+
+
+ <%-- Description columns --%>
+
+
+
+
+
+
+
+ <%-- Modified Date column --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+