From 424b21e37cd9aeac01588ce0defd3ee665944b1d Mon Sep 17 00:00:00 2001 From: Simon Green Date: Thu, 14 Aug 2014 09:40:47 +1000 Subject: Bug 1012506 - Allow a bug to have multiple aliases r=dkl, a=sgreen --- Bugzilla/Bug.pm | 157 ++++++++++++++++++++------ Bugzilla/DB/Schema.pm | 18 ++- Bugzilla/Install/DB.pm | 16 +++ Bugzilla/Search.pm | 16 ++- Bugzilla/Search/Quicksearch.pm | 2 +- Bugzilla/WebService/Bug.pm | 60 ++++++++-- js/field.js | 13 +-- process_bug.cgi | 13 ++- skins/standard/bug.css | 4 +- template/en/default/bug/edit.html.tmpl | 124 ++++++++++++-------- template/en/default/bug/show-header.html.tmpl | 4 +- 11 files changed, 310 insertions(+), 117 deletions(-) diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index c4ddb943c..07266da9c 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -49,7 +49,7 @@ use parent qw(Bugzilla::Object Exporter); use constant DB_TABLE => 'bugs'; use constant ID_FIELD => 'bug_id'; -use constant NAME_FIELD => 'alias'; +use constant NAME_FIELD => 'bug_id'; use constant LIST_ORDER => ID_FIELD; # Bugs have their own auditing table, bugs_activity. use constant AUDIT_CREATES => 0; @@ -65,7 +65,6 @@ sub DB_COLUMNS { my @custom_names = map {$_->name} @custom; my @columns = (qw( - alias assigned_to bug_file_loc bug_id @@ -208,7 +207,6 @@ sub UPDATE_COLUMNS { Bugzilla->active_custom_fields; my @custom_names = map {$_->name} @custom; my @columns = qw( - alias assigned_to bug_file_loc bug_severity @@ -318,7 +316,16 @@ sub new { || (ref($param) && $param->{id} =~ /\D/)) { if ($param) { - $param = { name => ref($param) ? $param->{id} : $param, + my $alias = ref($param) ? $param->{id} : $param; + my $bug_id = bug_alias_to_id($alias); + if (! $bug_id) { + my $error_self = {}; + bless $error_self, $class; + $error_self->{'bug_id'} = $alias; + $error_self->{'error'} = 'InvalidBugId'; + return $error_self; + } + $param = { id => $bug_id, cache => ref($param) ? $param->{cache} : 0 }; } else { @@ -690,6 +697,7 @@ sub create { # These are not a fields in the bugs table, so we don't pass them to # insert_create_data. + my $bug_aliases = delete $params->{alias}; my $cc_ids = delete $params->{cc}; my $groups = delete $params->{groups}; my $depends_on = delete $params->{dependson}; @@ -788,6 +796,13 @@ sub create { # but sometimes it's blank. Bugzilla::Comment->insert_create_data($creation_comment); + # Set up aliases + my $sth_aliases = $dbh->prepare('INSERT INTO bugs_aliases (alias, bug_id) VALUES (?, ?)'); + foreach my $alias (@$bug_aliases) { + trick_taint($alias); + $sth_aliases->execute($alias, $bug->bug_id); + } + Bugzilla::Hook::process('bug_end_of_create', { bug => $bug, timestamp => $timestamp, }); @@ -907,7 +922,26 @@ sub update { my $added_names = join(', ', (map {$_->login} @$added_users)); $changes->{cc} = [$removed_names, $added_names]; } - + + # Aliases + my $old_aliases = $old_bug->alias; + my $new_aliases = $self->alias; + my ($removed_aliases, $added_aliases) = diff_arrays($old_aliases, $new_aliases); + + foreach my $alias (@$removed_aliases) { + $dbh->do('DELETE FROM bugs_aliases WHERE bug_id = ? AND alias = ?', + undef, $self->id, $alias); + } + foreach my $alias (@$added_aliases) { + trick_taint($alias); + $dbh->do('INSERT INTO bugs_aliases (bug_id, alias) VALUES (?,?)', + undef, $self->id, $alias); + } + # If any changes were found, record it in the activity log + if (scalar @$removed_aliases || scalar @$added_aliases) { + $changes->{alias} = [join(', ', @$removed_aliases), join(', ', @$added_aliases)]; + } + # Keywords my @old_kw_ids = map { $_->id } @{$old_bug->keyword_objects}; my @new_kw_ids = map { $_->id } @{$self->keyword_objects}; @@ -1311,32 +1345,38 @@ sub _send_bugmail { ##################################################################### sub _check_alias { - my ($invocant, $alias) = @_; - $alias = trim($alias); - return undef if (!$alias); - - # Make sure the alias isn't too long. - if (length($alias) > 20) { - ThrowUserError("alias_too_long"); - } - # Make sure the alias isn't just a number. - if ($alias =~ /^\d+$/) { - ThrowUserError("alias_is_numeric", { alias => $alias }); - } - # Make sure the alias has no commas or spaces. - if ($alias =~ /[, ]/) { - ThrowUserError("alias_has_comma_or_space", { alias => $alias }); - } - # Make sure the alias is unique, or that it's already our alias. - my $other_bug = new Bugzilla::Bug($alias); - if (!$other_bug->{error} - && (!ref $invocant || $other_bug->id != $invocant->id)) - { - ThrowUserError("alias_in_use", { alias => $alias, - bug_id => $other_bug->id }); + my ($invocant, $aliases) = @_; + $aliases = ref $aliases ? $aliases : [split(/[\s,]+/, $aliases)]; + + # Remove empty aliases + @$aliases = grep { $_ } @$aliases; + + foreach my $alias (@$aliases) { + $alias = trim($alias); + + # Make sure the alias isn't too long. + if (length($alias) > 40) { + ThrowUserError("alias_too_long"); + } + # Make sure the alias isn't just a number. + if ($alias =~ /^\d+$/) { + ThrowUserError("alias_is_numeric", { alias => $alias }); + } + # Make sure the alias has no commas or spaces. + if ($alias =~ /[, ]/) { + ThrowUserError("alias_has_comma_or_space", { alias => $alias }); + } + # Make sure the alias is unique, or that it's already our alias. + my $other_bug = new Bugzilla::Bug($alias); + if (!$other_bug->{error} + && (!ref $invocant || $other_bug->id != $invocant->id)) + { + ThrowUserError("alias_in_use", { alias => $alias, + bug_id => $other_bug->id }); + } } - return $alias; + return $aliases; } sub _check_assigned_to { @@ -2376,6 +2416,13 @@ sub set_all { work_time => $params->{'work_time'} }); } + if (exists $params->{alias} && $params->{alias}{set}) { + $params->{alias} = { + add => $params->{alias}{set}, + remove => $self->alias, + }; + } + my %normal_set_all; foreach my $name (keys %$params) { # These are handled separately below. @@ -2400,6 +2447,7 @@ sub set_all { } $self->_add_remove($params, 'cc'); + $self->_add_remove($params, 'alias'); # Theoretically you could move a product without ever specifying # a new assignee or qa_contact, or adding/removing any CCs. So, @@ -2416,14 +2464,13 @@ sub _add_remove { my ($self, $params, $name) = @_; my @add = @{ $params->{$name}->{add} || [] }; my @remove = @{ $params->{$name}->{remove} || [] }; - $name =~ s/s$//; + $name =~ s/s$// if $name ne 'alias'; my $add_method = "add_$name"; my $remove_method = "remove_$name"; $self->$add_method($_) foreach @add; $self->$remove_method($_) foreach @remove; } -sub set_alias { $_[0]->set('alias', $_[1]); } sub set_assigned_to { my ($self, $value) = @_; $self->set('assigned_to', $value); @@ -2840,6 +2887,21 @@ sub remove_cc { @$cc_users = grep { $_->id != $user->id } @$cc_users; } +sub add_alias { + my ($self, $alias) = @_; + return if !$alias; + my $aliases = $self->_check_alias($alias); + $alias = $aliases->[0]; + my $bug_aliases = $self->alias; + push(@$bug_aliases, $alias) if !grep($_ eq $alias, @$bug_aliases); +} + +sub remove_alias { + my ($self, $alias) = @_; + my $bug_aliases = $self->alias; + @$bug_aliases = grep { $_ ne $alias } @$bug_aliases; +} + # $bug->add_comment("comment", {isprivate => 1, work_time => 10.5, # type => CMT_NORMAL, extra_data => $data}); sub add_comment { @@ -3167,7 +3229,6 @@ sub tags { # These are accessors that don't need to access the database. # Keep them in alphabetical order. -sub alias { return $_[0]->{alias} } sub bug_file_loc { return $_[0]->{bug_file_loc} } sub bug_id { return $_[0]->{bug_id} } sub bug_severity { return $_[0]->{bug_severity} } @@ -3277,6 +3338,24 @@ sub actual_time { return $self->{'actual_time'}; } +sub alias { + my ($self) = @_; + return $self->{'alias'} if exists $self->{'alias'}; + return [] if $self->{'error'}; + + my $dbh = Bugzilla->dbh; + $self->{'alias'} = $dbh->selectcol_arrayref( + q{SELECT alias + FROM bugs_aliases + WHERE bug_id = ? + ORDER BY alias}, + undef, $self->bug_id); + + $self->{'alias'} = [] if !scalar(@{$self->{'alias'}}); + + return $self->{'alias'}; +} + sub any_flags_requesteeble { my ($self) = @_; return $self->{'any_flags_requesteeble'} @@ -3868,7 +3947,7 @@ sub bug_alias_to_id { my $dbh = Bugzilla->dbh; trick_taint($alias); return $dbh->selectrow_array( - "SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias); + "SELECT bug_id FROM bugs_aliases WHERE alias = ?", undef, $alias); } ##################################################################### @@ -4497,6 +4576,16 @@ __END__ Ensures the accessors for custom fields are always created. +=item C + +Adds an alias to the internal respresentation of the bug. You will need to +call L to make the changes permanent. + +=item C + +Removes an alias from the internal respresentation of the bug. You will need to +call L to make the changes permanent. + =item C Creates or updates a L for this bug and the supplied @@ -4664,8 +4753,6 @@ $user, the timestamp given as $last_visit. =item remove_group -=item set_alias - =item set_dup_id =item set_target_milestone diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 8c81f7a59..d1c1dc7e9 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -278,11 +278,8 @@ use constant ABSTRACT_SCHEMA => { remaining_time => {TYPE => 'decimal(7,2)', NOTNULL => 1, DEFAULT => '0'}, deadline => {TYPE => 'DATETIME'}, - alias => {TYPE => 'varchar(20)'}, ], INDEXES => [ - bugs_alias_idx => {FIELDS => ['alias'], - TYPE => 'UNIQUE'}, bugs_assigned_to_idx => ['assigned_to'], bugs_creation_ts_idx => ['creation_ts'], bugs_delta_ts_idx => ['delta_ts'], @@ -359,6 +356,21 @@ use constant ABSTRACT_SCHEMA => { ], }, + bugs_aliases => { + FIELDS => [ + alias => {TYPE => 'varchar(40)', NOTNULL => 1}, + bug_id => {TYPE => 'INT3', + REFERENCES => {TABLE => 'bugs', + COLUMN => 'bug_id', + DELETE => 'CASCADE'}}, + ], + INDEXES => [ + bugs_aliases_bug_id_idx => ['bug_id'], + bugs_aliases_alias_idx => {FIELDS => ['alias'], + TYPE => 'UNIQUE'}, + ], + }, + cc => { FIELDS => [ bug_id => {TYPE => 'INT3', NOTNULL => 1, diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index dd0f3608b..b136e6d83 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -727,6 +727,9 @@ sub update_table_definitions { # 2014-07-27 LpSolit@gmail.com - Bug 1044561 _fix_user_api_keys_indexes(); + # 2014-08-11 sgreen@redhat.com - Bug 1012506 + _update_alias(); + ################################################################ # New --TABLE-- changes should go *** A B O V E *** this point # ################################################################ @@ -3899,6 +3902,19 @@ sub _fix_user_api_keys_indexes { } } +sub _update_alias { + my $dbh = Bugzilla->dbh; + return unless $dbh->bz_column_info('bugs', 'alias'); + + # We need to move the aliases from the bugs table to the bugs_aliases table + $dbh->do(q{ + INSERT INTO bugs_aliases (bug_id, alias) + SELECT bug_id, alias FROM bugs WHERE alias IS NOT NULL + }); + + $dbh->bz_drop_column('bugs', 'alias'); +} + 1; __END__ diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 59d7f86ec..b2e8da096 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -265,7 +265,7 @@ use constant OPERATOR_FIELD_OVERRIDE => { }, # General Bug Fields - alias => { _non_changed => \&_nullable }, + alias => { _non_changed => \&_alias_nonchanged }, 'attach_data.thedata' => MULTI_SELECT_OVERRIDE, # We check all attachment fields against this. attachments => MULTI_SELECT_OVERRIDE, @@ -456,6 +456,10 @@ sub COLUMN_JOINS { . ' FROM longdescs GROUP BY bug_id)', join => 'INNER', }, + alias => { + table => 'bugs_aliases', + as => 'map_alias', + }, assigned_to => { from => 'assigned_to', to => 'userid', @@ -586,6 +590,7 @@ sub COLUMNS { # like "bugs.bug_id". my $total_time = "(map_actual_time.total + bugs.remaining_time)"; my %special_sql = ( + alias => $dbh->sql_group_concat('DISTINCT map_alias.alias'), deadline => $dbh->sql_date_format('bugs.deadline', '%Y-%m-%d'), actual_time => 'map_actual_time.total', @@ -2727,6 +2732,15 @@ sub _product_nonchanged { "products.id", "products", $term); } +sub _alias_nonchanged { + my ($self, $args) = @_; + + $args->{full_field} = "bugs_aliases.alias"; + $self->_do_operator_function($args); + $args->{term} = build_subselect("bugs.bug_id", + "bugs_aliases.bug_id", "bugs_aliases", $args->{term}); +} + sub _classification_nonchanged { my ($self, $args) = @_; my $joins = $args->{joins}; diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm index c00f18351..830177f8b 100644 --- a/Bugzilla/Search/Quicksearch.pm +++ b/Bugzilla/Search/Quicksearch.pm @@ -322,7 +322,7 @@ sub _handle_alias { my $alias = $1; # We use this direct SQL because we want quicksearch to be VERY fast. my $bug_id = Bugzilla->dbh->selectrow_array( - q{SELECT bug_id FROM bugs WHERE alias = ?}, undef, $alias); + q{SELECT bug_id FROM bugs_aliases WHERE alias = ?}, undef, $alias); # If the user cannot see the bug or if we are using a webservice, # do not resolve its alias. if ($bug_id && Bugzilla->user->can_see_bug($bug_id) && !i_am_webservice()) { diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index 4689ae0f2..334be1057 100644 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -468,7 +468,7 @@ sub history { # alias is returned in case users passes a mixture of ids and aliases # then they get to know which bug activity relates to which value # they passed - $item{alias} = $self->type('string', $bug->alias); + $item{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; push(@return, \%item); } @@ -632,6 +632,16 @@ sub update { # called using those field names. delete $values{dependencies}; + # For backwards compatibility, treat alias string or array as a set action + if (exists $values{alias}) { + if (not ref $values{alias}) { + $values{alias} = { set => [ $values{alias} ] }; + } + elsif (ref $values{alias} eq 'ARRAY') { + $values{alias} = { set => $values{alias} }; + } + } + my $flags = delete $values{flags}; foreach my $bug (@bugs) { @@ -669,7 +679,7 @@ sub update { # alias is returned in case users pass a mixture of ids and aliases, # so that they can know which set of changes relates to which value # they passed. - $hash{alias} = $self->type('string', $bug->alias); + $hash{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; my %changes = %{ $all_changes{$bug->id} }; foreach my $field (keys %changes) { @@ -1163,7 +1173,6 @@ sub _bug_to_hash { # A bug attribute is "basic" if it doesn't require an additional # database call to get the info. my %item = %{ filter $params, { - alias => $self->type('string', $bug->alias), creation_time => $self->type('dateTime', $bug->creation_ts), # No need to format $bug->deadline specially, because Bugzilla::Bug # already does it for us. @@ -1187,6 +1196,9 @@ sub _bug_to_hash { # First we handle any fields that require extra SQL calls. # We don't do the SQL calls at all if the filter would just # eliminate them anyway. + if (filter_wants $params, 'alias') { + $item{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; + } if (filter_wants $params, 'assigned_to') { $item{'assigned_to'} = $self->type('email', $bug->assigned_to->login); $item{'assigned_to_detail'} = $self->_user_to_hash($bug->assigned_to, $params, undef, 'assigned_to'); @@ -2168,7 +2180,8 @@ in the return value. =item C -C The unique alias of this bug. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item C @@ -2613,7 +2626,8 @@ C The numeric id of the bug. =item alias -C The alias of this bug. If there is no alias, this will be undef. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item history @@ -2796,7 +2810,8 @@ just reuse the query parameter portion in the REST call itself. =item C -C The unique alias for this bug. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item C @@ -3053,7 +3068,7 @@ in by the developer, compared to the developer's other bugs. =item C (string) B - How severe the bug is. -=item C (string) - A brief alias for the bug that can be used +=item C (array) - A brief alias for the bug that can be used instead of a bug number when accessing this bug. Must be unique in all of this Bugzilla. @@ -3754,9 +3769,29 @@ bugs you are updating. =item C -(string) The alias of the bug. You can only set this if you are modifying -a single bug. If there is more than one bug specified in C, passing in -a value for C will cause an error to be thrown. +C These specify the aliases of a bug that can be used instead of a bug +number when acessing this bug. To set these, you should pass a hash as the +value. The hash may contain the following fields: + +=over + +=item C An array of Cs. Aliases to add to this field. + +=item C An array of Cs. Aliases to remove from this field. +If the aliases are not already in the field, they will be ignored. + +=item C An array of Cs. An exact set of aliases to set this +field to, overriding the current value. If you specify C, then C +and C will be ignored. + +=back + +You can only set this if you are modifying a single bug. If there is more +than one bug specified in C, passing in a value for C will cause +an error to be thrown. + +For backwards compatibility, you can also specify a single string. This will +be treated as if you specified the set key above. =item C @@ -4075,7 +4110,8 @@ C The id of the bug that was updated. =item C -C The alias of the bug that was updated, if this bug has an alias. +C of Cs The aliases of the bug that was updated, if this bug +has any alias. =item C @@ -4109,7 +4145,7 @@ Here's an example of what a return value might look like: bugs => [ { id => 123, - alias => 'foo', + alias => [ 'foo' ], last_change_time => '2010-01-01T12:34:56', changes => { status => { diff --git a/js/field.js b/js/field.js index f865a141f..7c5c5b64e 100644 --- a/js/field.js +++ b/js/field.js @@ -295,7 +295,7 @@ function checkForChangedFieldValues(e, ContainerInputArray ) { if ( el ) { if ( !ContainerInputArray[4] && (el.value != ContainerInputArray[3] - || (el.value == "" && el.id != "alias" && el.id != "qa_contact")) ) + || (el.value == "" && el.id != "qa_contact")) ) { unhide = true; } @@ -316,17 +316,6 @@ function checkForChangedFieldValues(e, ContainerInputArray ) { } -function hideAliasAndSummary(short_desc_value, alias_value) { - // check the short desc field - hideEditableField( 'summary_alias_container','summary_alias_input', - 'editme_action','short_desc', short_desc_value); - // check that the alias hasn't changed - var bz_alias_check_array = new Array('summary_alias_container', - 'summary_alias_input', 'alias', alias_value); - YAHOO.util.Event.addListener( window, 'load', checkForChangedFieldValues, - bz_alias_check_array); -} - function showPeopleOnChange( field_id_list ) { for(var i = 0; i < field_id_list.length; i++) { YAHOO.util.Event.addListener( field_id_list[i],'change', showEditableField, diff --git a/process_bug.cgi b/process_bug.cgi index bc558682e..37beee14a 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -289,8 +289,17 @@ if (defined $cgi->param('newcc') if (defined $cgi->param('id')) { # Since aliases are unique (like bug numbers), they can only be changed # for one bug at a time. - if (defined $cgi->param('alias')) { - $set_all_fields{alias} = $cgi->param('alias'); + if (defined $cgi->param('newalias') || defined $cgi->param('removealias')) { + my @alias_add = split /[, ]+/, $cgi->param('newalias'); + + # We came from bug_form which uses a select box to determine what + # aliases need to be removed... + my @alias_remove = (); + if ($cgi->param('removealias') && $cgi->param('alias')) { + @alias_remove = $cgi->param('alias'); + } + + $set_all_fields{alias} = { add => \@alias_add, remove => \@alias_remove }; } } diff --git a/skins/standard/bug.css b/skins/standard/bug.css index e23475a35..851b1bdba 100644 --- a/skins/standard/bug.css +++ b/skins/standard/bug.css @@ -114,7 +114,7 @@ table#attachment_flags th, table#attachment_flags td { /* show_bug.cgi (start) */ -.bz_alias_short_desc_container { +.bz_short_desc_container { margin: 8px 0; padding: 0.3em; background-color: rgb(208, 208, 208); @@ -231,7 +231,7 @@ table#flags { .text_input, .bz_userfield, #keywords_container, #tag_container { width: 100%; } -.bz_bug .bz_alias_short_desc_container { +.bz_bug .bz_short_desc_container { width: inherit; } diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl index 8b55dedcb..6917a89ec 100644 --- a/template/en/default/bug/edit.html.tmpl +++ b/template/en/default/bug/edit.html.tmpl @@ -66,9 +66,13 @@ [%# *** ID, product, component, status, resolution, Hardware, and OS *** %] [% PROCESS section_status %] - + [% PROCESS section_spacer %] - + + [% PROCESS section_aliases %] + + [% PROCESS section_spacer %] + [% PROCESS section_details1 %] [% PROCESS section_spacer %] @@ -173,61 +177,37 @@ [% BLOCK section_title %] [%# That's the main table, which contains all editable fields. %] -
+
[% PROCESS commit_button id="_top"%] [%-# %][% terms.Bug %] [% bug.bug_id FILTER html %] - [%-# %] - [% IF bug.alias != "" %] - ([% bug.alias FILTER html %]) + [%-# %] + [% IF bug.alias.size > 0 %] + ([% bug.alias.join(', ') FILTER html %]) [% END %] - [% bug.short_desc FILTER quoteUrls(bug) %] - [% IF bug.check_can_change_field('short_desc', 0, 1) || - bug.check_can_change_field('alias', 0, 1) %] - (edit) + [% IF bug.check_can_change_field('short_desc', 0, 1) %] + (edit) [% END %] - - -
-
- - [% IF bug.check_can_change_field('alias', 0, 1) %] - [% INCLUDE "bug/field-label.html.tmpl" - field = bug_fields.alias - editable = 1 - %] - - - [%# *** Summary *** %] - - [% INCLUDE "bug/field-label.html.tmpl" - field = bug_fields.short_desc - editable = 1 - accesskey = "s" - %] - - -
- [% ELSIF bug.alias %] - ( - [% ELSE %] - - [% END %] - [% PROCESS input inputname => "alias" - size => "20" - maxlength => "20" - no_td => 1 - %][% ")" IF NOT bug.check_can_change_field('alias', 0, 1) - && bug.alias %] -
- [% PROCESS input inputname => "short_desc" size => "80" colspan => 2 - maxlength => 255 spellcheck => "true" no_td => 1 %] -
+ +
+ [% INCLUDE "bug/field-label.html.tmpl" + field = bug_fields.short_desc + editable = 1 + accesskey = "s" + tag_name = 'span' + %] + [% PROCESS input inputname => "short_desc" size => "80" + maxlength => 255 spellcheck => "true" no_td => 1 %]
[% END %] @@ -867,6 +847,56 @@ [% END %] [% END %] +[% BLOCK section_aliases %] + + [% INCLUDE "bug/field-label.html.tmpl" + field = bug_fields.alias, editable = 1 + %] + + [% IF bug.alias.size %] + [% bug.alias.join(', ') FILTER html %] + [% ELSE %] + None + [% END %] + [% IF bug.check_can_change_field('alias', 0, 1) %] + + (edit) + +
+
+
+
+ +
+ +
+ [% IF bug.alias.size %] + +
+ + + + + [% END %] +
+ + [% END %] + + +[% END %] + [%############################################################################%] [%# Block for FLAGS #%] [%############################################################################%] diff --git a/template/en/default/bug/show-header.html.tmpl b/template/en/default/bug/show-header.html.tmpl index 6dfc19dfb..3b1f27252 100644 --- a/template/en/default/bug/show-header.html.tmpl +++ b/template/en/default/bug/show-header.html.tmpl @@ -13,7 +13,7 @@ # be overridden by the calling templates. #%] -[% filtered_alias = bug.alias FILTER html %] +[% filtered_alias = bug.alias.join(', ') FILTER html %] [% filtered_desc = bug.short_desc FILTER html %] [% filtered_timestamp = bug.delta_ts FILTER time %] @@ -34,7 +34,7 @@ [% header_addl_info = "Last modified: $filtered_timestamp" %] [% unfiltered_title = "$bug.bug_id – " %] [% IF bug.alias != '' %] - [% unfiltered_title = unfiltered_title _ "($bug.alias) " %] + [% unfiltered_title = unfiltered_title _ "(" _ bug.alias.join(', ') _ ") " %] [% END %] [% unfiltered_title = unfiltered_title _ bug.short_desc %] [% javascript = BLOCK %] -- cgit v1.2.3-24-g4f1b