mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
- Next checkpoint of workflow
- Made the date picker renderer allow user to set date to "None" git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3554 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -182,6 +182,9 @@ lock=Lock
|
|||||||
unlock=Unlock
|
unlock=Unlock
|
||||||
items_per_page=Items Per Page
|
items_per_page=Items Per Page
|
||||||
raise_issue=Raise an Issue
|
raise_issue=Raise an Issue
|
||||||
|
click_to_set_date=Click to set a date
|
||||||
|
today=Today
|
||||||
|
reset=Reset
|
||||||
|
|
||||||
# Properties
|
# Properties
|
||||||
username=User Name
|
username=User Name
|
||||||
@@ -935,9 +938,11 @@ start_workflow_options_desc=Select options for the workflow
|
|||||||
start_workflow_finish_instruction=To start the workflow press Finish. To review or change your selections click Back.
|
start_workflow_finish_instruction=To start the workflow press Finish. To review or change your selections click Back.
|
||||||
start_workflow_no_metadata=There is no metadata to collect for this particular workflow.
|
start_workflow_no_metadata=There is no metadata to collect for this particular workflow.
|
||||||
users_and_roles=Users and their Roles
|
users_and_roles=Users and their Roles
|
||||||
|
resources=Resources
|
||||||
manage_workitem=Manage WorkItem
|
manage_workitem=Manage WorkItem
|
||||||
manage_workitem_title=Manage WorkItem
|
manage_workitem_title=Manage WorkItem
|
||||||
manage_workitem_desc=This dialog allows the work item to be managed
|
manage_workitem_desc=This dialog allows the work item to be managed
|
||||||
|
workitem_properties=Work Item Properties
|
||||||
id=Id
|
id=Id
|
||||||
status=Status
|
status=Status
|
||||||
my_workitems_todo_title=My Work Items To Do
|
my_workitems_todo_title=My Work Items To Do
|
||||||
@@ -949,6 +954,7 @@ completed_on=Completed on
|
|||||||
outcome=Outcome
|
outcome=Outcome
|
||||||
reassign=Reassign
|
reassign=Reassign
|
||||||
|
|
||||||
|
|
||||||
# Admin Console messages
|
# Admin Console messages
|
||||||
title_admin_console=Administration Console
|
title_admin_console=Administration Console
|
||||||
admin_console=Administration Console
|
admin_console=Administration Console
|
||||||
|
@@ -7,18 +7,18 @@
|
|||||||
<config evaluator="node-type" condition="bpm:workflowTask">
|
<config evaluator="node-type" condition="bpm:workflowTask">
|
||||||
<property-sheet>
|
<property-sheet>
|
||||||
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
|
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
|
||||||
<show-property name="bpm:taskId" ignore-if-missing="false" read-only="true" />
|
<show-property name="bpm:taskId" ignore-if-missing="false" />
|
||||||
|
<show-property name="bpm:startDate" ignore-if-missing="false" />
|
||||||
|
<show-property name="bpm:status" ignore-if-missing="false" />
|
||||||
<show-property name="bpm:dueDate" ignore-if-missing="false" />
|
<show-property name="bpm:dueDate" ignore-if-missing="false" />
|
||||||
<!-- Need to show a text field not a drop down even though there are constraints!
|
<show-property name="bpm:priority" ignore-if-missing="false" />
|
||||||
<show-property name="bpm:status" ignore-if-missing="false" /> -->
|
|
||||||
<!-- Need to make sure that we can handle int/long based constraints!
|
|
||||||
<show-property name="bpm:priority" ignore-if-missing="false" /> -->
|
|
||||||
</property-sheet>
|
</property-sheet>
|
||||||
</config>
|
</config>
|
||||||
|
|
||||||
<config evaluator="node-type" condition="wf:submitReviewTask">
|
<config evaluator="node-type" condition="wf:submitReviewTask">
|
||||||
<property-sheet>
|
<property-sheet>
|
||||||
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
|
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
|
||||||
|
<!-- <show-property name="bpm:priority" ignore-if-missing="false" /> -->
|
||||||
<show-property name="wf:reviewDueDate" ignore-if-missing="false" />
|
<show-property name="wf:reviewDueDate" ignore-if-missing="false" />
|
||||||
<separator name="sep2" display-label-id="users_and_roles" component-generator="HeaderSeparatorGenerator" />
|
<separator name="sep2" display-label-id="users_and_roles" component-generator="HeaderSeparatorGenerator" />
|
||||||
<show-association name="wf:reviewer" ignore-if-missing="false" />
|
<show-association name="wf:reviewer" ignore-if-missing="false" />
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<action>wizard:startWorkflow</action>
|
<action>wizard:startWorkflow</action>
|
||||||
<action-listener>#{WizardManager.setupParameters}</action-listener>
|
<action-listener>#{WizardManager.setupParameters}</action-listener>
|
||||||
<params>
|
<params>
|
||||||
<param name="id">#{actionContext.id}</param>
|
<param name="item-to-workflow">#{actionContext.id}</param>
|
||||||
</params>
|
</params>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
@@ -51,6 +51,10 @@
|
|||||||
<action idref="start-workflow" />
|
<action idref="start-workflow" />
|
||||||
</action-group>
|
</action-group>
|
||||||
|
|
||||||
|
<action-group id="doc_details_actions">
|
||||||
|
<action idref="start-workflow" />
|
||||||
|
</action-group>
|
||||||
|
|
||||||
<action-group id="workitem_actions">
|
<action-group id="workitem_actions">
|
||||||
<action idref="reassign-workflow" />
|
<action idref="reassign-workflow" />
|
||||||
</action-group>
|
</action-group>
|
||||||
|
@@ -4,6 +4,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import javax.faces.component.UIComponent;
|
import javax.faces.component.UIComponent;
|
||||||
import javax.faces.component.UIOutput;
|
import javax.faces.component.UIOutput;
|
||||||
|
import javax.faces.component.UISelectOne;
|
||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
import javax.faces.convert.Converter;
|
import javax.faces.convert.Converter;
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ import org.alfresco.web.app.servlet.FacesHelper;
|
|||||||
import org.alfresco.web.ui.common.ComponentConstants;
|
import org.alfresco.web.ui.common.ComponentConstants;
|
||||||
import org.alfresco.web.ui.common.converter.XMLDateConverter;
|
import org.alfresco.web.ui.common.converter.XMLDateConverter;
|
||||||
import org.alfresco.web.ui.repo.RepoConstants;
|
import org.alfresco.web.ui.repo.RepoConstants;
|
||||||
|
import org.alfresco.web.ui.repo.component.UIMultiValueEditor;
|
||||||
import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
|
import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
|
||||||
import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
|
import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
|
||||||
|
|
||||||
@@ -97,8 +99,26 @@ public class DatePickerGenerator extends BaseComponentGenerator
|
|||||||
UIPropertySheet propertySheet, PropertySheetItem item,
|
UIPropertySheet propertySheet, PropertySheetItem item,
|
||||||
UIComponent component, boolean realTimeChecking, String idSuffix)
|
UIComponent component, boolean realTimeChecking, String idSuffix)
|
||||||
{
|
{
|
||||||
// a date picker will always have a date value so there
|
if (component instanceof UIMultiValueEditor)
|
||||||
// is no need to create a mandatory validation rule
|
{
|
||||||
|
// Override the setup of the mandatory validation
|
||||||
|
// so we can send the _current_value id suffix.
|
||||||
|
// We also enable real time so the page load
|
||||||
|
// check disables the ok button if necessary, as the user
|
||||||
|
// adds or removes items from the multi value list the
|
||||||
|
// page will be refreshed and therefore re-check the status.
|
||||||
|
|
||||||
|
super.setupMandatoryValidation(context, propertySheet, item,
|
||||||
|
component, true, "_current_value");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// setup the client validation rule with real time validation enabled
|
||||||
|
// so that the initial page load checks the state of the date
|
||||||
|
super.setupMandatoryValidation(context, propertySheet, item,
|
||||||
|
component, true, idSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -84,12 +84,17 @@ public class TextFieldGenerator extends BaseComponentGenerator
|
|||||||
|
|
||||||
if (propertySheet.inEditMode())
|
if (propertySheet.inEditMode())
|
||||||
{
|
{
|
||||||
// if the field has the list of values constraint a
|
// if the field has the list of values constraint
|
||||||
// SelectOne component is required otherwise create
|
// and it is editable a SelectOne component is
|
||||||
// the standard edit component
|
// required otherwise create the standard edit component
|
||||||
ListOfValuesConstraint constraint = getListOfValuesConstraint(
|
ListOfValuesConstraint constraint = getListOfValuesConstraint(
|
||||||
context, propertySheet, item);
|
context, propertySheet, item);
|
||||||
if (constraint != null)
|
|
||||||
|
PropertyDefinition propDef = this.getPropertyDefinition(context,
|
||||||
|
propertySheet.getNode(), item.getName());
|
||||||
|
|
||||||
|
if (constraint != null && item.isReadOnly() == false &&
|
||||||
|
propDef != null && propDef.isProtected() == false)
|
||||||
{
|
{
|
||||||
component = context.getApplication().createComponent(
|
component = context.getApplication().createComponent(
|
||||||
UISelectOne.COMPONENT_TYPE);
|
UISelectOne.COMPONENT_TYPE);
|
||||||
|
@@ -13,6 +13,8 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a transient node i.e. it is not and will not be present in the repository.
|
* Represents a transient node i.e. it is not and will not be present in the repository.
|
||||||
@@ -28,6 +30,8 @@ public class TransientNode extends Node
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 2140554155948154106L;
|
private static final long serialVersionUID = 2140554155948154106L;
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(TransientNode.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -50,6 +54,9 @@ public class TransientNode extends Node
|
|||||||
|
|
||||||
// initialise the node
|
// initialise the node
|
||||||
initNode(data);
|
initNode(data);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Constructed transient node: " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,20 +1,29 @@
|
|||||||
package org.alfresco.web.bean.workflow;
|
package org.alfresco.web.bean.workflow;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowModel;
|
||||||
|
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||||
|
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;
|
||||||
import org.alfresco.web.bean.repository.TransientNode;
|
import org.alfresco.web.bean.repository.TransientNode;
|
||||||
@@ -34,6 +43,7 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
protected Node workItemNode;
|
protected Node workItemNode;
|
||||||
protected WorkflowTask workItem;
|
protected WorkflowTask workItem;
|
||||||
protected WorkflowTransition[] transitions;
|
protected WorkflowTransition[] transitions;
|
||||||
|
protected List<Node> resources;
|
||||||
|
|
||||||
protected static final String ID_PREFIX = "transition_";
|
protected static final String ID_PREFIX = "transition_";
|
||||||
protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX;
|
protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX;
|
||||||
@@ -57,9 +67,6 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
WorkflowTaskDefinition taskDef = this.workItem.definition;
|
WorkflowTaskDefinition taskDef = this.workItem.definition;
|
||||||
this.workItemNode = new TransientNode(taskDef.metadata.getName(),
|
this.workItemNode = new TransientNode(taskDef.metadata.getName(),
|
||||||
"task_" + System.currentTimeMillis(), this.workItem.properties);
|
"task_" + System.currentTimeMillis(), this.workItem.properties);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Created node for work item: " + this.workItemNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +75,7 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Saving work item with params: " + this.workItemNode.getProperties());
|
logger.debug("Saving work item: " + this.workItemNode.getId());
|
||||||
|
|
||||||
// prepare the edited parameters for saving
|
// prepare the edited parameters for saving
|
||||||
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
|
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
|
||||||
@@ -96,7 +103,7 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
|
|
||||||
for (WorkflowTransition trans : this.transitions)
|
for (WorkflowTransition trans : this.transitions)
|
||||||
{
|
{
|
||||||
buttons.add(new DialogButtonConfig(ID_PREFIX + trans, trans.title, null,
|
buttons.add(new DialogButtonConfig(ID_PREFIX + trans.title, trans.title, null,
|
||||||
"#{DialogManager.bean.transition}", "false", null));
|
"#{DialogManager.bean.transition}", "false", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,6 +132,9 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
{
|
{
|
||||||
String outcome = getDefaultFinishOutcome();
|
String outcome = getDefaultFinishOutcome();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Transitioning work item: " + this.workItemNode.getId());
|
||||||
|
|
||||||
// to find out which transition button was pressed we need
|
// to find out which transition button was pressed we need
|
||||||
// to look for the button's id in the request parameters,
|
// to look for the button's id in the request parameters,
|
||||||
// the first non-null result is the button that was pressed.
|
// the first non-null result is the button that was pressed.
|
||||||
@@ -134,7 +144,7 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
String selectedTransition = null;
|
String selectedTransition = null;
|
||||||
for (WorkflowTransition trans : this.transitions)
|
for (WorkflowTransition trans : this.transitions)
|
||||||
{
|
{
|
||||||
Object result = reqParams.get(CLIENT_ID_PREFIX + trans);
|
Object result = reqParams.get(CLIENT_ID_PREFIX + trans.title);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
// this was the button that was pressed
|
// this was the button that was pressed
|
||||||
@@ -195,6 +205,88 @@ public class ManageWorkItemDialog extends BaseDialogBean
|
|||||||
return this.workItemNode;
|
return this.workItemNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of resources associated with this work item
|
||||||
|
* i.e. the children of the workflow package
|
||||||
|
*
|
||||||
|
* @return The list of nodes
|
||||||
|
*/
|
||||||
|
public List<Node> getResources()
|
||||||
|
{
|
||||||
|
NodeRef workflowPackage = (NodeRef)this.workItem.properties.get(WorkflowModel.ASSOC_PACKAGE);
|
||||||
|
|
||||||
|
this.resources = new ArrayList<Node>(4);
|
||||||
|
|
||||||
|
if (workflowPackage != null)
|
||||||
|
{
|
||||||
|
UserTransaction tx = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
|
tx = Repository.getUserTransaction(context, true);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Found workflow package for work item '" +
|
||||||
|
this.workItem.id + "': " + workflowPackage );
|
||||||
|
|
||||||
|
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(workflowPackage,
|
||||||
|
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
|
for (ChildAssociationRef ref: childRefs)
|
||||||
|
{
|
||||||
|
// create our Node representation from the NodeRef
|
||||||
|
NodeRef nodeRef = ref.getChildRef();
|
||||||
|
|
||||||
|
if (this.nodeService.exists(nodeRef))
|
||||||
|
{
|
||||||
|
// find it's type so we can see if it's a node we are interested in
|
||||||
|
QName type = this.nodeService.getType(nodeRef);
|
||||||
|
|
||||||
|
// make sure the type is defined in the data dictionary
|
||||||
|
TypeDefinition typeDef = this.dictionaryService.getType(type);
|
||||||
|
|
||||||
|
if (typeDef != null)
|
||||||
|
{
|
||||||
|
// look for content nodes or links to content
|
||||||
|
// NOTE: folders within workflow packages are ignored for now
|
||||||
|
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
|
||||||
|
ContentModel.TYPE_FILELINK.equals(type))
|
||||||
|
{
|
||||||
|
// create our Node representation
|
||||||
|
MapNode node = new MapNode(nodeRef, this.nodeService, true);
|
||||||
|
this.browseBean.setupCommonBindingProperties(node);
|
||||||
|
|
||||||
|
this.resources.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit the transaction
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||||
|
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||||
|
this.resources = Collections.<Node>emptyList();
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Failed to find workflow package for work item: " + this.workItem.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.resources;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the workflow service to use
|
* Sets the workflow service to use
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package org.alfresco.web.bean.workflow;
|
package org.alfresco.web.bean.workflow;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -9,14 +10,20 @@ import java.util.ResourceBundle;
|
|||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
import javax.faces.model.SelectItem;
|
import javax.faces.model.SelectItem;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowModel;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
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.TransientNode;
|
import org.alfresco.web.bean.repository.TransientNode;
|
||||||
import org.alfresco.web.bean.wizard.BaseWizardBean;
|
import org.alfresco.web.bean.wizard.BaseWizardBean;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -66,11 +73,41 @@ public class StartWorkflowWizard extends BaseWizardBean
|
|||||||
// TODO: Deal with workflows that don't require any data
|
// TODO: Deal with workflows that don't require any data
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Starting workflow with params: " + this.startTaskNode.getProperties());
|
logger.debug("Starting workflow: " + this.selectedWorkflow);
|
||||||
|
|
||||||
|
// prepare the parameters from the current state of the property sheet
|
||||||
|
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.startTaskNode);
|
||||||
|
|
||||||
|
// create a workflow package for the attached items and add them
|
||||||
|
String itemToWorkflowId = this.parameters.get("item-to-workflow");
|
||||||
|
if (itemToWorkflowId != null && itemToWorkflowId.length() > 0)
|
||||||
|
{
|
||||||
|
// create the node ref for the item and determine its type
|
||||||
|
NodeRef itemToWorkflow = new NodeRef(Repository.getStoreRef(), itemToWorkflowId);
|
||||||
|
QName type = this.nodeService.getType(itemToWorkflow);
|
||||||
|
|
||||||
|
NodeRef workflowPackage = null;
|
||||||
|
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) ||
|
||||||
|
this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDERLINK))
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("Workflow on a folder is not supported yet!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create a workflow package and add the given item to workflow as a child
|
||||||
|
workflowPackage = this.workflowService.createPackage(null);
|
||||||
|
this.nodeService.addChild(workflowPackage, itemToWorkflow,
|
||||||
|
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||||
|
QName.createValidLocalName((String)this.nodeService.getProperty(
|
||||||
|
itemToWorkflow, ContentModel.PROP_NAME))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the workflow package to the parameter map
|
||||||
|
params.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage);
|
||||||
|
}
|
||||||
|
|
||||||
// start the workflow to get access to the start task
|
// start the workflow to get access to the start task
|
||||||
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow,
|
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow, params);
|
||||||
WorkflowBean.prepareWorkItemParams(this.startTaskNode));
|
|
||||||
if (path != null)
|
if (path != null)
|
||||||
{
|
{
|
||||||
// extract the start task
|
// extract the start task
|
||||||
@@ -111,7 +148,7 @@ public class StartWorkflowWizard extends BaseWizardBean
|
|||||||
WorkflowDefinition flowDef = this.workflows.get(this.selectedWorkflow);
|
WorkflowDefinition flowDef = this.workflows.get(this.selectedWorkflow);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Starting workflow: "+ flowDef);
|
logger.debug("Selected workflow: "+ flowDef);
|
||||||
|
|
||||||
WorkflowTaskDefinition taskDef = flowDef.startTaskDefinition;
|
WorkflowTaskDefinition taskDef = flowDef.startTaskDefinition;
|
||||||
if (taskDef != null)
|
if (taskDef != null)
|
||||||
@@ -122,9 +159,6 @@ public class StartWorkflowWizard extends BaseWizardBean
|
|||||||
// create an instance of a task from the data dictionary
|
// create an instance of a task from the data dictionary
|
||||||
this.startTaskNode = new TransientNode(taskDef.metadata.getName(),
|
this.startTaskNode = new TransientNode(taskDef.metadata.getName(),
|
||||||
"task_" + System.currentTimeMillis(), null);
|
"task_" + System.currentTimeMillis(), null);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Created node for task: " + this.startTaskNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -143,6 +143,9 @@ public class WorkflowBean
|
|||||||
params.put(assocQName, (Serializable)targets);
|
params.put(assocQName, (Serializable)targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Prepared parameters: " + params);
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,9 +169,6 @@ public class WorkflowBean
|
|||||||
node.getProperties().put("type", taskDef.metadata.getTitle());
|
node.getProperties().put("type", taskDef.metadata.getTitle());
|
||||||
node.getProperties().put("id", task.id);
|
node.getProperties().put("id", task.id);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Created node for work item with id '" + task.id + "' " + node);
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,9 @@ import javax.faces.convert.ConverterException;
|
|||||||
import javax.faces.model.SelectItem;
|
import javax.faces.model.SelectItem;
|
||||||
|
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
|
import org.alfresco.web.ui.common.Utils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kevinr
|
* @author kevinr
|
||||||
@@ -51,6 +54,12 @@ public class DatePickerRenderer extends BaseRenderer
|
|||||||
private static final String FIELD_DAY = "_day";
|
private static final String FIELD_DAY = "_day";
|
||||||
private static final String FIELD_HOUR = "_hour";
|
private static final String FIELD_HOUR = "_hour";
|
||||||
private static final String FIELD_MINUTE = "_minute";
|
private static final String FIELD_MINUTE = "_minute";
|
||||||
|
private static final String FIELD_CMD = "_cmd";
|
||||||
|
private static final int CMD_SET = 1;
|
||||||
|
private static final int CMD_RESET = 2;
|
||||||
|
private static final int CMD_TODAY = 3;
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(DatePickerRenderer.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
|
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
|
||||||
@@ -66,26 +75,68 @@ public class DatePickerRenderer extends BaseRenderer
|
|||||||
// TODO: should check for disabled/readonly here - no need to decode
|
// TODO: should check for disabled/readonly here - no need to decode
|
||||||
String clientId = component.getClientId(context);
|
String clientId = component.getClientId(context);
|
||||||
Map params = context.getExternalContext().getRequestParameterMap();
|
Map params = context.getExternalContext().getRequestParameterMap();
|
||||||
String year = (String)params.get(clientId + FIELD_YEAR);
|
|
||||||
if (year != null)
|
// see if a command was invoked
|
||||||
|
String cmd = (String)params.get(clientId + FIELD_CMD);
|
||||||
|
if (cmd != null && cmd.length() > 0)
|
||||||
{
|
{
|
||||||
// found data for our component
|
int action = Integer.parseInt(cmd);
|
||||||
String month = (String)params.get(clientId + FIELD_MONTH);
|
|
||||||
String day = (String)params.get(clientId + FIELD_DAY);
|
|
||||||
String hour = (String)params.get(clientId + FIELD_HOUR);
|
|
||||||
String minute = (String)params.get(clientId + FIELD_MINUTE);
|
|
||||||
|
|
||||||
// we encode the values needed for the component as we see fit
|
switch (action)
|
||||||
int[] parts = new int[5];
|
{
|
||||||
parts[0] = Integer.parseInt(year);
|
case CMD_RESET:
|
||||||
parts[1] = Integer.parseInt(month);
|
{
|
||||||
parts[2] = Integer.parseInt(day);
|
// set the submitted value to be null
|
||||||
parts[3] = Integer.parseInt(hour);
|
((EditableValueHolder)component).setSubmittedValue(null);
|
||||||
parts[4] = Integer.parseInt(minute);
|
|
||||||
|
|
||||||
// save the data in an object for our component as the "EditableValueHolder"
|
// set the component value to be null too
|
||||||
// all UI Input Components support this interface for the submitted value
|
((EditableValueHolder)component).setValue(null);
|
||||||
((EditableValueHolder)component).setSubmittedValue(parts);
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// the user is either trying to set the date for the first
|
||||||
|
// time or set it back to today's date, create the parts array
|
||||||
|
// to represent this and set as the submitted value
|
||||||
|
int[] parts = new int[5];
|
||||||
|
|
||||||
|
Calendar date = Calendar.getInstance();
|
||||||
|
parts[0] = date.get(Calendar.YEAR);
|
||||||
|
parts[1] = date.get(Calendar.MONTH);
|
||||||
|
parts[2] = date.get(Calendar.DAY_OF_MONTH);
|
||||||
|
parts[3] = date.get(Calendar.HOUR_OF_DAY);
|
||||||
|
parts[4] = date.get(Calendar.MINUTE);
|
||||||
|
|
||||||
|
((EditableValueHolder)component).setSubmittedValue(parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// a command was not invoked so decode the date the user set (if present)
|
||||||
|
String year = (String)params.get(clientId + FIELD_YEAR);
|
||||||
|
if (year != null)
|
||||||
|
{
|
||||||
|
// found data for our component
|
||||||
|
String month = (String)params.get(clientId + FIELD_MONTH);
|
||||||
|
String day = (String)params.get(clientId + FIELD_DAY);
|
||||||
|
String hour = (String)params.get(clientId + FIELD_HOUR);
|
||||||
|
String minute = (String)params.get(clientId + FIELD_MINUTE);
|
||||||
|
|
||||||
|
// we encode the values needed for the component as we see fit
|
||||||
|
int[] parts = new int[5];
|
||||||
|
parts[0] = Integer.parseInt(year);
|
||||||
|
parts[1] = Integer.parseInt(month);
|
||||||
|
parts[2] = Integer.parseInt(day);
|
||||||
|
parts[3] = Integer.parseInt(hour);
|
||||||
|
parts[4] = Integer.parseInt(minute);
|
||||||
|
|
||||||
|
// save the data in an object for our component as the "EditableValueHolder"
|
||||||
|
// all UI Input Components support this interface for the submitted value
|
||||||
|
((EditableValueHolder)component).setSubmittedValue(parts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NumberFormatException nfe)
|
catch (NumberFormatException nfe)
|
||||||
@@ -124,6 +175,9 @@ public class DatePickerRenderer extends BaseRenderer
|
|||||||
if (component.isRendered() == true)
|
if (component.isRendered() == true)
|
||||||
{
|
{
|
||||||
Date date = null;
|
Date date = null;
|
||||||
|
String clientId = component.getClientId(context);
|
||||||
|
ResponseWriter out = context.getResponseWriter();
|
||||||
|
String cmdFieldName = clientId + FIELD_CMD;
|
||||||
|
|
||||||
// this is part of the spec:
|
// this is part of the spec:
|
||||||
// first you attempt to build the date from the submitted value
|
// first you attempt to build the date from the submitted value
|
||||||
@@ -136,57 +190,119 @@ public class DatePickerRenderer extends BaseRenderer
|
|||||||
{
|
{
|
||||||
// second if no submitted value is found, default to the current value
|
// second if no submitted value is found, default to the current value
|
||||||
Object value = ((ValueHolder)component).getValue();
|
Object value = ((ValueHolder)component).getValue();
|
||||||
// finally check for null value and create default if needed
|
if (value instanceof Date)
|
||||||
date = value instanceof Date ? (Date)value : new Date();
|
{
|
||||||
|
date = (Date)value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the attributes from the component we need for rendering
|
// create a flag to show if the component is disabled
|
||||||
int nStartYear;
|
Boolean disabled = (Boolean)component.getAttributes().get("disabled");
|
||||||
Integer startYear = (Integer)component.getAttributes().get("startYear");
|
if (disabled == null)
|
||||||
if (startYear != null)
|
|
||||||
{
|
{
|
||||||
nStartYear = startYear.intValue();
|
disabled = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date != null)
|
||||||
|
{
|
||||||
|
// get the attributes from the component we need for rendering
|
||||||
|
int nStartYear;
|
||||||
|
Integer startYear = (Integer)component.getAttributes().get("startYear");
|
||||||
|
if (startYear != null)
|
||||||
|
{
|
||||||
|
nStartYear = startYear.intValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nStartYear = new Date().getYear() + 1900 + 2; // for "effectivity date" searches
|
||||||
|
}
|
||||||
|
|
||||||
|
int nYearCount = 25;
|
||||||
|
Integer yearCount = (Integer)component.getAttributes().get("yearCount");
|
||||||
|
if (yearCount != null)
|
||||||
|
{
|
||||||
|
nYearCount = yearCount.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we render the output for our component
|
||||||
|
// we create 3 drop-down menus for day, month and year and
|
||||||
|
// two text fields for the hour and minute
|
||||||
|
|
||||||
|
// note that we build a client id for our form elements that we are then
|
||||||
|
// able to decode() as above.
|
||||||
|
Calendar calendar = new GregorianCalendar();
|
||||||
|
calendar.setTime(date);
|
||||||
|
renderMenu(out, component, getDays(), calendar.get(Calendar.DAY_OF_MONTH), clientId + FIELD_DAY);
|
||||||
|
renderMenu(out, component, getMonths(), calendar.get(Calendar.MONTH), clientId + FIELD_MONTH);
|
||||||
|
renderMenu(out, component, getYears(nStartYear, nYearCount), calendar.get(Calendar.YEAR), clientId + FIELD_YEAR);
|
||||||
|
|
||||||
|
// make sure we have a flag to determine whether to show the time
|
||||||
|
Boolean showTime = (Boolean)component.getAttributes().get("showTime");
|
||||||
|
if (showTime == null)
|
||||||
|
{
|
||||||
|
showTime = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(" ");
|
||||||
|
renderTimeElement(out, component, calendar.get(Calendar.HOUR_OF_DAY), clientId + FIELD_HOUR, showTime.booleanValue());
|
||||||
|
if (showTime.booleanValue())
|
||||||
|
{
|
||||||
|
out.write(" : ");
|
||||||
|
}
|
||||||
|
renderTimeElement(out, component, calendar.get(Calendar.MINUTE), clientId + FIELD_MINUTE, showTime.booleanValue());
|
||||||
|
out.write(" ");
|
||||||
|
|
||||||
|
// render 2 links (if the component is not disabled) to allow the user to reset the
|
||||||
|
// date back to null or to select today's date
|
||||||
|
if (disabled.booleanValue() == false)
|
||||||
|
{
|
||||||
|
out.write("<input type=\"button\" onclick=\"");
|
||||||
|
out.write(Utils.generateFormSubmit(context, component, cmdFieldName, Integer.toString(CMD_TODAY)));
|
||||||
|
out.write("\" value=\"");
|
||||||
|
out.write(Application.getMessage(context, "today"));
|
||||||
|
out.write("\"> <input type=\"button\" onclick=\"");
|
||||||
|
out.write(Utils.generateFormSubmit(context, component, cmdFieldName, Integer.toString(CMD_RESET)));
|
||||||
|
out.write("\" value=\"");
|
||||||
|
out.write(Application.getMessage(context, "none"));
|
||||||
|
out.write("\">");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nStartYear = new Date().getYear() + 1900 + 2; // for "effectivity date" searches
|
// Render a link indicating there isn't a date set (unless the property is disabled)
|
||||||
|
out.write("<div style=\"padding: 3px;");
|
||||||
|
if (disabled.booleanValue() == false)
|
||||||
|
{
|
||||||
|
out.write("\"><a href=\"#\" title=\"");
|
||||||
|
out.write(Application.getMessage(context, "click_to_set_date"));
|
||||||
|
out.write("\" onclick=\"");
|
||||||
|
out.write(Utils.generateFormSubmit(context, component, cmdFieldName, Integer.toString(CMD_SET)));
|
||||||
|
out.write("\">");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.write(" color: #666666; font-style: italic;\">");
|
||||||
|
}
|
||||||
|
out.write(Application.getMessage(context, "none"));
|
||||||
|
if (disabled.booleanValue() == false)
|
||||||
|
{
|
||||||
|
out.write("</a>");
|
||||||
|
}
|
||||||
|
out.write("</div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
int nYearCount = 25;
|
// also output a hidden field containing the current value of the date, this will
|
||||||
Integer yearCount = (Integer)component.getAttributes().get("yearCount");
|
// allow JavaScript to determine if a value is set for validation purposes.
|
||||||
if (yearCount != null)
|
out.write("<input type=\"hidden\" ");
|
||||||
|
outputAttribute(out, clientId, "id");
|
||||||
|
outputAttribute(out, clientId, "name");
|
||||||
|
String strValue = "";
|
||||||
|
if (date != null)
|
||||||
{
|
{
|
||||||
nYearCount = yearCount.intValue();
|
strValue = date.toString();
|
||||||
}
|
}
|
||||||
|
outputAttribute(out, strValue, "value");
|
||||||
// now we render the output for our component
|
out.write("/>");
|
||||||
// we create 3 drop-down menus for day, month and year and
|
|
||||||
// two text fields for the hour and minute
|
|
||||||
String clientId = component.getClientId(context);
|
|
||||||
ResponseWriter out = context.getResponseWriter();
|
|
||||||
|
|
||||||
// note that we build a client id for our form elements that we are then
|
|
||||||
// able to decode() as above.
|
|
||||||
Calendar calendar = new GregorianCalendar();
|
|
||||||
calendar.setTime(date);
|
|
||||||
renderMenu(out, component, getDays(), calendar.get(Calendar.DAY_OF_MONTH), clientId + FIELD_DAY);
|
|
||||||
renderMenu(out, component, getMonths(), calendar.get(Calendar.MONTH), clientId + FIELD_MONTH);
|
|
||||||
renderMenu(out, component, getYears(nStartYear, nYearCount), calendar.get(Calendar.YEAR), clientId + FIELD_YEAR);
|
|
||||||
|
|
||||||
// make sure we have a flag to determine whether to show the time
|
|
||||||
Boolean showTime = (Boolean)component.getAttributes().get("showTime");
|
|
||||||
if (showTime == null)
|
|
||||||
{
|
|
||||||
showTime = Boolean.FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.write(" ");
|
|
||||||
renderTimeElement(out, component, calendar.get(Calendar.HOUR_OF_DAY), clientId + FIELD_HOUR, showTime.booleanValue());
|
|
||||||
if (showTime.booleanValue())
|
|
||||||
{
|
|
||||||
out.write(" : ");
|
|
||||||
}
|
|
||||||
renderTimeElement(out, component, calendar.get(Calendar.MINUTE), clientId + FIELD_MINUTE, showTime.booleanValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,5 +19,60 @@
|
|||||||
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
||||||
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
||||||
|
|
||||||
<r:propertySheetGrid id="work-item-props" value="#{DialogManager.bean.workItemNode}"
|
<a:panel id="props-panel" label="#{msg.workitem_properties}"
|
||||||
var="workItemProps" columns="1" externalConfig="true" />
|
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE" styleClass="mainSubTitle">
|
||||||
|
|
||||||
|
<r:propertySheetGrid id="work-item-props" value="#{DialogManager.bean.workItemNode}"
|
||||||
|
var="workItemProps" columns="1" externalConfig="true" />
|
||||||
|
</a:panel>
|
||||||
|
|
||||||
|
<h:outputText styleClass="paddingRow" value=" " escape="false" />
|
||||||
|
|
||||||
|
<a:panel id="resources-panel" label="#{msg.resources}"
|
||||||
|
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE" styleClass="mainSubTitle">
|
||||||
|
|
||||||
|
<a:richList id="resources-list" viewMode="details" value="#{DialogManager.bean.resources}" var="r"
|
||||||
|
styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow"
|
||||||
|
altRowStyleClass="recordSetRowAlt" width="100%" pageSize="10"
|
||||||
|
initialSortColumn="name" initialSortDescending="true">
|
||||||
|
|
||||||
|
<%-- Primary column for details view mode --%>
|
||||||
|
<a:column primary="true" width="200" style="padding:2px;text-align:left">
|
||||||
|
<f:facet name="header">
|
||||||
|
<a:sortLink label="#{msg.name}" value="name" mode="case-insensitive" styleClass="header"/>
|
||||||
|
</f:facet>
|
||||||
|
<f:facet name="small-icon">
|
||||||
|
<h:graphicImage url="/images/icons/post.gif" />
|
||||||
|
</f:facet>
|
||||||
|
<h:outputText value="#{r.name}" />
|
||||||
|
</a:column>
|
||||||
|
|
||||||
|
<%-- Description column --%>
|
||||||
|
<a:column style="text-align:left">
|
||||||
|
<f:facet name="header">
|
||||||
|
<a:sortLink label="#{msg.description}" value="description" styleClass="header"/>
|
||||||
|
</f:facet>
|
||||||
|
<h:outputText value="#{r.description}" />
|
||||||
|
</a:column>
|
||||||
|
|
||||||
|
<%-- Path column --%>
|
||||||
|
<a:column style="text-align:left">
|
||||||
|
<f:facet name="header">
|
||||||
|
<a:sortLink label="#{msg.path}" value="path" styleClass="header"/>
|
||||||
|
</f:facet>
|
||||||
|
<h:outputText value="#{r.path}" />
|
||||||
|
</a:column>
|
||||||
|
|
||||||
|
<%-- Actions column --%>
|
||||||
|
<a:column actions="true" style="text-align:left">
|
||||||
|
<f:facet name="header">
|
||||||
|
<h:outputText value="#{msg.actions}"/>
|
||||||
|
</f:facet>
|
||||||
|
|
||||||
|
<%-- actions are configured in web-client-config-actions.xml --%>
|
||||||
|
<r:actions id="actions-col-actions" value="workflow_actions" context="#{r}" showLink="false" styleClass="inlineAction" />
|
||||||
|
</a:column>
|
||||||
|
|
||||||
|
<a:dataPager styleClass="pager" />
|
||||||
|
</a:richList>
|
||||||
|
</a:panel>
|
Reference in New Issue
Block a user