Changes between Version 2 and Version 3 of QueuesPlugin


Ignore:
Timestamp:
Jan 4, 2011, 3:47:58 AM (13 years ago)
Author:
Rob Guttman
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • QueuesPlugin

    v2 v3  
    55== Description ==
    66
    7 This plugin converts one or more reports into ticket 'queues'.  A ticket queue allows you to drag-and-drop tickets in your desired order.  Ticket positions in a queue get maintained in a custom field.
    8 
    9 The motivation for this plugin is for when you want to organize a queue of tickets in the order you intend to tackle the work.  Tickets could either use the milestone field as the 'bucket' or use a separate (custom) field.  See the [wiki:QueuesPlugin#Examples examples below] for more details.
     7This plugin converts one or more reports into ticket 'queues'.  A ticket queue allows you to drag-and-drop tickets into your desired order (similar to the Netflix Queue).  Ticket positions in a queue get maintained in a custom field of your choosing.
     8
     9The motivation for this plugin is for when you want to organize a workload in the order you intend to tackle it.  Tickets could either use the milestone field as the 'bucket' or use a separate (custom) field.  See the [wiki:QueuesPlugin#Examples examples below] for more details.
    1010
    1111
     
    6363You can check out QueuesPlugin from [http://trac-hacks.org/svn/queuesplugin here] using Subversion, or [source:queuesplugin browse the source] with Trac.
    6464
    65 == Example ==
    66 
    67 Examples...
     65== Examples ==
     66This plugin is built from several simple parts many of which are built into Trac (e.g., reports, dynamic variables).  This is to take advantage of what Trac already offers while still providing a great deal of flexibility in how you configure the queues.  Which means you can shoot yourself in the foot if not careful.
     67
     68=== Team work queue for all tickets ===
     69The simplest example is a queue of all tickets.  Assuming you already created a new custom {{{position}}} field as described [wiki:QueuesPlugin#Configuration above], you can create a new report like this:
     70{{{
     71SELECT s.value AS __color__,
     72       p.value as position, t.id AS ticket, summary,
     73       t.type AS type, t.severity, t.owner
     74FROM ticket t
     75LEFT JOIN enum s ON s.name = t.severity AND s.type = 'severity'
     76LEFT OUTER JOIN ticket_custom p ON p.ticket = t.id and p.name = 'position'
     77WHERE t.status <> 'closed'
     78ORDER BY CAST((CASE p.value
     79                WHEN '' THEN '0'
     80                ELSE COALESCE(p.value,'0') END) AS INTEGER) ASC,
     81         t.changetime DESC
     82}}}
     83
     84Notice that the first column is the {{{position}}} custom field and is defined as {{{p.value as position}}} - this is required.  The first column must always match the name of the custom field used to maintain the queue position.  In the ORDER BY clause, we cast the position field to an integer.  This example is for sqlite3; you'll need to check the syntax for the database you're using.  If your database does not support casting, you can use position padding option described below.  There are no other restrictions to the SQL you use for your reports (as far as I'm aware!).
     85
     86If the report above was created as, say, report {{{9}}}, then you would need to add it to the {{{[queues]}}} section of the {{{{trac.ini}}} file:
     87{{{
     88[queues]
     89reports = 9
     90}}}
     91
     92You may need to restart your Trac web server afterwards.  Here's a screenshot of the result with a few sample tickets:
     93
     94[[Image(example1.png)]]
     95
     96To reorder the tickets, simply drag and drop them to their desired location in the queue.
     97
     98=== Team work queue per milestone ===
     99To order your work queue within a milestone, you could create a single report that uses a {{{MILESTONE}}} [http://trac.edgewall.org/wiki/TracReports#AdvancedReports:DynamicVariables report dynamic variable] to set the milestone:
     100{{{
     101SELECT s.value AS __color__,
     102       p.value as position, t.id AS ticket, summary,
     103       t.type AS type, t.severity, t.owner
     104FROM ticket t
     105LEFT JOIN enum s ON s.name = t.severity AND s.type = 'severity'
     106LEFT OUTER JOIN ticket_custom p ON p.ticket = t.id and p.name = 'position'
     107WHERE t.status <> 'closed' and t.milestone = '$MILESTONE'
     108ORDER BY CAST((CASE p.value
     109                 WHEN '' THEN '0'
     110                 ELSE COALESCE(p.value,'0') END) AS INTEGER) ASC,
     111         t.changetime DESC
     112}}}
     113
     114If this was created as report {{{10}}}, update the {{{trac.ini}}} file as so (and restart your web server if needed):
     115{{{
     116[queues]
     117reports = 9,10
     118}}}
     119
     120Here's the screenshot of the report:
     121
     122[[Image(example2.png)]]
     123
     124In this example, I'm using the optional DynamicVariablesPlugin which converts the {{{MILESTONE}}} dynamic variable (aka argument) from a freeform textbox to a convenient dropdown menu at the right.
     125
     126=== Team work queue per milestone with a Triage group ===
     127The problem with the above example is that new tickets without a {{{position}}} field will get ordered above your other tickets.  This may not always be what you want.  So instead you can group the tickets into those with a position and those without and then individually drag-and-drop the new tickets into the ordered queue at your leisure.  Here's what the report could look like:
     128{{{
     129SELECT s.value AS __color__,
     130          (CASE p.value
     131             WHEN '' THEN 'Triage'
     132             WHEN NULL THEN 'Triage'
     133             ELSE '$MILESTONE'
     134            END) AS __group__,
     135       p.value as position, t.id AS ticket, summary,
     136       t.type AS type, t.severity, t.owner
     137FROM ticket t
     138LEFT JOIN enum s ON s.name = t.severity AND s.type = 'severity'
     139LEFT OUTER JOIN ticket_custom p ON p.ticket = t.id and p.name = 'position'
     140WHERE t.status <> 'closed' and t.milestone = '$MILESTONE'
     141ORDER BY (CASE p.value
     142                 WHEN '' THEN 'Triage'
     143                 WHEN NULL THEN 'Triage'
     144                 ELSE $MILESTONE END = 'Triage') DESC,
     145         CAST((CASE p.value
     146                 WHEN '' THEN '0'
     147                 ELSE COALESCE(p.value,'0') END) AS INTEGER) ASC,
     148         t.changetime DESC
     149}}}
     150
     151In addition to the updating {{{trac.ini}}} with the new report number, you now also need to describe what operation the plugin should take for each group as follows:
     152{{{
     153[queues]
     154reports = 9,10,11
     155group.triage = clear
     156}}}
     157
     158The {{{group.triage = clear}}} tells the plugin that the {{{Triage}}} group shouldn't reorder positions (the default operation).  The name {{{Triage}}} is just an example - you can use any name as long as you make the config match the name used in the SQL statement.  Here's the screenshot of the report:
     159
     160[[Image(example2.png)]]
     161
     162The tickets are now grouped with the Triage group at the top.  You can drag-and-drop tickets from the {{{Triage}}} group to anywhere in the {{{milestone1}}} group.  Furthermore, you can also clear the position from any ticket by moving it from the {{{milestone1}}} group to anywhere in the {{{Triage}}} group (hence the full meaning the the {{{clear}}} operation described above).  If you don't want to see the tickets The full list of operation directives are:
     163
     164 * reorder (the default)
     165 * clear
     166 * ignore
     167
     168There should only be one {{{reorder}}} group but any number of clear and ignore groups.  The {{{ignore}}} operation will simply list the tickets that match your grouping but tickets can't be moved out of or into it.  This is useful, for example, if you want to show work in the queue that has been implemented but still in a {{{verifying}}} state and not yet closed.  The SQL syntax is left as an exercise to the reader.  :)  TIP: You can click on any {{{clear}}} or {{{ignore}}} group heading to toggle between hiding and showing its contents.
     169
     170=== Team work queue per custom field ===
     171Another use case is when you want to retain the use of milestones as an orthogonal date-based means to manage projects and use a separate custom field to 'bucket' tickets into queues.  For example:
     172{{{
     173[ticket-custom]
     174position = text
     175queue = select
     176queue.options = |Queues 1|Queue 2|Queue 3
     177}}}
     178
     179You can simply re-write your SQL query to pivot on a {{{QUEUE}}} dynamic variable instead of (or perhaps in addition to) a {{{MILESTONE}}} dynamic variable.  The important thing is that the {{{position}}} custom field should be used for one and only one queue.
     180
     181=== Personal work queue ===
     182It should be clear now that you can create a queue for just about any SQL query as long as the {{{position}}} custom field is used for one and only one queue.  Another use case is if you want to use queues simply to let users manage their own work load.  You can simply create a report that pivots on the special, built-in {{{$USER}}} dynamic variable.  Viola!  Personal work queues for everyone using a single report.
     183
     184=== Team work queue ''and'' personal work queue ===
     185What if you wanted to both a team work queue that pivoted on, say, a custom {{{queue}}} field and personal work queues as described above.  We can't reuse the same {{{position}}} field for each purpose.  The answer?  Create a second custom field to manage the personal work queue's position:
     186{{{
     187[ticket-custom]
     188position = text
     189myposition = text
     190queue = select
     191queue.options = |Queues 1|Queue 2|Queue 3
     192}}}
     193
     194Now you can use the {{{position}}} field as before in the team work queues and the {{{myposition}}} field in the personal work queues using all of the techniques described above.  So for instance, the personal work queue in this case may define the first column as {{{p.value as "My Position"}}}.  Any uppercase letters are converted to lowercase and any spaces are removed in order to determine the correct field name.
     195
     196=== Development work queue ''and'' Product Management work queue ===
     197The same principle described above for supporting team and personal work queues simultaneously can be used to enable work queues for multiple stakeholders by using separate {{{position}}} fields.  So for example, Product Management may want to express their preferred order of work (beyond what a {{{priority}}} field permits) while the development team can creates report that shows Product Management's preferred ordering alongside their own ordering.
     198
     199Hopefully it's clear that many variants of this use case are also possible.
     200
     201
     202== Tips ==
     203Depending on how you use work queues, several complementary plugins may be beneficial to you:
     204
     205 * DynamicVariablesPlugin - as described above, this converts dynamic variable textboxes into dropdown menus for those fields which are select fields.  This can make navigating amongst queues much easier.
     206 * DynamicFieldsPlugin - allows you to clear the {{{position}}} field when the queue changes, for example, and hide the {{{myposition}}} field from general view - as just examples of how it can enhance the user experience of this queues plugin.
     207 * HideChangesPlugin - can hide ticket changes that do not have comments thus reducing the noise from queue reordering changes.*
     208
     209=== *Auditing ticket reorderings ===
     210Changing the value of custom fields would normally cause a ticket change which would show up on the ticket.  This may be just what you want to audit queue reorderings, however it can be quite noisy.  So this plugin provides several different methods to audit queue reorderings that gets set in {{{trac.ini}}} as follows:
     211{{{
     212[queues]
     213audit = log
     214}}}
     215
     216There are three valid values to the {{{audit}}} option:
     217 * {{{ticket}}} - normal ticket changes
     218 * {{{log}}} (default) - gets written to log file only (if enabled in {{{logging}}} sectipn)
     219 * {{{none}}} - no auditing at all
     220
     221Please note that the default audit option is {{{log}}}.  It is recommended that you use and configure the HideChangesPlugin to hide commentless changes if you opt for the {{{ticket}}} auditing method.
     222
    68223
    69224== Recent Changes ==