AnsweredAssumed Answered

[Résolu] Dashlet tâches actives

Question asked by ptitmat on Jul 1, 2009
Latest reply on Jul 30, 2009 by jayjayecl
Bonjour,

Je suis entrain de mettre en place une dashlet qui permettra de voir les taches actives de l'utilisateur et uniquement les siennes.

Je reprends actuellement le travail de Huberd dont un premier post avait été créé à l'adresse suivante http://forums.alfresco.com/fr/viewtopic.php?f=11&t=1947&p=9364&hilit=taskInstance#p9364

Etant nouveau sur le développement d'alfresco. J'ai quelques problèmes de configurations.

Je souhaiterais afficher une nouvelle dashlet que j'ai crée de manière identique à la dashlet tasks-active-dashlet.jsp

<%@ 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:outputText value="#{msg.no_tasks}" rendered="#{empty CustomWorkflowBean.allActiveTasks}" />

<a:richList id="personal-tasks-active-list" viewMode="details" value="#{CustomWorkflowBean.allActiveTasks}" var="r"
styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow"
altRowStyleClass="recordSetRowAlt" width="100%" pageSize="10"
initialSortColumn="created" initialSortDescending="true"
rendered="#{not empty CustomWorkflowBean.allActiveTasks}" refreshOnBind="true">

<%– Primary column for details view mode –%>
<a:column id="col1" primary="true" width="200" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col1-sort" label="#{msg.description}" value="bpm:description" mode="case-insensitive" styleClass="header"/>
</f:facet>
<f:facet name="small-icon">
<a:actionLink id="col1-act1" value="#{r['bpm:description']}" image="/images/icons/workflow_task.gif" showLink="false"
actionListener="#{CustomWorflowBean.setupTaskDialog}" action="dialog:manageTask">
<f:param name="id" value="#{r.id}" />
<f:param name="type" value="#{r.type}" />
</a:actionLink>
</f:facet>
<a:actionLink id="col1-act2" value="#{r['bpm:description']}" actionListener="#{CustomWorflowBean.setupTaskDialog}"
action="dialog:manageTask">
<f:param name="id" value="#{r.id}" />
<f:param name="type" value="#{r.type}" />
</a:actionLink>
</a:column>

<%– Task type –%>
<a:column id="col2" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col2-sort" label="#{msg.type}" value="name" mode="case-insensitive" styleClass="header"/>
</f:facet>
<h:outputText id="col2-txt" value="#{r.name}" />
</a:column>

<%– Task owner column –%>
<a:column id="col2a" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col2a-sort" label="#{msg.owner}" value="cm:owner" styleClass="header"/>
</f:facet>
<h:outputText id="col2a-txt" value="#{r['cm:owner']}" />
</a:column>

<%– Task id column –%>
<a:column id="col3" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col3-sort" label="#{msg.id}" value="bpm:taskId" styleClass="header"/>
</f:facet>
<h:outputText id="col3-txt" value="#{r['bpm:taskId']}" />
</a:column>

<%– Created Date column –%>
<a:column id="col4" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col4-sort" label="#{msg.created}" value="created" styleClass="header"/>
</f:facet>
<h:outputText id="col4-txt" value="#{r.created}">
<a:convertXMLDate type="both" pattern="#{msg.date_time_pattern}" />
</h:outputText>
</a:column>

<%– Due date column –%>
<a:column id="col5" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col5-sort" label="#{msg.due_date}" value="bpm:dueDate" styleClass="header"/>
</f:facet>
<h:outputText id="col5-txt" value="#{r['bpm:dueDate']}">
<a:convertXMLDate type="both" pattern="#{msg.date_pattern}" />
</h:outputText>
</a:column>

<%– Status column –%>
<a:column id="col6" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col6-sort" label="#{msg.status}" value="bpm:status" styleClass="header"/>
</f:facet>
<h:outputText id="col6-txt" value="#{r['bpm:status']}" />
</a:column>

<%– Priority column –%>
<a:column id="col7" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col7-sort" label="#{msg.priority}" value="bpm:priority" styleClass="header"/>
</f:facet>
<h:outputText id="col7-txt" value="#{r['bpm:priority']}" />
</a:column>

<%– Actions column –%>
<a:column id="col8" actions="true" style="padding:2px;text-align:left">
<f:facet name="header">
<h:outputText id="col8-txt" value="#{msg.actions}"/>
</f:facet>
<r:actions id="col8-actions" value="dashlet_todo_actions" context="#{r}" showLink="false"
styleClass="inlineAction" />
</a:column>

<a:dataPager styleClass="pager" />
</a:richList>

J'ai crée une nouvelle classe dans eclipse qui reprend l'exemple du code WorkflowBean (qui permet d'obtenir toutes les taches actives).
package lpr.alfresco.web.bean.workflow;

/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.transaction.UserTransaction;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.repository.NodeService;
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.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.NavigationBean;
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.TransientNode;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Managed bean used for providing support for the workflow task dashlets
*
* @author gavinc
*/
public class CustomWorkflowBean
{
   protected NavigationBean navigationBean;
   protected NodeService nodeService;
   protected WorkflowService workflowService;
   protected List<Node> tasks;
   protected List<Node> activeTasks;
   protected List<Node> pooledTasks;
   protected List<Node> completedTasks;
  
   private static final Log logger = LogFactory.getLog(CustomWorkflowBean.class);
  
   public static final String BEAN_NAME = "CustomWorkflowBean";
  
  
   // ——————————————————————————
   // Bean Getters and Setters
  
   /**
    * Returns a list of nodes representing the "all" active tasks.
    *
    * @return List of all active tasks
    */
   public List<Node> getAllActiveTasks()
   {
      if (this.activeTasks == null)
      {
         // get the current username
         FacesContext context = FacesContext.getCurrentInstance();
         User user = Application.getCurrentUser(context);
         String userName = user.getUserName();
        
         UserTransaction tx = null;
         try
         {
            tx = Repository.getUserTransaction(context, true);
            tx.begin();
           
            // query for all active tasks
            WorkflowTaskQuery query = new WorkflowTaskQuery();
            List<WorkflowTask> tasks = this.workflowService.queryTasks(query);
           
            // create a list of transient nodes to represent
            this.activeTasks = new ArrayList<Node>(tasks.size());
            for (WorkflowTask task : tasks)
            {
               
               Node node = createTask(task);
               this.activeTasks.add(node);
              
               if (logger.isDebugEnabled())
                  logger.debug("Added active task: " + node);
            }
           
            // commit the changes
            tx.commit();
         }
         catch (Throwable e)
         {
            // rollback the transaction
            try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
            Utils.addErrorMessage("Failed to get all active tasks: " + e.toString(), e);
         }
      }
     
      return this.activeTasks;
   }
     
   /**
    * Returns a list of nodes representing the "pooled" to do tasks the
    * current user has.
    *
    * @return List of to do tasks
    */
  
   public List<Node> getPooledTasks()
   {
      if (this.pooledTasks == null)
      {
         // get the current username
         FacesContext context = FacesContext.getCurrentInstance();
         User user = Application.getCurrentUser(context);
         String userName = user.getUserName();
        
         UserTransaction tx = null;
         try
         {
            tx = Repository.getUserTransaction(context, true);
            tx.begin();
           
            // get the current pooled tasks for the current user
            List<WorkflowTask> tasks = this.workflowService.getPooledTasks(userName);
           
            // create a list of transient nodes to represent
            this.pooledTasks = new ArrayList<Node>(tasks.size());
            for (WorkflowTask task : tasks)
            {
               Node node = createTask(task);
               this.pooledTasks.add(node);
              
               if (logger.isDebugEnabled())
                  logger.debug("Added pooled task: " + node);
            }
           
            // commit the changes
            tx.commit();
         }
         catch (Throwable e)
         {
            // rollback the transaction
            try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
            Utils.addErrorMessage("Failed to get pooled tasks: " + e.toString(), e);
         }
      }
     
      return this.pooledTasks;
   }

   /**
    * Returns a list of nodes representing the to do tasks the
    * current user has.
    *
    * @return List of to do tasks
    */
   public List<Node> getTasksToDo()
   {
      if (this.tasks == null)
      {
         // get the current username
         FacesContext context = FacesContext.getCurrentInstance();
         User user = Application.getCurrentUser(context);
         String userName = user.getUserName();
        
         UserTransaction tx = null;
         try
         {
            tx = Repository.getUserTransaction(context, true);
            tx.begin();
           
            // get the current in progress tasks for the current user
            List<WorkflowTask> tasks = this.workflowService.getAssignedTasks(
                  userName, WorkflowTaskState.IN_PROGRESS);
           
            // create a list of transient nodes to represent
            this.tasks = new ArrayList<Node>(tasks.size());
            for (WorkflowTask task : tasks)
            {
               Node node = createTask(task);
               this.tasks.add(node);
              
               if (logger.isDebugEnabled())
                  logger.debug("Added to do task: " + node);
            }
           
            // commit the changes
            tx.commit();
         }
         catch (Throwable e)
         {
            // rollback the transaction
            try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
            Utils.addErrorMessage("Failed to get to do tasks: " + e.toString(), e);
         }
      }
     
      return this.tasks;
   }
   /**
    * Returns a list of nodes representing the completed tasks the
    * current user has.
    *
    * @return List of completed tasks
    */
   public List<Node> getTasksCompleted()
   {
      if (this.completedTasks == null)
      {
         // get the current username
         FacesContext context = FacesContext.getCurrentInstance();
         User user = Application.getCurrentUser(context);
         String userName = user.getUserName();
        
         UserTransaction tx = null;
         try
         {
            tx = Repository.getUserTransaction(context, true);
            tx.begin();
           
            // get the current in progress tasks for the current user
            List<WorkflowTask> tasks = this.workflowService.getAssignedTasks(
                  userName, WorkflowTaskState.COMPLETED);
           
            // create a list of transient nodes to represent
            this.completedTasks = new ArrayList<Node>(tasks.size());
            for (WorkflowTask task : tasks)
            {
               Node node = createTask(task);
               this.completedTasks.add(node);
              
               if (logger.isDebugEnabled())
                  logger.debug("Added completed task: " + node);
            }
           
            // commit the changes
            tx.commit();
         }
         catch (Throwable e)
         {
            // rollback the transaction
            try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
            Utils.addErrorMessage("Failed to get completed tasks: " + e.toString(), e);
         } 
      }
     
      return this.completedTasks;
   }
   /**
    * Sets the navigation bean to use
    *
    * @param navigationBean The NavigationBean to set.
    */
   public void setNavigationBean(NavigationBean navigationBean)
   {
      this.navigationBean = navigationBean;
   }
  
   /**
    * Sets the workflow service to use
    *
    * @param workflowService WorkflowService instance
    */
   public void setWorkflowService(WorkflowService workflowService)
   {
      this.workflowService = workflowService;
   }
  
   /**
    * Sets the node service to use
    *
    * @param nodeService NodeService instance
    */
   public void setNodeService(NodeService nodeService)
   {
      this.nodeService = nodeService;
   }
  
  
   // ——————————————————————————
   // Navigation handlers
  
   public void setupTaskDialog(ActionEvent event)
   {
      UIActionLink link = (UIActionLink)event.getComponent();
      Map<String, String> params = link.getParameterMap();
      String id = params.get("id");
      String type = params.get("type");
     
      // setup the dispatch context with the task we're opening a dialog for
      TransientNode node = new TransientNode(QName.createQName(type), id, null);
      this.navigationBean.setupDispatchContext(node);
     
      // pass on parameters for the dialog
      Application.getDialogManager().setupParameters(event);
   }
  
   public void setupTaskDialog(String id, String type)
   {
      ParameterCheck.mandatoryString("Task ID", id);
      ParameterCheck.mandatoryString("Task Type", type);
     
      // setup the dispatch context with the task we're opening a dialog for
      TransientNode node = new TransientNode(QName.createQName(type), id, null);
      this.navigationBean.setupDispatchContext(node);
     
      // pass on parameters for the dialog
      Map<String, String> params = new HashMap<String, String>(2, 1.0f);
      params.put("id", id);
      params.put("type", type);
      Application.getDialogManager().setupParameters(params);
   }
  
  
   // ——————————————————————————
   // Helper methods
  
   /**
    * 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 TransientMapNode createTask(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.title, task.properties);
     
      // add properties for the other useful metadata
      node.getProperties().put(ContentModel.PROP_NAME.toString(), task.title);
      node.getProperties().put("type", node.getType().toString());
      node.getProperties().put("id", task.id);
     
      // add extra properties for completed tasks
      if (task.state.equals(WorkflowTaskState.COMPLETED))
      {
         // add the outcome label for any completed task
         String outcome = null;
         String transition = (String)task.properties.get(WorkflowModel.PROP_OUTCOME);
         if (transition != null)
         {
            WorkflowTransition[] transitions = task.definition.node.transitions;
            for (WorkflowTransition trans : transitions)
            {
               if (trans.id.equals(transition))
               {
                  outcome = trans.title;
                  break;
               }
            }
           
            if (outcome != null)
            {
               node.getProperties().put("outcome", outcome);
            }
         }
        
         // add the workflow instance id and name this taks belongs to
         node.getProperties().put("workflowInstanceId", task.path.instance.id);
        
         // add the task itself as a property
         node.getProperties().put("workflowTask", task);
      }
     
      return node;
   }
}


Je change ensuite le fichiers de configuration faces-config-beans.

<managed-bean>
      <managed-bean-name>CustomWorkflowBean</managed-bean-name>
      <managed-bean-class>lpr.alfresco.web.bean.workflow.CustomWorkflowBean</managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
      <managed-property>
         <property-name>navigationBean</property-name>
         <value>#{NavigationBean}</value>
      </managed-property>
      <managed-property>
         <property-name>nodeService</property-name>
         <value>#{NodeService}</value>
      </managed-property>
      <managed-property>
         <property-name>workflowService</property-name>
         <value>#{WorkflowService}</value>
      </managed-property>
   </managed-bean>

Pour compiler ma classe, je l'export dans un jarfile et je met ce jar dans les lib d'Alfresco.

Le résultat donne que dans le dashboard je vois bien apparaitre mes taches actives (donc la création de la dashlet se passe bien). Mais je ne vois pas l'ensemble des taches actives qui devrait apparaitre.

Alors que dans la dashlet toutes les taches actives il y en a 7 qui apparaissent.

Je pense donc qu'alfresco ne fait pas la liaison entre la dashlet et le CustomWorkflowBean. Et je pense donc à un problème de configuration mais je ne trouve pas l'erreur.

Donc si quelqu'un peut m'aider à trouver mon erreur, je lui serait reconnaissant.

Ptitmat

Outcomes