From 2de6a6923b43752f7699c5f3e661a46dceaa496e Mon Sep 17 00:00:00 2001 From: mdb Date: Fri, 8 Nov 2002 21:49:18 +0000 Subject: [PATCH] Notes, edits, tigers, oh my! git-svn-id: https://samskivert.googlecode.com/svn/trunk@898 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- runtime/twodue/etc/messages.properties | 35 +++++- .../java/com/samskivert/twodue/data/Task.java | 4 +- .../twodue/data/TaskRepository.java | 19 ++- .../com/samskivert/twodue/logic/detail.java | 89 ++++++++++++++ .../com/samskivert/twodue/logic/edit.java | 109 ++++++++++++++++++ .../com/samskivert/twodue/logic/index.java | 17 ++- runtime/twodue/src/sql/tasks-schema.sql | 7 +- runtime/twodue/web/detail.wm | 43 +++++++ runtime/twodue/web/edit.wm | 106 +++++++++++++---- runtime/twodue/web/index.wm | 33 +++--- 10 files changed, 404 insertions(+), 58 deletions(-) create mode 100644 runtime/twodue/src/java/com/samskivert/twodue/logic/detail.java create mode 100644 runtime/twodue/src/java/com/samskivert/twodue/logic/edit.java create mode 100644 runtime/twodue/web/detail.wm diff --git a/runtime/twodue/etc/messages.properties b/runtime/twodue/etc/messages.properties index 0d9eb334..aed2c177 100644 --- a/runtime/twodue/etc/messages.properties +++ b/runtime/twodue/etc/messages.properties @@ -1,6 +1,6 @@ # -*- mode: makefile -*- # -# $Id: messages.properties,v 1.1 2002/11/08 09:14:20 mdb Exp $ +# $Id: messages.properties,v 1.2 2002/11/08 21:49:17 mdb Exp $ # # Translation messages for Two Due application @@ -21,6 +21,17 @@ header.title={0} app_footer.summary_link=Task Summary app_footer.account_link=Login/out +# +# General task editing messages + +task.error.missing_summary = No summary provided for task. +task.error.missing_category = No category provided for task. +task.error.missing_complexity = No complexity selection for task. +task.error.invalid_priority = No priority selection for task. +task.error.invalid_creator = Creator not specified. +task.error.missing_taskid = Internal error. No task id provided. +task.error.no_such_task = No task exists with that task id. + # # index.wm @@ -30,8 +41,20 @@ index.message.task_created = Task created. index.message.task_claimed = Task claimed. index.message.task_completed = Task marked as completed. -index.error.missing_summary = No summary provided for new task. -index.error.missing_category = No category provided for new task. -index.error.missing_complexity = No complexity selection for new task. -index.error.invalid_priority = No priority selection for new task. -index.error.missing_taskid = Internal error. No task id provided. +index.error.invalid_detail_task = Task id specified for inspection not valid. + +# +# edit.wm + +edit.title = Edit Task + +edit.message.task_updated = Task updated. +edit.message.note_added = Note added. +edit.message.notes_updated = Notes updated. + +edit.error.missing_note = Can\'t add blank note. + +# +# detail.wm + +detail.title = Task Details diff --git a/runtime/twodue/src/java/com/samskivert/twodue/data/Task.java b/runtime/twodue/src/java/com/samskivert/twodue/data/Task.java index c67656e0..78ae89a1 100644 --- a/runtime/twodue/src/java/com/samskivert/twodue/data/Task.java +++ b/runtime/twodue/src/java/com/samskivert/twodue/data/Task.java @@ -1,5 +1,5 @@ // -// $Id: Task.java,v 1.1 2002/11/08 09:14:21 mdb Exp $ +// $Id: Task.java,v 1.2 2002/11/08 21:49:17 mdb Exp $ package com.samskivert.twodue.data; @@ -31,5 +31,5 @@ public class Task public Date completion; - public transient ArrayList notes; + public String notes; } diff --git a/runtime/twodue/src/java/com/samskivert/twodue/data/TaskRepository.java b/runtime/twodue/src/java/com/samskivert/twodue/data/TaskRepository.java index 07fdcb64..58bb1c3a 100644 --- a/runtime/twodue/src/java/com/samskivert/twodue/data/TaskRepository.java +++ b/runtime/twodue/src/java/com/samskivert/twodue/data/TaskRepository.java @@ -1,5 +1,5 @@ // -// $Id: TaskRepository.java,v 1.1 2002/11/08 09:14:21 mdb Exp $ +// $Id: TaskRepository.java,v 1.2 2002/11/08 21:49:17 mdb Exp $ package com.samskivert.twodue.data; @@ -75,6 +75,7 @@ public class TaskRepository extends JORARepository task.complexity = complexity; task.priority = priority; task.creator = creator; + task.notes = ""; createTask(task); return task; } @@ -102,18 +103,24 @@ public class TaskRepository extends JORARepository /** * Loads up the specified task. + * + * @return the requested task or null if no tasks exists with that id. */ - public Task loadTask (int taskId) + public Task loadTask (final int taskId) throws PersistenceException { return (Task)execute(new Operation () { public Object invoke (Connection conn, DatabaseLiaison liaison) throws PersistenceException, SQLException { - String query = "where COMPLETOR IS NULL AND OWNER IS NULL " + - "ORDER BY CATEGORY, PRIORITY"; - Cursor tc = _ttable.select(query); - return tc.toArrayList(); + String query = "where TASK_ID = " + taskId; + Cursor ec = _ttable.select(query); + Task task = (Task)ec.next(); + if (task != null) { + // call next() again to cause the cursor to close itself + ec.next(); + } + return task; } }); } diff --git a/runtime/twodue/src/java/com/samskivert/twodue/logic/detail.java b/runtime/twodue/src/java/com/samskivert/twodue/logic/detail.java new file mode 100644 index 00000000..1c44b5f8 --- /dev/null +++ b/runtime/twodue/src/java/com/samskivert/twodue/logic/detail.java @@ -0,0 +1,89 @@ +// +// $Id: detail.java,v 1.1 2002/11/08 21:49:17 mdb Exp $ + +package com.samskivert.twodue.logic; + +import java.util.StringTokenizer; +import javax.servlet.http.HttpServletRequest; + +import com.samskivert.servlet.user.User; +import com.samskivert.servlet.util.ParameterUtil; +import com.samskivert.util.StringUtil; +import com.samskivert.velocity.InvocationContext; + +import com.samskivert.twodue.Log; +import com.samskivert.twodue.TwoDueApp; +import com.samskivert.twodue.data.Task; + +/** + * Displays the details of a single task. + */ +public class detail extends UserLogic +{ + public void invoke (InvocationContext ctx, TwoDueApp app, User user) + throws Exception + { + HttpServletRequest req = ctx.getRequest(); + + int taskId = ParameterUtil.requireIntParameter( + ctx.getRequest(), "task", "task.error.missing_taskid"); + + // we use this to determine whether to show "complete" buttons for + // tasks + ctx.put("username", user.username); + + // load up the task in question + Task task = app.getRepository().loadTask(taskId); + if (task == null) { + ctx.put("error", "task.error.no_such_task"); + } else { + // format the notes and stuff those in the context + ctx.put("notes", formatNotes(task.notes)); + // stick the task in the context + ctx.put("task", task); + } + } + + protected String formatNotes (String notes) + { + if (StringUtil.blank(notes)) { + return notes; + } + + StringBuffer fnotes = new StringBuffer(); + StringTokenizer tok = new StringTokenizer(notes, "\n", true); + boolean excepting = false, eatnewline = false; + + while (tok.hasMoreTokens()) { + String line = tok.nextToken(); + boolean sawexcept = false; + if (line.indexOf("Exception:") != -1) { + sawexcept = true; + fnotes.append("
\n");
+            }
+
+            if (line.equals("\n")) {
+                if (!eatnewline) {
+                    fnotes.append("

\n"); + } else { + eatnewline = false; + } + // no further processing on newlines + continue; + + } else { + fnotes.append(line).append("\n"); + eatnewline = true; + } + + if (excepting && line.indexOf(" at ") == -1) { + excepting = false; + fnotes.append("

"); + } + if (sawexcept) { + excepting = true; + } + } + return fnotes.toString(); + } +} diff --git a/runtime/twodue/src/java/com/samskivert/twodue/logic/edit.java b/runtime/twodue/src/java/com/samskivert/twodue/logic/edit.java new file mode 100644 index 00000000..90cb771c --- /dev/null +++ b/runtime/twodue/src/java/com/samskivert/twodue/logic/edit.java @@ -0,0 +1,109 @@ +// +// $Id: edit.java,v 1.1 2002/11/08 21:49:17 mdb Exp $ + +package com.samskivert.twodue.logic; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import javax.servlet.http.HttpServletRequest; + +import com.samskivert.util.QuickSort; +import com.samskivert.util.StringUtil; + +import com.samskivert.servlet.RedirectException; +import com.samskivert.servlet.user.User; +import com.samskivert.servlet.util.ParameterUtil; +import com.samskivert.velocity.InvocationContext; + +import com.samskivert.twodue.Log; +import com.samskivert.twodue.TwoDueApp; +import com.samskivert.twodue.data.Task; + +/** + * Allows a single task to be edited. + */ +public class edit extends UserLogic +{ + public void invoke (InvocationContext ctx, TwoDueApp app, User user) + throws Exception + { + HttpServletRequest req = ctx.getRequest(); + + int taskId = ParameterUtil.requireIntParameter( + ctx.getRequest(), "task", "task.error.missing_taskid"); + + // load up the task in question + Task task = app.getRepository().loadTask(taskId); + if (task == null) { + ctx.put("error", "edit.error.no_such_task"); + } else { + // stick the task in the context + ctx.put("task", task); + } + + // if they've submitted the form, we update the task database + if (ParameterUtil.parameterEquals( + ctx.getRequest(), "action", "update")) { + // extract our fields + task.summary = ParameterUtil.requireParameter( + ctx.getRequest(), "summary", "task.error.missing_summary"); + // remove extra spaces introduced by our friend the textarea + task.summary = task.summary.trim(); + + task.category = ParameterUtil.requireParameter( + ctx.getRequest(), "category", + "task.error.missing_category"); + task.complexity = ParameterUtil.requireParameter( + ctx.getRequest(), "complexity", + "task.error.missing_complexity"); + task.priority = ParameterUtil.requireIntParameter( + ctx.getRequest(), "priority", + "task.error.invalid_priority"); + task.creator = ParameterUtil.requireParameter( + ctx.getRequest(), "creator", + "task.error.missing_creator"); + + // preserve the null-status of non-owned tasks + String owner = ParameterUtil.getParameter( + ctx.getRequest(), "owner", true); + task.owner = (StringUtil.blank(owner)) ? null : owner; + + app.getRepository().updateTask(task); + ctx.put("error", "edit.message.task_updated"); + + } else if (ParameterUtil.parameterEquals( + ctx.getRequest(), "action", "reopen")) { + // clear out the completor and completion dates + task.completor = null; + task.completion = null; + + app.getRepository().updateTask(task); + ctx.put("error", "edit.message.task_reopened"); + + } else if (ParameterUtil.parameterEquals( + ctx.getRequest(), "action", "addnote")) { + // extract our fields + String note = ParameterUtil.requireParameter( + ctx.getRequest(), "note", "edit.error.missing_note"); + // prefix the note with a creator identifier + note = "[" + user.username + "] " + note.trim(); + + if (StringUtil.blank(task.notes)) { + task.notes = note; + } else { + task.notes += "\n\n" + note; + } + + app.getRepository().updateTask(task); + ctx.put("error", "edit.message.note_added"); + + } else if (ParameterUtil.parameterEquals( + ctx.getRequest(), "action", "editnotes")) { + task.notes = ParameterUtil.getParameter( + ctx.getRequest(), "notes", false).trim(); + app.getRepository().updateTask(task); + ctx.put("error", "edit.message.notes_updated"); + } + } +} diff --git a/runtime/twodue/src/java/com/samskivert/twodue/logic/index.java b/runtime/twodue/src/java/com/samskivert/twodue/logic/index.java index ab0cef3e..028b0070 100644 --- a/runtime/twodue/src/java/com/samskivert/twodue/logic/index.java +++ b/runtime/twodue/src/java/com/samskivert/twodue/logic/index.java @@ -1,5 +1,5 @@ // -// $Id: index.java,v 1.1 2002/11/08 09:14:21 mdb Exp $ +// $Id: index.java,v 1.2 2002/11/08 21:49:17 mdb Exp $ package com.samskivert.twodue.logic; @@ -47,19 +47,18 @@ public class index extends UserLogic // set the creator from the username of the calling user Task task = new Task(); task.creator = user.username; + task.notes = ""; // no notes to start // parse our fields task.summary = ParameterUtil.requireParameter( - ctx.getRequest(), "summary", "index.error.missing_summary"); + ctx.getRequest(), "summary", "task.error.missing_summary"); task.category = ParameterUtil.requireParameter( - ctx.getRequest(), "category", - "index.error.missing_category"); + ctx.getRequest(), "category", "task.error.missing_category"); task.complexity = ParameterUtil.requireParameter( ctx.getRequest(), "complexity", - "index.error.missing_complexity"); + "task.error.missing_complexity"); task.priority = ParameterUtil.requireIntParameter( - ctx.getRequest(), "priority", - "index.error.invalid_priority"); + ctx.getRequest(), "priority", "task.error.invalid_priority"); // insert the task into the repository app.getRepository().createTask(task); @@ -72,7 +71,7 @@ public class index extends UserLogic } else if (ParameterUtil.parameterEquals( ctx.getRequest(), "action", "complete")) { int taskId = ParameterUtil.requireIntParameter( - ctx.getRequest(), "task", "index.error.missing_taskid"); + ctx.getRequest(), "task", "task.error.missing_taskid"); app.getRepository().completeTask(taskId, user.username); // let the user know we updated the database @@ -81,7 +80,7 @@ public class index extends UserLogic } else if (ParameterUtil.parameterEquals( ctx.getRequest(), "action", "claim")) { int taskId = ParameterUtil.requireIntParameter( - ctx.getRequest(), "task", "index.error.missing_taskid"); + ctx.getRequest(), "task", "task.error.missing_taskid"); app.getRepository().claimTask(taskId, user.username); // let the user know we updated the database diff --git a/runtime/twodue/src/sql/tasks-schema.sql b/runtime/twodue/src/sql/tasks-schema.sql index bf7ca300..8ab5d807 100644 --- a/runtime/twodue/src/sql/tasks-schema.sql +++ b/runtime/twodue/src/sql/tasks-schema.sql @@ -1,5 +1,5 @@ /** - * $Id: tasks-schema.sql,v 1.1 2002/11/08 09:14:21 mdb Exp $ + * $Id: tasks-schema.sql,v 1.2 2002/11/08 21:49:18 mdb Exp $ * * Schema for the Two Due tasks and notes table. */ @@ -61,6 +61,11 @@ CREATE TABLE TASKS */ COMPLETION DATE, + /** + * Free form notes associated with this task. + */ + NOTES TEXT NOT NULL, + /** * Defines our table keys. */ diff --git a/runtime/twodue/web/detail.wm b/runtime/twodue/web/detail.wm new file mode 100644 index 00000000..78d4ecba --- /dev/null +++ b/runtime/twodue/web/detail.wm @@ -0,0 +1,43 @@ +#set ($title = $i18n.xlate("detail.title")) +#import ("/header.wm") + +

+ + + + + +$form.fixedHidden("task", "$task.taskId") + + + + + + + + +#if (!$string.blank($notes)) + + +#end + + +
$task.complexity
+#if ($task.owner) +#if ($username == $task.owner) +$form.imageSubmit("submit", "", "images/complete.png", "Mark as completed") +#else +  +#end +#else +$form.imageSubmit("action", "claim", "images/claim.png", "Claim this task") +#end +$task.summary   +[$task.creator] +$task.category +
  +

+$notes +

+ +#import ("/footer.wm") diff --git a/runtime/twodue/web/edit.wm b/runtime/twodue/web/edit.wm index 8cbdef75..53ce5489 100644 --- a/runtime/twodue/web/edit.wm +++ b/runtime/twodue/web/edit.wm @@ -3,49 +3,113 @@

-

-$form.fixedHidden("action", "update") + + +
- + +#if ($task && $task.completor) + +$form.fixedHidden("action", "reopen") + + + + +#end + + +$form.fixedHidden("action", "update") + +$form.text("category", "size='10'", $task.category) + + + + + + + +
 
+Task is completed. +
+$form.submit("submit", "Reopen")
 
Summary:
Category:
- -$form.text("category", "size='10'", "") -
Complexity:
- -
Priority:
- -
Creator:
+$form.text("creator", "size='10'", $task.creator) +
 Owner:
+#if ($task.owner) +$form.text("owner", "size='10'", $task.owner) +#else +$form.text("owner", "size='10'", "") +#end +
$form.submit("submit", "Update")
+
+ + + + +$form.fixedHidden("action", "addnote") + + + + + + +$form.fixedHidden("action", "editnotes") + + + + + + + +
Add a note:
+ +
+$form.submit("submit", "Add")
Notes:
+ +
+$form.submit("submit", "Update")
+ +
+ #import ("/footer.wm") diff --git a/runtime/twodue/web/index.wm b/runtime/twodue/web/index.wm index 83750a4c..f48c2a49 100644 --- a/runtime/twodue/web/index.wm +++ b/runtime/twodue/web/index.wm @@ -13,9 +13,9 @@ #foreach ($otask in $otasks) #if ($vidx > 0) -  +  #end -$otask.name +$otask.name #foreach ($task in $otask.tasks)
@@ -34,7 +34,9 @@ $form.imageSubmit("submit", "", "images/complete.png", "Mark as completed") #end $task.summary -$task.category +$task.category + +
#end #end @@ -48,10 +50,10 @@ $form.imageSubmit("submit", "", "images/complete.png", "Mark as completed") #foreach ($xtask in $xtasks) #if ($vidx > 0) - + #end - +[$task.creator] +#if (!$string.blank($task.notes)) +  [...] +#end + + #end @@ -99,7 +107,9 @@ $form.fixedHidden("task", "$task.taskId") - + + #end
 
 
$xtask.name + #if ($xtask.pruned > 0) ($xtask.pruned ...) #else @@ -70,8 +72,14 @@ $form.fixedHidden("task", "$task.taskId")
$form.imageSubmit("action", "claim", "images/claim.png", "Claim this task") $task.summary   -[$task.creator] $task.category +
$task.completion
[$task.completor]
$task.summary$task.category
$task.category +
@@ -117,12 +127,10 @@ $form.fixedHidden("action", "create") Category:
- $form.text("category", "size='10'", "") - + Complexity:
- - + Priority:
- - + $form.submit("submit", "Create")