blob: 4ab53511463290ef7cab257290983ebef110fb4e [file] [log] [blame]
<!--!
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--!
groups - a dict, where:
key - is the value shared by all results in this group
value - is the list of corresponding tickets
headers - a sequence of header structure:
.name - field name for this header
.label - what to display for this header
fields - dict of field name to field structure:
.label - field label
query - the actual Query instance used to perform the query
-->
<div xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:i18n="http://genshi.edgewall.org/i18n"
xmlns:xi="http://www.w3.org/2001/XInclude">
<div py:if="paginator.has_more_pages">
<div class="report-result" style="float: left; margin-right: 1.6em;">
Results <span class="numresults">(${paginator.displayed_items()})</span>
</div>
<xi:include py:if="paginator.show_index" href="page_index.html" />
</div>
<py:def function="group_heading(groupname, results, is_first=False)">
<div class="report-result" py:if="groupname is not None"
style="${'border: 1px #DDDDDD solid; border-bottom: none; font-weight: bold; padding: 4px 5px;' if is_first else None}"
i18n:msg="grouplabel, groupname, count"
py:with="grouplabel = fields[query.group].label;
groupname = authorinfo(groupname) if query.group in ['owner', 'reporter'] else (groupname or _('None'));
count = ngettext('%(num)s match', '%(num)s matches', len(results))">
${grouplabel}: ${groupname} <span class="numrows">(${count})</span>
</div>
</py:def>
<py:def function="column_headers()">
<tr class="trac-columns">
<th py:for="header in headers"
class="$header.name${(' desc' if query.desc else ' asc') if query.order == header.name else ''}" py:with="">
<?python asc = _('(ascending)'); desc = _('(descending)') ?>
<a title="${_('Sort by %(col)s %(direction)s', col=header.label,
direction=(desc if query.order == header.name and not query.desc else asc))}"
href="$header.href">
${header.label}
<i py:if="query.order == header.name"
class="${'icon-chevron-down' if query.desc else 'icon-chevron-up'}"></i>
</a>
</th>
</tr>
</py:def>
<!--! TODO: Find an elegant solution for styling -->
<style>
.table-bordered.query thead:first-child tr:first-child th:first-child,
.table-bordered.query tbody:first-child tr:first-child td:first-child {
border-top-left-radius: 0px;
}
</style>
${group_heading(*groups[0], is_first=True) if groups else None}
<table class="listing tickets table table-bordered table-condensed query"
style="border-radius: 0px 0px 4px 4px">
<thead py:strip="group_index">
${column_headers()}
</thead>
<py:for each="group_index, (groupname, results) in enumerate(groups)">
<tbody py:if="group_index">
<tr py:if="groupname is not None" class="trac-group">
<th colspan="${len(headers)}">
${group_heading(groupname, results)}
</th>
</tr>
${column_headers()}
</tbody>
<tbody>
<tr py:if="not results" class="even">
<td colspan="${len(headers)}">
No tickets found
</td>
</tr>
<py:for each="idx, result in enumerate(results)">
<py:with vars="ticket_context = context.child('ticket', result.id)">
<py:if test="'TICKET_VIEW' in perm(ticket_context.resource)">
<tr class="${'odd' if idx % 2 else 'even'} prio${result.priority_value}${
' added' if 'added' in result else ''}${
' changed' if 'changed' in result else ''}${
' removed' if 'removed' in result else ''}">
<py:for each="idx, header in enumerate(headers)" py:choose="">
<py:with vars="name = header.name; value = result[name]">
<td py:when="name == 'id'" class="id"><a href="$result.href" title="View ticket"
class="${classes(closed=result.status == 'closed')}">#$result.id</a></td>
<td py:otherwise="" class="$name" py:choose="">
<a py:when="name == 'summary'" href="$result.href" title="View ticket">$value</a>
<py:when test="isinstance(value, datetime)">${pretty_dateinfo(value, dateonly=True)}</py:when>
<py:when test="name == 'reporter'">${authorinfo(value)}</py:when>
<py:when test="name == 'cc'">${format_emails(ticket_context, value)}</py:when>
<py:when test="name == 'owner' and value">${authorinfo(value)}</py:when>
<py:when test="name == 'milestone'"><a py:if="value" title="View milestone" href="${href.milestone(value)}">${value}</a></py:when>
<py:when test="header.wikify">${wiki_to_oneliner(ticket_context, value)}</py:when>
<py:otherwise>$value</py:otherwise>
</td>
</py:with>
</py:for>
</tr>
<py:with vars="result_rows = [t for t in row if result[t]]">
<py:choose>
<tr py:when="ticket_context.resource in context" class="fullrow">
<td colspan="${len(headers)}">
<p class="meta"><em>(this ticket)</em></p>
</td>
</tr>
<tr py:otherwise="" py:for="r in result_rows" class="fullrow">
<th class="meta">${fields.get(r, {'label': r or 'none'}).label}</th>
<td colspan="${len(headers)-1}" xml:space="preserve">
${wiki_to_html(ticket_context, result[r])}
</td>
</tr>
</py:choose>
</py:with>
</py:if>
</py:with>
</py:for>
<tr py:if="group_index == len(groups)-1 and last_group_is_partial">
<td colspan="${len(headers)}">
<i>(more results for this group on next page)</i>
</td>
</tr>
</tbody>
</py:for>
</table>
<xi:include py:if="paginator.show_index" href="page_index.html" />
</div>