summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Lawrence <dkl@redhat.com>2010-08-31 06:20:07 +0200
committerDave Lawrence <dkl@redhat.com>2010-08-31 06:20:07 +0200
commit77b3addad28c0f3ffc1fb4db1fcdc00527aeb48d (patch)
treea813d550674b01ce0c6d3d63e9f4f0b619841b31
parentc75bcea5f0510417a1f6a14b2f88f2249b3a4109 (diff)
downloadbugzilla-77b3addad28c0f3ffc1fb4db1fcdc00527aeb48d.tar.gz
bugzilla-77b3addad28c0f3ffc1fb4db1fcdc00527aeb48d.tar.xz
Bug 77193 - Add the ability to retire (disable) old versions, components and milestones
r/a=mkanat
-rw-r--r--Bugzilla/Component.pm6
-rw-r--r--Bugzilla/DB/Schema.pm6
-rw-r--r--Bugzilla/Install/DB.pm23
-rw-r--r--Bugzilla/Milestone.pm15
-rw-r--r--Bugzilla/Version.pm11
-rwxr-xr-xbuglist.cgi8
-rwxr-xr-xeditcomponents.cgi5
-rwxr-xr-xeditmilestones.cgi10
-rwxr-xr-xeditversions.cgi2
-rwxr-xr-xenter_bug.cgi4
-rw-r--r--template/en/default/admin/components/confirm-delete.html.tmpl2
-rw-r--r--template/en/default/admin/components/edit.html.tmpl5
-rw-r--r--template/en/default/admin/components/list.html.tmpl5
-rw-r--r--template/en/default/admin/milestones/edit.html.tmpl6
-rw-r--r--template/en/default/admin/milestones/list.html.tmpl5
-rw-r--r--template/en/default/admin/versions/edit.html.tmpl6
-rw-r--r--template/en/default/admin/versions/list.html.tmpl5
-rw-r--r--template/en/default/bug/create/create.html.tmpl13
-rw-r--r--template/en/default/bug/edit.html.tmpl1
-rw-r--r--template/en/default/bug/field.html.tmpl1
-rw-r--r--template/en/default/global/messages.html.tmpl19
21 files changed, 128 insertions, 30 deletions
diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm
index e5eb78a2d..2a176f5dc 100644
--- a/Bugzilla/Component.pm
+++ b/Bugzilla/Component.pm
@@ -45,6 +45,7 @@ use constant DB_COLUMNS => qw(
initialowner
initialqacontact
description
+ isactive
);
use constant UPDATE_COLUMNS => qw(
@@ -52,6 +53,7 @@ use constant UPDATE_COLUMNS => qw(
initialowner
initialqacontact
description
+ isactive
);
use constant REQUIRED_FIELD_MAP => {
@@ -66,6 +68,7 @@ use constant VALIDATORS => {
description => \&_check_description,
initial_cc => \&_check_cc_list,
name => \&_check_name,
+ isactive => \&Bugzilla::Object::check_boolean,
};
use constant VALIDATOR_DEPENDENCIES => {
@@ -300,6 +303,7 @@ sub _create_series {
sub set_name { $_[0]->set('name', $_[1]); }
sub set_description { $_[0]->set('description', $_[1]); }
+sub set_is_active { $_[0]->set('isactive', $_[1]); }
sub set_default_assignee {
my ($self, $owner) = @_;
@@ -416,6 +420,7 @@ sub product {
sub description { return $_[0]->{'description'}; }
sub product_id { return $_[0]->{'product_id'}; }
+sub is_active { return $_[0]->{'isactive'}; }
##############################################
# Implement Bugzilla::Field::ChoiceInterface #
@@ -423,7 +428,6 @@ sub product_id { return $_[0]->{'product_id'}; }
use constant FIELD_NAME => 'component';
use constant is_default => 0;
-use constant is_active => 1;
sub is_set_on_bug {
my ($self, $bug) = @_;
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index 2efdbefc4..356480e3b 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -718,6 +718,8 @@ use constant ABSTRACT_SCHEMA => {
REFERENCES => {TABLE => 'products',
COLUMN => 'id',
DELETE => 'CASCADE'}},
+ isactive => {TYPE => 'BOOLEAN', NOTNULL => 1,
+ DEFAULT => 'TRUE'},
],
INDEXES => [
versions_product_id_idx => {FIELDS => [qw(product_id value)],
@@ -736,6 +738,8 @@ use constant ABSTRACT_SCHEMA => {
value => {TYPE => 'varchar(20)', NOTNULL => 1},
sortkey => {TYPE => 'INT2', NOTNULL => 1,
DEFAULT => 0},
+ isactive => {TYPE => 'BOOLEAN', NOTNULL => 1,
+ DEFAULT => 'TRUE'},
],
INDEXES => [
milestones_product_id_idx => {FIELDS => [qw(product_id value)],
@@ -1264,6 +1268,8 @@ use constant ABSTRACT_SCHEMA => {
COLUMN => 'userid',
DELETE => 'SET NULL'}},
description => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
+ isactive => {TYPE => 'BOOLEAN', NOTNULL => 1,
+ DEFAULT => 'TRUE'},
],
INDEXES => [
components_product_id_idx => {FIELDS => [qw(product_id name)],
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index 21739fab9..df4ea737e 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -631,6 +631,9 @@ sub update_table_definitions {
# 2010-07-18 LpSolit@gmail.com - Bug 119703
_remove_attachment_isurl();
+ # 2009-05-07 ghendricks@novell.com - Bug 77193
+ _add_isactive_to_product_fields();
+
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
@@ -3397,6 +3400,26 @@ sub _remove_attachment_isurl {
}
}
+sub _add_isactive_to_product_fields {
+ my $dbh = Bugzilla->dbh;
+
+ # If we add the isactive column all values should start off as active
+ if (!$dbh->bz_column_info('components', 'isactive')) {
+ $dbh->bz_add_column('components', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+
+ if (!$dbh->bz_column_info('versions', 'isactive')) {
+ $dbh->bz_add_column('versions', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+
+ if (!$dbh->bz_column_info('milestones', 'isactive')) {
+ $dbh->bz_add_column('milestones', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+}
+
sub _migrate_field_visibility_value {
my $dbh = Bugzilla->dbh;
diff --git a/Bugzilla/Milestone.pm b/Bugzilla/Milestone.pm
index cb7d53da3..92bc2192a 100644
--- a/Bugzilla/Milestone.pm
+++ b/Bugzilla/Milestone.pm
@@ -43,6 +43,7 @@ use constant DB_COLUMNS => qw(
value
product_id
sortkey
+ isactive
);
use constant REQUIRED_FIELD_MAP => {
@@ -52,12 +53,14 @@ use constant REQUIRED_FIELD_MAP => {
use constant UPDATE_COLUMNS => qw(
value
sortkey
+ isactive
);
use constant VALIDATORS => {
- product => \&_check_product,
- sortkey => \&_check_sortkey,
- value => \&_check_value,
+ product => \&_check_product,
+ sortkey => \&_check_sortkey,
+ value => \&_check_value,
+ isactive => \&Bugzilla::Object::check_boolean,
};
use constant VALIDATOR_DEPENDENCIES => {
@@ -203,8 +206,9 @@ sub _check_product {
# Methods
################################
-sub set_name { $_[0]->set('value', $_[1]); }
-sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
+sub set_name { $_[0]->set('value', $_[1]); }
+sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
+sub set_is_active { $_[0]->set('isactive', $_[1]); }
sub bug_count {
my $self = shift;
@@ -226,6 +230,7 @@ sub bug_count {
sub name { return $_[0]->{'value'}; }
sub product_id { return $_[0]->{'product_id'}; }
sub sortkey { return $_[0]->{'sortkey'}; }
+sub is_active { return $_[0]->{'isactive'}; }
sub product {
my $self = shift;
diff --git a/Bugzilla/Version.pm b/Bugzilla/Version.pm
index 4270b1e5f..7f53add13 100644
--- a/Bugzilla/Version.pm
+++ b/Bugzilla/Version.pm
@@ -44,6 +44,7 @@ use constant DB_COLUMNS => qw(
id
value
product_id
+ isactive
);
use constant REQUIRED_FIELD_MAP => {
@@ -52,11 +53,13 @@ use constant REQUIRED_FIELD_MAP => {
use constant UPDATE_COLUMNS => qw(
value
+ isactive
);
use constant VALIDATORS => {
- product => \&_check_product,
- value => \&_check_value,
+ product => \&_check_product,
+ value => \&_check_value,
+ isactive => \&Bugzilla::Object::check_boolean,
};
use constant VALIDATOR_DEPENDENCIES => {
@@ -153,6 +156,7 @@ sub remove_from_db {
###############################
sub product_id { return $_[0]->{'product_id'}; }
+sub is_active { return $_[0]->{'isactive'}; }
sub product {
my $self = shift;
@@ -166,7 +170,8 @@ sub product {
# Validators
################################
-sub set_name { $_[0]->set('value', $_[1]); }
+sub set_name { $_[0]->set('value', $_[1]); }
+sub set_is_active { $_[0]->set('isactive', $_[1]); }
sub _check_value {
my ($invocant, $name, undef, $params) = @_;
diff --git a/buglist.cgi b/buglist.cgi
index d43e06535..38681ff93 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -1171,11 +1171,11 @@ if ($dotweak && scalar @bugs) {
# versions for the product (if there is only one product on the list of
# products), and a list of components for the product.
if ($one_product) {
- $vars->{'versions'} = [map($_->name ,@{ $one_product->versions })];
- $vars->{'components'} = [map($_->name, @{ $one_product->components })];
+ $vars->{'versions'} = [map($_->name, grep($_->is_active, @{ $one_product->versions }))];
+ $vars->{'components'} = [map($_->name, grep($_->is_active, @{ $one_product->components }))];
if (Bugzilla->params->{'usetargetmilestone'}) {
- $vars->{'targetmilestones'} = [map($_->name,
- @{ $one_product->milestones })];
+ $vars->{'targetmilestones'} = [map($_->name, grep($_->is_active,
+ @{ $one_product->milestones }))];
}
}
}
diff --git a/editcomponents.cgi b/editcomponents.cgi
index fd30daed4..7da22211b 100755
--- a/editcomponents.cgi
+++ b/editcomponents.cgi
@@ -128,6 +128,7 @@ if ($action eq 'new') {
my $default_qa_contact = trim($cgi->param('initialqacontact') || '');
my $description = trim($cgi->param('description') || '');
my @initial_cc = $cgi->param('initialcc');
+ my $isactive = $cgi->param('isactive');
my $component = Bugzilla::Component->create({
name => $comp_name,
@@ -230,7 +231,8 @@ if ($action eq 'update') {
my $default_qa_contact = trim($cgi->param('initialqacontact') || '');
my $description = trim($cgi->param('description') || '');
my @initial_cc = $cgi->param('initialcc');
-
+ my $isactive = $cgi->param('isactive');
+
my $component =
Bugzilla::Component->check({ product => $product, name => $comp_old_name });
@@ -239,6 +241,7 @@ if ($action eq 'update') {
$component->set_default_assignee($default_assignee);
$component->set_default_qa_contact($default_qa_contact);
$component->set_cc_list(\@initial_cc);
+ $component->set_is_active($isactive);
my $changes = $component->update();
$vars->{'message'} = 'component_updated';
diff --git a/editmilestones.cgi b/editmilestones.cgi
index ff5076bee..ca1c4368e 100755
--- a/editmilestones.cgi
+++ b/editmilestones.cgi
@@ -60,6 +60,7 @@ my $sortkey = trim($cgi->param('sortkey') || 0);
my $action = trim($cgi->param('action') || '');
my $showbugcounts = (defined $cgi->param('showbugcounts'));
my $token = $cgi->param('token');
+my $isactive = $cgi->param('isactive');
#
# product = '' -> Show nice list of products
@@ -115,9 +116,11 @@ if ($action eq 'add') {
if ($action eq 'new') {
check_token_data($token, 'add_milestone');
- my $milestone = Bugzilla::Milestone->create({ value => $milestone_name,
- product => $product,
- sortkey => $sortkey });
+
+ my $milestone = Bugzilla::Milestone->create({ value => $milestone_name,
+ product => $product,
+ sortkey => $sortkey });
+
delete_token($token);
$vars->{'message'} = 'milestone_created';
@@ -205,6 +208,7 @@ if ($action eq 'update') {
$milestone->set_name($milestone_name);
$milestone->set_sortkey($sortkey);
+ $milestone->set_is_active($isactive);
my $changes = $milestone->update();
# Reloading the product since the default milestone name
# could have been changed.
diff --git a/editversions.cgi b/editversions.cgi
index 0888ef0c6..165a174b5 100755
--- a/editversions.cgi
+++ b/editversions.cgi
@@ -63,6 +63,7 @@ my $version_name = trim($cgi->param('version') || '');
my $action = trim($cgi->param('action') || '');
my $showbugcounts = (defined $cgi->param('showbugcounts'));
my $token = $cgi->param('token');
+my $isactive = $cgi->param('isactive');
#
# product = '' -> Show nice list of products
@@ -204,6 +205,7 @@ if ($action eq 'update') {
$dbh->bz_start_transaction();
$version->set_name($version_name);
+ $version->set_is_active($isactive);
my $changes = $version->update();
$dbh->bz_commit_transaction();
diff --git a/enter_bug.cgi b/enter_bug.cgi
index b1889cd03..9b5eb52c0 100755
--- a/enter_bug.cgi
+++ b/enter_bug.cgi
@@ -502,7 +502,7 @@ else {
#
# Eventually maybe each product should have a "current version"
# parameter.
-$vars->{'version'} = [map($_->name, @{$product->versions})];
+$vars->{'version'} = $product->versions;
my $version_cookie = $cgi->cookie("VERSION-" . $product->name);
@@ -521,7 +521,7 @@ if ( ($cloned_bug_id) &&
# Get list of milestones.
if ( Bugzilla->params->{'usetargetmilestone'} ) {
- $vars->{'target_milestone'} = [map($_->name, @{$product->milestones})];
+ $vars->{'target_milestone'} = $product->milestones;
if (formvalue('target_milestone')) {
$default{'target_milestone'} = formvalue('target_milestone');
} else {
diff --git a/template/en/default/admin/components/confirm-delete.html.tmpl b/template/en/default/admin/components/confirm-delete.html.tmpl
index e2caa5208..da934f420 100644
--- a/template/en/default/admin/components/confirm-delete.html.tmpl
+++ b/template/en/default/admin/components/confirm-delete.html.tmpl
@@ -83,7 +83,7 @@ from '[% product.name FILTER html %]' product
</tr>
<tr>
<TD VALIGN="top">Open for [% terms.bugs %]:</TD>
- <TD VALIGN="top">[% IF product.is_active %]Yes[% ELSE %]No[% END %]</td>
+ <TD VALIGN="top">[% IF product.is_active && comp.isactive %]Yes[% ELSE %]No[% END %]</td>
</tr>
<tr>
<td valign="top">[% terms.Bugs %]:</td>
diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl
index e34e18d0c..b5fc3c321 100644
--- a/template/en/default/admin/components/edit.html.tmpl
+++ b/template/en/default/admin/components/edit.html.tmpl
@@ -43,6 +43,11 @@
[% PROCESS "admin/components/edit-common.html.tmpl" %]
<tr>
+ <td><label for="isactive">Enabled For [% terms.Bugs %]:</label></td>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF comp.isactive %]></td>
+ </tr>
+ <tr>
<td>[% terms.Bugs %]:</td>
<td>
[% IF comp.bug_count > 0 %]
diff --git a/template/en/default/admin/components/list.html.tmpl b/template/en/default/admin/components/list.html.tmpl
index b62ce1bae..b45b97565 100644
--- a/template/en/default/admin/components/list.html.tmpl
+++ b/template/en/default/admin/components/list.html.tmpl
@@ -56,6 +56,11 @@
name => "initialowner"
heading => "Default Assignee"
},
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
+ },
]
%]
diff --git a/template/en/default/admin/milestones/edit.html.tmpl b/template/en/default/admin/milestones/edit.html.tmpl
index dfe9d1bd8..6a2be869e 100644
--- a/template/en/default/admin/milestones/edit.html.tmpl
+++ b/template/en/default/admin/milestones/edit.html.tmpl
@@ -47,7 +47,11 @@
<td><input id="sortkey" size="20" maxlength="20" name="sortkey" value="
[%- milestone.sortkey FILTER html %]"></td>
</tr>
-
+ <tr>
+ <th><label for="isactive">Enabled For [% terms.Bugs %]:</label></th>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF milestone.isactive %]></td>
+ </tr>
</table>
<input type="hidden" name="milestoneold" value="[% milestone.name FILTER html %]">
diff --git a/template/en/default/admin/milestones/list.html.tmpl b/template/en/default/admin/milestones/list.html.tmpl
index 56f621e1e..6392f567f 100644
--- a/template/en/default/admin/milestones/list.html.tmpl
+++ b/template/en/default/admin/milestones/list.html.tmpl
@@ -53,6 +53,11 @@
{
name => "sortkey"
heading => "Sortkey"
+ },
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
}
]
%]
diff --git a/template/en/default/admin/versions/edit.html.tmpl b/template/en/default/admin/versions/edit.html.tmpl
index 2a7c78423..1de233567 100644
--- a/template/en/default/admin/versions/edit.html.tmpl
+++ b/template/en/default/admin/versions/edit.html.tmpl
@@ -41,7 +41,11 @@
<td><input id="version" size="64" maxlength="64" name="version" value="
[%- version.name FILTER html %]"></td>
</tr>
-
+ <tr>
+ <th><label for="isactive">Enabled For [% terms.Bugs %]:</label></th>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF version.isactive %]></td>
+ </tr>
</table>
<input type="hidden" name="versionold" value="[% version.name FILTER html %]">
diff --git a/template/en/default/admin/versions/list.html.tmpl b/template/en/default/admin/versions/list.html.tmpl
index ae21bbf5c..69435d220 100644
--- a/template/en/default/admin/versions/list.html.tmpl
+++ b/template/en/default/admin/versions/list.html.tmpl
@@ -45,6 +45,11 @@
name => "name"
heading => "Edit version..."
contentlink => edit_contentlink
+ },
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
}
]
%]
diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl
index 08eb44c4e..ebb222850 100644
--- a/template/en/default/bug/create/create.html.tmpl
+++ b/template/en/default/bug/create/create.html.tmpl
@@ -238,6 +238,7 @@ TUI_hide_default('attachment_text_field');
[% END %]
[%- FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
<option value="[% c.name FILTER html %]"
id="v[% c.id FILTER html %]_component"
[% IF c.name == default.component_ %]
@@ -288,8 +289,9 @@ TUI_hide_default('attachment_text_field');
<td rowspan="3">
<select name="version" id="version" size="5">
[%- FOREACH v = version %]
- <option value="[% v FILTER html %]"
- [% ' selected="selected"' IF v == default.version %]>[% v FILTER html -%]
+ [% NEXT IF NOT v.is_active %]
+ <option value="[% v.name FILTER html %]"
+ [% ' selected="selected"' IF v.name == default.version %]>[% v.name FILTER html -%]
</option>
[%- END %]
</select>
@@ -733,9 +735,10 @@ TUI_hide_default('attachment_text_field');
<select name="[% field.name FILTER html %]"
id="[% field.name FILTER html %]">
[%- FOREACH x = ${field.name} %]
- <option value="[% x FILTER html %]"
- [% " selected=\"selected\"" IF x == default.${field.name} %]>
- [% display_value(field.name, x) FILTER html %]
+ [% NEXT IF NOT x.is_active %]
+ <option value="[% x.name FILTER html %]"
+ [% " selected=\"selected\"" IF x.name == default.${field.name} %]>
+ [% display_value(field.name, x.name) FILTER html %]
</option>
[% END %]
</select>
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 0a558ecc1..4b5e7769e 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -1117,6 +1117,7 @@
AND bug.choices.${selname}.size > 1 %]
<select id="[% selname %]" name="[% selname %]">
[% FOREACH x = bug.choices.${selname} %]
+ [% NEXT IF NOT x.is_active AND x.name != bug.${selname} %]
<option value="[% x.name FILTER html %]"
[% " selected" IF x.name == bug.${selname} %]>
[%- x.name FILTER html %]
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
index 34347b21c..4065b3af0 100644
--- a/template/en/default/bug/field.html.tmpl
+++ b/template/en/default/bug/field.html.tmpl
@@ -124,6 +124,7 @@
[% legal_values = field.legal_values %]
[% END %]
[% FOREACH legal_value = legal_values %]
+ [% NEXT IF NOT legal_value.is_active AND NOT value.contains(legal_value.name).size %]
<option value="[% legal_value.name FILTER html %]"
id="v[% legal_value.id FILTER html %]_
[%- field.name FILTER html %]"
diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl
index 85c2ed513..8747c56bf 100644
--- a/template/en/default/global/messages.html.tmpl
+++ b/template/en/default/global/messages.html.tmpl
@@ -234,6 +234,9 @@
<li>Default CC list deleted</li>
[% END %]
[% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% comp.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
[% Hook.process('component_updated_fields') %]
</ul>
[% ELSE %]
@@ -547,6 +550,9 @@
[% IF changes.sortkey.defined %]
<li>Sortkey updated to <em>[% milestone.sortkey FILTER html %]</em>
[% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% milestone.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
</ul>
[% ELSE %]
No changes made to milestone <em>[% milestone.name FILTER html %]</em>.
@@ -831,9 +837,16 @@
[% ELSIF message_tag == "version_updated" %]
[% title = "Version Updated" %]
[% IF changes.size %]
- [% IF changes.value.defined %]
- Version renamed to <em>[% version.name FILTER html %]</em>.
- [% END %]
+ Changes to the version <em>[% version.name FILTER html %]</em>
+ have been saved:
+ <ul>
+ [% IF changes.value.defined %]
+ <li>Version renamed to <em>[% version.name FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% version.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
+ </ul>
[% ELSE %]
No changes made to version <em>[% version.name FILTER html %]</em>.
[% END %]