First cut of the start workflow wizard

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3483 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2006-08-11 12:22:18 +00:00
parent 60cf6056c5
commit 65f394a878
13 changed files with 663 additions and 31 deletions

View File

@@ -901,10 +901,23 @@ old_password=Old Password
new_password=New Password
# Workflow messages
start_workflow=Start Workflow
start_workflow_wizard=Start New Workflow Wizard
start_workflow_desc=This wizard helps you start a workflow for an item in the repository.
available_workflows=Available workflows
step_choose_workflow=Choose Workflow
start_workflow_choose_title=Choose Workflow
start_workflow_choose_desc=Choose the workflow you want to start
step_workflow_options=Workflow Options
start_workflow_options_title=Workflow Options
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_no_metadata=There is no metadata to collect for this particular workflow.
users_and_roles=Users and their Roles
manage_workitem=Manage WorkItem
manage_workitem_title=Manage WorkItem
manage_workitem_desc=This dialog allows the workitem to be managed
reassign=Reassign Task
reassign=Reassign
# Admin Console messages
title_admin_console=Administration Console

View File

@@ -12,6 +12,7 @@
<value>classpath:alfresco/web-client-config-properties.xml</value>
<value>classpath:alfresco/web-client-config-navigation.xml</value>
<value>classpath:alfresco/web-client-config-actions.xml</value>
<value>classpath:alfresco/web-client-config-workflow.xml</value>
<value>classpath:alfresco/web-client-config-forum-actions.xml</value>
<value>classpath:alfresco/extension/web-client-config-custom.xml</value>
</list>

View File

@@ -182,6 +182,31 @@
</step>
</wizard>
<wizard name="startWorkflow" managed-bean="StartWorkflowWizard"
title-id="start_workflow_wizard" description-id="start_workflow_desc"
icon="/images/icons/users_large.gif">
<step name="choose-workflow" title-id="step_choose_workflow"
description-id="start_workflow_choose_desc">
<page path="/jsp/workflow/start-workflow-wizard/choose-workflow.jsp"
title-id="start_workflow_choose_title"
description-id="start_workflow_choose_desc"
instruction-id="default_instruction" />
</step>
<step name="options" title-id="step_workflow_options"
description-id="start_workflow_options_desc">
<page path="/jsp/workflow/start-workflow-wizard/workflow-options.jsp"
title-id="start_workflow_options_title"
description-id="start_workflow_options_desc"
instruction-id="default_instruction" />
</step>
<step name="summary" title-id="summary" description-id="summary_step_description">
<page path="/jsp/wizard/summary.jsp"
title-id="summary"
description-id="summary_desc"
instruction-id="start_workflow_finish_instruction" />
</step>
</wizard>
</wizards>
</config>

View File

@@ -0,0 +1,40 @@
<alfresco-config>
<!-- -->
<!-- Properties -->
<!-- -->
<config evaluator="node-type" condition="wf:submitReviewTask">
<property-sheet>
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
<show-property name="wf:reviewDueDate" ignore-if-missing="false" />
<separator name="sep2" display-label-id="users_and_roles" component-generator="HeaderSeparatorGenerator" />
<show-association name="wf:reviewer" ignore-if-missing="false" />
</property-sheet>
</config>
<!-- -->
<!-- Actions -->
<!-- -->
<config>
<actions>
<action id="start-workflow">
<label-id>start_workflow</label-id>
<image>/images/icons/create_forum.gif</image>
<action>wizard:startWorkflow</action>
<action-listener>#{WizardManager.setupParameters}</action-listener>
<params>
<param name="id">#{actionContext.id}</param>
</params>
</action>
<!--
<action-group id="document_browse_menu">
<action idref="start-workflow" />
</action-group>
-->
</actions>
</config>
</alfresco-config>

View File

@@ -36,8 +36,6 @@ import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Lighweight client side representation of a node held in the repository.
@@ -48,28 +46,25 @@ public class Node implements Serializable
{
private static final long serialVersionUID = 3544390322739034169L;
protected static final Log logger = LogFactory.getLog(Node.class);
protected NodeRef nodeRef;
private String name;
private QName type;
private String path;
private String id;
private Set<QName> aspects = null;
private Map<String, Boolean> permissions;
private Boolean locked = null;
private Boolean workingCopyOwner = null;
protected String name;
protected QName type;
protected String path;
protected String id;
protected Set<QName> aspects = null;
protected Map<String, Boolean> permissions;
protected Boolean locked = null;
protected Boolean workingCopyOwner = null;
protected QNameNodeMap<String, Object> properties;
protected boolean propsRetrieved = false;
protected ServiceRegistry services = null;
protected boolean childAssocsRetrieved = false;
protected QNameNodeMap childAssociations;
protected boolean assocsRetrieved = false;
protected QNameNodeMap associations;
private boolean childAssocsRetrieved = false;
private QNameNodeMap childAssociations;
private Map<String, Map<String, ChildAssociationRef>> childAssociationsAdded;
private Map<String, Map<String, ChildAssociationRef>> childAssociationsRemoved;
private boolean assocsRetrieved = false;
private QNameNodeMap associations;
private Map<String, Map<String, AssociationRef>> associationsAdded;
private Map<String, Map<String, AssociationRef>> associationsRemoved;
@@ -94,7 +89,7 @@ public class Node implements Serializable
/**
* @return All the properties known about this node.
*/
public Map<String, Object> getProperties()
public final Map<String, Object> getProperties()
{
if (this.propsRetrieved == false)
{
@@ -120,7 +115,7 @@ public class Node implements Serializable
{
if (this.assocsRetrieved == false)
{
associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
this.associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
List<AssociationRef> assocs = getServiceRegistry().getNodeService().getTargetAssocs(this.nodeRef, RegexQNamePattern.MATCH_ALL);
@@ -341,7 +336,7 @@ public class Node implements Serializable
*
* @return true if the permission is applied to the node for this user, false otherwise
*/
public final boolean hasPermission(String permission)
public boolean hasPermission(String permission)
{
Boolean valid = null;
if (permissions != null)

View File

@@ -16,15 +16,11 @@
*/
package org.alfresco.web.bean.repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QNameMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A extension of the repo QNameMap to provide custom property resolving support for Node wrappers.
@@ -86,6 +82,7 @@ public final class QNameNodeMap<K,V> extends QNameMap implements Map, Cloneable
/**
* @see java.util.Map#get(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public Object get(Object key)
{
String qnameKey = Repository.resolveToQNameString(key.toString());
@@ -120,6 +117,7 @@ public final class QNameNodeMap<K,V> extends QNameMap implements Map, Cloneable
/**
* Shallow copy the map by copying keys and values into a new QNameNodeMap
*/
@SuppressWarnings("unchecked")
public Object clone()
{
QNameNodeMap map = new QNameNodeMap(this.resolver, this.parent);

View File

@@ -0,0 +1,141 @@
package org.alfresco.web.bean.repository;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
/**
* Represents a transient node i.e. it is not and will not be present in the repository.
* <p>
* This type of node is typically used to drive the property sheet when data collection
* is required for a type but the node does not need to be stored in the repository. An
* example use is the workflow, transient nodes are used to collect workitem metadata.
*
* @author gavinc
*/
public class TransientNode extends Node
{
private static final long serialVersionUID = 2140554155948154106L;
/**
* Constructor.
* <p>
* NOTE: The name is NOT automatically added to the map of properties,
* if you need the name of this node to be in the map then add it to
* the map passed in to this constructor.
*
* @param type The type this node will represent
* @param name The name of the node
* @param data The properties and associations this node will have
*/
public TransientNode(QName type, String name, Map<QName, Serializable> data)
{
// create a dummy NodeRef to pass to the constructor
super(new NodeRef(Repository.getStoreRef(), GUID.generate()));
this.type = type;
this.name = name;
// initialise the node
initNode(data);
}
/**
* Initialises the node.
*
* @param data The properties and associations to initialise the node with
*/
protected void initNode(Map<QName, Serializable> data)
{
// setup the transient node so that the super class methods work
// and do not need to go back to the repository
DictionaryService ddService = this.getServiceRegistry().getDictionaryService();
// marshall the given properties and associations into the internal maps
this.associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
this.childAssociations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
if (data != null)
{
// go through all data items and allocate to the correct internal list
for (QName item : data.keySet())
{
PropertyDefinition propDef = ddService.getProperty(item);
if (propDef != null)
{
this.properties.put(item, data.get(item));
}
else
{
// see if the item is either type of association
AssociationDefinition assocDef = ddService.getAssociation(item);
if (assocDef != null)
{
if (assocDef.isChild())
{
this.childAssociations.put(item, data.get(item));
}
else
{
this.associations.put(item, data.get(item));
}
}
}
}
}
// show that the maps have been initialised
this.propsRetrieved = true;
this.assocsRetrieved = true;
this.childAssocsRetrieved = true;
// setup the list of aspects the node would have
TypeDefinition typeDef = ddService.getType(this.type);
if (typeDef == null)
{
throw new AlfrescoRuntimeException("Failed to find type definition for start task: " + this.type);
}
this.aspects = new HashSet<QName>();
for (AspectDefinition aspectDef : typeDef.getDefaultAspects())
{
this.aspects.add(aspectDef.getName());
}
// setup remaining variables
this.path = "";
this.locked = Boolean.FALSE;
this.workingCopyOwner = Boolean.FALSE;
}
@Override
public boolean hasPermission(String permission)
{
return true;
}
@Override
public void reset()
{
// don't reset anything otherwise we'll lose our data
// with no way of getting it back!!
}
@Override
public String toString()
{
return "Transient node of type: " + getType() +
"\nProperties: " + this.getProperties().toString();
}
}

View File

@@ -188,6 +188,18 @@ public class WizardManager
return Integer.toString(this.currentStep);
}
/**
* Returns the name of the current step, wizards should use
* the name of the step rather than the step number to discover
* the position as extra steps can be added via configuration.
*
* @return The name of the current step
*/
public String getCurrentStepName()
{
return ((StepConfig)this.steps.get(this.currentStep-1)).getName();
}
/**
* Returns a list of UIListItems representing the steps of the wizard
*

View File

@@ -0,0 +1,286 @@
package org.alfresco.web.bean.workflow;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
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.bean.repository.TransientNode;
import org.alfresco.web.bean.wizard.BaseWizardBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Bean implementation for the Start Workflow Wizard.
*
* @author gavinc
*/
public class StartWorkflowWizard extends BaseWizardBean
{
protected String selectedWorkflow;
protected List<SelectItem> availableWorkflows;
protected Map<String, WorkflowDefinition> workflows;
protected WorkflowService workflowService;
protected Node startTaskNode;
protected boolean nextButtonDisabled = false;
private static final Log logger = LogFactory.getLog(StartWorkflowWizard.class);
// ------------------------------------------------------------------------------
// Wizard implementation
@Override
public void init(Map<String, String> parameters)
{
super.init(parameters);
// reset the selected workflow
if (this.availableWorkflows != null && this.availableWorkflows.size() > 0)
{
this.selectedWorkflow = (String)this.availableWorkflows.get(0).getValue();
}
else
{
this.selectedWorkflow = null;
}
this.startTaskNode = null;
}
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
// TODO: Deal with workflows that don't require any data
if (logger.isDebugEnabled())
logger.debug("Starting workflow with params: " + this.startTaskNode.getProperties());
// start the workflow to get access to the start task
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow, prepareTaskParams());
if (path != null)
{
// extract the start task
List<WorkflowTask> tasks = this.workflowService.getTasksForWorkflowPath(path.id);
if (tasks.size() == 1)
{
WorkflowTask startTask = tasks.get(0);
if (logger.isDebugEnabled())
logger.debug("Found start task:" + startTask);
if (startTask.state == WorkflowTaskState.IN_PROGRESS)
{
// end the start task to trigger the first 'proper'
// task in the workflow
this.workflowService.endTask(startTask.id, null);
}
}
if (logger.isDebugEnabled())
logger.debug("Started workflow: " + this.selectedWorkflow);
}
return outcome;
}
@Override
public String next()
{
String stepName = Application.getWizardManager().getCurrentStepName();
if ("options".equals(stepName) && this.startTaskNode == null)
{
// retrieve the start task for the selected workflow, get the task
// definition and create a transient node to allow the property
// sheet to collect the required data.
WorkflowDefinition flowDef = this.workflows.get(this.selectedWorkflow);
if (logger.isDebugEnabled())
logger.debug("Starting workflow: "+ flowDef);
WorkflowTaskDefinition taskDef = flowDef.startTaskDefinition;
if (taskDef != null)
{
if (logger.isDebugEnabled())
logger.debug("Start task definition: " + taskDef);
// create an instance of a task from the data dictionary
this.startTaskNode = new TransientNode(taskDef.metadata.getName(),
"task_" + System.currentTimeMillis(), null);
if (logger.isDebugEnabled())
logger.debug("Created node for task: " + this.startTaskNode);
}
}
return null;
}
@Override
public boolean getNextButtonDisabled()
{
return this.nextButtonDisabled;
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/**
* Returns the workflow selected by the user
*
* @return The selected workflow
*/
public String getSelectedWorkflow()
{
return selectedWorkflow;
}
/**
* Sets the selected workflow
*
* @param selectedWorkflow The workflow selected
*/
public void setSelectedWorkflow(String selectedWorkflow)
{
this.selectedWorkflow = selectedWorkflow;
}
/**
* Returns the Node representing the start task metadata required
*
* @return The Node for the start task
*/
public Node getTaskMetadataNode()
{
return this.startTaskNode;
}
/**
* @return Returns the summary data for the wizard.
*/
public String getSummary()
{
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
String workflowName = null;
for (SelectItem item : this.availableWorkflows)
{
if (item.getValue().equals(this.selectedWorkflow))
{
workflowName = item.getLabel();
break;
}
}
return buildSummary(
new String[] {bundle.getString("start_workflow")},
new String[] {workflowName});
}
/**
* Returns a list of workflows that can be started.
*
* @return List of SelectItem objects representing the workflows
*/
public List<SelectItem> getStartableWorkflows()
{
if (this.availableWorkflows == null)
{
this.availableWorkflows = new ArrayList<SelectItem>(4);
this.workflows = new HashMap<String, WorkflowDefinition>(4);
List<WorkflowDefinition> workflowDefs = this.workflowService.getDefinitions();
for (WorkflowDefinition workflowDef : workflowDefs)
{
this.availableWorkflows.add(new SelectItem(workflowDef.id, workflowDef.name));
this.workflows.put(workflowDef.id, workflowDef);
}
// set the initial selected workflow to the first in the list, unless there are no
// workflows, in which disable the next button
if (this.availableWorkflows.size() > 0)
{
this.selectedWorkflow = (String)this.availableWorkflows.get(0).getValue();
}
else
{
this.nextButtonDisabled = true;
}
}
return availableWorkflows;
}
/**
* Sets the workflow service to use
*
* @param workflowService WorkflowService instance
*/
public void setWorkflowService(WorkflowService workflowService)
{
this.workflowService = workflowService;
}
protected Map<QName, Serializable> prepareTaskParams()
{
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
// marshal the properties and associations captured by the property sheet
// back into a Map to pass to the workflow service
// go through all the properties in the transient node and add them to
// params map
Map<String, Object> props = this.startTaskNode.getProperties();
for (String propName : props.keySet())
{
QName propQName = Repository.resolveToQName(propName);
params.put(propQName, (Serializable)props.get(propName));
}
// go through any associations that have been added to the start task
// and build a list of NodeRefs representing the targets
Map<String, Map<String, AssociationRef>> assocs = this.startTaskNode.getAddedAssociations();
for (String assocName : assocs.keySet())
{
QName assocQName = Repository.resolveToQName(assocName);
// get the associations added and create list of targets
Map<String, AssociationRef> addedAssocs = assocs.get(assocName);
List<NodeRef> targets = new ArrayList<NodeRef>(addedAssocs.size());
for (AssociationRef assoc : addedAssocs.values())
{
targets.add(assoc.getTargetRef());
}
// add the targets for this particular association
params.put(assocQName, (Serializable)targets);
}
// String reviewer = (String)this.startTaskNode.getProperties().get(
// ContentModel.PROP_NAME);
// Map<QName, Serializable> params = new HashMap<QName, Serializable>(1);
// params.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), reviewer);
return params;
}
}

View File

@@ -35,6 +35,7 @@ import org.alfresco.config.Config;
import org.alfresco.config.ConfigLookupContext;
import org.alfresco.config.ConfigService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.repository.Node;
@@ -626,8 +627,13 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
// create the property component
UIProperty propComp = (UIProperty)context.getApplication().
createComponent(RepoConstants.ALFRESCO_FACES_PROPERTY);
FacesHelper.setupComponentId(context, propComp, PROP_ID_PREFIX + propertyName);
propComp.setName(propertyName);
// get the property name in it's prefix form
QName qname = QName.createQName(propertyName);
String prefixPropName = qname.toPrefixString();
FacesHelper.setupComponentId(context, propComp, PROP_ID_PREFIX + prefixPropName);
propComp.setName(prefixPropName);
// if this property sheet is set as read only, set all properties to read only
if (isReadOnly())
@@ -642,7 +648,7 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
if (logger.isDebugEnabled())
logger.debug("Created property component " + propComp + "(" +
propComp.getClientId(context) +
") for '" + propertyName +
") for '" + prefixPropName +
"' and added it to property sheet " + this);
}
@@ -654,8 +660,13 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
String assocName = (String)iter.next();
UIAssociation assocComp = (UIAssociation)context.getApplication().
createComponent(RepoConstants.ALFRESCO_FACES_ASSOCIATION);
FacesHelper.setupComponentId(context, assocComp, ASSOC_ID_PREFIX + assocName);
assocComp.setName(assocName);
// get the association name in it's prefix form
QName qname = QName.createQName(assocName);
String prefixAssocName = qname.toPrefixString();
FacesHelper.setupComponentId(context, assocComp, ASSOC_ID_PREFIX + prefixAssocName);
assocComp.setName(prefixAssocName);
// if this property sheet is set as read only, set all properties to read only
if (isReadOnly())
@@ -670,7 +681,7 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
if (logger.isDebugEnabled())
logger.debug("Created association component " + assocComp + "(" +
assocComp.getClientId(context) +
") for '" + assocName +
") for '" + prefixAssocName +
"' and added it to property sheet " + this);
}

View File

@@ -1739,6 +1739,44 @@
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>StartWorkflowWizard</managed-bean-name>
<managed-bean-class>org.alfresco.web.bean.workflow.StartWorkflowWizard</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>nodeService</property-name>
<value>#{NodeService}</value>
</managed-property>
<managed-property>
<property-name>fileFolderService</property-name>
<value>#{FileFolderService}</value>
</managed-property>
<managed-property>
<property-name>searchService</property-name>
<value>#{SearchService}</value>
</managed-property>
<managed-property>
<property-name>navigator</property-name>
<value>#{NavigationBean}</value>
</managed-property>
<managed-property>
<property-name>browseBean</property-name>
<value>#{BrowseBean}</value>
</managed-property>
<managed-property>
<property-name>dictionaryService</property-name>
<value>#{DictionaryService}</value>
</managed-property>
<managed-property>
<property-name>namespaceService</property-name>
<value>#{NamespaceService}</value>
</managed-property>
<managed-property>
<property-name>workflowService</property-name>
<value>#{WorkflowService}</value>
</managed-property>
</managed-bean>
<!-- ==================== COMPONENT GENERATOR BEANS ==================== -->
<managed-bean>
<description>

View File

@@ -0,0 +1,28 @@
<%--
Copyright (C) 2005 Alfresco, Inc.
Licensed under the Mozilla Public License version 1.1
with a permitted attribution clause. You may obtain a
copy of the License at
http://www.alfresco.org/legal/license.txt
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific
language governing permissions and limitations under the
License.
--%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<h:panelGrid columns="1" style="border: 1px solid #676767; background-color: #efefef; padding: 6px;">
<h:outputText value="#{msg.available_workflows}:"/>
<h:selectOneRadio id="selected-workflow" value="#{WizardManager.bean.selectedWorkflow}"
layout="pageDirection">
<f:selectItems value="#{WizardManager.bean.startableWorkflows}" />
</h:selectOneRadio>
</h:panelGrid>

View File

@@ -0,0 +1,44 @@
<%--
Copyright (C) 2005 Alfresco, Inc.
Licensed under the Mozilla Public License version 1.1
with a permitted attribution clause. You may obtain a
copy of the License at
http://www.alfresco.org/legal/license.txt
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific
language governing permissions and limitations under the
License.
--%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<h:panelGroup rendered="#{empty WizardManager.bean.taskMetadataNode}">
<f:verbatim>
<%PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc");%>
<table><tr><td>
</f:verbatim>
<h:graphicImage url="/images/icons/info_icon.gif" />
<f:verbatim>
</td><td>
</f:verbatim>
<h:outputText value="#{msg.start_workflow_no_metadata}" />
<f:verbatim>
</td></tr></table>
<%PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner");%>
</f:verbatim>
</h:panelGroup>
<h:panelGroup rendered="#{not empty WizardManager.bean.taskMetadataNode}">
<r:propertySheetGrid id="task-props" value="#{WizardManager.bean.taskMetadataNode}"
var="taskProps" columns="1" externalConfig="true" />
</h:panelGroup>