[Zope3-checkins] CVS: zopeproducts/bugtracker/browser -
bug_listing_compressed.pt:1.1 bug_listing_normal.pt:1.1
bug.py:1.11 bug_overview.pt:1.5 configure.zcml:1.9
dependencies.pt:1.4 tracker.py:1.12 tracker_overview.pt:1.8
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Aug 28 02:23:02 EDT 2003
Update of /cvs-repository/zopeproducts/bugtracker/browser
In directory cvs.zope.org:/tmp/cvs-serv11184/browser
Modified Files:
bug.py bug_overview.pt configure.zcml dependencies.pt
tracker.py tracker_overview.pt
Added Files:
bug_listing_compressed.pt bug_listing_normal.pt
Log Message:
Major usibility improvements landed:
- You can now filter also by the owner. This is good when you want to
see all the bugs you are responsible for for example.
- There is a "View Type" in the tracker overview, which specifes how the
found bugs are displayed. "normal" is what we had till now and
"compressed" displays the bugs in a table (one bug per line). This
feature was requested by Fred Drake, who liked this particular feature
in the SF bug tracker.
- You can now collapse the filter options, so that more bugs fit on your
screen.
- When seeing the bug overview, you now have an "Add Bug" link there, which
enables you to add a new bug that is a dependency of the currently viewed
one. This feature will increase input speed by multiples. Thanks goes to
Jim for suggesting this.
- In the bug dependency screen you can also collapse the edit interface.
- The dependency edit interface is not shown as part of the "Dependencies"
screen, if the user has not the necessary rights to modify this data.
- The management widget for dependencies has been switched to a different
model which is more scalable and user savy. Furthermore, you cannot just
set Dependencies (children) but also Dependents (Parents), which makes it
much easier to manage dependencies in general, since you often want to
specify the Dependent and not the Dependency. Thanks to Jim again for
suggesting this.
- Chnaged the dependency annotation key to be a valid file, so that it
plays nice with fssync. This means, if you have an existing bug tracker
you cannot just upgrade your software, since you would loose all of your
dependencies. The easy solution is to export the entire bug tracker to
XML first, before upgrading, so that you can easily import it after the
upgrade again.
** WARNING: THIS CHECKIN BREAKS BACKWARD COMPATIBILITY! SEE LAST NOTE ABOVE**
=== Added File zopeproducts/bugtracker/browser/bug_listing_compressed.pt ===
<table class="listing" width="100%"
style="font-size:80%;">
<tr>
<th width="70%">Title (ID)</th>
<th width="10%">Submitter</th>
<th width="10%">Date/Time</th>
<th width="10%">Owners</th>
</tr>
<tal:block repeat="bug view/getBugs" i18n:domain="bugtracker">
<tr class=""
tal:define="oddrow repeat/bug/odd"
tal:attributes="class python:oddrow and 'even' or 'odd'">
<td>
<a class="" href=""
tal:attributes="
href string:./${bug/name};
class string:node ${bug/context/status} ${bug/context/priority}">
<span tal:replace="bug/context/title" />
(<span tal:replace="bug/name" />)
</a>
</td>
<td tal:content="bug/submitter/getLogin" />
<td tal:content="bug/shortCreated" />
<td tal:content="bug/owners" />
</tr>
</tal:block>
</table>
=== Added File zopeproducts/bugtracker/browser/bug_listing_normal.pt ===
<tal:block repeat="bug view/getBugs" i18n:domain="bugtracker">
<div class=""
tal:define="oddrow repeat/bug/odd"
tal:attributes="class python:oddrow and 'even' or 'odd'">
<h5 class="summary_title" >
<a href=""
tal:attributes="href string:./${bug/name}/@@overview.html"
i18n:translate="">
Bug #<d tal:replace="bug/name" i18n:name="bug_id">1</d> -
<d tal:replace="bug/context/title" i18n:name="bug_title">
Bug Title
</d>
</a>
</h5>
<div class="summary_content">
<div class="summary_condition">
<span i18n:translate="">Status:</span>
<span tal:attributes="class bug/context/status"
tal:content="bug/status/title">New</span> -
<span i18n:translate="">Priority:</span>
<span tal:attributes="class bug/context/priority"
tal:content="bug/priority/title">Normal</span> -
<span i18n:translate="">Type: </span>
<b tal:replace="bug/type/title">Bug</b>
</div>
<div class="summary_body" tal:content="bug/descriptionPreview">
Message Description Sneak Preview goes here...
</div>
<div class="summary_metadata" i18n:translate="">
Posted by <b tal:content="bug/submitter/getTitle"
i18n:name="submitter">Submitter</b>
on <b tal:replace="bug/created"
i18n:name="created_date">2003/01/01</b>
- <b tal:replace="bug/numberOfComments"
i18n:name="num_comments">3</b> comments
</div>
</div>
</div>
</tal:block>
=== zopeproducts/bugtracker/browser/bug.py 1.10 => 1.11 ===
--- zopeproducts/bugtracker/browser/bug.py:1.10 Tue Aug 12 23:41:48 2003
+++ zopeproducts/bugtracker/browser/bug.py Thu Aug 28 01:22:31 2003
@@ -15,13 +15,10 @@
$Id$
"""
+import docutils
import re
-from zope.component import getService, getAdapter
-from zope.component.interfaces import IViewFactory
-from zope.interface import implements
-from zope.proxy import removeAllProxies
-from zope.schema.vocabulary import getVocabularyRegistry
+from zope.app import zapi
from zope.app.browser.form.vocabularywidget import VocabularyEditWidget
from zope.app.browser.form.widget import TextWidget, TextAreaWidget
from zope.app.context import ContextWrapper
@@ -29,12 +26,17 @@
from zope.app.security.grants.principalrole import principalRoleManager
from zope.app.security.settings import Allow
from zope.app.services.servicenames import Authentication
-from zope.app.traversing import getParent, getName
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.interfaces.size import ISized
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.browser.form.widget import MultiListWidget, ListWidget
from zope.app.browser.container.adding import Adding
+from zope.component.interfaces import IViewFactory
+from zope.exceptions import Unauthorized, ForbiddenAttribute
+from zope.interface import implements
+from zope.proxy import removeAllProxies
+from zope.schema.vocabulary import getVocabularyRegistry
+from zope.security.checker import getChecker, ProxyFactory
from zopeproducts.bugtracker.interfaces import IComment
from zopeproducts.bugtracker.interfaces import IBugDependencies
@@ -71,52 +73,86 @@
"""Get's all the fancy expressions for the attribute values."""
def created(self):
- dc = getAdapter(self.context, IZopeDublinCore)
+ dc = zapi.getAdapter(self.context, IZopeDublinCore)
formatter = self.request.locale.getDateTimeFormatter('short')
return formatter.format(dc.created)
def modified(self):
- dc = getAdapter(self.context, IZopeDublinCore)
+ dc = zapi.getAdapter(self.context, IZopeDublinCore)
formatter = self.request.locale.getDateTimeFormatter('short')
if dc.modified is None:
return self.created()
return formatter.format(dc.modified)
def submitter(self):
- auth = getService(self.context, Authentication)
+ auth = zapi.getService(self.context, Authentication)
return auth.getPrincipal(self.context.submitter)
def description(self):
- html = HTML(self.context.description, level=3)
+ # format with strings
+ pub = docutils.core.Publisher()
+ pub.set_reader('standalone', None, 'restructuredtext')
+ pub.set_writer('html')
+
+ # go with the defaults
+ pub.get_settings()
+
+ # this is needed, but doesn't seem to do anything
+ pub.settings._destination = ''
+
+ # use the Zope 3 stylesheet
+ pub.settings.stylesheet = 'zope3.css'
+
+ # set the reporting level to something sane (1 being the smallest)
+ pub.settings.report_level = 1
+
+ # don't break if we get errors
+ pub.settings.halt_level = 6
+
+ # input
+ pub.source = docutils.io.StringInput(source=self.context.description)
+
+ # output - not that it's needed
+ pub.destination = docutils.io.StringOutput(encoding='UTF-8')
+
+ # parse!
+ document = pub.reader.read(pub.source, pub.parser, pub.settings)
+
+ # transform
+ pub.apply_transforms(document)
+
+ # do the format
+ html = pub.writer.write(document, pub.destination)
html = re.sub(
- r'(?sm)^<html.*<body.*?>\n(.*)</body>\n</html>\n',r'\1', html)
+ r'(?sm)^<\?xml.*<html.*<body.*?>\n(.*)</body>\n</html>\n',r'\1',
+ html)
return html
def status(self):
registry = getVocabularyRegistry()
- types = registry.get(getParent(self.context), 'Stati')
+ types = registry.get(zapi.getParent(self.context), 'Stati')
return types.getTerm(self.context.status)
def type(self):
registry = getVocabularyRegistry()
- types = registry.get(getParent(self.context), 'BugTypes')
+ types = registry.get(zapi.getParent(self.context), 'BugTypes')
return types.getTerm(self.context.type)
def release(self):
if self.context.release is None:
return u'not specified'
registry = getVocabularyRegistry()
- types = registry.get(getParent(self.context), 'Releases')
+ types = registry.get(zapi.getParent(self.context), 'Releases')
return types.getTerm(self.context.release)
def priority(self):
registry = getVocabularyRegistry()
- types = registry.get(getParent(self.context), 'Priorities')
+ types = registry.get(zapi.getParent(self.context), 'Priorities')
return types.getTerm(self.context.priority)
def owners(self):
registry = getVocabularyRegistry()
- users = registry.get(getParent(self.context), 'Users')
+ users = registry.get(zapi.getParent(self.context), 'Users')
return map(lambda owner: users.getTerm(owner), self.context.owners)
@@ -159,6 +195,23 @@
return '../'+self.context.contentName
+class AddDependentBug(BugForm):
+
+ def __init__(self, context, request):
+ super(AddDependentBug, self).__init__(context, request)
+ self.label = "Add Bug (Dependent: %s)" %context.title
+
+ def add(self, content):
+ container = zapi.getParent(self.context)
+ name = container.setObject('auto', content)
+ deps = zapi.getAdapter(self.context, IBugDependencies)
+ deps.dependencies += (name,)
+ return container[name]
+
+ def nextURL(self):
+ return './overview.html'
+
+
class EditBug(BugBaseView, BugForm):
def update(self):
@@ -185,34 +238,65 @@
attchs = []
for name, obj in self.context.items():
if not IComment.isImplementedBy(obj):
- size = getAdapter(obj, ISized)
+ size = zapi.getAdapter(obj, ISized)
attchs.append({'name': name, 'size': size.sizeForDisplay()})
return attchs
def dependencies(self):
- deps = getAdapter(self.context, IBugDependencies)
+ deps = zapi.getAdapter(self.context, IBugDependencies)
return deps.dependencies
class Dependencies(object):
- def dependencies(self):
- deps = getAdapter(self.context, IBugDependencies)
- return deps.dependencies
+ def __init__(self, context, request):
+ super(Dependencies, self).__init__(context, request)
+ # For efficiency get these values once and be done.
+ deps = zapi.getAdapter(self.context, IBugDependencies)
+ # If the two conditions are not fulfilled, we are not going to need
+ # the values.
+ if self.canChangeDependencies() and self.getShowDepsOptions():
+ self.dependencies = deps.dependencies
+ self.dependents = deps.dependents
+
+ def dependencyValues(self):
+ deps = zapi.getAdapter(self.context, IBugDependencies)
+ dep_type = self.request.get('dep_type', 'dependencies')
+ if dep_type == 'dependencies':
+ return self.dependencies
+ else:
+ return self.dependents
def availableBugs(self):
- tracker = getParent(self.context)
+ tracker = zapi.getParent(self.context)
bugs = []
for name, bug in tracker.items():
# Make sure we do not list the bug itself
- if name != getName(self.context):
+ if name != zapi.name(self.context):
bugs.append({'name': name, 'title': bug.title})
return bugs
- def setDependencies(self, dependencies=()):
- deps = getAdapter(self.context, IBugDependencies)
- deps.setDependencies(dependencies)
- return self.request.response.redirect('./@@dependencies.html')
+ def setDependencyValues(self):
+ dep_type = self.request.get('dep_type', 'dependencies')
+ deps = zapi.getAdapter(self.context, IBugDependencies)
+
+ if 'ADD' in self.request and 'add_deps' in self.request:
+ if dep_type == 'dependencies':
+ deps.addDependencies(tuple(self.request['add_deps']))
+ else:
+ deps.addDependents(tuple(self.request['add_deps']))
+
+ if 'DELETE' in self.request and 'del_deps' in self.request:
+ if dep_type == 'dependencies':
+ deps.deleteDependencies(tuple(self.request['del_deps']))
+ else:
+ deps.deleteDependents(tuple(self.request['del_deps']))
+
+ self.setShowDepsOptions()
+ self.setDepType()
+
+ return self.request.response.redirect(
+ './@@dependencies.html?dep_type=' + dep_type)
def _branchHTML(self, children):
html = '<ul>\n'
@@ -224,7 +308,7 @@
return html
def branch(self):
- deps = getAdapter(self.context, IBugDependencies)
+ deps = zapi.getAdapter(self.context, IBugDependencies)
children = deps.findChildren()
return self._branchHTML(children)
@@ -235,7 +319,7 @@
return all
def getStatistics(self):
- deps = getAdapter(self.context, IBugDependencies)
+ deps = zapi.getAdapter(self.context, IBugDependencies)
children = deps.findChildren()
all = self._getAllSubs(children)
all_num = len(all)
@@ -254,13 +338,31 @@
}
return stats
+ def getDepType(self):
+ return self.request.cookies.get('dep_type', 'dependencies')
+
+ def setDepType(self):
+ value = self.request.get('dep_type', 'dependencies')
+ self.request.response.setCookie('dep_type', value)
+
+ def getShowDepsOptions(self):
+ return int(self.request.cookies.get('show_deps_options', '1'))
+
+ def setShowDepsOptions(self):
+ if 'COLLAPSE' in self.request:
+ value = '0'
+ else:
+ value = '1'
+ self.request.response.setCookie('show_deps_options', value)
+
def canChangeDependencies(self):
- pid = self.request.user.getId()
- # 100% buggy!
- roles = principalRoleManager.getRolesForPrincipal(pid)
- roles = filter(lambda r: r[1] == Allow, roles)
- roles = map(lambda r: r[0], roles)
- #return 'bugtracker.Editor' in roles
+ deps = zapi.getAdapter(self.context, IBugDependencies)
+ proxy = ProxyFactory(deps)
+ checker = getChecker(proxy)
+ try:
+ checker.check_setattr(self, 'dependencies')
+ except (Unauthorized, ForbiddenAttribute):
+ return False
return True
legend = ViewPageTemplateFile('legend.pt')
@@ -273,7 +375,7 @@
self.request = request
def name(self):
- return getName(self.context)
+ return zapi.name(self.context)
__call__ = ViewPageTemplateFile('branchentry.pt')
=== zopeproducts/bugtracker/browser/bug_overview.pt 1.4 => 1.5 ===
--- zopeproducts/bugtracker/browser/bug_overview.pt:1.4 Tue Aug 12 18:50:57 2003
+++ zopeproducts/bugtracker/browser/bug_overview.pt Thu Aug 28 01:22:31 2003
@@ -69,6 +69,9 @@
</tal:block>
</div>
+ <div class="action" i18n:domain="bugtracker">
+ <a href="./@@AddBug" i18n:translate="">Add Bug</a>
+ </div>
<h4 i18n:translate="" i18n:domain="bugtracker">Attachments</h4>
<ul id="attachments" tal:condition="view/attachments">
=== zopeproducts/bugtracker/browser/configure.zcml 1.8 => 1.9 ===
--- zopeproducts/bugtracker/browser/configure.zcml:1.8 Tue Aug 12 14:55:11 2003
+++ zopeproducts/bugtracker/browser/configure.zcml Thu Aug 28 01:22:31 2003
@@ -127,6 +127,19 @@
class=".bug.AddBug"
menu="add_bugtracker" title="Bug"/>
+ <!-- Add Dependent Bug -->
+ <addform
+ label="Add Dependent Bug"
+ name="AddBug"
+ for="zopeproducts.bugtracker.interfaces.IBug"
+ schema="zopeproducts.bugtracker.interfaces.IBug"
+ content_factory="zopeproducts.bugtracker.bug.Bug"
+ permission="bugtracker.AddBug"
+ fields="title description type owners status priority release"
+ template="bug_add.pt"
+ class=".bug.AddDependentBug"
+ menu="add_bugtracker" title="Bug"/>
+
<editform
schema="zopeproducts.bugtracker.interfaces.IBug"
for="zopeproducts.bugtracker.interfaces.IBug"
@@ -152,7 +165,7 @@
permission="bugtracker.ViewBug">
<page name="dependencies.html" template="dependencies.pt"
menu="zmi_views" title="Dependencies" />
- <page name="setDependencies.html" attribute="setDependencies" />
+ <page name="setDependencies.html" attribute="setDependencyValues" />
</pages>
<pages
=== zopeproducts/bugtracker/browser/dependencies.pt 1.3 => 1.4 ===
--- zopeproducts/bugtracker/browser/dependencies.pt:1.3 Tue Aug 12 14:55:11 2003
+++ zopeproducts/bugtracker/browser/dependencies.pt Thu Aug 28 01:22:31 2003
@@ -9,49 +9,99 @@
</head>
<body i18n:domain="bugtracker">
-<div metal:fill-slot="body">
+<div metal:fill-slot="body"
+ tal:define="dep_type python:view.request.get('dep_type', 'dependencies')">
- <form action="setDependencies.html" method="post"
- tal:condition="view/canChangeDependencies">
-
- <div id="explanation" i18n:translate="">
- In the selection box below you can select the bugs that have to be
- completed <em>before</em> this bug can be completed.
- </div>
+ <div class="box"
+ tal:condition="view/canChangeDependencies">
+ <h4 style="padding: 0.3em;">Set Dependencies/Dependents</h4>
+ <div class="body"><div class="even">
+ <div id="explanation"
+ tal:condition="view/getShowDepsOptions">
+ Depending on which view you selected, you look at the dependencies
+ differently, once you look at the parents and once at the children of a
+ bug in the dependency tree:
+ <ul>
+ <li i18n:translate="">Dependencies - Bugs that have to be completed
+ before this bug can be closed.</li>
+ <li i18n:translate="">Dependents - This bug has to be completed in
+ before the Dependents can be closed.</li>
+ </ul>
+ </div>
+
+ <form action="setDependencies.html" method="post">
+
+ <div
+ tal:condition="view/getShowDepsOptions">
- <div>
- <div class="row">
- <div class="label" i18n:translate="">Dependencies</div>
- <div class="field">
- <select name="dependencies:list" size="5" multiple="">
- <div tal:repeat="bug view/availableBugs" tal:omit-tag="">
- <b tal:content="bug/name" />
- <b tal:content="bug/title" />
- <option
- value="" selected=""
- tal:content="string: ${bug/title} (${bug/name})"
- tal:attributes="value bug/name"
- tal:condition="python: bug['name'] in view.dependencies()">
- Bug1
- </option>
- <option
- tal:content="string: ${bug/title} (${bug/name})"
- tal:attributes="value bug/name"
- tal:condition="
- python: bug['name'] not in view.dependencies()">
- Bug1
- </option>
+ <div class="row">
+ <div class="field">
+ <table width="100%"><tr><td width="48%">
+ <b i18n:translate="">Available Bugs</b><br/>
+ <select name="add_deps:list" size="5" multiple=""
+ style="width: 100%">
+ <div tal:repeat="bug view/availableBugs" tal:omit-tag="">
+ <option
+ value=""
+ tal:content="string: ${bug/title} (${bug/name})"
+ tal:attributes="value bug/name"
+ tal:condition="
+ python: bug['name'] not in view.dependencyValues()">
+ Bug1
+ </option>
+ </div>
+ </select>
+ </td><td width="4%">
+ <input type="submit" name="ADD" value="-->" /><br/>
+ <input type="submit" name="DELETE" value="<--" />
+ </td><td width="48%">
+ <div tal:condition="python:dep_type == 'dependencies'">
+ <b i18n:translate="">Dependencies</b>
+ [<a href="@@setDependencies.html?dep_type=dependents"
+ i18n:translate="">Dependents</a>]
+ </div>
+ <div tal:condition="python:dep_type == 'dependents'">
+ <b i18n:translate="">Dependents</b>
+ [<a href="@@setDependencies.html?dep_type=dependencies"
+ i18n:translate="">Dependencies</a>]
+ </div>
+ <input type="hidden" name="dep_type" value=""
+ tal:attributes="value dep_type">
+
+ <br/>
+ <select name="del_deps:list" size="5" multiple=""
+ style="width: 100%">
+ <div tal:repeat="bug view/availableBugs" tal:omit-tag="">
+ <option
+ tal:content="string: ${bug/title} (${bug/name})"
+ tal:attributes="value bug/name"
+ tal:condition="
+ python: bug['name'] in view.dependencyValues()">
+ Bug1
+ </option>
+ </div>
+ </select>
+ </td></tr></table>
</div>
- </select>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="field">
+ <input type="submit" name="COLLAPSE" value="Collapse"
+ tal:condition="view/getShowDepsOptions"
+ i18n:attributes="value collapse-button" />
+
+ <input type="submit" name="EXPAND" value="Expand"
+ tal:condition="not: view/getShowDepsOptions"
+ i18n:attributes="value expand-button" />
+ </div>
</div>
- </div>
- </div>
- <div class="row">
- <input type="submit" name="submit" value="Change"
- i18n:attributes="value change-button" />
- </div>
- </form>
+ </form>
+ <div style="clear: both;"/>
+ </div></div>
+ </div>
<h4 i18n:translate="">Dependency Statistics</h4>
=== zopeproducts/bugtracker/browser/tracker.py 1.11 => 1.12 ===
--- zopeproducts/bugtracker/browser/tracker.py:1.11 Tue Aug 12 18:50:57 2003
+++ zopeproducts/bugtracker/browser/tracker.py Thu Aug 28 01:22:31 2003
@@ -19,6 +19,7 @@
from zope.app.browser.container.adding import Adding
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.interfaces.index.text import ISearchableText
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.services.servicenames import Authentication
from zope.app.traversing import getName
from zope.component import getAdapter, getService
@@ -137,8 +138,12 @@
def checkBug(bug, criteria, search_text):
for name, values in criteria:
- if values and not getattr(bug, name) in values:
- return False
+ if name is 'owners':
+ if values and not filter(lambda u: u in bug.owners, values):
+ return False
+ else:
+ if values and not getattr(bug, name) in values:
+ return False
# XXX: Extremely crude text search; should use indexes
text = ' '.join(getAdapter(bug, ISearchableText).getSearchableText())
@@ -173,10 +178,18 @@
auth = getService(self.context, Authentication)
return auth.getPrincipal(self.context.submitter)
+ def owners(self):
+ return ', '.join(self.context.owners)
+
+ def shortCreated(self):
+ return self.created().split()[0]
class Overview(object):
"""Overview of all the bugs."""
+ bug_listing_normal = ViewPageTemplateFile('bug_listing_normal.pt')
+ bug_listing_compressed = ViewPageTemplateFile('bug_listing_compressed.pt')
+
# Tuple values:
# - collection name
# - Vocabulary Registry name
@@ -186,12 +199,15 @@
('types', 'BugTypes', 'Type', 'type'),
('releases', 'Releases', 'Release', 'release'),
('priorities', 'Priorities', 'Priority', 'priority'),
+ ('owners', 'Users', 'Owners', 'owners'),
)
def getBugs(self):
"""Return a list of all bugs having a status listed in the parameter.
If the parameter is an empty list/tuple, then show all bugs."""
+ if hasattr(self, '_bugs'):
+ return self._bugs
criteria = []
for collName, dummy1, dummy2, name in self.filter_vars:
@@ -208,7 +224,8 @@
start = int(self.request.get('start', 0))
size = int(self.request.get('size', 20))
- return Batch(result, start, size)
+ self._bugs = Batch(result, start, size)
+ return self._bugs
def updateSettings(self):
for collName, dummy1, dummy2, dummy3 in self.filter_vars:
@@ -216,6 +233,8 @@
self.request.response.setCookie('filter_'+collName,
', '.join(values))
self.setSearchText()
+ self.setViewType()
+ self.setShowFilterOptions()
return self.request.response.redirect('./overview.html')
def getSettingsInfo(self):
@@ -235,6 +254,23 @@
def setSearchText(self):
value = self.request.get('search_text', '')
self.request.response.setCookie('search_text', value)
+
+ def getViewType(self):
+ return self.request.cookies.get('view_type', 'normal')
+
+ def setViewType(self):
+ value = self.request.get('view_type', 'normal')
+ self.request.response.setCookie('view_type', value)
+
+ def getShowFilterOptions(self):
+ return int(self.request.cookies.get('show_filter_options', '1'))
+
+ def setShowFilterOptions(self):
+ if 'COLLAPSE' in self.request:
+ value = '0'
+ else:
+ value = '1'
+ self.request.response.setCookie('show_filter_options', value)
def numberOfBugs(self):
return len(self.context)
=== zopeproducts/bugtracker/browser/tracker_overview.pt 1.7 => 1.8 ===
--- zopeproducts/bugtracker/browser/tracker_overview.pt:1.7 Tue Aug 12 18:50:57 2003
+++ zopeproducts/bugtracker/browser/tracker_overview.pt Thu Aug 28 01:22:31 2003
@@ -11,43 +11,80 @@
<body>
<div metal:fill-slot="body" tal:define="bugs view/getBugs">
- <form action="updateOverviewSettings.html" method="post"
- tal:define="settings view/getSettingsInfo">
-
- <div class="row">
- <div class="field">
- Filter Text:
- <input type="text" name="search_text" value=""
- tal:attributes="value view/getSearchText">
- </div>
- </div>
-
- <div class="row">
- <div class="field" tal:repeat="var settings">
-
- <tal:block replace="var/title">Status</tal:block>:<br>
- <select size="5" name="stati:list" multiple="yes"
- tal:attributes="name string:${var/name}:list">
- <tal:block repeat="entry var/all">
- <option value=""
- tal:condition="python: entry.value in var['setting']"
- tal:attributes="value entry/value"
- tal:content="entry/title" selected="">New</option>
- <option value=""
- tal:condition="python: entry.value not in var['setting']"
- tal:attributes="value entry/value"
- tal:content="entry/title">New</option>
- </tal:block>
- </select>
-
- </div>
- <div class="field">
- <input type="submit" value="Apply Filter"
- i18n:attributes="value save_filter-button" />
- </div>
+ <div class="box">
+ <h4 style="padding: 0.3em">Filter Options</h4>
+ <div class="body">
+ <form action="updateOverviewSettings.html" method="post"
+ class="even" style="padding: 0.5em;"
+ tal:define="settings view/getSettingsInfo">
+
+ <div class="row"
+ tal:condition="view/getShowFilterOptions">
+ <div class="field">
+ <b>Filter Text</b>
+ <input type="text" name="search_text" value=""
+ tal:attributes="value view/getSearchText">
+ </div>
+ <div class="field"> </div>
+ <div class="field">
+ <b>View Type</b>
+ <select name="view_type">
+ <tal:block repeat="vt python: ('normal', 'compressed')">
+ <option selected=""
+ tal:content="vt"
+ tal:attributes="value vt"
+ tal:condition="python: view.getViewType() == vt" />
+ <option
+ tal:content="vt"
+ tal:attributes="value vt"
+ tal:condition="python: view.getViewType() != vt" />
+ </tal:block>
+ </select>
+ </div>
+ </div>
+
+ <div class="row"
+ tal:condition="view/getShowFilterOptions">
+ <div class="field" tal:repeat="var settings">
+
+ <b tal:content="var/title">Status</b><br/>
+ <select size="5" name="stati:list" multiple="yes"
+ tal:attributes="name string:${var/name}:list">
+ <tal:block repeat="entry var/all">
+ <option value=""
+ tal:condition="python: entry.value in var['setting']"
+ tal:attributes="value entry/value"
+ tal:content="entry/title" selected="">New</option>
+ <option value=""
+ tal:condition="python: entry.value not in var['setting']"
+ tal:attributes="value entry/value"
+ tal:content="entry/title">New</option>
+ </tal:block>
+ </select>
+
+ </div>
+ </div>
+ <div class="row">
+ <div class="field">
+ <input type="submit" value="Apply Filter/Changes"
+ tal:condition="view/getShowFilterOptions"
+ i18n:attributes="value save-filter-changes-button" />
+ </div>
+ <div class="field">
+ <input type="submit" name="COLLAPSE" value="Collapse"
+ tal:condition="view/getShowFilterOptions"
+ i18n:attributes="value collapse-button" />
+
+ <input type="submit" name="EXPAND" value="Expand"
+ tal:condition="not: view/getShowFilterOptions"
+ i18n:attributes="value expand-button" />
+ </div>
+ </div>
+ <div class="clear"/>
+
+ </form>
</div>
-
- </form>
+ </div>
<div class="row" i18n:domain="bugtracker">
<div class="control">
@@ -89,49 +126,13 @@
<div class="clear"></div>
</div>
- <tal:block repeat="bug bugs" i18n:domain="bugtracker">
- <div class=""
- tal:define="oddrow repeat/bug/odd"
- tal:attributes="class python:oddrow and 'even' or 'odd'">
- <h5 class="summary_title" >
- <a href=""
- tal:attributes="href string:./${bug/name}/@@overview.html"
- i18n:translate="">
- Bug #<d tal:replace="bug/name" i18n:name="bug_id">1</d> -
- <d tal:replace="bug/context/title" i18n:name="bug_title">
- Bug Title
- </d>
- </a>
- </h5>
-
- <div class="summary_content">
- <div class="summary_condition">
- <span i18n:translate="">Status:</span>
- <span tal:attributes="class bug/context/status"
- tal:content="bug/status/title">New</span> -
- <span i18n:translate="">Priority:</span>
- <span tal:attributes="class bug/context/priority"
- tal:content="bug/priority/title">Normal</span> -
- <span i18n:translate="">Type: </span>
- <b tal:replace="bug/type/title">Bug</b>
- </div>
-
- <div class="summary_body" tal:content="bug/descriptionPreview">
- Message Description Sneak Preview goes here...
- </div>
-
- <div class="summary_metadata" i18n:translate="">
- Posted by <b tal:content="bug/submitter/getTitle"
- i18n:name="submitter">Submitter</b>
- on <b tal:replace="bug/created"
- i18n:name="created_date">2003/01/01</b>
- - <b tal:replace="bug/numberOfComments"
- i18n:name="num_comments">3</b> comments
- </div>
- </div>
- </div>
-
- </tal:block>
+ <div
+ tal:condition="python: view.getViewType() == 'normal'"
+ tal:replace="structure view/bug_listing_normal" />
+
+ <div
+ tal:condition="python: view.getViewType() == 'compressed'"
+ tal:replace="structure view/bug_listing_compressed" />
<div class="batch" tal:condition="bugs/startNumber" i18n:domain="bugtracker">
<div class="prev_batch" tal:define="prev bugs/prevBatch">
More information about the Zope3-Checkins
mailing list