Commit ff222adc authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 385415: Bugs marked as duplicate or moved to another installation always go…

Bug 385415: Bugs marked as duplicate or moved to another installation always go to the RESOLVED state, even if the workflow has RESOLVED excluded from it (or if this bug status has been removed or renamed). Some major problems related to the workflow when upgrading or installing 3.1 are also fixed here - Patch by Fré©ric Buclin <LpSolit@gmail.com> r/a=mkanat
parent 012d45ae
...@@ -1986,10 +1986,10 @@ sub get_new_status_and_resolution { ...@@ -1986,10 +1986,10 @@ sub get_new_status_and_resolution {
# Leaving the status unchanged doesn't need more investigation. # Leaving the status unchanged doesn't need more investigation.
return ($self->bug_status, $self->resolution, $self->everconfirmed); return ($self->bug_status, $self->resolution, $self->everconfirmed);
} }
elsif ($action eq 'duplicate') { elsif ($action eq 'duplicate' || $action eq 'move') {
# Only alter the bug status if the bug is currently open. # Always change the bug status, even if the bug was already "closed".
$status = is_open_state($self->bug_status) ? 'RESOLVED' : $self->bug_status; $status = Bugzilla->params->{'duplicate_or_move_bug_status'};
$resolution = 'DUPLICATE'; $resolution = ($action eq 'duplicate') ? 'DUPLICATE' : 'MOVED';
} }
elsif ($action eq 'change_resolution') { elsif ($action eq 'change_resolution') {
$status = $self->bug_status; $status = $self->bug_status;
......
...@@ -34,13 +34,35 @@ package Bugzilla::Config::BugChange; ...@@ -34,13 +34,35 @@ package Bugzilla::Config::BugChange;
use strict; use strict;
use Bugzilla::Config::Common; use Bugzilla::Config::Common;
use Bugzilla::Status;
$Bugzilla::Config::BugChange::sortkey = "03"; $Bugzilla::Config::BugChange::sortkey = "03";
sub get_param_list { sub get_param_list {
my $class = shift; my $class = shift;
# Hardcoded bug statuses which existed before Bugzilla 3.1.
my @closed_bug_statuses = ('RESOLVED', 'VERIFIED', 'CLOSED');
# If we are upgrading from 3.0 or older, bug statuses are not customisable
# and bug_status.is_open is not yet defined (hence the eval), so we use
# the bug statuses above as they are still hardcoded.
eval {
my @current_closed_states = map {$_->name} Bugzilla::Status::closed_bug_statuses();
# If no closed state was found, use the default list above.
@closed_bug_statuses = @current_closed_states if scalar(@current_closed_states);
};
my @param_list = ( my @param_list = (
{ {
name => 'duplicate_or_move_bug_status',
type => 's',
choices => \@closed_bug_statuses,
default => $closed_bug_statuses[0],
checker => \&check_bug_status
},
{
name => 'letsubmitterchoosepriority', name => 'letsubmitterchoosepriority',
type => 'b', type => 'b',
default => 1 default => 1
......
...@@ -40,6 +40,7 @@ use Bugzilla::Util; ...@@ -40,6 +40,7 @@ use Bugzilla::Util;
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::Field; use Bugzilla::Field;
use Bugzilla::Group; use Bugzilla::Group;
use Bugzilla::Status;
use base qw(Exporter); use base qw(Exporter);
@Bugzilla::Config::Common::EXPORT = @Bugzilla::Config::Common::EXPORT =
...@@ -48,7 +49,7 @@ use base qw(Exporter); ...@@ -48,7 +49,7 @@ use base qw(Exporter);
check_opsys check_shadowdb check_urlbase check_webdotbase check_opsys check_shadowdb check_urlbase check_webdotbase
check_netmask check_user_verify_class check_image_converter check_netmask check_user_verify_class check_image_converter
check_languages check_mail_delivery_method check_notification check_languages check_mail_delivery_method check_notification
check_timezone check_utf8 check_timezone check_utf8 check_bug_status
); );
# Checking functions for the various values # Checking functions for the various values
...@@ -166,6 +167,15 @@ sub check_opsys { ...@@ -166,6 +167,15 @@ sub check_opsys {
return ""; return "";
} }
sub check_bug_status {
my $bug_status = shift;
my @closed_bug_statuses = map {$_->name} Bugzilla::Status::closed_bug_statuses();
if (lsearch(\@closed_bug_statuses, $bug_status) < 0) {
return "Must be a valid closed status: one of " . join(', ', @closed_bug_statuses);
}
return "";
}
sub check_group { sub check_group {
my $group_name = shift; my $group_name = shift;
return "" unless $group_name; return "" unless $group_name;
......
...@@ -2783,85 +2783,102 @@ sub _initialize_workflow { ...@@ -2783,85 +2783,102 @@ sub _initialize_workflow {
my $old_params = shift; my $old_params = shift;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
if (!$dbh->bz_column_info('bug_status', 'is_open')) { $dbh->bz_add_column('bug_status', 'is_open',
$dbh->bz_add_column('bug_status', 'is_open', {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
# Till now, bug statuses were not customizable. Nevertheless, local
# changes are possible and so we will try to respect these changes.
# This means: get the status of bugs having a resolution different from ''
# and mark these statuses as 'closed', even if some of these statuses are
# expected to be open statuses. Bug statuses we have no information about
# are left as 'open'.
my @statuses =
@{$dbh->selectcol_arrayref('SELECT DISTINCT bug_status FROM bugs
WHERE resolution != ?', undef, '')};
# Append the default list of closed statuses. Duplicated statuses don't hurt. # Till now, bug statuses were not customizable. Nevertheless, local
@statuses = map {$dbh->quote($_)} (@statuses, qw(RESOLVED VERIFIED CLOSED)); # changes are possible and so we will try to respect these changes.
# This means: get the status of bugs having a resolution different from ''
# and mark these statuses as 'closed', even if some of these statuses are
# expected to be open statuses. Bug statuses we have no information about
# are left as 'open'.
my @closed_statuses =
@{$dbh->selectcol_arrayref('SELECT DISTINCT bug_status FROM bugs
WHERE resolution != ?', undef, '')};
# Append the default list of closed statuses *unless* we detect at least
# one closed state in the DB (i.e. with is_open = 0). This would mean that
# the DB has already been updated at least once and maybe the admin decided
# that e.g. 'RESOLVED' is now an open state, in which case we don't want to
# override this attribute. At least one bug status has to be a closed state
# anyway (due to the 'duplicate_or_move_bug_status' parameter) so it's safe
# to use this criteria.
my $num_closed_states = $dbh->selectrow_array('SELECT COUNT(*) FROM bug_status
WHERE is_open = 0');
if (!$num_closed_states) {
@closed_statuses =
map {$dbh->quote($_)} (@closed_statuses, qw(RESOLVED VERIFIED CLOSED));
print "Marking closed bug statuses as such...\n"; print "Marking closed bug statuses as such...\n";
$dbh->do('UPDATE bug_status SET is_open = 0 WHERE value IN (' . $dbh->do('UPDATE bug_status SET is_open = 0 WHERE value IN (' .
join(', ', @statuses) . ')'); join(', ', @closed_statuses) . ')');
} }
# Populate the status_workflow table. We do nothing if the table already # Populate the status_workflow table. We do nothing if the table already
# has entries. If all bug status transitions have been deleted, the # has entries. If all bug status transitions have been deleted, the
# workflow will be restored to its default schema. # workflow will be restored to its default schema.
my $count = $dbh->selectrow_array('SELECT COUNT(*) FROM status_workflow'); my $count = $dbh->selectrow_array('SELECT COUNT(*) FROM status_workflow');
return if $count;
if (!$count) {
my $create = $old_params->{'commentoncreate'}; # Make sure the variables below are defined as
my $confirm = $old_params->{'commentonconfirm'}; # status_workflow.require_comment cannot be NULL.
my $accept = $old_params->{'commentonaccept'}; my $create = $old_params->{'commentoncreate'} || 0;
my $resolve = $old_params->{'commentonresolve'}; my $confirm = $old_params->{'commentonconfirm'} || 0;
my $verify = $old_params->{'commentonverify'}; my $accept = $old_params->{'commentonaccept'} || 0;
my $close = $old_params->{'commentonclose'}; my $resolve = $old_params->{'commentonresolve'} || 0;
my $reopen = $old_params->{'commentonreopen'}; my $verify = $old_params->{'commentonverify'} || 0;
# This was till recently the only way to get back to NEW for my $close = $old_params->{'commentonclose'} || 0;
# confirmed bugs, so we use this parameter here. my $reopen = $old_params->{'commentonreopen'} || 0;
my $reassign = $old_params->{'commentonreassign'}; # This was till recently the only way to get back to NEW for
# confirmed bugs, so we use this parameter here.
# This is the default workflow. my $reassign = $old_params->{'commentonreassign'} || 0;
my @workflow = ([undef, 'UNCONFIRMED', $create],
[undef, 'NEW', $create], # This is the default workflow.
[undef, 'ASSIGNED', $create], my @workflow = ([undef, 'UNCONFIRMED', $create],
['UNCONFIRMED', 'NEW', $confirm], [undef, 'NEW', $create],
['UNCONFIRMED', 'ASSIGNED', $accept], [undef, 'ASSIGNED', $create],
['UNCONFIRMED', 'RESOLVED', $resolve], ['UNCONFIRMED', 'NEW', $confirm],
['NEW', 'ASSIGNED', $accept], ['UNCONFIRMED', 'ASSIGNED', $accept],
['NEW', 'RESOLVED', $resolve], ['UNCONFIRMED', 'RESOLVED', $resolve],
['ASSIGNED', 'NEW', $reassign], ['NEW', 'ASSIGNED', $accept],
['ASSIGNED', 'RESOLVED', $resolve], ['NEW', 'RESOLVED', $resolve],
['REOPENED', 'NEW', $reassign], ['ASSIGNED', 'NEW', $reassign],
['REOPENED', 'ASSIGNED', $accept], ['ASSIGNED', 'RESOLVED', $resolve],
['REOPENED', 'RESOLVED', $resolve], ['REOPENED', 'NEW', $reassign],
['RESOLVED', 'UNCONFIRMED', $reopen], ['REOPENED', 'ASSIGNED', $accept],
['RESOLVED', 'REOPENED', $reopen], ['REOPENED', 'RESOLVED', $resolve],
['RESOLVED', 'VERIFIED', $verify], ['RESOLVED', 'UNCONFIRMED', $reopen],
['RESOLVED', 'CLOSED', $close], ['RESOLVED', 'REOPENED', $reopen],
['VERIFIED', 'UNCONFIRMED', $reopen], ['RESOLVED', 'VERIFIED', $verify],
['VERIFIED', 'REOPENED', $reopen], ['RESOLVED', 'CLOSED', $close],
['VERIFIED', 'CLOSED', $close], ['VERIFIED', 'UNCONFIRMED', $reopen],
['CLOSED', 'UNCONFIRMED', $reopen], ['VERIFIED', 'REOPENED', $reopen],
['CLOSED', 'REOPENED', $reopen]); ['VERIFIED', 'CLOSED', $close],
['CLOSED', 'UNCONFIRMED', $reopen],
print "Now filling the 'status_workflow' table with valid bug status transitions...\n"; ['CLOSED', 'REOPENED', $reopen]);
my $sth_select = $dbh->prepare('SELECT id FROM bug_status WHERE value = ?');
my $sth = $dbh->prepare('INSERT INTO status_workflow (old_status, new_status, print "Now filling the 'status_workflow' table with valid bug status transitions...\n";
require_comment) VALUES (?, ?, ?)'); my $sth_select = $dbh->prepare('SELECT id FROM bug_status WHERE value = ?');
my $sth = $dbh->prepare('INSERT INTO status_workflow (old_status, new_status,
foreach my $transition (@workflow) { require_comment) VALUES (?, ?, ?)');
my ($from, $to);
# If it's an initial state, there is no "old" value. foreach my $transition (@workflow) {
$from = $dbh->selectrow_array($sth_select, undef, $transition->[0]) my ($from, $to);
if $transition->[0]; # If it's an initial state, there is no "old" value.
$to = $dbh->selectrow_array($sth_select, undef, $transition->[1]); $from = $dbh->selectrow_array($sth_select, undef, $transition->[0])
# If one of the bug statuses doesn't exist, the transition is invalid. if $transition->[0];
next if (($transition->[0] && !$from) || !$to); $to = $dbh->selectrow_array($sth_select, undef, $transition->[1]);
# If one of the bug statuses doesn't exist, the transition is invalid.
$sth->execute($from, $to, $transition->[2] ? 1 : 0); next if (($transition->[0] && !$from) || !$to);
$sth->execute($from, $to, $transition->[2] ? 1 : 0);
}
} }
# Make sure the bug status used by the 'duplicate_or_move_bug_status'
# parameter has all the required transitions set.
Bugzilla::Status::add_missing_bug_status_transitions();
} }
1; 1;
......
...@@ -54,15 +54,22 @@ sub is_open { return $_[0]->{'is_open'}; } ...@@ -54,15 +54,22 @@ sub is_open { return $_[0]->{'is_open'}; }
##### Methods #### ##### Methods ####
############################### ###############################
sub closed_bug_statuses {
my @bug_statuses = Bugzilla::Status->get_all;
@bug_statuses = grep { !$_->is_open } @bug_statuses;
return @bug_statuses;
}
sub can_change_to { sub can_change_to {
my $self = shift; my $self = shift;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
if (!ref($self) || !defined $self->{'can_change_to'}) { if (!ref($self) || !defined $self->{'can_change_to'}) {
my ($cond, @args); my ($cond, @args, $self_exists);
if (ref($self)) { if (ref($self)) {
$cond = '= ?'; $cond = '= ?';
push(@args, $self->id); push(@args, $self->id);
$self_exists = 1;
} }
else { else {
$cond = 'IS NULL'; $cond = 'IS NULL';
...@@ -78,12 +85,37 @@ sub can_change_to { ...@@ -78,12 +85,37 @@ sub can_change_to {
AND old_status $cond", AND old_status $cond",
undef, @args); undef, @args);
# Allow the bug status to remain unchanged.
push(@$new_status_ids, $self->id) if $self_exists;
$self->{'can_change_to'} = Bugzilla::Status->new_from_list($new_status_ids); $self->{'can_change_to'} = Bugzilla::Status->new_from_list($new_status_ids);
} }
return $self->{'can_change_to'}; return $self->{'can_change_to'};
} }
sub add_missing_bug_status_transitions {
my $bug_status = shift || Bugzilla->params->{'duplicate_or_move_bug_status'};
my $dbh = Bugzilla->dbh;
my $new_status = new Bugzilla::Status({name => $bug_status});
# Silently discard invalid bug statuses.
$new_status || return;
my $missing_statuses = $dbh->selectcol_arrayref('SELECT id
FROM bug_status
LEFT JOIN status_workflow
ON old_status = id
AND new_status = ?
WHERE old_status IS NULL',
undef, $new_status->id);
my $sth = $dbh->prepare('INSERT INTO status_workflow
(old_status, new_status) VALUES (?, ?)');
foreach my $old_status_id (@$missing_statuses) {
next if ($old_status_id == $new_status->id);
$sth->execute($old_status_id, $new_status->id);
}
}
1; 1;
...@@ -100,6 +132,10 @@ Bugzilla::Status - Bug status class. ...@@ -100,6 +132,10 @@ Bugzilla::Status - Bug status class.
my $bug_status = new Bugzilla::Status({name => 'ASSIGNED'}); my $bug_status = new Bugzilla::Status({name => 'ASSIGNED'});
my $bug_status = new Bugzilla::Status(4); my $bug_status = new Bugzilla::Status(4);
my @closed_bug_statuses = Bugzilla::Status::closed_bug_statuses();
Bugzilla::Status::add_missing_bug_status_transitions($bug_status);
=head1 DESCRIPTION =head1 DESCRIPTION
Status.pm represents a bug status object. It is an implementation Status.pm represents a bug status object. It is an implementation
...@@ -113,6 +149,15 @@ below. ...@@ -113,6 +149,15 @@ below.
=over =over
=item C<closed_bug_statuses>
Description: Returns a list of C<Bugzilla::Status> objects which can have
a resolution associated with them ("closed" bug statuses).
Params: none.
Returns: A list of Bugzilla::Status objects.
=item C<can_change_to> =item C<can_change_to>
Description: Returns the list of active statuses a bug can be changed to Description: Returns the list of active statuses a bug can be changed to
...@@ -122,6 +167,14 @@ below. ...@@ -122,6 +167,14 @@ below.
Returns: A list of Bugzilla::Status objects. Returns: A list of Bugzilla::Status objects.
=item C<add_missing_bug_status_transitions>
Description: Insert all missing transitions to a given bug status.
Params: $bug_status - The value (name) of a bug status.
Returns: nothing.
=back =back
=cut =cut
...@@ -34,6 +34,7 @@ use Bugzilla::Error; ...@@ -34,6 +34,7 @@ use Bugzilla::Error;
use Bugzilla::Token; use Bugzilla::Token;
use Bugzilla::User; use Bugzilla::User;
use Bugzilla::User::Setting; use Bugzilla::User::Setting;
use Bugzilla::Status;
my $user = Bugzilla->login(LOGIN_REQUIRED); my $user = Bugzilla->login(LOGIN_REQUIRED);
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
...@@ -137,6 +138,9 @@ if ($action eq 'save' && $current_module) { ...@@ -137,6 +138,9 @@ if ($action eq 'save' && $current_module) {
if ($name eq 'languages') { if ($name eq 'languages') {
$update_lang_user_pref = 1; $update_lang_user_pref = 1;
} }
if ($name eq 'duplicate_or_move_bug_status') {
Bugzilla::Status::add_missing_bug_status_transitions($value);
}
} }
} }
if ($update_lang_user_pref) { if ($update_lang_user_pref) {
......
...@@ -29,6 +29,7 @@ use Bugzilla::Config qw(:admin); ...@@ -29,6 +29,7 @@ use Bugzilla::Config qw(:admin);
use Bugzilla::Token; use Bugzilla::Token;
use Bugzilla::Field; use Bugzilla::Field;
use Bugzilla::Bug; use Bugzilla::Bug;
use Bugzilla::Status;
# List of different tables that contain the changeable field values # List of different tables that contain the changeable field values
# (the old "enums.") Keep them in alphabetical order by their # (the old "enums.") Keep them in alphabetical order by their
...@@ -136,7 +137,7 @@ $defaults{'bug_severity'} = 'defaultseverity'; ...@@ -136,7 +137,7 @@ $defaults{'bug_severity'} = 'defaultseverity';
# Alternatively, a list of non-editable values can be specified. # Alternatively, a list of non-editable values can be specified.
# In this case, only the sortkey can be altered. # In this case, only the sortkey can be altered.
my %static; my %static;
$static{'bug_status'} = ['UNCONFIRMED']; $static{'bug_status'} = ['UNCONFIRMED', Bugzilla->params->{'duplicate_or_move_bug_status'}];
$static{'resolution'} = ['', 'FIXED', 'MOVED', 'DUPLICATE']; $static{'resolution'} = ['', 'FIXED', 'MOVED', 'DUPLICATE'];
$static{$_->name} = ['---'] foreach (@custom_fields); $static{$_->name} = ['---'] foreach (@custom_fields);
...@@ -234,9 +235,14 @@ if ($action eq 'new') { ...@@ -234,9 +235,14 @@ if ($action eq 'new') {
$dbh->do("INSERT INTO $field (value, sortkey) VALUES (?, ?)", $dbh->do("INSERT INTO $field (value, sortkey) VALUES (?, ?)",
undef, ($value, $sortkey)); undef, ($value, $sortkey));
if ($field eq 'bug_status' && !$cgi->param('is_open')) { if ($field eq 'bug_status') {
# The bug status is a closed state, but they are open by default. unless ($cgi->param('is_open')) {
$dbh->do('UPDATE bug_status SET is_open = 0 WHERE value = ?', undef, $value); # The bug status is a closed state, but they are open by default.
$dbh->do('UPDATE bug_status SET is_open = 0 WHERE value = ?', undef, $value);
}
# Allow the transition from this new bug status to the one used
# by the 'duplicate_or_move_bug_status' parameter.
Bugzilla::Status::add_missing_bug_status_transitions();
} }
delete_token($token); delete_token($token);
......
...@@ -100,7 +100,10 @@ elsif ($action eq 'update') { ...@@ -100,7 +100,10 @@ elsif ($action eq 'update') {
foreach my $new (@$statuses) { foreach my $new (@$statuses) {
next if $old->id == $new->id; next if $old->id == $new->id;
if ($cgi->param('w_' . $old->id . '_' . $new->id)) { # All transitions to 'duplicate_or_move_bug_status' must be valid.
if ($cgi->param('w_' . $old->id . '_' . $new->id)
|| ($new->name eq Bugzilla->params->{'duplicate_or_move_bug_status'}))
{
$sth_insert->execute($old->id, $new->id) $sth_insert->execute($old->id, $new->id)
unless defined $workflow->{$old->id}->{$new->id}; unless defined $workflow->{$old->id}->{$new->id};
} }
......
...@@ -496,8 +496,9 @@ if ($action eq Bugzilla->params->{'move-button-text'}) { ...@@ -496,8 +496,9 @@ if ($action eq Bugzilla->params->{'move-button-text'}) {
local $Storable::forgive_me = 1; local $Storable::forgive_me = 1;
my $bugs = dclone(\@bug_objects); my $bugs = dclone(\@bug_objects);
foreach my $bug (@bug_objects) { foreach my $bug (@bug_objects) {
$bug->set_status('RESOLVED'); my ($status, $resolution) = $bug->get_new_status_and_resolution('move');
$bug->set_resolution('MOVED'); $bug->set_status($status);
$bug->set_resolution($resolution);
} }
$_->update() foreach @bug_objects; $_->update() foreach @bug_objects;
$dbh->bz_unlock_tables(); $dbh->bz_unlock_tables();
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
%] %]
[% param_descs = { [% param_descs = {
duplicate_or_move_bug_status => "When $terms.abug is marked as a duplicate of another one " _
"or is moved to another installation, use this $terms.bug status."
letsubmitterchoosepriority => "If this is on, then people submitting $terms.bugs can " _ letsubmitterchoosepriority => "If this is on, then people submitting $terms.bugs can " _
"choose an initial priority for that ${terms.bug}. " _ "choose an initial priority for that ${terms.bug}. " _
"If off, then all $terms.bugs initially have the default " _ "If off, then all $terms.bugs initially have the default " _
......
...@@ -69,12 +69,14 @@ ...@@ -69,12 +69,14 @@
[% FOREACH new_status = statuses %] [% FOREACH new_status = statuses %]
[% IF status.id != new_status.id %] [% IF status.id != new_status.id %]
<td align="center" class="checkbox-cell [% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
[% " checked" IF workflow.${status.id}.${new_status.id}.defined %]" [% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
<td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
title="From [% status.name FILTER html %] to [% new_status.name FILTER html %]"> title="From [% status.name FILTER html %] to [% new_status.name FILTER html %]">
<input type="checkbox" name="w_[% status.id %]_[% new_status.id %]" <input type="checkbox" name="w_[% status.id %]_[% new_status.id %]"
id="w_[% status.id %]_[% new_status.id %]" onclick="toggle_cell(this)" id="w_[% status.id %]_[% new_status.id %]" onclick="toggle_cell(this)"
[% " checked='checked'" IF workflow.${status.id}.${new_status.id}.defined %]> [%+ "checked='checked'" IF checked || mandatory %]
[%+ "disabled='disabled'" IF mandatory %]>
</td> </td>
[% ELSE %] [% ELSE %]
<td class="checkbox-cell forbidden">&nbsp;</td> <td class="checkbox-cell forbidden">&nbsp;</td>
...@@ -84,6 +86,17 @@ ...@@ -84,6 +86,17 @@
[% END %] [% END %]
</table> </table>
<p>
When [% terms.abug %] is marked as a duplicate of another one or is moved
to another installation, the [% terms.bug %] status is automatically set to
<b>[% Param("duplicate_or_move_bug_status") FILTER html %]</b>. All transitions to
this [% terms.bug %] status must then be valid (this is the reason why you cannot edit
them above).<br>
Note: you can change this setting by visiting the
<a href="editparams.cgi?section=bugchange#duplicate_or_move_bug_status">Parameters</a>
page and editing the <i>duplicate_or_move_bug_status</i> parameter.
</p>
<p align="center"> <p align="center">
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" name="token" value="[% token FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]">
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
[% NEXT IF !bug.isopened && (bug.everconfirmed && bug_status.name == "UNCONFIRMED" [% NEXT IF !bug.isopened && (bug.everconfirmed && bug_status.name == "UNCONFIRMED"
|| !bug.everconfirmed && bug_status.name == "REOPENED") %] || !bug.everconfirmed && bug_status.name == "REOPENED") %]
[% PROCESS initial_action %] [% PROCESS initial_action %]
[% NEXT IF bug_status.name == bug.bug_status %]
<input type="radio" id="knob_[% bug_status.id FILTER html %]" name="knob" <input type="radio" id="knob_[% bug_status.id FILTER html %]" name="knob"
value="[% bug_status.name FILTER html %]"> value="[% bug_status.name FILTER html %]">
<label for="knob_[% bug_status.id FILTER html %]"> <label for="knob_[% bug_status.id FILTER html %]">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment