From 66f1b610525a0b6e4ed04d624f463ff6436dd0c6 Mon Sep 17 00:00:00 2001 From: Gavin Cornwell Date: Tue, 15 Aug 2006 14:46:43 +0000 Subject: [PATCH] Checkpoint for workflow features git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3518 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 7 +- config/alfresco/web-client-config-dialogs.xml | 15 -- config/alfresco/web-client-config-wizards.xml | 25 --- .../alfresco/web-client-config-workflow.xml | 70 ++++++- config/alfresco/web-client-config.xml | 8 +- .../web/bean/repository/TransientMapNode.java | 149 ++++++++++++++ .../web/bean/repository/TransientNode.java | 2 + .../bean/workflow/ManageWorkItemDialog.java | 193 +++++++++++++++--- .../bean/workflow/StartWorkflowWizard.java | 52 +---- .../web/bean/workflow/WorkflowBean.java | 140 +++++++++++++ source/web/WEB-INF/faces-config-beans.xml | 14 ++ .../jsp/dashboards/dashlets/my-tasks-todo.png | Bin 15216 -> 0 bytes .../manage-workitem-dialog.jsp} | 5 +- source/web/jsp/workflow/manage-workitem.jsp | 28 --- .../start-workflow-wizard/choose-workflow.jsp | 2 +- .../jsp/workflow/workitems-todo-dashlet.jsp | 88 ++++++++ 16 files changed, 647 insertions(+), 151 deletions(-) create mode 100644 source/java/org/alfresco/web/bean/repository/TransientMapNode.java create mode 100644 source/java/org/alfresco/web/bean/workflow/WorkflowBean.java delete mode 100644 source/web/jsp/dashboards/dashlets/my-tasks-todo.png rename source/web/jsp/{dashboards/dashlets/tasklist-todo.jsp => workflow/manage-workitem-dialog.jsp} (78%) delete mode 100644 source/web/jsp/workflow/manage-workitem.jsp create mode 100644 source/web/jsp/workflow/workitems-todo-dashlet.jsp diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 59326d4573..71c0b8ae2d 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -919,7 +919,12 @@ start_workflow_no_metadata=There is no metadata to collect for this particular w 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 +manage_workitem_desc=This dialog allows the work item to be managed +id=Id +status=Status +my_workitems_todo_title=My Work Items To Do +my_workitems_todo_desc=List of your workflow items still to complete +due_date=Due Date reassign=Reassign # Admin Console messages diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index e34558df8e..1b6028ba91 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -38,21 +38,6 @@ icon="/images/icons/delete_large.gif" title-id="delete_file" description-id="delete_file_info" /> - - - - - - - diff --git a/config/alfresco/web-client-config-wizards.xml b/config/alfresco/web-client-config-wizards.xml index 1936302ae0..a3aad002c2 100644 --- a/config/alfresco/web-client-config-wizards.xml +++ b/config/alfresco/web-client-config-wizards.xml @@ -182,31 +182,6 @@ - - - - - - - - - - - - diff --git a/config/alfresco/web-client-config-workflow.xml b/config/alfresco/web-client-config-workflow.xml index 1202b210a8..2bb90ba827 100644 --- a/config/alfresco/web-client-config-workflow.xml +++ b/config/alfresco/web-client-config-workflow.xml @@ -4,6 +4,18 @@ + + + + + + + + + + @@ -29,12 +41,66 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index f36a592dbe..348988f768 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -188,14 +188,14 @@ + + - - + * This type of node is typically used to drive rich lists where the Map implementation + * is required for sorting columns. + *

+ * + * @author gavinc + */ +public class TransientMapNode extends TransientNode implements Map +{ + private static final long serialVersionUID = 1120307465342597322L; + + /** + * Constructor. + *

+ * 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 TransientMapNode(QName type, String name, Map data) + { + super(type, name, data); + } + + @Override + public String toString() + { + return "Transient map node of type: " + getType() + + "\nProperties: " + this.getProperties().toString(); + } + + // ------------------------------------------------------------------------------ + // Map implementation - allows the Node bean to be accessed using JSF expression syntax + + /** + * @see java.util.Map#clear() + */ + public void clear() + { + getProperties().clear(); + } + + /** + * @see java.util.Map#containsKey(java.lang.Object) + */ + public boolean containsKey(Object key) + { + return getProperties().containsKey(key); + } + + /** + * @see java.util.Map#containsValue(java.lang.Object) + */ + public boolean containsValue(Object value) + { + return getProperties().containsKey(value); + } + + /** + * @see java.util.Map#entrySet() + */ + @SuppressWarnings("unchecked") + public Set entrySet() + { + return getProperties().entrySet(); + } + + /** + * @see java.util.Map#get(java.lang.Object) + */ + public Object get(Object key) + { + return getProperties().get(key); + } + + /** + * @see java.util.Map#isEmpty() + */ + public boolean isEmpty() + { + return getProperties().isEmpty(); + } + + /** + * @see java.util.Map#keySet() + */ + @SuppressWarnings("unchecked") + public Set keySet() + { + return getProperties().keySet(); + } + + /** + * @see java.util.Map#put(K, V) + */ + public Object put(String key, Object value) + { + return getProperties().put(key, value); + } + + /** + * @see java.util.Map#putAll(java.util.Map) + */ + @SuppressWarnings("unchecked") + public void putAll(Map t) + { + getProperties().putAll(t); + } + + /** + * @see java.util.Map#remove(java.lang.Object) + */ + public Object remove(Object key) + { + return getProperties().remove(key); + } + + /** + * @see java.util.Map#size() + */ + public int size() + { + return getProperties().size(); + } + + /** + * @see java.util.Map#values() + */ + @SuppressWarnings("unchecked") + public Collection values() + { + return getProperties().values(); + } +} diff --git a/source/java/org/alfresco/web/bean/repository/TransientNode.java b/source/java/org/alfresco/web/bean/repository/TransientNode.java index 8ef05da567..21dfbe340e 100644 --- a/source/java/org/alfresco/web/bean/repository/TransientNode.java +++ b/source/java/org/alfresco/web/bean/repository/TransientNode.java @@ -20,6 +20,7 @@ import org.alfresco.util.GUID; * 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 */ @@ -33,6 +34,7 @@ public class TransientNode extends Node * 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 diff --git a/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java b/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java index a25eea0e9b..75241e0144 100644 --- a/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java +++ b/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java @@ -1,12 +1,24 @@ package org.alfresco.web.bean.workflow; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.faces.context.FacesContext; +import javax.transaction.UserTransaction; +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.namespace.QName; +import org.alfresco.web.app.Application; import org.alfresco.web.bean.dialog.BaseDialogBean; +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.config.DialogsConfigElement.DialogButtonConfig; +import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -17,51 +29,186 @@ import org.apache.commons.logging.LogFactory; */ public class ManageWorkItemDialog extends BaseDialogBean { - private static final Log logger = LogFactory.getLog(ManageWorkItemDialog.class); + protected WorkflowService workflowService; + protected Node workItemNode; + protected WorkflowTask workItem; + protected String[] transitions; + + protected static final String ID_PREFIX = "transition_"; + protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX; + private static final Log logger = LogFactory.getLog(ManageWorkItemDialog.class); + // ------------------------------------------------------------------------------ // Dialog implementation + + @Override + public void init(Map parameters) + { + super.init(parameters); + + String taskId = this.parameters.get("id"); + this.workItem = this.workflowService.getTaskById(taskId); + + if (this.workItem != null) + { + // setup a transient node to represent the work item we're managing + WorkflowTaskDefinition taskDef = this.workItem.definition; + this.workItemNode = new TransientNode(taskDef.metadata.getName(), + "task_" + System.currentTimeMillis(), this.workItem.properties); + + if (logger.isDebugEnabled()) + logger.debug("Created node for work item: " + this.workItemNode); + } + } @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - return null; + if (logger.isDebugEnabled()) + logger.debug("Saving work item with params: " + this.workItemNode.getProperties()); + + // prepare the edited parameters for saving + Map params = WorkflowBean.prepareWorkItemParams(this.workItemNode); + + // update the task with the updated parameters + this.workflowService.updateTask(this.workItem.id, params, null, null); + + return outcome; } - + @Override public List getAdditionalButtons() { - List buttons = new ArrayList(1); - buttons.add(new DialogButtonConfig("reassign-button", - "Reassign", null, "#{ManageWorkItemDialog.reassign}", "false", null)); + List buttons = null; + + if (this.workItem != null) + { + // get the transitions available from this work item and + // show them in the dialog as additional buttons + this.transitions = this.workItem.path.node.transitions; + + if (this.transitions != null) + { + buttons = new ArrayList(this.transitions.length); + + for (String trans : this.transitions) + { + // TODO: Tidy this up when the service returns the list of labels + String label = trans; + if (label.length() == 0) + { + label = "Done"; + } + + buttons.add(new DialogButtonConfig(ID_PREFIX + trans, label, null, + "#{DialogManager.bean.transition}", "false", null)); + } + } + } - return buttons; + return buttons; + } + + @Override + public String getFinishButtonLabel() + { + return Application.getMessage(FacesContext.getCurrentInstance(), "save"); } + @Override + public boolean getFinishButtonDisabled() + { + return false; + } + // ------------------------------------------------------------------------------ // Event handlers - - public void approve() + + @SuppressWarnings("unused") + public String transition() { - logger.info("approve button was pressed"); - } - - public void reject() - { - logger.info("reject button was pressed"); - } - - public void reassign() - { - logger.info("reassign button was pressed"); + String outcome = getDefaultFinishOutcome(); + + // to find out which transition button was pressed we need + // to look for the button's id in the request parameters, + // the first non-null result is the button that was pressed. + FacesContext context = FacesContext.getCurrentInstance(); + Map reqParams = context.getExternalContext().getRequestParameterMap(); + + String selectedTransition = null; + for (String trans : this.transitions) + { + Object result = reqParams.get(CLIENT_ID_PREFIX + trans); + if (result != null) + { + // this was the button that was pressed + selectedTransition = trans; + break; + } + } + + if (selectedTransition != null) + { + UserTransaction tx = null; + + try + { + tx = Repository.getUserTransaction(context); + tx.begin(); + + // prepare the edited parameters for saving + Map params = WorkflowBean.prepareWorkItemParams(this.workItemNode); + + // update the task with the updated parameters + this.workflowService.updateTask(this.workItem.id, params, null, null); + + // signal the selected transition to the workflow task + this.workflowService.endTask(this.workItem.id, selectedTransition); + + // commit the changes + tx.commit(); + + if (logger.isDebugEnabled()) + logger.debug("Ended work item with transition: " + selectedTransition); + } + catch (Throwable e) + { + // reset the flag so we can re-attempt the operation + isFinished = false; + + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + Utils.addErrorMessage(formatErrorMessage(e)); + outcome = this.getErrorOutcome(e); + } + } + + return outcome; } // ------------------------------------------------------------------------------ // Bean Getters and Setters - - public boolean getApproveDisabled() + + /** + * Returns the Node representing the work item + * + * @return The node + */ + public Node getWorkItemNode() { - return true; + return this.workItemNode; + } + + /** + * Sets the workflow service to use + * + * @param workflowService + * WorkflowService instance + */ + public void setWorkflowService(WorkflowService workflowService) + { + this.workflowService = workflowService; } } diff --git a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java index 6393ebd320..9a1300c250 100644 --- a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java +++ b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java @@ -1,6 +1,5 @@ package org.alfresco.web.bean.workflow; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -10,18 +9,14 @@ 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; @@ -74,7 +69,8 @@ public class StartWorkflowWizard extends BaseWizardBean 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()); + WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow, + WorkflowBean.prepareWorkItemParams(this.startTaskNode)); if (path != null) { // extract the start task @@ -239,48 +235,4 @@ public class StartWorkflowWizard extends BaseWizardBean { this.workflowService = workflowService; } - - protected Map prepareTaskParams() - { - Map params = new HashMap(); - - // 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 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> assocs = this.startTaskNode.getAddedAssociations(); - for (String assocName : assocs.keySet()) - { - QName assocQName = Repository.resolveToQName(assocName); - - // get the associations added and create list of targets - Map addedAssocs = assocs.get(assocName); - List targets = new ArrayList(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 params = new HashMap(1); -// params.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), reviewer); - - - return params; - } } diff --git a/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java b/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java new file mode 100644 index 0000000000..cafb7e1e79 --- /dev/null +++ b/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java @@ -0,0 +1,140 @@ +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 javax.faces.context.FacesContext; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +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.util.ISO9075; +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.TransientMapNode; +import org.alfresco.web.bean.repository.User; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Managed bean used for handling workflow related features + * + * @author gavinc + */ +public class WorkflowBean +{ + protected WorkflowService workflowService; + protected List workItems; + + private static final Log logger = LogFactory.getLog(WorkflowBean.class); + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + public List getWorkItemsToDo() + { + // get the current username + FacesContext fc = FacesContext.getCurrentInstance(); + User user = Application.getCurrentUser(fc); + String userName = ISO9075.encode(user.getUserName()); + + // get the current in progress tasks for the current user + List tasks = this.workflowService.getAssignedTasks( + userName, WorkflowTaskState.IN_PROGRESS); + + // create a list of transient nodes to represent + this.workItems = new ArrayList(tasks.size()); + for (WorkflowTask task : tasks) + { + createWorkItem(task); + } + + return this.workItems; + } + + /** + * Sets the workflow service to use + * + * @param workflowService WorkflowService instance + */ + public void setWorkflowService(WorkflowService workflowService) + { + this.workflowService = workflowService; + } + + // ------------------------------------------------------------------------------ + // Helper methods + + public static Map prepareWorkItemParams(Node node) + { + Map params = new HashMap(); + + // 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 props = node.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> assocs = node.getAddedAssociations(); + for (String assocName : assocs.keySet()) + { + QName assocQName = Repository.resolveToQName(assocName); + + // get the associations added and create list of targets + Map addedAssocs = assocs.get(assocName); + List targets = new ArrayList(addedAssocs.size()); + for (AssociationRef assoc : addedAssocs.values()) + { + targets.add(assoc.getTargetRef()); + } + + // add the targets for this particular association + params.put(assocQName, (Serializable)targets); + } + + return params; + } + + /** + * Creates and populates a TransientNode to represent the given + * workflow task from the repository workflow engine + * + * @param task The task to create a representation of + */ + protected void createWorkItem(WorkflowTask task) + { + // get the type of the task + WorkflowTaskDefinition taskDef = task.definition; + + // create the basic transient node + TransientMapNode node = new TransientMapNode(taskDef.metadata.getName(), + task.name, task.properties); + + // add properties for the other useful metadata + node.getProperties().put(ContentModel.PROP_NAME.toString(), task.name); + node.getProperties().put("type", taskDef.metadata.getTitle()); + node.getProperties().put("id", task.id); + + if (logger.isDebugEnabled()) + logger.debug("Created node for work item with id '" + task.id + "' " + node); + + this.workItems.add(node); + } +} diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index d79b3e25bc..4f0504bcb6 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -1737,6 +1737,10 @@ namespaceService #{NamespaceService} + + workflowService + #{WorkflowService} + @@ -1777,6 +1781,16 @@ + + WorkflowBean + org.alfresco.web.bean.workflow.WorkflowBean + session + + workflowService + #{WorkflowService} + + + diff --git a/source/web/jsp/dashboards/dashlets/my-tasks-todo.png b/source/web/jsp/dashboards/dashlets/my-tasks-todo.png deleted file mode 100644 index e34ceee2aac106b23650393c5a32c47fe804f74e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15216 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 <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - + \ No newline at end of file diff --git a/source/web/jsp/workflow/manage-workitem.jsp b/source/web/jsp/workflow/manage-workitem.jsp deleted file mode 100644 index b518813ad9..0000000000 --- a/source/web/jsp/workflow/manage-workitem.jsp +++ /dev/null @@ -1,28 +0,0 @@ -<%-- - 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" %> - -<%-- - ---%> - - \ No newline at end of file diff --git a/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp b/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp index d57f91f593..a3799bbefb 100644 --- a/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp +++ b/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp @@ -19,7 +19,7 @@ <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - + diff --git a/source/web/jsp/workflow/workitems-todo-dashlet.jsp b/source/web/jsp/workflow/workitems-todo-dashlet.jsp new file mode 100644 index 0000000000..59ec036ddb --- /dev/null +++ b/source/web/jsp/workflow/workitems-todo-dashlet.jsp @@ -0,0 +1,88 @@ +<%@ 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" %> + + + + <%-- Primary column for details view mode --%> + + + + + + + + + + + + + + + + + <%-- Description column --%> + + + + + + + + <%-- Type column --%> + + + + + + + + <%-- Due date column --%> + + + + + + + + + + <%-- Status column --%> + + + + + + + + <%-- Actions column --%> + <%-- + + + + + + + + + + + + + + --%> + + + + + \ No newline at end of file