Workflow goodness. Tasks are now sorted by priority in the main summary

display, those with priority >= Next release all shown so that project
managers can move tasks from Soon or below into the "Next release"
priority where developers will see them and "claim" them.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@928 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2002-11-12 22:32:02 +00:00
parent da0e6968d5
commit 0da72988d8
4 changed files with 98 additions and 40 deletions
@@ -1,16 +1,27 @@
// //
// $Id: Task.java,v 1.4 2002/11/09 02:11:22 mdb Exp $ // $Id: Task.java,v 1.5 2002/11/12 22:32:02 mdb Exp $
package com.samskivert.twodue.data; package com.samskivert.twodue.data;
import java.util.ArrayList;
import java.sql.Date; import java.sql.Date;
import java.util.ArrayList;
import com.samskivert.util.StringUtil;
/** /**
* Contains the basic data associated with a task. * Contains the basic data associated with a task.
*/ */
public class Task public class Task
{ {
public static final String[] COMPLEXITIES = {
"Simple hack", "Minor feature", "Major feature",
"Subsystem", "Major refactor",
};
public static final int[] COMPLEXITY_VALUES = {
5, 10, 15, 20, 25,
};
public int taskId; public int taskId;
public String summary; public String summary;
@@ -33,16 +44,42 @@ public class Task
public String notes; public String notes;
/**
* Converts numerical priority to a string.
*/
public String getPriorityName () public String getPriorityName ()
{ {
switch (priority) { if (priority > 25) {
case 50: return "Urgent"; return "Urgent";
case 25: return "Next release"; } else if (priority > 15) {
case 15: return "Soon"; return "Next release";
case 10: return "Before launch"; } else if (priority > 10) {
case 5: return "Post launch"; return "Soon";
case 1: return "On the list"; } else if (priority > 5) {
default: return "Unknown"; return "Before launch";
} else if (priority > 1) {
return "Post launch";
} else {
return "On the list";
} }
} }
/**
* Converts string complexity to a value, lower meaning less complex,
* higher meaning more complex.
*/
public int getComplexityValue ()
{
for (int ii = 0; ii < COMPLEXITIES.length; ii++) {
if (COMPLEXITIES[ii].equals(complexity)) {
return COMPLEXITY_VALUES[ii];
}
}
return 50;
}
public String getDisplayCategory ()
{
return StringUtil.replace(category, ",", "<br>");
}
} }
@@ -1,5 +1,5 @@
// //
// $Id: TaskRepository.java,v 1.3 2002/11/09 01:40:01 mdb Exp $ // $Id: TaskRepository.java,v 1.4 2002/11/12 22:32:02 mdb Exp $
package com.samskivert.twodue.data; package com.samskivert.twodue.data;
@@ -126,27 +126,24 @@ public class TaskRepository extends JORARepository
} }
/** /**
* Loads up and returns all unowned, uncompleted tasks, ordered by * Loads up and returns all unowned, uncompleted tasks.
* priority.
*/ */
public ArrayList loadTasks () public ArrayList loadTasks ()
throws PersistenceException throws PersistenceException
{ {
return loadTasks("where COMPLETOR IS NULL AND OWNER IS NULL " + return loadTasks("where COMPLETOR IS NULL AND OWNER IS NULL");
"ORDER BY PRIORITY DESC");
} }
/** /**
* Loads up and returns all unowned, uncompleted tasks, whose summary * Loads up and returns all unowned, uncompleted tasks, whose summary
* or category contain the specified string, ordered by priority. * or category contain the specified string.
*/ */
public ArrayList findTasks (String query) public ArrayList findTasks (String query)
throws PersistenceException throws PersistenceException
{ {
return loadTasks("where COMPLETOR IS NULL AND OWNER IS NULL " + return loadTasks("where COMPLETOR IS NULL AND OWNER IS NULL " +
" AND (SUMMARY LIKE '%" + query + " AND (SUMMARY LIKE '%" + query +
"%' OR CATEGORY LIKE '%" + query + "%') " + "%' OR CATEGORY LIKE '%" + query + "%')");
"ORDER BY PRIORITY DESC");
} }
/** /**
@@ -1,14 +1,15 @@
// //
// $Id: index.java,v 1.3 2002/11/09 01:40:01 mdb Exp $ // $Id: index.java,v 1.4 2002/11/12 22:32:02 mdb Exp $
package com.samskivert.twodue.logic; package com.samskivert.twodue.logic;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import com.samskivert.util.QuickSort;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.samskivert.servlet.RedirectException; import com.samskivert.servlet.RedirectException;
@@ -89,6 +90,8 @@ public class index extends UserLogic
// load up outstanding tasks and break them down by complexity // load up outstanding tasks and break them down by complexity
String expand = ParameterUtil.getParameter(req, "expand", false); String expand = ParameterUtil.getParameter(req, "expand", false);
ctx.put("expand", expand);
ArrayList tasks = null; ArrayList tasks = null;
String query = ParameterUtil.getParameter(req, "query", false); String query = ParameterUtil.getParameter(req, "query", false);
if (StringUtil.blank(query)) { if (StringUtil.blank(query)) {
@@ -98,9 +101,12 @@ public class index extends UserLogic
tasks = app.getRepository().findTasks(query); tasks = app.getRepository().findTasks(query);
} }
// sort the tasks by priority, then complexity
Collections.sort(tasks, PLEX_PARATOR);
CatList[] xtasks = categorize(tasks, expand, new Categorizer() { CatList[] xtasks = categorize(tasks, expand, new Categorizer() {
public String category (Task task) { public String category (Task task) {
return task.complexity; return task.getPriorityName();
} }
}); });
ctx.put("xtasks", xtasks); ctx.put("xtasks", xtasks);
@@ -111,6 +117,7 @@ public class index extends UserLogic
// load up owned tasks and break them down by owner // load up owned tasks and break them down by owner
tasks = app.getRepository().loadOwnedTasks(); tasks = app.getRepository().loadOwnedTasks();
Collections.sort(tasks, PLEX_PARATOR);
CatList[] otasks = categorize(tasks, null, new Categorizer() { CatList[] otasks = categorize(tasks, null, new Categorizer() {
public String category (Task task) { public String category (Task task) {
return task.owner; return task.owner;
@@ -147,6 +154,7 @@ public class index extends UserLogic
return new CatList[0]; return new CatList[0];
} }
ArrayList cats = new ArrayList();
HashMap cmap = new HashMap(); HashMap cmap = new HashMap();
int tcount = tasks.size(); int tcount = tasks.size();
for (int ii = 0; ii < tcount; ii++) { for (int ii = 0; ii < tcount; ii++) {
@@ -157,23 +165,34 @@ public class index extends UserLogic
clist = new CatList(); clist = new CatList();
clist.name = category; clist.name = category;
clist.tasks = new ArrayList(); clist.tasks = new ArrayList();
cats.add(clist);
cmap.put(category, clist); cmap.put(category, clist);
} }
if (expand == null || clist.tasks.size() < 2 || if (expand == null || clist.tasks.size() < 2 ||
expand.equals("all") || expand.equals(category)) { expand.equals("all") ||
(task.priority > 15) || expand.equals(category)) {
clist.tasks.add(task); clist.tasks.add(task);
} else { } else {
clist.pruned++; clist.pruned++;
} }
} }
CatList[] ctasks = new CatList[cmap.size()]; CatList[] ctasks = new CatList[cats.size()];
Iterator iter = cmap.values().iterator(); cats.toArray(ctasks);
for (int ii = 0; iter.hasNext(); ii++) {
ctasks[ii] = (CatList)iter.next();
}
QuickSort.sort(ctasks);
return ctasks; return ctasks;
} }
// sorts tasks by relative complexity, simplest to most complex
protected static final Comparator PLEX_PARATOR = new Comparator() {
public int compare (Object o1, Object o2) {
Task t1 = (Task)o1, t2 = (Task)o2;
// sort first by reverse priority, then by complexity
if (t1.priority == t2.priority) {
return t1.getComplexityValue() - t2.getComplexityValue();
} else {
return t2.priority - t1.priority;
}
}
};
} }
+17 -12
View File
@@ -11,6 +11,11 @@
Tasks matching '$query': Tasks matching '$query':
#else #else
Outstanding tasks: Outstanding tasks:
#if ($expand == "all")
<a href="index.wm">[trim]</a>
#else
<a href="index.wm?expand=all">[show all]</a>
#end
#end #end
</b></td></tr> </b></td></tr>
@@ -40,7 +45,7 @@ $form.imageSubmit("submit", "", "images/complete.png", "Mark as completed")
#end #end
</td> </td>
<td>$task.summary</td> <td>$task.summary</td>
<td valign="top">$task.category</td> <td valign="top">$task.getDisplayCategory()</td>
<td valign="top"><a href="edit.wm?task=$task.taskId"> <td valign="top"><a href="edit.wm?task=$task.taskId">
<img src="images/edit.png" border="0"></a></td></tr> <img src="images/edit.png" border="0"></a></td></tr>
</form> </form>
@@ -67,15 +72,15 @@ $form.imageSubmit("submit", "", "images/complete.png", "Mark as completed")
#end #end
</td></tr> </td></tr>
#set ($priority = "") #set ($complexity = "")
#foreach ($task in $xtask.tasks) #foreach ($task in $xtask.tasks)
<form action="index.wm"> <form action="index.wm">
$form.fixedHidden("task", "$task.taskId") $form.fixedHidden("task", "$task.taskId")
#if ($task.getPriorityName() != $priority) #if ($task.complexity != $complexity)
#set ($priority = $task.getPriorityName()) #set ($complexity = $task.complexity)
<tr><td colspan="4" class="small">$task.getPriorityName()</td></tr> <tr><td colspan="4" class="small">$task.complexity</td></tr>
#end #end
#if ($vidx%2 == 0) #if ($vidx%2 == 0)
@@ -91,7 +96,7 @@ $form.fixedHidden("task", "$task.taskId")
&nbsp; <a href="detail.wm?task=$task.taskId">[...]</a> &nbsp; <a href="detail.wm?task=$task.taskId">[...]</a>
#end #end
</td> </td>
<td valign="top">$task.category</td> <td valign="top">$task.getDisplayCategory()</td>
<td valign="top"><a href="edit.wm?task=$task.taskId"> <td valign="top"><a href="edit.wm?task=$task.taskId">
<img src="images/edit.png" border="0"></a></td> <img src="images/edit.png" border="0"></a></td>
</tr> </tr>
@@ -130,7 +135,7 @@ Filter on single word:<br>
<tr bgcolor="$rowcolor"> <tr bgcolor="$rowcolor">
<td valign="top" align="center">$task.completion<br>[$task.completor]</td> <td valign="top" align="center">$task.completion<br>[$task.completor]</td>
<td>$task.summary</td> <td>$task.summary</td>
<td valign="top">$task.category</td> <td valign="top">$task.getDisplayCategory()</td>
<td valign="top"><a href="edit.wm?task=$task.taskId"> <td valign="top"><a href="edit.wm?task=$task.taskId">
<img src="images/edit.png" border="0"></a></td></tr> <img src="images/edit.png" border="0"></a></td></tr>
#end #end
@@ -155,11 +160,11 @@ $form.text("category", "size='10'", "")
<td>Complexity:<br> <td>Complexity:<br>
<select name="complexity"> <select name="complexity">
$form.option("complexity", "1 - Simple hack", "Simple hack", "1 - Simple hack") $form.option("complexity", "Simple hack", "Simple hack", "Simple hack")
$form.option("complexity", "2 - Minor feature", "Minor feature", "1 - Simple hack") $form.option("complexity", "Minor feature", "Minor feature", "Simple hack")
$form.option("complexity", "3 - Major feature", "Major feature", "1 - Simple hack") $form.option("complexity", "Major feature", "Major feature", "Simple hack")
$form.option("complexity", "4 - Subsystem", "Subsystem", "1 - Simple hack") $form.option("complexity", "Subsystem", "Subsystem", "Simple hack")
$form.option("complexity", "5 - Major refactor", "Major refactor", "1 - Simple hack") $form.option("complexity", "Major refactor", "Major refactor", "Simple hack")
</select> </select>
</td> </td>