diff options
author | Frédéric Buclin <LpSolit@gmail.com> | 2012-05-07 17:58:22 +0200 |
---|---|---|
committer | Frédéric Buclin <LpSolit@gmail.com> | 2012-05-07 17:58:22 +0200 |
commit | 92a81752931c5fd7cdbf4b63305389844193d029 (patch) | |
tree | 13cae837e5d0491e9ad5d6426b558de741d261eb | |
parent | 4e5dcf363dd1ffa63f0d7a190fa61891061ddea2 (diff) | |
download | bugzilla-92a81752931c5fd7cdbf4b63305389844193d029.tar.gz bugzilla-92a81752931c5fd7cdbf4b63305389844193d029.tar.xz |
Bug 616191: Implement UI to easily tag bugs from the bug report directly (and get rid of the current form in the footer)
r=timello a=LpSolit
-rw-r--r-- | Bugzilla/Field.pm | 3 | ||||
-rw-r--r-- | Bugzilla/Install.pm | 5 | ||||
-rw-r--r-- | Bugzilla/Template.pm | 4 | ||||
-rwxr-xr-x | buglist.cgi | 53 | ||||
-rw-r--r-- | js/field.js | 34 | ||||
-rwxr-xr-x | process_bug.cgi | 12 | ||||
-rw-r--r-- | skins/standard/IE-fixes.css | 2 | ||||
-rw-r--r-- | skins/standard/global.css | 4 | ||||
-rw-r--r-- | skins/standard/search_form.css | 2 | ||||
-rw-r--r-- | skins/standard/show_bug.css | 2 | ||||
-rw-r--r-- | template/en/default/bug/edit.html.tmpl | 11 | ||||
-rw-r--r-- | template/en/default/bug/field-help.none.tmpl | 7 | ||||
-rw-r--r-- | template/en/default/bug/field.html.tmpl | 16 | ||||
-rw-r--r-- | template/en/default/filterexceptions.pl | 4 | ||||
-rw-r--r-- | template/en/default/global/field-descs.none.tmpl | 2 | ||||
-rw-r--r-- | template/en/default/global/messages.html.tmpl | 12 | ||||
-rw-r--r-- | template/en/default/global/per-bug-queries.html.tmpl | 88 | ||||
-rw-r--r-- | template/en/default/global/setting-descs.none.tmpl | 1 | ||||
-rw-r--r-- | template/en/default/global/useful-links.html.tmpl | 2 | ||||
-rw-r--r-- | template/en/default/search/field.html.tmpl | 16 | ||||
-rw-r--r-- | template/en/default/search/form.html.tmpl | 1 |
21 files changed, 85 insertions, 196 deletions
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 4ec592164..c244e66d9 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -248,7 +248,8 @@ use constant DEFAULT_FIELDS => ( {name => "owner_idle_time", desc => "Time Since Assignee Touched"}, {name => 'see_also', desc => "See Also", type => FIELD_TYPE_BUG_URLS}, - {name => 'tag', desc => 'Tags', buglist => 1}, + {name => 'tag', desc => 'Tags', buglist => 1, + type => FIELD_TYPE_KEYWORDS}, ); ################ diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm index bd591ecc8..f2c3902e4 100644 --- a/Bugzilla/Install.pm +++ b/Bugzilla/Install.pm @@ -61,8 +61,6 @@ sub SETTINGS { csv_colsepchar => { options => [',',';'], default => ',' }, # 2005-10-26 wurblzap@gmail.com -- Bug 291459 zoom_textareas => { options => ["on", "off"], default => "on" }, - # 2005-10-21 LpSolit@gmail.com -- Bug 313020 - per_bug_queries => { options => ['on', 'off'], default => 'off' }, # 2006-05-01 olav@bkor.dhs.org -- Bug 7710 state_addselfcc => { options => ['always', 'never', 'cc_unless_role'], default => 'cc_unless_role' }, @@ -192,6 +190,9 @@ sub update_settings { $settings{$setting}->{subclass}, undef, !$any_settings); } + + # Delete the obsolete 'per_bug_queries' user preference. Bug 616191. + $dbh->do('DELETE FROM setting WHERE name = ?', undef, 'per_bug_queries'); } sub update_system_groups { diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 78c537cc3..e5bd8edb7 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -928,7 +928,9 @@ sub create { 'use_keywords' => sub { return Bugzilla::Keyword->any_exist; }, # All the keywords. - 'all_keywords' => sub { return Bugzilla::Keyword->get_all(); }, + 'all_keywords' => sub { + return [map { $_->name } Bugzilla::Keyword->get_all()]; + }, 'feature_enabled' => sub { return Bugzilla->feature(@_); }, diff --git a/buglist.cgi b/buglist.cgi index 89ba3fe46..f0e778464 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -23,10 +23,8 @@ use Bugzilla::Search; use Bugzilla::Search::Quicksearch; use Bugzilla::Search::Recent; use Bugzilla::Search::Saved; -use Bugzilla::User; use Bugzilla::Bug; use Bugzilla::Product; -use Bugzilla::Keyword; use Bugzilla::Field; use Bugzilla::Status; use Bugzilla::Token; @@ -445,51 +443,18 @@ elsif (($cmdtype eq "doit") && defined $cgi->param('remtype')) { my $new_query = $cgi->param('newquery'); my $token = $cgi->param('token'); check_hash_token($token, ['savedsearch']); - # If list_of_bugs is true, we are adding/removing tags to/from - # individual bugs. - if ($cgi->param('list_of_bugs')) { - # We add/remove tags based on the action choosen. - my $action = trim($cgi->param('action') || ''); - $action =~ /^(add|remove)$/ - || ThrowUserError('unknown_action', {action => $action}); - - my $method = "${action}_tag"; - - # If no new tag name has been given, use the selected one. - $query_name ||= $cgi->param('oldqueryname') - or ThrowUserError('no_tag_to_edit', {action => $action}); - - my @buglist; - # Validate all bug IDs before editing tags in any of them. - foreach my $bug_id (split(/[\s,]+/, $cgi->param('bug_ids'))) { - next unless $bug_id; - push(@buglist, Bugzilla::Bug->check($bug_id)); - } - - foreach my $bug (@buglist) { - $bug->$method($query_name); - } - - $vars->{'message'} = 'tag_updated'; - $vars->{'action'} = $action; - $vars->{'tag'} = $query_name; - $vars->{'buglist'} = [map { $_->id } @buglist]; + my $existed_before = InsertNamedQuery($query_name, $new_query, 1); + if ($existed_before) { + $vars->{'message'} = "buglist_updated_named_query"; } else { - my $existed_before = InsertNamedQuery($query_name, $new_query, 1); - if ($existed_before) { - $vars->{'message'} = "buglist_updated_named_query"; - } - else { - $vars->{'message'} = "buglist_new_named_query"; - } - - # Make sure to invalidate any cached query data, so that the footer is - # correctly displayed - $user->flush_queries_cache(); - - $vars->{'queryname'} = $query_name; + $vars->{'message'} = "buglist_new_named_query"; } + $vars->{'queryname'} = $query_name; + + # Make sure to invalidate any cached query data, so that the footer is + # correctly displayed + $user->flush_queries_cache(); print $cgi->header(); $template->process("global/message.html.tmpl", $vars) diff --git a/js/field.js b/js/field.js index 9583db02c..1e5595081 100644 --- a/js/field.js +++ b/js/field.js @@ -870,27 +870,29 @@ YAHOO.bugzilla.userAutocomplete = { } }; -YAHOO.bugzilla.keywordAutocomplete = { - dataSource : null, - init_ds : function(){ - this.dataSource = new YAHOO.util.LocalDataSource( YAHOO.bugzilla.keyword_array ); +YAHOO.bugzilla.fieldAutocomplete = { + dataSource : [], + init_ds : function( field ) { + this.dataSource[field] = + new YAHOO.util.LocalDataSource( YAHOO.bugzilla.field_array[field] ); }, init : function( field, container ) { - if( this.dataSource == null ){ - this.init_ds(); + if( this.dataSource[field] == null ) { + this.init_ds( field ); } - var keywordAutoComp = new YAHOO.widget.AutoComplete(field, container, this.dataSource); - keywordAutoComp.maxResultsDisplayed = YAHOO.bugzilla.keyword_array.length; - keywordAutoComp.minQueryLength = 0; - keywordAutoComp.useIFrame = true; - keywordAutoComp.delimChar = [","," "]; - keywordAutoComp.resultTypeList = false; - keywordAutoComp.queryDelay = 0; - /* Causes all the possibilities in the keyword to appear when a user + var fieldAutoComp = + new YAHOO.widget.AutoComplete(field, container, this.dataSource[field]); + fieldAutoComp.maxResultsDisplayed = YAHOO.bugzilla.field_array[field].length; + fieldAutoComp.minQueryLength = 0; + fieldAutoComp.useIFrame = true; + fieldAutoComp.delimChar = [","," "]; + fieldAutoComp.resultTypeList = false; + fieldAutoComp.queryDelay = 0; + /* Causes all the possibilities in the field to appear when a user * focuses on the textbox */ - keywordAutoComp.textboxFocusEvent.subscribe( function(){ - var sInputValue = YAHOO.util.Dom.get('keywords').value; + fieldAutoComp.textboxFocusEvent.subscribe( function(){ + var sInputValue = YAHOO.util.Dom.get(field).value; if( sInputValue.length === 0 ){ this.sendQuery(sInputValue); this.collapseContainer(); diff --git a/process_bug.cgi b/process_bug.cgi index 30e30b622..29cc54e9f 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -28,10 +28,6 @@ use Bugzilla::Bug; use Bugzilla::User; use Bugzilla::Util; use Bugzilla::Error; -use Bugzilla::Field; -use Bugzilla::Product; -use Bugzilla::Component; -use Bugzilla::Keyword; use Bugzilla::Flag; use Bugzilla::Status; use Bugzilla::Token; @@ -330,6 +326,14 @@ if (defined $cgi->param('id')) { my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi( $first_bug, undef, $vars); $first_bug->set_flags($flags, $new_flags); + + # Tags can only be set to one bug at once. + if (should_set('tag')) { + my @new_tags = split(/[\s,]+/, $cgi->param('tag')); + my ($tags_removed, $tags_added) = diff_arrays($first_bug->tags, \@new_tags); + $first_bug->remove_tag($_) foreach @$tags_removed; + $first_bug->add_tag($_) foreach @$tags_added; + } } ############################## diff --git a/skins/standard/IE-fixes.css b/skins/standard/IE-fixes.css index 727667f73..9574d5f9e 100644 --- a/skins/standard/IE-fixes.css +++ b/skins/standard/IE-fixes.css @@ -44,7 +44,7 @@ form#Create #comp_desc { display: inline; } -#keyword_container .yui-ac-content { +#keywords_container .yui-ac-content { _height: 30em; /* ie6 */ } diff --git a/skins/standard/global.css b/skins/standard/global.css index 905a97158..07b289ec2 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -526,12 +526,12 @@ input.required, select.required, span.required_explanation { overflow-x: hidden; } -#keyword_container { +#keywords_container { padding-top: .2em; } -#keyword_container .yui-ac-content { +#keywords_container .yui-ac-content { margin-left: -1px; } diff --git a/skins/standard/search_form.css b/skins/standard/search_form.css index aa04b6ffe..e3a2ba1c4 100644 --- a/skins/standard/search_form.css +++ b/skins/standard/search_form.css @@ -99,7 +99,7 @@ width: inherit; } -#keyword_container { +#keywords_container { padding-bottom: 0; } diff --git a/skins/standard/show_bug.css b/skins/standard/show_bug.css index 9c15599ee..fb47335be 100644 --- a/skins/standard/show_bug.css +++ b/skins/standard/show_bug.css @@ -118,7 +118,7 @@ table#flags { float: right; } -.text_input, .bz_userfield, #keyword_container { +.text_input, .bz_userfield, #keywords_container, #tag_container { width: 100%; } .bz_bug .bz_alias_short_desc_container { diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl index d7c564fdb..d8803e677 100644 --- a/template/en/default/bug/edit.html.tmpl +++ b/template/en/default/bug/edit.html.tmpl @@ -523,11 +523,20 @@ [% INCLUDE bug/field.html.tmpl bug = bug, field = bug_fields.keywords, value = bug.keywords editable = bug.check_can_change_field("keywords", 0, 1), - no_tds = 1 + no_tds = 1, possible_values = all_keywords %] </td> </tr> [% END %] + + [% IF user.id %] + <tr> + [% INCLUDE bug/field.html.tmpl + bug = bug, field = bug_fields.tag, value = bug.tags.join(", "), + editable = 1, possible_values = user.tags.keys + %] + </tr> + [% END %] [% END %] [%############################################################################%] diff --git a/template/en/default/bug/field-help.none.tmpl b/template/en/default/bug/field-help.none.tmpl index a74de2e32..f76fa9639 100644 --- a/template/en/default/bug/field-help.none.tmpl +++ b/template/en/default/bug/field-help.none.tmpl @@ -137,6 +137,13 @@ status_whiteboard => "Each $terms.bug has a free-form single line text entry box for" _ " adding tags and status information.", +tag => + "Unlike ${vars.field_descs.keywords} which are global and visible by + all users, ${vars.field_descs.tag} are personal and can only be + viewed and edited by their author. + Editing them won't send any notification to other users. Use them + to tag and keep track of ${terms.bugs}.", + target_milestone => "The $vars.field_descs.target_milestone field is used to define when the" _ " engineer the $terms.bug is assigned to expects to fix it.", diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl index 0cc75c288..e6660256f 100644 --- a/template/en/default/bug/field.html.tmpl +++ b/template/en/default/bug/field.html.tmpl @@ -171,19 +171,21 @@ </script> [% END %] [% CASE constants.FIELD_TYPE_KEYWORDS %] - <div id="keyword_container"> + <div id="[% field.name FILTER html %]_container"> <input type="text" id="[% field.name FILTER html %]" size="40" class="text_input" name="[% field.name FILTER html %]" value="[% value FILTER html %]"> - <div id="keyword_autocomplete"></div> + <div id="[% field.name FILTER html %]_autocomplete"></div> </div> <script type="text/javascript" defer="defer"> - YAHOO.bugzilla.keyword_array = [ - [%- FOREACH keyword = all_keywords %] - [%-# %]"[% keyword.name FILTER js %]" + if (typeof YAHOO.bugzilla.field_array === "undefined") + YAHOO.bugzilla.field_array = []; + YAHOO.bugzilla.field_array["[% field.name FILTER js %]"] = [ + [%- FOREACH val = possible_values %] + [%-# %]"[% val FILTER js %]" [%- "," IF NOT loop.last %][% END %]]; - YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]', - 'keyword_autocomplete'); + YAHOO.bugzilla.fieldAutocomplete.init('[% field.name FILTER js %]', + '[% field.name FILTER js %]_autocomplete'); </script> [% END %] [% ELSE %] diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 31a686a00..e3cfec8a2 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -177,10 +177,6 @@ 'series.frequency * 2', ], -'global/per-bug-queries.html.tmpl' => [ - '" value=\"$bugids\"" IF bugids', -], - 'global/select-menu.html.tmpl' => [ 'options', 'size', diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl index 27926c802..5f956c714 100644 --- a/template/en/default/global/field-descs.none.tmpl +++ b/template/en/default/global/field-descs.none.tmpl @@ -118,7 +118,7 @@ "settings" => "Settings", "short_desc" => "Summary", "status_whiteboard" => "Whiteboard", - "tag.name" => "Tags", + "tag" => "Tags", "target_milestone" => "Target Milestone", "version" => "Version", "work_time" => "Hours Worked", diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index dcaf4b81a..fe5029ebc 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -849,18 +849,6 @@ The cookie that was remembering your login is now gone. [% END %] - [% ELSIF message_tag == "tag_updated" %] - [% title = "Tag Updated" %] - The '<a href="buglist.cgi?tag=[% tag FILTER uri %]">[% tag FILTER html %]</a>' - tag has been - [% IF action == "add" %] - added to - [% ELSE %] - removed from - [% END %] - [%+ buglist.size > 1 ? terms.bugs : terms.bug %] - [%+ buglist.join(", ") FILTER html %]. - [% ELSIF message_tag == "term" %] [% terms.$term FILTER html %] diff --git a/template/en/default/global/per-bug-queries.html.tmpl b/template/en/default/global/per-bug-queries.html.tmpl deleted file mode 100644 index 766c71332..000000000 --- a/template/en/default/global/per-bug-queries.html.tmpl +++ /dev/null @@ -1,88 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% IF user.id && user.settings.per_bug_queries.value == "on" %] - <li id="links-special"> - <script type="text/javascript"> - <!-- - function update_text() { - // 'lob' means list_of_bugs. - var lob_action = document.getElementById('lob_action'); - var action = lob_action.options[lob_action.selectedIndex].value; - var text = document.getElementById('lob_direction'); - var new_query_text = document.getElementById('lob_new_query_text'); - - if (action == "add") { - text.innerHTML = "to"; - new_query_text.style.display = 'inline'; - } - else { - text.innerHTML = "from"; - new_query_text.style.display = 'none'; - } - } - - function manage_old_lists() { - var old_lists = document.getElementById('lob_oldqueryname'); - // If there is no saved searches available, returns. - if (!old_lists) return; - - var new_query = document.getElementById('lob_newqueryname').value; - - if (new_query != "") { - old_lists.disabled = true; - } - else { - old_lists.disabled = false; - } - } - //--> - </script> - - <div class="label"></div> - <ul class="links"><li class="form"> - <form id="list_of_bugs" action="buglist.cgi" method="get"> - <input type="hidden" name="cmdtype" value="doit"> - <input type="hidden" name="remtype" value="asnamed"> - <input type="hidden" name="list_of_bugs" value="1"> - <input type="hidden" name="token" value="[% issue_hash_token(['savedsearch']) FILTER html %]"> - <select id="lob_action" name="action" onchange="update_text();"> - <option value="add">Add</option> - [% IF user.tags.size %] - <option value="remove">Remove</option> - [% END %] - </select> - - [% IF Param('docs_urlbase') %] - <a href="[% docs_urlbase FILTER html %]query.html#individual-buglists">the named tag</a> - [% ELSE %] - the named tag - [% END %] - - [% IF user.tags.size %] - <select id="lob_oldqueryname" name="oldqueryname"> - [% FOREACH tag = user.tags.keys %] - <option value="[% tag FILTER html %]">[% tag FILTER html %]</option> - [% END %] - </select> - [% END %] - <span id="lob_new_query_text"> - [% " or create and add the tag" IF user.tags.size %] - <input class="txt" type="text" id="lob_newqueryname" - size="20" maxlength="64" name="newqueryname" - onkeyup="manage_old_lists();"> - </span> - <span id="lob_direction">to</span> - [%+ terms.bugs %] - <input type="text" name="bug_ids" size="12" maxlength="80" - [%- " value=\"$bugids\"" IF bugids %]> - <input type="submit" value="Commit" id="commit_list_of_bugs"> - </form> - </li></ul> - </li> -[% END %] diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl index 28ecad755..f2dd43de5 100644 --- a/template/en/default/global/setting-descs.none.tmpl +++ b/template/en/default/global/setting-descs.none.tmpl @@ -18,7 +18,6 @@ "off" => "Off", "oldest_to_newest" => "Oldest to Newest", "on" => "On", - "per_bug_queries" => "Enable tags for $terms.bugs", "post_bug_submit_action" => "After changing $terms.abug", "next_bug" => "Show next $terms.bug in my list", "same_bug" => "Show the updated $terms.bug", diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl index ea14be8fe..1b5ba9a30 100644 --- a/template/en/default/global/useful-links.html.tmpl +++ b/template/en/default/global/useful-links.html.tmpl @@ -58,8 +58,6 @@ [%# Individual bugs addition %] - [% PROCESS "global/per-bug-queries.html.tmpl" %] - [%# Sections of links to more things users can do on this installation. %] [% Hook.process("end") %] </ul> diff --git a/template/en/default/search/field.html.tmpl b/template/en/default/search/field.html.tmpl index d3f71ae3f..dd5e1fac7 100644 --- a/template/en/default/search/field.html.tmpl +++ b/template/en/default/search/field.html.tmpl @@ -35,20 +35,22 @@ types = types, selected = type_selected %] - <div id="keyword_container"> + <div id="[% field.name FILTER html %]_container"> <input name="[% field.name FILTER html %]" id="[% field.name FILTER html %]" size="40" [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %] value="[% value FILTER html %]"> - <div id="keyword_autocomplete"></div> + <div id="[% field.name FILTER html %]_autocomplete"></div> </div> <script type="text/javascript" defer="defer"> - YAHOO.bugzilla.keyword_array = [ - [%- FOREACH keyword = all_keywords %] - [%-# %]"[% keyword.name FILTER js %]" + if (typeof YAHOO.bugzilla.field_array === "undefined") + YAHOO.bugzilla.field_array = []; + YAHOO.bugzilla.field_array["[% field.name FILTER js %]"] = [ + [%- FOREACH val = possible_values %] + [%-# %]"[% val FILTER js %]" [%- "," IF NOT loop.last %][% END %]]; - YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]', - 'keyword_autocomplete'); + YAHOO.bugzilla.fieldAutocomplete.init('[% field.name FILTER js %]', + '[% field.name FILTER js %]_autocomplete'); </script> [% CASE constants.FIELD_TYPE_DATETIME %] [% INCLUDE "bug/field-label.html.tmpl" diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl index 4b7ac4b07..fc6f597cf 100644 --- a/template/en/default/search/form.html.tmpl +++ b/template/en/default/search/form.html.tmpl @@ -142,6 +142,7 @@ TUI_hide_default('information_query'); %] <div class="search_field_row"> [% type = field_container.field.name _ "_type" %] + [% possible_values = field_container.field.name == 'keywords' ? all_keywords : [] %] [% INCLUDE "search/field.html.tmpl" field => field_container.field types => field_container.qtypes || query_types |