Skip to content

Commit

Permalink
Merge pull request #7 from batkinson/master
Browse files Browse the repository at this point in the history
Fixes for reported issues #4 and #5

This allows anyone with TICKET_VIEW to view the backlog, but you need BACKLOG_ADMIN to modify the backlog (instead of TICKET_MODIFY).  Also, allow configuration of the fields via a preference pane.
  • Loading branch information
jszakmeister committed Dec 8, 2011
2 parents 0551977 + d96aed9 commit 20837a4
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 21 deletions.
47 changes: 47 additions & 0 deletions backlog/prefs.py
@@ -0,0 +1,47 @@
# Copyright (C) 2011 Brent Atkinson
# All rights reserved.
#
# This software is licensed as described in the file LICENSE.txt, which
# you should have received as part of this distribution.

from trac.core import *
from trac.prefs import IPreferencePanelProvider
from trac.util.translation import _
from trac.web.chrome import add_notice, ITemplateProvider

class BacklogPluginPrefPanel(Component):
implements(IPreferencePanelProvider, ITemplateProvider)

_form_fields = [
'id', 'summary', 'component', 'version', 'type', 'owner', 'status',
'time_created'
]

# IPreferencePanelProvider methods

def get_preference_panels(self, req):
yield ('backlog', _('Backlog'))


def render_preference_panel(self, req, panel):

if req.method == 'POST':
fields = req.args.get('backlog_fields')
req.session['backlog_fields'] = fields
add_notice(req,_('Your backlog preferences have been saved.'))
req.redirect(req.href.prefs(panel or None))

return 'prefs_backlog.html', {
'shown_fields': req.session.get('backlog_fields') or self._form_fields
}

# ITemplateProvider methods

def get_htdocs_dirs(self):
from pkg_resources import resource_filename
return [('backlog', resource_filename(__name__, 'htdocs'))]

def get_templates_dirs(self):
from pkg_resources import resource_filename
return [resource_filename(__name__, 'templates')]

32 changes: 16 additions & 16 deletions backlog/templates/backlog.html
Expand Up @@ -167,26 +167,26 @@ <h1>$title backlog</h1>
<table id="tickets_table" class="listing tickets">
<thead>
<tr>
<th>Id</th>
<th>Summary</th>
<th>Component</th>
<th>Version</th>
<th>Type</th>
<th>Owner</th>
<th>Status</th>
<th>Created</th>
<th py:if="'id' in shown_fields">Id</th>
<th py:if="'summary' in shown_fields">Summary</th>
<th py:if="'component' in shown_fields">Component</th>
<th py:if="'version' in shown_fields">Version</th>
<th py:if="'type' in shown_fields">Type</th>
<th py:if="'owner' in shown_fields">Owner</th>
<th py:if="'status' in shown_fields">Status</th>
<th py:if="'time_created' in shown_fields">Created</th>
</tr>
</thead>
<tbody id="tickets">
<tr py:for="ticket in tickets" id="ticket_${ticket.id}" class="dojoDndItem">
<td><a href="${base_path}/ticket/${ticket.id}">#$ticket.id</a></td>
<td><a href="${base_path}/ticket/${ticket.id}">$ticket.summary</a></td>
<td>$ticket.component</td>
<td>$ticket.version</td>
<td>$ticket.type</td>
<td>$ticket.owner</td>
<td>$ticket.status</td>
<td>${format_datetime(ticket.time_created)}</td>
<td py:if="'id' in shown_fields"><a href="${base_path}/ticket/${ticket.id}">#$ticket.id</a></td>
<td py:if="'summary' in shown_fields"><a href="${base_path}/ticket/${ticket.id}">$ticket.summary</a></td>
<td py:if="'component' in shown_fields">$ticket.component</td>
<td py:if="'version' in shown_fields">$ticket.version</td>
<td py:if="'type' in shown_fields">$ticket.type</td>
<td py:if="'owner' in shown_fields">$ticket.owner</td>
<td py:if="'status' in shown_fields">$ticket.status</td>
<td py:if="'time_created' in shown_fields">${format_date(ticket.time_created)}</td>
</tr>
</tbody>
</table>
Expand Down
45 changes: 45 additions & 0 deletions backlog/templates/prefs_backlog.html
@@ -0,0 +1,45 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="prefs.html" />
<head>
<title>Backlog</title>
<style type="text/css">
label {
padding-right: .5em;
}
</style>
</head>
<body>
<div class="field">
<label>Shown Ticket Fields:</label>
<label>
<input type="checkbox" name="backlog_fields" value="id" checked="${'id' in shown_fields or None}" />Id
</label>
<label>
<input type="checkbox" name="backlog_fields" value="summary" checked="${'summary' in shown_fields or None}" />Summary
</label>
<label>
<input type="checkbox" name="backlog_fields" value="component" checked="${'component' in shown_fields or None}" />Component
</label>
<label>
<input type="checkbox" name="backlog_fields" value="version" checked="${'version' in shown_fields or None}" />Version
</label>
<label>
<input type="checkbox" name="backlog_fields" value="type" checked="${'type' in shown_fields or None}" />Type
</label>
<label>
<input type="checkbox" name="backlog_fields" value="owner" checked="${'owner' in shown_fields or None}" />Owner
</label>
<label>
<input type="checkbox" name="backlog_fields" value="status" checked="${'status' in shown_fields or None}" />Status
</label>
<label>
<input type="checkbox" name="backlog_fields" value="time_created" checked="${'time_created' in shown_fields or None}" />Created
</label>
</div>
</body>
</html>
17 changes: 14 additions & 3 deletions backlog/web_ui.py
Expand Up @@ -10,6 +10,7 @@
from trac.core import *
from trac.db import DatabaseManager
from trac.env import IEnvironmentSetupParticipant
from trac.perm import IPermissionRequestor
from trac.ticket.api import ITicketChangeListener
from trac.ticket.model import Ticket
from trac.web.chrome import INavigationContributor, ITemplateProvider
Expand Down Expand Up @@ -50,7 +51,12 @@
class BacklogPlugin(Component):
implements(INavigationContributor, IRequestHandler,
IEnvironmentSetupParticipant, ITemplateProvider,
ITicketChangeListener)
ITicketChangeListener, IPermissionRequestor)

_ticket_fields = [
'id', 'summary', 'component', 'version', 'type', 'owner', 'status',
'time_created'
]

# IEnvironmentSetupParticipant
def environment_created(self):
Expand Down Expand Up @@ -120,6 +126,9 @@ def upgrade_environment(self, db):
db.commit()

# INavigationContributor methods
def get_permission_actions(self):
return ['BACKLOG_ADMIN']

def get_active_navigation_item(self, req):
return 'backlog'

Expand Down Expand Up @@ -164,9 +173,10 @@ def match_request(self, req):
return False

def process_request(self, req):

req.perm.require('TICKET_VIEW')
if req.method == 'POST':
req.perm.require('TICKET_MODIFY')
req.perm.require('BACKLOG_ADMIN')

if 'move_after' in req.path_info:
return self._move_after(req)
Expand Down Expand Up @@ -197,8 +207,9 @@ def __init__(self):
data['form_token'] = req.form_token
data['active_milestones'] = self._get_active_milestones(milestone)
data['base_path'] = req.base_path
data['shown_fields'] = req.session.get('backlog_fields') or self._ticket_fields

if 'TICKET_MODIFY' in req.perm:
if 'BACKLOG_ADMIN' in req.perm:
data['allow_sorting'] = True

add_stylesheet(req, 'backlog/css/backlog.css')
Expand Down
7 changes: 5 additions & 2 deletions setup.py
Expand Up @@ -19,8 +19,11 @@
'scripts/*'
]},
entry_points={
'trac.plugins': ['backlog = backlog.web_ui']
},
'trac.plugins': [
'backlog = backlog.web_ui',
'backlog_prefs = backlog.prefs',
]
},
install_requires=[
'simplejson>=2.0',
],
Expand Down

0 comments on commit 20837a4

Please sign in to comment.