|
2 | 2 | Customising Roundup |
3 | 3 | =================== |
4 | 4 |
|
5 | | -:Version: $Revision: 1.55 $ |
| 5 | +:Version: $Revision: 1.56 $ |
6 | 6 |
|
7 | 7 | .. This document borrows from the ZopeBook section on ZPT. The original is at: |
8 | 8 | http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx |
@@ -705,7 +705,7 @@ triggered by using a ``:action`` CGI variable, where the value is one of: |
705 | 705 |
|
706 | 706 | :link=designator:property and :multilink=designator:property |
707 | 707 | The value specifies an item designator and the property on that |
708 | | - item to add _this_ item to as a link or multilink. |
| 708 | + item to add *this* item to as a link or multilink. |
709 | 709 | :note |
710 | 710 | Create a message and attach it to the current item's |
711 | 711 | "messages" property. |
@@ -2264,7 +2264,7 @@ Setting up a "wizard" (or "druid") for controlled adding of issues |
2264 | 2264 | encode those actions in methods on the interfaces Client class and insert |
2265 | 2265 | hooks to those actions in the "actions" attribute on that class, like so:: |
2266 | 2266 |
|
2267 | | - actions = client.Class.actions + ( |
| 2267 | + actions = client.Client.actions + ( |
2268 | 2268 | ('page1_submit', 'page1SubmitAction'), |
2269 | 2269 | ) |
2270 | 2270 |
|
@@ -2411,6 +2411,134 @@ very useful, and relatively easy to stop. |
2411 | 2411 | which filters out the users that have the vacation flag set to true. |
2412 | 2412 |
|
2413 | 2413 |
|
| 2414 | +Adding a time log to your issues |
| 2415 | +-------------------------------- |
| 2416 | + |
| 2417 | +We want to log the dates and amount of time spent working on issues, and be |
| 2418 | +able to give a summary of the total time spent on a particular issue. |
| 2419 | + |
| 2420 | +1. Add a new class to your tracker ``dbinit.py``:: |
| 2421 | + |
| 2422 | + # storage for time logging |
| 2423 | + timelog = Class(db, "timelog", period=Interval()) |
| 2424 | + |
| 2425 | + Note that we automatically get the date of the time log entry creation |
| 2426 | + through the standard property "creation". |
| 2427 | + |
| 2428 | +2. Link to the new class from your issue class (again, in ``dbinit.py``):: |
| 2429 | + |
| 2430 | + issue = IssueClass(db, "issue", |
| 2431 | + assignedto=Link("user"), topic=Multilink("keyword"), |
| 2432 | + priority=Link("priority"), status=Link("status"), |
| 2433 | + times=Multilink("timelog")) |
| 2434 | + |
| 2435 | + the "times" property is the new link to the "timelog" class. |
| 2436 | + |
| 2437 | +3. We'll need to let people add in times to the issue, so in the web interface |
| 2438 | + we'll have a new entry field, just below the change note box:: |
| 2439 | + |
| 2440 | + <tr> |
| 2441 | + <th nowrap>Time Log</th> |
| 2442 | + <td colspan=3><input name=":timelog"> |
| 2443 | + (enter as "3y 1m 4d 2:40:02" or parts thereof) |
| 2444 | + </td> |
| 2445 | + </tr> |
| 2446 | + |
| 2447 | + Note that we've made up a new form variable, but since we place a colon ":" |
| 2448 | + in front of it, it won't clash with any existing property variables. The |
| 2449 | + names you *can't* use are ``:note``, ``:file``, ``:action``, ``:required`` |
| 2450 | + and ``:template``. These variables are described in the section |
| 2451 | + `performing actions in web requests`_. |
| 2452 | + |
| 2453 | +4. We also need to handle this new field in the CGI interface - the way to |
| 2454 | + do this is through implementing a new form action (see `Setting up a |
| 2455 | + "wizard" (or "druid") for controlled adding of issues`_ for another example |
| 2456 | + where we implemented a new CGI form action). |
| 2457 | + |
| 2458 | + In this case, we'll want our action to: |
| 2459 | + |
| 2460 | + 1. create a new "timelog" entry, |
| 2461 | + 2. fake that the issue's "times" property has been edited, and then |
| 2462 | + 3. call the normal CGI edit action handler. |
| 2463 | + |
| 2464 | + The code to do this is:: |
| 2465 | + |
| 2466 | + actions = client.Client.actions + ( |
| 2467 | + ('edit_with_timelog', 'timelogEditAction'), |
| 2468 | + ) |
| 2469 | + |
| 2470 | + def timelogEditAction(self): |
| 2471 | + ''' Handle the creation of a new time log entry if necessary. |
| 2472 | + |
| 2473 | + If we create a new entry, fake up a CGI form value for the altered |
| 2474 | + "times" property of the issue being edited. |
| 2475 | + |
| 2476 | + Punt to the regular edit action when we're done. |
| 2477 | + ''' |
| 2478 | + # if there's a timelog value specified, create an entry |
| 2479 | + if self.form.has_key(':timelog') and \ |
| 2480 | + self.form[':timelog'].value.strip(): |
| 2481 | + period = Interval(self.form[':timelog'].value) |
| 2482 | + # create it |
| 2483 | + newid = self.db.timelog.create(period=period) |
| 2484 | + |
| 2485 | + # if we're editing an existing item, get the old timelog value |
| 2486 | + if self.nodeid: |
| 2487 | + l = self.db.issue.get(self.nodeid, 'times') |
| 2488 | + l.append(newid) |
| 2489 | + else: |
| 2490 | + l = [newid] |
| 2491 | + |
| 2492 | + # now make the fake CGI form values |
| 2493 | + for entry in l: |
| 2494 | + self.form.list.append(MiniFieldStorage('times', entry)) |
| 2495 | + |
| 2496 | + # punt to the normal edit action |
| 2497 | + return self.editItemAction() |
| 2498 | + |
| 2499 | + you add this code to your Client class in your tracker's ``interfaces.py`` |
| 2500 | + file. |
| 2501 | + |
| 2502 | +5. You'll also need to modify your ``issue.item`` form submit action so it |
| 2503 | + calls the time logging action we just created:: |
| 2504 | + |
| 2505 | + <tr> |
| 2506 | + <td> </td> |
| 2507 | + <td colspan=3> |
| 2508 | + <tal:block tal:condition="context/id"> |
| 2509 | + <input type="hidden" name=":action" value="edit_with_timelog"> |
| 2510 | + <input type="submit" name="submit" value="Submit Changes"> |
| 2511 | + </tal:block> |
| 2512 | + <tal:block tal:condition="not:context/id"> |
| 2513 | + <input type="hidden" name=":action" value="new"> |
| 2514 | + <input type="submit" name="submit" value="Submit New Issue"> |
| 2515 | + </tal:block> |
| 2516 | + </td> |
| 2517 | + </tr> |
| 2518 | + |
| 2519 | + Note that the "context/submit" command usually handles all that for you - |
| 2520 | + isn't it handy? The important change is setting the action to |
| 2521 | + "edit_with_timelog" for edit operations (where the item exists) |
| 2522 | + |
| 2523 | +6. Display the time log for an issue:: |
| 2524 | + |
| 2525 | + <table class="otherinfo" tal:condition="context/times"> |
| 2526 | + <tr><th colspan="3" class="header">Time Log</th></tr> |
| 2527 | + <tr><th>Date</th><th>Period</th><th>Logged By</th></tr> |
| 2528 | + <tr tal:repeat="time context/times"> |
| 2529 | + <td tal:content="time/creation"></td> |
| 2530 | + <td tal:content="time/period"></td> |
| 2531 | + <td tal:content="time/creator"></td> |
| 2532 | + </tr> |
| 2533 | + </table> |
| 2534 | + |
| 2535 | + I put this just above the Messages log in my issue display. |
| 2536 | + |
| 2537 | +6. If you're using a persistent web server - roundup-server or mod_python for |
| 2538 | + example - then you'll need to restart that to pick up the code changes. |
| 2539 | + When that's done, you'll be able to use the new time logging interface. |
| 2540 | + |
| 2541 | + |
2414 | 2542 | ------------------- |
2415 | 2543 |
|
2416 | 2544 | Back to `Table of Contents`_ |
|
0 commit comments