Merged V1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3876 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3925 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3927 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-09-26 00:02:52 +00:00
parent 7df3c602a1
commit d4c5c3562a
26 changed files with 1299 additions and 461 deletions

View File

@@ -93,7 +93,6 @@ no_categories_applied_space=This space does not yet have any categories applied.
has_following_categories_space=This space has the following categories applied... has_following_categories_space=This space has the following categories applied...
moved=moved moved=moved
copied=copied copied=copied
document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken.
clipboard=Clipboard clipboard=Clipboard
recent_spaces=Recent Spaces recent_spaces=Recent Spaces
shortcuts=Shortcuts shortcuts=Shortcuts
@@ -155,6 +154,7 @@ move=Move
type=Type type=Type
aspect=Aspect aspect=Aspect
workflow=Workflow workflow=Workflow
workflows=Workflows
rules=Rules rules=Rules
system_error=System Error system_error=System Error
login=Login login=Login
@@ -521,7 +521,6 @@ custom_view=Custom View
view_links=Links view_links=Links
not_inline_editable=This document is not inline editable. not_inline_editable=This document is not inline editable.
allow_inline_editing=Allow Inline Editing allow_inline_editing=Allow Inline Editing
not_in_workflow=This document is not part of any workflow.
not_in_category=This document is not categorized. not_in_category=This document is not categorized.
not_in_category_space=This space is not categorized. not_in_category_space=This space is not categorized.
not_versioned=This document has no version history. not_versioned=This document has no version history.
@@ -947,14 +946,24 @@ email_space_users=Email Space users
email_space_users_desc=Send an email to the users and groups assigned to this space. email_space_users_desc=Send an email to the users and groups assigned to this space.
# Workflow messages # Workflow messages
doc_not_in_simple_workflow=This document is not part of a simple workflow.
space_not_in_simple_workflow=This space is not part of a simple workflow.
doc_not_in_advanced_workflow=This document is not part of any advanced workflows.
space_not_in_advanced_workflow=This space is not part of any advanced workflows.
simple_workflow=Simple Workflow
advanced_workflows=Advanced Workflows
document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken.
space_action=The space will be {0} to ''{1}'' if the ''{2}'' action is taken.
doc_part_of_advanced_workflows=This document is part of the following advanced workflow(s)
space_part_of_advanced_workflows=This document is part of the following advanced workflow(s)
modify_workflow_props=Modify Properties of Simple Workflow modify_workflow_props=Modify Properties of Simple Workflow
name_approve_step=Name for approve step name_approve_step=Name for approve step
name_reject_step=Name for reject step name_reject_step=Name for reject step
select_reject_step=Do you want to provide a reject step? select_reject_step=Do you want to provide a reject step?
choose_copy_move_location=Choose whether you want to move or copy the content and also the location. choose_copy_move_location=Choose whether you want to move or copy the content and also the location.
start_workflow=Start Workflow start_workflow=Start Advanced Workflow
start_workflow_wizard=Start New Workflow Wizard start_workflow_wizard=Start Advanced Workflow Wizard
start_workflow_desc=This wizard helps you start a workflow for an item in the repository. start_workflow_desc=This wizard helps you start an advanced workflow for an item in the repository.
available_workflows=Available workflows available_workflows=Available workflows
step_choose_workflow=Choose Workflow step_choose_workflow=Choose Workflow
start_workflow_choose_title=Choose Workflow start_workflow_choose_title=Choose Workflow
@@ -1004,6 +1013,7 @@ save_changes=Save Changes
no_tasks=No tasks found. no_tasks=No tasks found.
no_resources=No resources found. no_resources=No resources found.
in_progress=In Progress in_progress=In Progress
by=by
# Workflow Definitions # Workflow Definitions
wf_review_due_date=Review Due Date wf_review_due_date=Review Due Date

View File

@@ -254,6 +254,54 @@
</params> </params>
</action> </action>
<!-- 'Approve' workflow step for space -->
<action id="approve_space">
<evaluator>org.alfresco.web.action.evaluator.ApproveDocEvaluator</evaluator>
<label>#{actionContext["app:approveStep"]}</label>
<image>/images/icons/approve.gif</image>
<action-listener>#{SpaceDetailsBean.approve}</action-listener>
<action>browse</action>
<params>
<param name="id">#{actionContext.id}</param>
</params>
</action>
<!-- 'Reject' workflow step for space -->
<action id="reject_space">
<evaluator>org.alfresco.web.action.evaluator.RejectDocEvaluator</evaluator>
<label>#{actionContext["app:rejectStep"]}</label>
<image>/images/icons/reject.gif</image>
<action-listener>#{SpaceDetailsBean.reject}</action-listener>
<action>browse</action>
<params>
<param name="id">#{actionContext.id}</param>
</params>
</action>
<!-- 'Approve' workflow step for space details page -->
<action id="approve_space_details">
<evaluator>org.alfresco.web.action.evaluator.ApproveDocEvaluator</evaluator>
<label>#{actionContext.properties["app:approveStep"]}</label>
<image>/images/icons/approve.gif</image>
<action-listener>#{SpaceDetailsBean.approve}</action-listener>
<action>browse</action>
<params>
<param name="id">#{actionContext.id}</param>
</params>
</action>
<!-- 'Reject' workflow step for space details page-->
<action id="reject_space_details">
<evaluator>org.alfresco.web.action.evaluator.RejectDocEvaluator</evaluator>
<label>#{actionContext.properties["app:rejectStep"]}</label>
<image>/images/icons/reject.gif</image>
<action-listener>#{SpaceDetailsBean.reject}</action-listener>
<action>browse</action>
<params>
<param name="id">#{actionContext.id}</param>
</params>
</action>
<!-- Cut a document or space to the clipboard, from browse or doc details screens --> <!-- Cut a document or space to the clipboard, from browse or doc details screens -->
<action id="cut_node"> <action id="cut_node">
<permissions> <permissions>
@@ -361,7 +409,7 @@
<!-- Manage Space Rules --> <!-- Manage Space Rules -->
<action id="manage_space_rules"> <action id="manage_space_rules">
<permissions> <permissions>
<permission allow="true">Write</permission> <permission allow="true">CreateChildren</permission>
</permissions> </permissions>
<label-id>manage_rules</label-id> <label-id>manage_rules</label-id>
<image>/images/icons/rule.gif</image> <image>/images/icons/rule.gif</image>
@@ -555,6 +603,8 @@
<!-- Actions Menu for a space in the Browse screen --> <!-- Actions Menu for a space in the Browse screen -->
<action-group id="space_browse_menu"> <action-group id="space_browse_menu">
<action idref="delete_space" /> <action idref="delete_space" />
<action idref="approve_space" />
<action idref="reject_space" />
</action-group> </action-group>
<!-- Actions Menu for Create in Browse screen --> <!-- Actions Menu for Create in Browse screen -->
@@ -603,6 +653,8 @@
<!-- Actions Menu for Space Details screen --> <!-- Actions Menu for Space Details screen -->
<action-group id="space_details_actions"> <action-group id="space_details_actions">
<action idref="approve_space_details" />
<action idref="reject_space_details" />
<action idref="cut_node" /> <action idref="cut_node" />
<action idref="copy_node" /> <action idref="copy_node" />
<action idref="delete_space" /> <action idref="delete_space" />

View File

@@ -25,18 +25,18 @@
<!-- Definition of the view content properties dialog --> <!-- Definition of the view content properties dialog -->
<dialog name="viewContentProperties" page="/jsp/content/view-content-properties.jsp" <dialog name="viewContentProperties" page="/jsp/content/view-content-properties.jsp"
managed-bean="ViewContentPropertiesDialog" icon="/images/icons/details_large.gif" managed-bean="ViewContentPropertiesDialog" icon="/images/icons/view_properties_large.gif"
title-id="view_content_properties" description-id="view_content_description" title-id="view_content_properties" description-id="view_content_description"
show-ok-button="false" /> show-ok-button="false" />
<!-- Definition of the set content properties dialog --> <!-- Definition of the set content properties dialog -->
<dialog name="setContentProperties" page="/jsp/content/edit-content-properties.jsp" <dialog name="setContentProperties" page="/jsp/content/edit-content-properties.jsp"
managed-bean="SetContentPropertiesDialog" icon="/images/icons/details_large.gif" managed-bean="SetContentPropertiesDialog" icon="/images/icons/edit_properties_large.gif"
title-id="modify_content_properties" description-id="edit_content_description" /> title-id="modify_content_properties" description-id="edit_content_description" />
<!-- Definition of the edit content properties dialog --> <!-- Definition of the edit content properties dialog -->
<dialog name="editContentProperties" page="/jsp/content/edit-content-properties.jsp" <dialog name="editContentProperties" page="/jsp/content/edit-content-properties.jsp"
managed-bean="EditContentPropertiesDialog" icon="/images/icons/details_large.gif" managed-bean="EditContentPropertiesDialog" icon="/images/icons/edit_properties_large.gif"
title-id="modify_content_properties" description-id="edit_content_description" /> title-id="modify_content_properties" description-id="edit_content_description" />
<!-- Definition of the delete content dialog --> <!-- Definition of the delete content dialog -->

View File

@@ -159,6 +159,12 @@
</property-sheet> </property-sheet>
</config> </config>
<config evaluator="aspect-name" condition="cm:ownable">
<property-sheet>
<show-property name="cm:owner" />
</property-sheet>
</config>
<config evaluator="aspect-name" condition="app:inlineeditable"> <config evaluator="aspect-name" condition="app:inlineeditable">
<property-sheet> <property-sheet>
<show-property name="app:editInline" converter="org.alfresco.faces.BooleanLabelConverter" /> <show-property name="app:editInline" converter="org.alfresco.faces.BooleanLabelConverter" />

View File

@@ -16,13 +16,11 @@
*/ */
package org.alfresco.web.action.evaluator; package org.alfresco.web.action.evaluator;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.web.action.ActionEvaluator; import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
/** /**
* UI Action Evaluator - 'Approve' workflow step for document. * UI Action Evaluator - 'Approve' workflow step for document or space.
* *
* @author Kevin Roast * @author Kevin Roast
*/ */

View File

@@ -16,13 +16,11 @@
*/ */
package org.alfresco.web.action.evaluator; package org.alfresco.web.action.evaluator;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.web.action.ActionEvaluator; import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
/** /**
* UI Action Evaluator - 'Reject' workflow step for document. * UI Action Evaluator - 'Reject' workflow step for document or space.
* *
* @author Kevin Roast * @author Kevin Roast
*/ */

View File

@@ -16,6 +16,7 @@
*/ */
package org.alfresco.web.bean; package org.alfresco.web.bean;
import java.io.Serializable;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -25,16 +26,22 @@ import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent; import javax.faces.event.ActionEvent;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.bean.actions.handlers.SimpleWorkflowHandler;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode; import org.alfresco.web.ui.common.Utils.URLMode;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent; import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
/** /**
@@ -58,11 +65,27 @@ public abstract class BaseDetailsBean
/** OwnableService bean reference */ /** OwnableService bean reference */
protected OwnableService ownableService; protected OwnableService ownableService;
/** CopyService bean reference */
protected CopyService copyService;
/** Selected template Id */ /** Selected template Id */
protected String template; protected String template;
/** The map of workflow properties */
protected Map<String, Serializable> workflowProperties;
protected Map<String, Boolean> panels = new HashMap<String, Boolean>(4, 1.0f); protected Map<String, Boolean> panels = new HashMap<String, Boolean>(4, 1.0f);
private static final String MSG_ERROR_WORKFLOW_REJECT = "error_workflow_reject";
private static final String MSG_ERROR_WORKFLOW_APPROVE = "error_workflow_approve";
private static final String MSG_ERROR_UPDATE_SIMPLEWORKFLOW = "error_update_simpleworkflow";
public BaseDetailsBean()
{
// initial state of some panels that don't use the default
panels.put("workflow-panel", false);
panels.put("category-panel", false);
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Bean property getters and setters // Bean property getters and setters
@@ -103,6 +126,16 @@ public abstract class BaseDetailsBean
this.ownableService = ownableService; this.ownableService = ownableService;
} }
/**
* Sets the copy service instance the bean should use
*
* @param copyService The CopyService
*/
public void setCopyService(CopyService copyService)
{
this.copyService = copyService;
}
/** /**
* @return Returns the panels expanded state map. * @return Returns the panels expanded state map.
*/ */
@@ -249,6 +282,302 @@ public abstract class BaseDetailsBean
} }
}; };
/**
* Returns the properties for the attached workflow as a map
*
* @return Properties of the attached workflow, null if there is no workflow
*/
public Map<String, Serializable> getWorkflowProperties()
{
if (this.workflowProperties == null &&
getNode().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
// get the exisiting properties for the document
Map<String, Object> props = getNode().getProperties();
String approveStepName = (String)props.get(
ContentModel.PROP_APPROVE_STEP.toString());
String rejectStepName = (String)props.get(
ContentModel.PROP_REJECT_STEP.toString());
Boolean approveMove = (Boolean)props.get(
ContentModel.PROP_APPROVE_MOVE.toString());
Boolean rejectMove = (Boolean)props.get(
ContentModel.PROP_REJECT_MOVE.toString());
NodeRef approveFolder = (NodeRef)props.get(
ContentModel.PROP_APPROVE_FOLDER.toString());
NodeRef rejectFolder = (NodeRef)props.get(
ContentModel.PROP_REJECT_FOLDER.toString());
// put the workflow properties in a separate map for use by the JSP
this.workflowProperties = new HashMap<String, Serializable>(7);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME,
approveStepName);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_ACTION,
approveMove ? "move" : "copy");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_FOLDER, approveFolder);
if (rejectStepName == null || rejectMove == null || rejectFolder == null)
{
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "no");
}
else
{
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT,
"yes");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME,
rejectStepName);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_ACTION,
rejectMove ? "move" : "copy");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_FOLDER,
rejectFolder);
}
}
return this.workflowProperties;
}
/**
* Cancel Workflow Edit dialog
*/
public String cancelWorkflowEdit()
{
// resets the workflow properties map so any changes made
// don't appear to be persisted
this.workflowProperties.clear();
this.workflowProperties = null;
return "cancel";
}
/**
* Saves the details of the workflow stored in workflowProperties
* to the current document
*
* @return The outcome string
*/
public String saveWorkflow()
{
String outcome = "cancel";
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// firstly retrieve all the properties for the current node
Map<QName, Serializable> updateProps = this.nodeService.getProperties(
getNode().getNodeRef());
// update the simple workflow properties
// set the approve step name
updateProps.put(ContentModel.PROP_APPROVE_STEP,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME));
// specify whether the approve step will copy or move the content
boolean approveMove = true;
String approveAction = (String)this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_ACTION);
if (approveAction != null && approveAction.equals("copy"))
{
approveMove = false;
}
updateProps.put(ContentModel.PROP_APPROVE_MOVE, Boolean.valueOf(approveMove));
// create node ref representation of the destination folder
updateProps.put(ContentModel.PROP_APPROVE_FOLDER,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_FOLDER));
// determine whether there should be a reject step
boolean requireReject = true;
String rejectStepPresent = (String)this.workflowProperties.get(
SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT);
if (rejectStepPresent != null && rejectStepPresent.equals("no"))
{
requireReject = false;
}
if (requireReject)
{
// set the reject step name
updateProps.put(ContentModel.PROP_REJECT_STEP,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME));
// specify whether the reject step will copy or move the content
boolean rejectMove = true;
String rejectAction = (String)this.workflowProperties.get(
SimpleWorkflowHandler.PROP_REJECT_ACTION);
if (rejectAction != null && rejectAction.equals("copy"))
{
rejectMove = false;
}
updateProps.put(ContentModel.PROP_REJECT_MOVE, Boolean.valueOf(rejectMove));
// create node ref representation of the destination folder
updateProps.put(ContentModel.PROP_REJECT_FOLDER,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_FOLDER));
}
else
{
// set all the reject properties to null to signify there should
// be no reject step
updateProps.put(ContentModel.PROP_REJECT_STEP, null);
updateProps.put(ContentModel.PROP_REJECT_MOVE, null);
updateProps.put(ContentModel.PROP_REJECT_FOLDER, null);
}
// set the properties on the node
this.nodeService.setProperties(getNode().getNodeRef(), updateProps);
// commit the transaction
tx.commit();
// reset the state of the current document so it reflects the changes just made
getNode().reset();
outcome = "finish";
}
catch (Throwable e)
{
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_SIMPLEWORKFLOW), e.getMessage()), e);
}
return outcome;
}
/**
* Returns the name of the approve step of the attached workflow
*
* @return The name of the approve step or null if there is no workflow
*/
public String getApproveStepName()
{
String approveStepName = null;
if (getNode().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
approveStepName = (String)getNode().getProperties().get(
ContentModel.PROP_APPROVE_STEP.toString());
}
return approveStepName;
}
/**
* Event handler called to handle the approve step of the simple workflow
*
* @param event The event that was triggered
*/
public void approve(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id == null || id.length() == 0)
{
throw new AlfrescoRuntimeException("approve called without an id");
}
NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// call the service to perform the approve
WorkflowUtil.approve(docNodeRef, this.nodeService, this.copyService);
// commit the transaction
tx.commit();
// if this was called via the document details dialog we need to reset the document node
if (getNode() != null)
{
getNode().reset();
}
// also make sure the UI will get refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_APPROVE), e.getMessage()), e);
}
}
/**
* Returns the name of the reject step of the attached workflow
*
* @return The name of the reject step or null if there is no workflow
*/
public String getRejectStepName()
{
String approveStepName = null;
if (getNode().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
approveStepName = (String)getNode().getProperties().get(
ContentModel.PROP_REJECT_STEP.toString());
}
return approveStepName;
}
/**
* Event handler called to handle the approve step of the simple workflow
*
* @param event The event that was triggered
*/
public void reject(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id == null || id.length() == 0)
{
throw new AlfrescoRuntimeException("reject called without an id");
}
NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// call the service to perform the reject
WorkflowUtil.reject(docNodeRef, this.nodeService, this.copyService);
// commit the transaction
tx.commit();
// if this was called via the document details dialog we need to reset the document node
if (getNode() != null)
{
getNode().reset();
}
// also make sure the UI will get refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_REJECT), e.getMessage()), e);
}
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Action event handlers // Action event handlers

View File

@@ -29,13 +29,11 @@ import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent; import javax.faces.event.ActionEvent;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.version.Version; import org.alfresco.service.cmr.version.Version;
@@ -43,9 +41,7 @@ import org.alfresco.service.cmr.version.VersionHistory;
import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.actions.handlers.SimpleWorkflowHandler;
import org.alfresco.web.bean.repository.MapNode; import org.alfresco.web.bean.repository.MapNode;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.Repository;
@@ -68,17 +64,12 @@ public class DocumentDetailsBean extends BaseDetailsBean
private static final String MSG_ERROR_ASPECT_INLINEEDITABLE = "error_aspect_inlineeditable"; private static final String MSG_ERROR_ASPECT_INLINEEDITABLE = "error_aspect_inlineeditable";
private static final String MSG_ERROR_ASPECT_VERSIONING = "error_aspect_versioning"; private static final String MSG_ERROR_ASPECT_VERSIONING = "error_aspect_versioning";
private static final String MSG_ERROR_ASPECT_CLASSIFY = "error_aspect_classify"; private static final String MSG_ERROR_ASPECT_CLASSIFY = "error_aspect_classify";
private static final String MSG_ERROR_WORKFLOW_REJECT = "error_workflow_reject";
private static final String MSG_ERROR_WORKFLOW_APPROVE = "error_workflow_approve";
private static final String MSG_ERROR_UPDATE_SIMPLEWORKFLOW = "error_update_simpleworkflow";
private static final String MSG_ERROR_UPDATE_CATEGORY = "error_update_category"; private static final String MSG_ERROR_UPDATE_CATEGORY = "error_update_category";
protected LockService lockService; protected LockService lockService;
protected CopyService copyService;
protected VersionService versionService; protected VersionService versionService;
protected CheckOutCheckInService cociService; protected CheckOutCheckInService cociService;
private Map<String, Serializable> workflowProperties;
private NodeRef addedCategory; private NodeRef addedCategory;
private List categories; private List categories;
@@ -91,9 +82,9 @@ public class DocumentDetailsBean extends BaseDetailsBean
*/ */
public DocumentDetailsBean() public DocumentDetailsBean()
{ {
super();
// initial state of some panels that don't use the default // initial state of some panels that don't use the default
panels.put("workflow-panel", false);
panels.put("category-panel", false);
panels.put("version-history-panel", false); panels.put("version-history-panel", false);
} }
@@ -369,391 +360,6 @@ public class DocumentDetailsBean extends BaseDetailsBean
return outcome; return outcome;
} }
/**
* Returns an overview summary of the current state of the attached
* workflow (if any)
*
* @return Summary HTML
*/
public String getWorkflowOverviewHTML()
{
String html = null;
if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
// get the simple workflow aspect properties
Map<String, Object> props = getDocument().getProperties();
String approveStepName = (String)props.get(
ContentModel.PROP_APPROVE_STEP.toString());
String rejectStepName = (String)props.get(
ContentModel.PROP_REJECT_STEP.toString());
Boolean approveMove = (Boolean)props.get(
ContentModel.PROP_APPROVE_MOVE.toString());
Boolean rejectMove = (Boolean)props.get(
ContentModel.PROP_REJECT_MOVE.toString());
NodeRef approveFolder = (NodeRef)props.get(
ContentModel.PROP_APPROVE_FOLDER.toString());
NodeRef rejectFolder = (NodeRef)props.get(
ContentModel.PROP_REJECT_FOLDER.toString());
String approveFolderName = null;
String rejectFolderName = null;
// get the approve folder name
if (approveFolder != null)
{
Node node = new Node(approveFolder);
approveFolderName = node.getName();
}
// get the reject folder name
if (rejectFolder != null)
{
Node node = new Node(rejectFolder);
rejectFolderName = node.getName();
}
StringBuilder builder = new StringBuilder();
// calculate the approve action string
String action = null;
if (approveMove.booleanValue())
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
}
else
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
}
String docActionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "document_action");
Object[] params = new Object[] {action, approveFolderName, approveStepName};
builder.append(MessageFormat.format(docActionPattern, params));
// add details of the reject step if there is one
if (rejectStepName != null && rejectMove != null && rejectFolderName != null)
{
if (rejectMove.booleanValue())
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
}
else
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
}
builder.append("<p>");
params = new Object[] {action, rejectFolderName, rejectStepName};
builder.append(MessageFormat.format(docActionPattern, params));
builder.append("</p>");
}
html = builder.toString();
}
return html;
}
/**
* Returns the properties for the attached workflow as a map
*
* @return Properties of the attached workflow, null if there is no workflow
*/
public Map<String, Serializable> getWorkflowProperties()
{
if (this.workflowProperties == null &&
getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
// get the exisiting properties for the document
Map<String, Object> props = getDocument().getProperties();
String approveStepName = (String)props.get(
ContentModel.PROP_APPROVE_STEP.toString());
String rejectStepName = (String)props.get(
ContentModel.PROP_REJECT_STEP.toString());
Boolean approveMove = (Boolean)props.get(
ContentModel.PROP_APPROVE_MOVE.toString());
Boolean rejectMove = (Boolean)props.get(
ContentModel.PROP_REJECT_MOVE.toString());
NodeRef approveFolder = (NodeRef)props.get(
ContentModel.PROP_APPROVE_FOLDER.toString());
NodeRef rejectFolder = (NodeRef)props.get(
ContentModel.PROP_REJECT_FOLDER.toString());
// put the workflow properties in a separate map for use by the JSP
this.workflowProperties = new HashMap<String, Serializable>(7);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME,
approveStepName);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_ACTION,
approveMove ? "move" : "copy");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_FOLDER, approveFolder);
if (rejectStepName == null || rejectMove == null || rejectFolder == null)
{
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "no");
}
else
{
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT,
"yes");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME,
rejectStepName);
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_ACTION,
rejectMove ? "move" : "copy");
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_FOLDER,
rejectFolder);
}
}
return this.workflowProperties;
}
/**
* Cancel Workflow Edit dialog
*/
public String cancelWorkflowEdit()
{
// resets the workflow properties map so any changes made
// don't appear to be persisted
this.workflowProperties.clear();
this.workflowProperties = null;
return "cancel";
}
/**
* Saves the details of the workflow stored in workflowProperties
* to the current document
*
* @return The outcome string
*/
public String saveWorkflow()
{
String outcome = "cancel";
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// firstly retrieve all the properties for the current node
Map<QName, Serializable> updateProps = this.nodeService.getProperties(
getDocument().getNodeRef());
// update the simple workflow properties
// set the approve step name
updateProps.put(ContentModel.PROP_APPROVE_STEP,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME));
// specify whether the approve step will copy or move the content
boolean approveMove = true;
String approveAction = (String)this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_ACTION);
if (approveAction != null && approveAction.equals("copy"))
{
approveMove = false;
}
updateProps.put(ContentModel.PROP_APPROVE_MOVE, Boolean.valueOf(approveMove));
// create node ref representation of the destination folder
updateProps.put(ContentModel.PROP_APPROVE_FOLDER,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_FOLDER));
// determine whether there should be a reject step
boolean requireReject = true;
String rejectStepPresent = (String)this.workflowProperties.get(
SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT);
if (rejectStepPresent != null && rejectStepPresent.equals("no"))
{
requireReject = false;
}
if (requireReject)
{
// set the reject step name
updateProps.put(ContentModel.PROP_REJECT_STEP,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME));
// specify whether the reject step will copy or move the content
boolean rejectMove = true;
String rejectAction = (String)this.workflowProperties.get(
SimpleWorkflowHandler.PROP_REJECT_ACTION);
if (rejectAction != null && rejectAction.equals("copy"))
{
rejectMove = false;
}
updateProps.put(ContentModel.PROP_REJECT_MOVE, Boolean.valueOf(rejectMove));
// create node ref representation of the destination folder
updateProps.put(ContentModel.PROP_REJECT_FOLDER,
this.workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_FOLDER));
}
else
{
// set all the reject properties to null to signify there should
// be no reject step
updateProps.put(ContentModel.PROP_REJECT_STEP, null);
updateProps.put(ContentModel.PROP_REJECT_MOVE, null);
updateProps.put(ContentModel.PROP_REJECT_FOLDER, null);
}
// set the properties on the node
this.nodeService.setProperties(getDocument().getNodeRef(), updateProps);
// commit the transaction
tx.commit();
// reset the state of the current document so it reflects the changes just made
getDocument().reset();
outcome = "finish";
}
catch (Throwable e)
{
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_SIMPLEWORKFLOW), e.getMessage()), e);
}
return outcome;
}
/**
* Returns the name of the approve step of the attached workflow
*
* @return The name of the approve step or null if there is no workflow
*/
public String getApproveStepName()
{
String approveStepName = null;
if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
approveStepName = (String)getDocument().getProperties().get(
ContentModel.PROP_APPROVE_STEP.toString());
}
return approveStepName;
}
/**
* Event handler called to handle the approve step of the simple workflow
*
* @param event The event that was triggered
*/
public void approve(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id == null || id.length() == 0)
{
throw new AlfrescoRuntimeException("approve called without an id");
}
NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// call the service to perform the approve
WorkflowUtil.approve(docNodeRef, this.nodeService, this.copyService);
// commit the transaction
tx.commit();
// if this was called via the document details dialog we need to reset the document node
if (getDocument() != null)
{
getDocument().reset();
}
// also make sure the UI will get refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_APPROVE), e.getMessage()), e);
}
}
/**
* Returns the name of the reject step of the attached workflow
*
* @return The name of the reject step or null if there is no workflow
*/
public String getRejectStepName()
{
String approveStepName = null;
if (getDocument().hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
approveStepName = (String)getDocument().getProperties().get(
ContentModel.PROP_REJECT_STEP.toString());
}
return approveStepName;
}
/**
* Event handler called to handle the approve step of the simple workflow
*
* @param event The event that was triggered
*/
public void reject(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id == null || id.length() == 0)
{
throw new AlfrescoRuntimeException("reject called without an id");
}
NodeRef docNodeRef = new NodeRef(Repository.getStoreRef(), id);
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// call the service to perform the reject
WorkflowUtil.reject(docNodeRef, this.nodeService, this.copyService);
// commit the transaction
tx.commit();
// if this was called via the document details dialog we need to reset the document node
if (getDocument() != null)
{
getDocument().reset();
}
// also make sure the UI will get refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_WORKFLOW_REJECT), e.getMessage()), e);
}
}
/** /**
* Applies the classifiable aspect to the current document * Applies the classifiable aspect to the current document
*/ */
@@ -1099,16 +705,6 @@ public class DocumentDetailsBean extends BaseDetailsBean
this.versionService = versionService; this.versionService = versionService;
} }
/**
* Sets the copy service instance the bean should use
*
* @param copyService The CopyService
*/
public void setCopyService(CopyService copyService)
{
this.copyService = copyService;
}
/** /**
* Sets the checkincheckout service instance the bean should use * Sets the checkincheckout service instance the bean should use
* *

View File

@@ -71,6 +71,8 @@ public class SpaceDetailsBean extends BaseDetailsBean
*/ */
public SpaceDetailsBean() public SpaceDetailsBean()
{ {
super();
// initial state of some panels that don't use the default // initial state of some panels that don't use the default
panels.put("rules-panel", false); panels.put("rules-panel", false);
panels.put("dashboard-panel", false); panels.put("dashboard-panel", false);

View File

@@ -55,7 +55,7 @@ public class WorkflowUtil
if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false) if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false)
{ {
throw new AlfrescoRuntimeException("Cannot approve a document that is not part of a workflow."); throw new AlfrescoRuntimeException("Cannot approve a node that is not part of a workflow.");
} }
// get the simple workflow aspect properties // get the simple workflow aspect properties
@@ -69,23 +69,28 @@ public class WorkflowUtil
if (approveMove.booleanValue()) if (approveMove.booleanValue())
{ {
// move the document to the specified folder // move the node to the specified folder
String qname = QName.createValidLocalName(docNode.getName()); String qname = QName.createValidLocalName(docNode.getName());
nodeService.moveNode(ref, approveFolder, ContentModel.ASSOC_CONTAINS, nodeService.moveNode(ref, approveFolder, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname)); QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname));
} }
else else
{ {
// copy the document to the specified folder // copy the node to the specified folder
String qname = QName.createValidLocalName(docNode.getName()); String name = docNode.getName();
copyService.copy(ref, approveFolder, ContentModel.ASSOC_CONTAINS, String qname = QName.createValidLocalName(name);
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname)); NodeRef newNode = copyService.copy(ref, approveFolder, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, qname), true);
// the copy service does not copy the name of the node so we
// need to update the property on the copied item
nodeService.setProperty(newNode, ContentModel.PROP_NAME, name);
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
String movedCopied = approveMove ? "moved" : "copied"; String movedCopied = approveMove ? "moved" : "copied";
logger.debug("Document has been approved and " + movedCopied + " to folder with id of " + logger.debug("Node has been approved and " + movedCopied + " to folder with id of " +
approveFolder.getId()); approveFolder.getId());
} }
} }
@@ -106,7 +111,7 @@ public class WorkflowUtil
if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false) if (docNode.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW) == false)
{ {
throw new AlfrescoRuntimeException("Cannot reject a document that is not part of a workflow."); throw new AlfrescoRuntimeException("Cannot reject a node that is not part of a workflow.");
} }
// get the simple workflow aspect properties // get the simple workflow aspect properties
@@ -118,7 +123,7 @@ public class WorkflowUtil
if (rejectStep == null && rejectMove == null && rejectFolder == null) if (rejectStep == null && rejectMove == null && rejectFolder == null)
{ {
throw new AlfrescoRuntimeException("The workflow does not have a reject step defined,"); throw new AlfrescoRuntimeException("The workflow does not have a reject step defined.");
} }
// first we need to take off the simpleworkflow aspect // first we need to take off the simpleworkflow aspect
@@ -142,7 +147,7 @@ public class WorkflowUtil
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
String movedCopied = rejectMove ? "moved" : "copied"; String movedCopied = rejectMove ? "moved" : "copied";
logger.debug("Document has been rejected and " + movedCopied + " to folder with id of " + logger.debug("Node has been rejected and " + movedCopied + " to folder with id of " +
rejectFolder.getId()); rejectFolder.getId());
} }
} }

View File

@@ -15,6 +15,10 @@ import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
@@ -141,8 +145,9 @@ public class ReassignTaskDialog extends BaseDialogBean
// build xpath to match available User/Person objects // build xpath to match available User/Person objects
NodeRef peopleRef = personService.getPeopleContainer(); NodeRef peopleRef = personService.getPeopleContainer();
// NOTE: see SearcherComponentTest // NOTE: see SearcherComponentTest
String xpath = "*[like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "firstName, '%" + contains + "%', false)" + String xpath = "*[not(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "userName='guest') and " +
" or " + "like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "lastName, '%" + contains + "%', false)]"; "(like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "firstName, '%" + contains + "%', false)" +
" or " + "like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "lastName, '%" + contains + "%', false))]";
List<NodeRef> nodes = searchService.selectNodes( List<NodeRef> nodes = searchService.selectNodes(
peopleRef, peopleRef,

View File

@@ -0,0 +1,349 @@
package org.alfresco.web.ui.repo.component;
import java.io.IOException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
/**
* JSF component that displays information about the workflows a node is involved in.
* <p>
* The node to show workflow information on.
*
* @author gavinc
*/
public class UINodeWorkflowInfo extends SelfRenderingComponent
{
protected Node value = null;
// ------------------------------------------------------------------------------
// Component Impl
@Override
public String getFamily()
{
return "org.alfresco.faces.NodeWorkflowInfo";
}
@Override
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.value = (Node)values[1];
}
@Override
public Object saveState(FacesContext context)
{
Object values[] = new Object[8];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.value;
return values;
}
@Override
@SuppressWarnings("unchecked")
public void encodeBegin(FacesContext context) throws IOException
{
if (!isRendered()) return;
// get the node to display the information for
Node node = getValue();
if (node != null)
{
// get the services we need
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
DictionaryService ddService = Repository.getServiceRegistry(context).getDictionaryService();
WorkflowService workflowService = Repository.getServiceRegistry(context).getWorkflowService();
ResponseWriter out = context.getResponseWriter();
ResourceBundle bundle = Application.getBundle(context);
// render simple workflow info
renderSimpleWorkflowInfo(context, node, nodeService, ddService, out, bundle);
// render advanced workflow info
renderAdvancedWorkflowInfo(context, node, nodeService, ddService, workflowService, out, bundle);
}
}
@Override
public void encodeEnd(FacesContext context) throws IOException
{
if (!isRendered()) return;
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* Get the value, this will be a node representing a piece of content or a space
*
* @return the value
*/
public Node getValue()
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = (Node)vb.getValue(getFacesContext());
}
return this.value;
}
/**
* Set the value, either a space or content node.
*
* @param value the value
*/
public void setValue(Node value)
{
this.value = value;
}
// ------------------------------------------------------------------------------
// Helper methods
/**
* Renders the simple workflow details for the given node.
*
* @param context Faces context
* @param node The node
* @param nodeService The NodeService instance
* @param ddService The Data Dictionary instance
* @param out The response writer
* @param bundle Message bundle to get strings from
*/
protected void renderSimpleWorkflowInfo(FacesContext context, Node node,
NodeService nodeService, DictionaryService ddService,
ResponseWriter out, ResourceBundle bundle)
throws IOException
{
boolean isContent = true;
QName type = nodeService.getType(node.getNodeRef());
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
{
isContent = false;
}
// Render HTML for simple workflow
if (isContent)
{
// TODO: for now we only support advanced workflow on content so only
// render the simple workflow title if the node is a content node
out.write("<div class=\"nodeWorkflowInfoTitle\">");
out.write(bundle.getString("simple_workflow"));
out.write("</div>");
}
out.write("<div class=\"nodeWorkflowInfoText\">");
if (node.hasAspect(ContentModel.ASPECT_SIMPLE_WORKFLOW))
{
// get the simple workflow aspect properties
Map<String, Object> props = node.getProperties();
String approveStepName = (String)props.get(
ContentModel.PROP_APPROVE_STEP.toString());
String rejectStepName = (String)props.get(
ContentModel.PROP_REJECT_STEP.toString());
Boolean approveMove = (Boolean)props.get(
ContentModel.PROP_APPROVE_MOVE.toString());
Boolean rejectMove = (Boolean)props.get(
ContentModel.PROP_REJECT_MOVE.toString());
NodeRef approveFolder = (NodeRef)props.get(
ContentModel.PROP_APPROVE_FOLDER.toString());
NodeRef rejectFolder = (NodeRef)props.get(
ContentModel.PROP_REJECT_FOLDER.toString());
String approveFolderName = null;
String rejectFolderName = null;
// get the approve folder name
if (approveFolder != null)
{
Node approveNode = new Node(approveFolder);
approveFolderName = approveNode.getName();
}
// get the reject folder name
if (rejectFolder != null)
{
Node rejectNode = new Node(rejectFolder);
rejectFolderName = rejectNode.getName();
}
// calculate the approve action string
String action = null;
if (approveMove.booleanValue())
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
}
else
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
}
String actionPattern = null;
if (isContent)
{
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "document_action");
}
else
{
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "space_action");
}
Object[] params = new Object[] {action, approveFolderName, approveStepName};
out.write(MessageFormat.format(actionPattern, params));
// add details of the reject step if there is one
if (rejectStepName != null && rejectMove != null && rejectFolderName != null)
{
if (rejectMove.booleanValue())
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
}
else
{
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
}
out.write("&nbsp;");
params = new Object[] {action, rejectFolderName, rejectStepName};
out.write(MessageFormat.format(actionPattern, params));
}
}
else
{
// work out which no workflow message to show depending on the node type
if (isContent)
{
out.write(bundle.getString("doc_not_in_simple_workflow"));
}
else
{
out.write(bundle.getString("space_not_in_simple_workflow"));
}
}
out.write("</div>");
}
/**
* Renders the advanced workflow details for the given node.
*
* @param context Faces context
* @param node The node
* @param nodeService The NodeService instance
* @param ddService The Data Dictionary instance
* @param workflowService The WorkflowService instance
* @param out The response writer
* @param bundle Message bundle to get strings from
*/
protected void renderAdvancedWorkflowInfo(FacesContext context, Node node,
NodeService nodeService, DictionaryService ddService, WorkflowService workflowService,
ResponseWriter out, ResourceBundle bundle)
throws IOException
{
boolean isContent = true;
QName type = nodeService.getType(node.getNodeRef());
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
{
isContent = false;
}
// TODO: for now we only support advanced workflow on content so don't render
// anything for other types
if (isContent)
{
// Render HTML for advanved workflow
out.write("<div class=\"nodeWorkflowInfoTitle\">");
out.write(bundle.getString("advanced_workflows"));
out.write("</div><div class=\"nodeWorkflowInfoText\">");
List<WorkflowInstance> workflows = workflowService.getWorkflowsForContent(
node.getNodeRef(), true);
if (workflows != null && workflows.size() > 0)
{
SimpleDateFormat format = new SimpleDateFormat(bundle.getString("date_pattern"));
// list out all the workflows the document is part of
if (isContent)
{
out.write(bundle.getString("doc_part_of_advanced_workflows"));
}
else
{
out.write(bundle.getString("space_part_of_advanced_workflows"));
}
out.write(":<br/><ul>");
for (WorkflowInstance wi : workflows)
{
out.write("<li>");
out.write(wi.definition.title);
if (wi.definition.description != null && wi.definition.description.length() > 0)
{
out.write(" (");
out.write(wi.definition.description);
out.write(")");
}
out.write("&nbsp;");
if (wi.startDate != null)
{
out.write(bundle.getString("started_on").toLowerCase());
out.write("&nbsp;");
out.write(format.format(wi.startDate));
out.write("&nbsp;");
}
if (wi.initiator != null)
{
out.write(bundle.getString("by"));
out.write("&nbsp;");
String userName = (String)nodeService.getProperty(wi.initiator,
ContentModel.PROP_USERNAME);
out.write(userName);
out.write(".");
}
out.write("</li>");
}
out.write("</ul>");
}
else
{
if (isContent)
{
out.write(bundle.getString("doc_not_in_advanced_workflow"));
}
else
{
out.write(bundle.getString("space_not_in_advanced_workflow"));
}
}
out.write("</div>");
}
}
}

View File

@@ -18,6 +18,7 @@
package org.alfresco.web.ui.repo.component.property; package org.alfresco.web.ui.repo.component.property;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -37,7 +38,9 @@ import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
@@ -701,7 +704,12 @@ public abstract class BaseAssociationEditor extends UIInput
if (ContentModel.TYPE_PERSON.equals(nodeService.getType(targetRef))) if (ContentModel.TYPE_PERSON.equals(nodeService.getType(targetRef)))
{ {
out.write((String)nodeService.getProperty(targetRef, ContentModel.PROP_USERNAME)); //out.write((String)nodeService.getProperty(targetRef, ContentModel.PROP_USERNAME));
Map<QName, Serializable> props = nodeService.getProperties(targetRef);
String firstName = (String)props.get(ContentModel.PROP_FIRSTNAME);
String lastName = (String)props.get(ContentModel.PROP_LASTNAME);
String fullName = firstName + " " + (lastName != null ? lastName : "");
out.write(fullName);
} }
else else
{ {
@@ -821,24 +829,36 @@ public abstract class BaseAssociationEditor extends UIInput
item.getId().equals(currentNode.getId()) == false) || item.getId().equals(currentNode.getId()) == false) ||
this.removed.containsKey(item.getId())) this.removed.containsKey(item.getId()))
{ {
out.write("<option value='");
out.write(item.getId());
out.write("'>");
// if the node represents a person, show the username instead of the name // if the node represents a person, show the username instead of the name
if (ContentModel.TYPE_PERSON.equals(nodeService.getType(item))) if (ContentModel.TYPE_PERSON.equals(nodeService.getType(item)))
{ {
out.write((String)nodeService.getProperty(item, ContentModel.PROP_USERNAME)); Map<QName, Serializable> props = nodeService.getProperties(item);
String userName = (String)props.get(ContentModel.PROP_USERNAME);
if (userName != null && (userName.equals(PermissionService.GUEST_AUTHORITY) == false))
{
out.write("<option value='");
out.write(item.getId());
out.write("'>");
String firstName = (String)props.get(ContentModel.PROP_FIRSTNAME);
String lastName = (String)props.get(ContentModel.PROP_LASTNAME);
String fullName = firstName + " " + (lastName != null ? lastName : "");
out.write(fullName);
out.write("</option>");
}
} }
else else
{ {
out.write("<option value='");
out.write(item.getId());
out.write("'>");
out.write(Repository.getDisplayPath(nodeService.getPath(item))); out.write(Repository.getDisplayPath(nodeService.getPath(item)));
out.write("/"); out.write("/");
out.write(Repository.getNameForNode(nodeService, item)); out.write(Repository.getNameForNode(nodeService, item));
}
out.write("</option>"); out.write("</option>");
} }
} }
} }
}
out.write("</select></td></tr>"); out.write("</select></td></tr>");
} }
@@ -877,34 +897,52 @@ public abstract class BaseAssociationEditor extends UIInput
if (contains != null && contains.length() > 0) if (contains != null && contains.length() > 0)
{ {
String safeContains = Utils.remove(contains.trim(), "\""); String safeContains = Utils.remove(contains.trim(), "\"");
query.append(" AND +@");
// if the association's target is the person type search on the // if the association's target is the person type search on the
// username instead of the name property // firstName and lastName properties instead of the name property
if (type.equals(ContentModel.TYPE_PERSON.toString())) if (type.equals(ContentModel.TYPE_PERSON.toString()))
{ {
String userName = Repository.escapeQName(QName.createQName( query.append(" AND (@");
NamespaceService.CONTENT_MODEL_1_0_URI, "userName")); String firstName = Repository.escapeQName(QName.createQName(
query.append(userName); NamespaceService.CONTENT_MODEL_1_0_URI, "firstName"));
query.append(firstName);
query.append(":*" + safeContains + "*");
query.append(" OR @");
String lastName = Repository.escapeQName(QName.createQName(
NamespaceService.CONTENT_MODEL_1_0_URI, "lastName"));
query.append(lastName);
query.append(":*" + safeContains + "*)");
} }
else else
{ {
query.append(" AND +@");
String nameAttr = Repository.escapeQName(QName.createQName( String nameAttr = Repository.escapeQName(QName.createQName(
NamespaceService.CONTENT_MODEL_1_0_URI, "name")); NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
query.append(nameAttr); query.append(nameAttr);
}
query.append(":*" + safeContains + "*"); query.append(":*" + safeContains + "*");
} }
}
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Query: " + query.toString()); logger.debug("Query: " + query.toString());
SearchParameters searchParams = new SearchParameters();
searchParams.addStore(Repository.getStoreRef());
searchParams.setLanguage(SearchService.LANGUAGE_LUCENE);
searchParams.setQuery(query.toString());
if (type.equals(ContentModel.TYPE_PERSON.toString()))
{
searchParams.addSort("@" + ContentModel.PROP_LASTNAME, true);
if (logger.isDebugEnabled())
logger.debug("Added lastname as sort column to query for people");
}
ResultSet results = null; ResultSet results = null;
try try
{ {
results = Repository.getServiceRegistry(context).getSearchService().query( results = Repository.getServiceRegistry(context).getSearchService().query(searchParams);
Repository.getStoreRef(), SearchService.LANGUAGE_LUCENE, query.toString());
this.availableOptions = results.getNodeRefs(); this.availableOptions = results.getNodeRefs();
} }
finally finally

View File

@@ -0,0 +1,77 @@
/*
* 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.ui.repo.tag;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.HtmlComponentTag;
/**
* Tag class for the UINodeWorkflowInfo component
*
* @author gavinc
*/
public class NodeWorkflowInfoTag extends HtmlComponentTag
{
private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.NodeWorkflowInfo";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringBindingProperty(component, "value", this.value);
}
/**
* @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
*/
public void release()
{
super.release();
this.value = null;
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
}

View File

@@ -1120,6 +1120,10 @@
<property-name>ownableService</property-name> <property-name>ownableService</property-name>
<value>#{OwnableService}</value> <value>#{OwnableService}</value>
</managed-property> </managed-property>
<managed-property>
<property-name>copyService</property-name>
<value>#{CopyService}</value>
</managed-property>
</managed-bean> </managed-bean>
<managed-bean> <managed-bean>

View File

@@ -293,6 +293,10 @@
<from-outcome>editCategories</from-outcome> <from-outcome>editCategories</from-outcome>
<to-view-id>/jsp/dialog/edit-space-category.jsp</to-view-id> <to-view-id>/jsp/dialog/edit-space-category.jsp</to-view-id>
</navigation-case> </navigation-case>
<navigation-case>
<from-outcome>editSimpleWorkflow</from-outcome>
<to-view-id>/jsp/dialog/edit-space-simple-workflow.jsp</to-view-id>
</navigation-case>
</navigation-rule> </navigation-rule>
<navigation-rule> <navigation-rule>
@@ -343,6 +347,18 @@
</navigation-case> </navigation-case>
</navigation-rule> </navigation-rule>
<navigation-rule>
<from-view-id>/jsp/dialog/edit-space-simple-workflow.jsp</from-view-id>
<navigation-case>
<from-outcome>cancel</from-outcome>
<to-view-id>/jsp/dialog/space-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>finish</from-outcome>
<to-view-id>/jsp/dialog/space-details.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule> <navigation-rule>
<from-view-id>/jsp/dialog/edit-category.jsp</from-view-id> <from-view-id>/jsp/dialog/edit-category.jsp</from-view-id>
<navigation-case> <navigation-case>

View File

@@ -154,6 +154,11 @@
<component-class>org.alfresco.web.ui.repo.component.UIWorkflowSummary</component-class> <component-class>org.alfresco.web.ui.repo.component.UIWorkflowSummary</component-class>
</component> </component>
<component>
<component-type>org.alfresco.faces.NodeWorkflowInfo</component-type>
<component-class>org.alfresco.web.ui.repo.component.UINodeWorkflowInfo</component-class>
</component>
<!-- ==================== CONVERTERS ==================== --> <!-- ==================== CONVERTERS ==================== -->
<component> <component>
<component-type>org.alfresco.faces.PermissionEvaluator</component-type> <component-type>org.alfresco.faces.PermissionEvaluator</component-type>

View File

@@ -1610,6 +1610,29 @@
</attribute> </attribute>
</tag> </tag>
<tag>
<name>nodeWorkflowInfo</name>
<tag-class>org.alfresco.web.ui.repo.tag.NodeWorkflowInfoTag</tag-class>
<body-content>JSP</body-content>
<description>
The nodeWorkflowInfo component displays information about the workflows
a node is currently involved in.
</description>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag> <tag>
<name>dialogButtons</name> <name>dialogButtons</name>
<tag-class>org.alfresco.web.ui.repo.tag.DialogButtonsTag</tag-class> <tag-class>org.alfresco.web.ui.repo.tag.DialogButtonsTag</tag-class>

View File

@@ -546,3 +546,16 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl
padding-right: 9px; padding-right: 9px;
padding-top: 4px; padding-top: 4px;
} }
.nodeWorkflowInfoTitle
{
font-weight: bold;
color: #003366;
padding-top: 3px;
padding-bottom: 3px;
}
.nodeWorkflowInfoText
{
padding-bottom: 8px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -190,6 +190,15 @@
</div> </div>
<table border=0 cellspacing=2 cellpadding=2> <table border=0 cellspacing=2 cellpadding=2>
<tr>
<td width=50% align=right>
Kofax Release Script:
</td>
<td>&nbsp;&#8226;&nbsp;</td>
<td width=50%>
<img src="<%=request.getContextPath()%>/images/logo/ardenringcroft_logo.png" border=0 alt="Arden Ringcroft">
</td>
</tr>
<tr> <tr>
<td width=50% align=right> <td width=50% align=right>
Meta Data Extraction Framework and PDF/Open Office Format meta data extraction: Meta Data Extraction Framework and PDF/Open Office Format meta data extraction:

View File

@@ -180,7 +180,7 @@
<h:panelGroup id="props-panel-facets"> <h:panelGroup id="props-panel-facets">
<f:facet name="title"> <f:facet name="title">
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write"> <r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write">
<a:actionLink id="titleLink1" value="#{msg.modify}" showLink="false" image="/images/icons/Change_details.gif" <a:actionLink id="titleLink1" value="#{msg.modify}" showLink="false" image="/images/icons/edit_properties.gif"
action="dialog:editContentProperties" /> action="dialog:editContentProperties" />
</r:permissionEvaluator> </r:permissionEvaluator>
</f:facet> </f:facet>
@@ -263,19 +263,16 @@
<h:panelGroup id="workflow-panel-facets"> <h:panelGroup id="workflow-panel-facets">
<f:facet name="title"> <f:facet name="title">
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write"> <r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write">
<a:actionLink id="titleLink2" value="#{msg.workflow}" showLink="false" image="/images/icons/Change_details.gif" action="editSimpleWorkflow" /> <a:actionLink id="titleLink2" value="#{msg.title_edit_simple_workflow}" showLink="false"
image="/images/icons/Change_details.gif" action="editSimpleWorkflow"
rendered="#{DocumentDetailsBean.approveStepName != null}" />
</r:permissionEvaluator> </r:permissionEvaluator>
</f:facet> </f:facet>
</h:panelGroup> </h:panelGroup>
<a:panel label="#{msg.workflow}" id="workflow-panel" facetsId="workflow-panel-facets" progressive="true" <a:panel label="#{msg.workflows}" id="workflow-panel" facetsId="workflow-panel-facets" progressive="true"
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE" rendered="#{DocumentDetailsBean.approveStepName != null}" border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE"
expanded='#{DocumentDetailsBean.panels["workflow-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}"> expanded='#{DocumentDetailsBean.panels["workflow-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<h:outputText id="workflow-overview" value="#{DocumentDetailsBean.workflowOverviewHTML}" escape="false" /> <r:nodeWorkflowInfo id="workflow-info" value="#{DocumentDetailsBean.document}" />
</a:panel>
<a:panel label="#{msg.workflow}" id="no-workflow-panel" progressive="true"
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE" rendered="#{DocumentDetailsBean.approveStepName == null}"
expanded='#{DocumentDetailsBean.panels["workflow-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<h:outputText id="no-workflow-msg" value="#{msg.not_in_workflow}" />
</a:panel> </a:panel>
<div style="padding:4px"></div> <div style="padding:4px"></div>

View File

@@ -0,0 +1,289 @@
<%--
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="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
<%@ page isELIgnored="false" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<r:page titleId="title_edit_simple_workflow">
<script language="JavaScript1.2">
window.onload = pageLoaded;
function pageLoaded()
{
document.getElementById("edit-simple-workflow:approve-step-name").focus();
checkButtonState();
}
function checkButtonState()
{
if (document.getElementById("edit-simple-workflow:approve-step-name").value.length == 0 ||
document.getElementById("edit-simple-workflow:client-approve-folder_selected").value.length == 0 ||
rejectValid() == false)
{
document.getElementById("edit-simple-workflow:ok-button").disabled = true;
}
else
{
document.getElementById("edit-simple-workflow:ok-button").disabled = false;
}
}
function rejectValid()
{
var result = true;
if (document.forms['edit-simple-workflow']['edit-simple-workflow:reject-step-present'][0].checked &&
(document.getElementById("edit-simple-workflow:reject-step-name").value.length == 0 ||
document.getElementById("edit-simple-workflow:client-reject-folder_selected").value.length == 0))
{
result = false;
}
return result;
}
</script>
<f:view>
<%-- load a bundle of properties with I18N strings --%>
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
<h:form acceptCharset="UTF-8" id="edit-simple-workflow">
<%-- Main outer table --%>
<table cellspacing="0" cellpadding="2">
<%-- Title bar --%>
<tr>
<td colspan="2">
<%@ include file="../parts/titlebar.jsp" %>
</td>
</tr>
<%-- Main area --%>
<tr valign="top">
<%-- Shelf --%>
<td>
<%@ include file="../parts/shelf.jsp" %>
</td>
<%-- Work Area --%>
<td width="100%">
<table cellspacing="0" cellpadding="0" width="100%">
<%-- Breadcrumb --%>
<%@ include file="../parts/breadcrumb.jsp" %>
<%-- Status and Actions --%>
<tr>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)" width="4"></td>
<td bgcolor="#EEEEEE">
<%-- Status and Actions inner contents table --%>
<%-- Generally this consists of an icon, textual summary and actions for the current object --%>
<table cellspacing="4" cellpadding="0" width="100%">
<tr>
<td width="32">
<h:graphicImage id="wizard-logo" url="/images/icons/edit_large.gif" />
</td>
<td>
<div class="mainTitle"><h:outputText value="#{msg.modify_workflow_props}" /></div>
<div class="mainSubText"><h:outputText value="#{msg.editworkflow_description}" /></div>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with gradient shadow --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif" width="4" height="9"></td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif" width="4" height="9"></td>
</tr>
<%-- Details --%>
<tr valign=top>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
<td>
<table cellspacing="0" cellpadding="3" border="0" width="100%">
<tr>
<td width="100%" valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
<table cellpadding="2" cellspacing="2" border="0" width="100%">
<tr>
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.approve_flow}" /></td>
</tr>
<tr>
<td><nobr><h:outputText value="#{msg.name_approve_step}" />:</nobr></td>
<td width="90%">
<h:inputText id="approve-step-name" value="#{SpaceDetailsBean.workflowProperties.approveStepName}"
onkeyup="javascript:checkButtonState();" />
</td>
</tr>
<tr><td colspan="2" class="paddingRow"></td></tr>
<tr><td colspan="2"><h:outputText value="#{msg.choose_copy_move_location}" /></td>
<tr>
<td colspan="2">
<table cellpadding="2" cellspacing="2" border="0">
<tr>
<td valign="top">
<h:selectOneRadio value="#{SpaceDetailsBean.workflowProperties.approveAction}">
<f:selectItem itemValue="move" itemLabel="Move" />
<f:selectItem itemValue="copy" itemLabel="Copy" />
</h:selectOneRadio>
</td>
<td style="padding-left:6px;"></td>
<td valign="top" style="padding-top:10px;"><h:outputText value="#{msg.to}" />:</td>
<td style="padding-left:6px;"></td>
<td style="padding-top:6px;">
<r:spaceSelector id="client-approve-folder" label="#{msg.select_destination_prompt}"
value="#{SpaceDetailsBean.workflowProperties.approveFolder}"
initialSelection="#{NavigationBean.currentNodeId}"
styleClass="selector"/>
</td>
</tr>
</table>
</td>
</tr>
<tr><td colspan="2" class="paddingRow"></td></tr>
<tr>
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.reject_flow}" /></td>
</tr>
<tr>
<td colspan="2"><h:outputText value="#{msg.select_reject_step}" /></td>
</tr>
<tr>
<td>
<h:selectOneRadio id="reject-step-present" value="#{SpaceDetailsBean.workflowProperties.rejectStepPresent}"
onclick="javascript:checkButtonState();">
<f:selectItem itemValue="yes" itemLabel="#{msg.yes}" />
<f:selectItem itemValue="no" itemLabel="#{msg.no}" />
</h:selectOneRadio>
</td>
</tr>
<tr>
<td colspan="2">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-left:24px;"></td>
<td>
<table cellpadding="2" cellspacing="2" border="0">
<tr>
<td><nobr>
<h:outputText value="#{msg.name_reject_step}" />:&nbsp;
<h:inputText id="reject-step-name" value="#{SpaceDetailsBean.workflowProperties.rejectStepName}"
onkeyup="javascript:checkButtonState();" />
</nobr></td>
</tr>
<tr><td class="paddingRow"></td></tr>
<tr><td><h:outputText value="#{msg.choose_copy_move_location}" /></td>
<tr>
<td>
<table cellpadding="2" cellspacing="2" border="0">
<tr>
<td valign="top">
<h:selectOneRadio value="#{SpaceDetailsBean.workflowProperties.rejectAction}">
<f:selectItem itemValue="move" itemLabel="#{msg.move}" />
<f:selectItem itemValue="copy" itemLabel="#{msg.copy}" />
</h:selectOneRadio>
</td>
<td style="padding-left:6px;"></td>
<td valign="top" style="padding-top:10px;"><h:outputText value="#{msg.to}" />:</td>
<td style="padding-left:6px;"></td>
<td style="padding-top:6px;">
<r:spaceSelector id="client-reject-folder"
label="#{msg.select_destination_prompt}"
value="#{SpaceDetailsBean.workflowProperties.rejectFolder}"
initialSelection="#{NavigationBean.currentNodeId}"
styleClass="selector"/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
</td>
<td valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
<table cellpadding="1" cellspacing="1" border="0">
<tr>
<td align="center">
<h:commandButton id="ok-button" value="#{msg.ok}" action="#{SpaceDetailsBean.saveWorkflow}"
styleClass="wizardButton" />
</td>
</tr>
<tr><td class="wizardButtonSpacing"></td></tr>
<tr>
<td align="center">
<h:commandButton value="#{msg.cancel}" action="#{SpaceDetailsBean.cancelWorkflowEdit}"
styleClass="wizardButton" />
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
</tr>
<%-- Error Messages --%>
<tr valign="top">
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
<td>
<%-- messages tag to show messages not handled by other specific message tags --%>
<h:messages globalOnly="true" styleClass="errorMessage" layout="table" />
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with bottom panel graphics --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif" width="4" height="4"></td>
<td width="100%" align="center" style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif" width="4" height="4"></td>
</tr>
</table>
</td>
</tr>
</table>
</h:form>
</f:view>
</r:page>

View File

@@ -161,7 +161,7 @@
<h:panelGroup id="props-panel-facets"> <h:panelGroup id="props-panel-facets">
<f:facet name="title"> <f:facet name="title">
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write"> <r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write">
<a:actionLink id="titleLink1" value="#{msg.modify}" showLink="false" image="/images/icons/Change_details.gif" <a:actionLink id="titleLink1" value="#{msg.modify}" showLink="false" image="/images/icons/edit_properties.gif"
action="dialog:editSpace" /> action="dialog:editSpace" />
</r:permissionEvaluator> </r:permissionEvaluator>
</f:facet> </f:facet>
@@ -201,6 +201,23 @@
<div style="padding:4px"></div> <div style="padding:4px"></div>
<h:panelGroup id="workflow-panel-facets">
<f:facet name="title">
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write">
<a:actionLink id="titleLink4" value="#{msg.title_edit_simple_workflow}" showLink="false"
image="/images/icons/Change_details.gif" action="editSimpleWorkflow"
rendered="#{SpaceDetailsBean.approveStepName != null}" />
</r:permissionEvaluator>
</f:facet>
</h:panelGroup>
<a:panel label="#{msg.workflows}" id="workflow-panel" facetsId="workflow-panel-facets" progressive="true"
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE"
expanded='#{SpaceDetailsBean.panels["workflow-panel"]}' expandedActionListener="#{SpaceDetailsBean.expandPanel}">
<r:nodeWorkflowInfo id="workflow-info" value="#{SpaceDetailsBean.space}" />
</a:panel>
<div style="padding:4px"></div>
<h:panelGroup id="category-panel-facets"> <h:panelGroup id="category-panel-facets">
<f:facet name="title"> <f:facet name="title">
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write"> <r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write">