!! Tasks Plugin

%%tabbedSection

%%tab-Introduction
''Tasks'' are specialized wiki pages that can be used as a simple database. In this model, pages with names that share a common prefix are treated as "rows" in a virtual table, and wiki tables in the beginning of the page define their "column" values. So for example, a page called {{~WorkItem_tsk_24}} with the content:
{{{
|title|Create scenarios
|owner|JohnDoe
|created|2005/07/15
}}}
belongs to the virtual ''table'' {{~WorkItem}} and has "columns" {{title}}, {{owner}} and {{created}}. 

Based on this concept - pages grouped by prefix, with metadata embedded in the wiki page itself - a set of plugins was developled to support the creation of tasks and the execution of queries and simple reports.

%%

%%tab-Plugins

!! ~TasksFormHandler

This plugin (inspired in [SubmitNewIdea]) is used with [WikiForms|http://www.jspwiki.org/wiki/WikiFormsExample] to create Wiki pages with with just enough structure to allow the later extration of named attributes, which are them used as columns in a database. The ~TasksFormHandler automatically generates a new name for the pages it creates, with the specified prefix. 

You can create any field you want, but some fields are treated in a special way:

;{{title}}: Mandatory. A short string that provides a short description of the task.

;{{created}} and {{submitter}}: Those are added by the plugin, with the date the entry was created and the name of the page creator (make sure you have your name set in the Wiki).

;{{description}}: This special field is associated with a text area, and will be used to form the page's body; all other fields are added to a table. The content is wrapped in special markers that use the CSS style {{invisible}}, which you have to define in your jspwiki.css as:

{{{
.invisible { display:none }
}}}

(I find it quite useful to add comments to a wiki page text that I don't want to see in the final rendered HTML page).

;{{derived}}: if specified, a {{~TasksQuery}} will be added to the bottom of the new page that collects all the pages that specify this page as their source. Formats accepted are {{PAGE_PREFIX}} and {{PAGE_PREFIX|LINK_NAME}}. If LINK_NAME is not specified, {{source}} will be used.

;{{page}}: if specified, will be used as the common prefix of all pages created by this form handler. Otherwise, the current page name will be used.


----
!! ~TasksQuery

This plugin traverses a set of pages created by the previous plugin, parsing their attributes and using them to match a set of conditions. The values in the specified columns of the pages that satisfied those conditions are then collected in a table with links back to the original pages.

''Hint:'' Wrap the plugin with the new [WikiStyleSortable|BrushedTemplateSortableTables] and [WikiStyleTableFilter|BrushedTemplateFilteredTables] for enhanced functionality).

Available parameters are:

;{{select}}: Comma-separated list of the column references that will compose the final result. Default values are {{title}} and {{created}}. 

A column reference can be ''direct'' (just the column name) or ''indirect'' (name '.' name ...). Indirect references implement the equivalent of a SQL JOIN operation; the value of the first value in the page being analysed is interpreted as a page name; that page is fetched and the next value is used to read the actual column value.

The selected values can be not only text, but any valid wiki markup that can go in a table cell.\\
Combined with indirect references, you can have some really cool effects like using references to attached images for icons or [graph bars|BrushedTemplateGraphBars] for each row.

;{{from}}: Comma-separated list of the page prefixes over which this query will operate. Default value is the current page name.
;{{where}}: Comma-separated list of the conditions that a page must satisfy to be added to the final result. If not specified all pages that share the prefixes listed in {{from}} will be returned. Each condition is of the form:
{{{
<COLUMN> <OPERATOR> VALUE
}}}
Where value is one of the following:
|| Symbol || Operator
| = | Equal
| < | Less than
| > | Greater than
| <= | Less than or equal
| >= | Greater than or equal
| <> | Not equal
| != | Not equal
| ~~ | Regexp match (as supported by the Java [Pattern|http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html] class)

Note that the value must __not__ be enclosed in quotes or single quotes; all values are treated as strings.
;{{link}}: column whose values in the final result will be "linked" to the original source page. Default value is "title".

----
!! ~TasksAggregate

This plugin collects all the pages of a given virtual table (that share the specified prefix) and optionally their "children" in one single wiki page. This is useful when we want to print all the entries in a given category.

Currently the page {{title}} field is used to specify a section title, and the page {{description}} field is used to specify the section contents. The current version has no support for explicit ordering.

Available parameters are:

;{{page}}: Comma-separated list of the page prefixes over which this query will operate. Default value is the current page name.
;{{derived}}: if specified, each entry will be followed by a recursive list of subsections created from the pages that list this entry as their source. Formats accepted are {{PAGE_PREFIX}} and {{PAGE_PREFIX|LINK_NAME}}. If LINK_NAME is not specified, {{source}} will be used.

%%

%%tab-Examples

You can use the Tasks plugins to implement typical project management activities, like tracking requirements, work items and defects.

! Creating Defects
Our {{New Defect}} page uses WikiForms with the ~TaskFormHandler to create defects. Here is the page body (see the resulting page in the "screenshots" tab):
{{{
[{FormSet form='defectform' 
   status='DefectOpened' 
   title=''
   fields='title,priority,owner,status,defectid'
   page='Defect'}]

[{FormOutput form='defectform' handler='TasksFormHandler' populate='handler'}]
[{FormOpen form='defectform'}]
|Title:   |[{FormInput type='text' name='title' size=60}]
|Priority:|[{FormSelect name='priority' value='Critical;High;*Medium;Low'}] 
|Owner:   |[{FormSelect name='owner' value='*-;NascifAbousalhNeto;JohnDoe'}] 
|[Status|DefStatus]:  |[{FormSelect name='status' value='*DefOpened;DefFixed;DefVerified;DefExternal;DefDeferred;DefNofix;DefNobug;DefFuture'}]
|SAS Defect|[{FormInput type='text' name='defectid' size=60}]

Please enter a free form description of the problem here.\\
Please add log messages and instructions on how to reproduce the bug when available.\\
You may use [WikiMarkup|EditPageHelp], but no HTML:

[{FormTextarea name='description' rows=20 cols=80}]\\
[{FormInput type='submit' name='x' value='Create Defect' size=100}]  (Please click only once!)
[{FormClose}]

----
Back to [Defects].
}}}

! Listing open defects
{{{
[{TasksQuery  select='title,created,priority,owner,status,defectid' 
  from='Defect' 
  where 'status~(DefRequested)|(DefOpened)'}]
}}}

! Listing open issues for the current release:
{{{
[{TasksQuery  select='title,source.title,release,status' from='OpenIssue' where='release=2.1'}]
}}}

! Open work items for this year:
{{{
[{TasksQuery select='category,title,status'  
  from='WorkItem' 
  where='owner=NascifAbousalhNeto,status~(WiCreated)|(WiAssigned)|(WiStarted),created>2006/01/01}]
}}}

%%

%%tab-Screenshots

! ~TasksQuery
This page shows the link to the {{New Defect}} page and the result of a {{~TasksQuery}} wrapped in the sortable and table-filter WikiStyles:

[tasks.png]

! ~TasksFormHandler

"New Defect" page with the form used to create a new defect (using the {{~TasksFormHandler}} plugin:

[new_defect.png]

! ~DefectTask

A "defect" task page created by the "New Defect" form:

[defect_tsk.png]

%%
%%tab-Spec

|| Attribute || Value
| Package | {{org.nascif.jspwiki.plugin.tasks}}
| JSPWiki version | 2.4.18
| JDK version | 5.0 
| Contact | NascifAbousalhNeto

%%

%%tab-ChangeLog
''2006-07-06'' -- added workaround for strange interaction between JSPWiki 2.4.18, VersioningFileProvider and BrushedTemplate that was causing multiple copies of a task to be created in response to calls to {{~TasksFormHandler}}. 

According to the [logs|tasks-log-20060706.zip], the page containing {{~TasksFormHandler}} is rendered multiple times - including all its previous versions - and that causes the plugin to be executed, which as a side-effect creates a new "task" wiki page. The plugin used to protect itself from that the reload scenario by "blanking" the title field, but this method is not working anymore - some information is being cached and replaces the changes made by the form handler. 

Also, the {{~FormInfo}} contract is not being honored - new instances are created for each invocation, losing the information that the form had already been "executed".

The workaround was to cache the titles that have already been used in the current servlet thread. It is a poor solution that I hope to remove later when the problem described above has been fixed. In the mean time, the side effect is that you won't be able to create multiple tasks of the same type in the same session - but I don't think that is a problem anyway.

%%

%%tab-Discussion
Great idea (I have to try it yet, but in theory it looks great). I especially like the {{SELECT/FROM/WHERE}} syntax, which I don't find nerdy, and seems perfectly understandable by MereMortals as well.

I just wish you use a more appropriate name. I guess ''Tasks'' comes from the original intent, but as you demonstrate in your examples it can be used for generic page queries.

As far as the name is concerned, ~MetadataPageQueryPlugin, or ~QueryPlugin, would be a better, although the latter is already taken (by a badly named plugin too : [QueryPlugin]

Note that there are several complementary ways to build page indexes, see discussion on IdeaWikiLinksThroughXPATHIncludingSubPagesSupport, I wish all of that be unified and standardized in the engine core.

--[JDuprez]

--Jerome Duprez, 24-May-2006

----

Thanks Jerome. You guessed right, "Tasks" is the original intent. Note that this is actually a family of plugins: one to create the pages, one to aggregate them, and one to create the page indexes. The last one is called "TasksQuery", which is close to your suggestion.

-- [NascifAbousalhNeto]


----

This looks nice, but I can't get it to work.  Can someon give an example of how the TasksFormHandler is integrated with a form?

--AnonymousCoward, 22-Jun-2006

;: I added examples and screenshots. Let me know if you still have problems.

----

Is there a wiki running with this plug-in where one could try it out (like a SandBox)?

-- another AnonymousCoward

;: Unfortunately no, I have it running on an corporation intranet. Sorry. Let me know if you need help with the installation instructions.


----

I was wondering how can I plugin in the system date to the(CURRENT_DATE)in the query like the below example.

[{TasksQuery  select='title,created,priority,owner,status,defectid' 
  from='Defect' 
  where 'created=(CURRENT_DATE)}]


--AnonymousCoward, 08-Sep-2006


----

Sorry the above comment sample should look like this:

{{{
[{TasksQuery  select='title,created,priority,owner,status,defectid' 
  from='Defect' 
  where 'created=(CURRENT_DATE)'}]
}}}


--AnonymousCoward, 08-Sep-2006
;: In the current version there is no way to do this. But it would be possible by adding wiki variable evaluation of the arguments, or ~JavaScript evaluation support. I will look into adding something like that in the next version.\\
--[NascifAbousalhNeto], 9/9/2006

----

--GregP, 02-Oct-2006
;: Can you please attach the wiki pages utilised to generate the screenshots. Seems like I can get everything working except for the TasksAggregate

I have it like

{{{
[{TasksAggregate page='ProjTask'}]
}}}

Where {{ProjTask}} is from

{{{
[{FormSet form='todoform' 
   status='taskOpened' 
   title='ProjTask'
   fields='title,priority,owner,year, month, day,type,status,type,taskid'
   page='ProjTask'}]

[{FormOutput form='todoform' handler='TasksFormHandler' populate='handler'}]
[{FormOpen form='todoform'}]
. 
.
.
}}}

;: It seems there is a problem with ~TasksAggregate in the latest version. I will provide a fix in the next update. Sorry about that.\\
--[NascifAbousalhNeto], 03-oct-2006
----
Hello, how to edit record after creation? The way of manual page editing is minimal enougth but the edit form is more sutuable.
--[Alexander Sokolov], 26-Oct-2006

;: Hi Alexander, currently that is the only way. I agree that an edit form would be better, and in the future it might be possible taking advantage of the BrushedTemplate metadata editor. But for now, you have to manually change the table. Using the WikiWizard table editor might make it a little cleaner.
--[NascifAbousalhNeto], 27-Oct-2006
----
Hello NascifAbousalhNeto once again,
Thank you very much for this so usefull plugin!
--[Alexander Sokolov], 29-Oct-2006
----
--[GregP], 16-Feb-2007

;: As per my question on 02-Oct-2006, when will TasksAggregate be working. You mentioned that you would be updating. Guess you've been busy? :)
;: Thanks

Wow, time flies. I have - both been busy, and distracted by too many ideas on what to do next with this plugin and ImageGen - including some form of integration. Sorry. I will try to come up with something soon (weeks, not days).
-- [NascifAbousalhNeto], 15-Feb-2007
----
--[ScottParker], 21-Feb-2007

;: OK, I've tried and tried but can't get any of the TasksPlugins to work. I get the following error in the JSPWiki log:

Wiki.jsp - Plugin failed while executing:
java.lang.UnsupportedClassVersionError: org/nascif/jspwiki/plugin/tasks/TasksFormHandler (Unsupported major.minor version 49.0)
	at java.lang.ClassLoader.defineClass0(Native Method)

I'm stumped. Can anyone help me figure out what's going on and how to fix it?

Hi Scott, I believe this is a JDK version issue. I compiled the plugins with version 5.0. Are you running on a JRE/JDK version 4? -- [NascifAbousalhNeto], 22_Feb-2007

OK, I'm not even smart enough to be a Java newbie, but here's what I get on my Windows XP machine when I run 'java -version':
{{{C:\Program Files\Support Tools>java -version
java version "1.5.0_11"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)
Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode, sharing)}}}
I'm thinking that means I'm running version 5. I'm running under Tomcat 5.0. I'd be grateful for any suggestions to get me unstuck. -- [ScottParker] 05-Mar-2007

I think (not 100% sure) that Tomcat will use the contents of your {{JAVA_HOME}} over what is in your classpath. Try typing:
{{{C:\Program Files\Support Tools>%JAVA_HOME%
}}}
in the command line.
-- [NascifAbousalhNeto], 07-Mar-2007

Thanks for the suggestion. Here's what I get when I do 'echo %JAVA_HOME%':
{{{C:\Program Files\Support Tools>echo %JAVA_HOME%
C:\usr\local\bin\jdk1.5.0_11}}}
Still not working. However, I installed the TasksPlugin on my Mac and it works fine. Didn't have to do any environment variable acrobatics. Lesson? Use a Mac.
-- [ScottParker] 13-Mar-2007
----
--[AlexanderSokolov], 12-Mar-2007
Hi Nascif,\\
I developed some changes and additional plugin for your great TasksPlugin.\\
Please see AlexSokolovTasksPlugin for details.\\
Best regards,\\
Alex.\\
--[AlexanderSokolov], 01-Aug-2007\\
Hi Nascif,\\
Please see my comments on AlexSokolovTasksPlugin.\\
Of course, I'll glad help to improve your Greate plugin.\\
Best Regards,\\
Alex.