]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 69267: Add the ability to deactivate keywords
authorDylan William Hardison <dylan@mozilla.com>
Fri, 1 May 2015 04:03:57 +0000 (00:03 -0400)
committerDylan William Hardison <dylan@hardison.net>
Fri, 1 May 2015 04:03:57 +0000 (00:03 -0400)
r/a=glob

14 files changed:
Bugzilla/Bug.pm
Bugzilla/DB/Schema.pm
Bugzilla/Install/DB.pm
Bugzilla/Keyword.pm
Bugzilla/Template.pm
Bugzilla/WebService/Bug.pm
docs/en/rst/administering/keywords.rst
editkeywords.cgi
template/en/default/admin/keywords/edit.html.tmpl
template/en/default/admin/keywords/list.html.tmpl
template/en/default/bug/create/create.html.tmpl
template/en/default/bug/edit.html.tmpl
template/en/default/global/user-error.html.tmpl
template/en/default/reports/keywords.html.tmpl

index 2f34d55e749f92b21f50a42f8e2da40e0581ac3d..6fcf14c5a15fb337b124c3546c4c1b542e585008 100644 (file)
@@ -1851,6 +1851,20 @@ sub _check_keywords {
         my $obj = Bugzilla::Keyword->check($keyword);
         $keywords{$obj->id} = $obj;
     }
+
+    my %old_kw_id;
+    if (blessed $invocant) {
+        my @old_keywords = @{$invocant->keyword_objects};
+        %old_kw_id  = map { $_->id => 1 } @old_keywords;
+    }
+
+    foreach my $keyword (values %keywords) {
+        next if $keyword->is_active || exists $old_kw_id{$keyword->id};
+
+        ThrowUserError('value_inactive',
+                        { value  => $keyword->name, class => ref $keyword });
+    }
+
     return [values %keywords];
 }
 
index d340cf03d9ed09dee834a7c9985bee48a1600d38..c089513e303ef4db26e6453efdbcb539abe85165 100644 (file)
@@ -588,6 +588,8 @@ use constant ABSTRACT_SCHEMA => {
                             PRIMARYKEY => 1},
             name        => {TYPE => 'varchar(64)', NOTNULL => 1},
             description => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
+            is_active   => {TYPE => 'BOOLEAN', NOTNULL => 1,
+                            DEFAULT => 'TRUE'},
         ],
         INDEXES => [
             keyworddefs_name_idx   => {FIELDS => ['name'],
@@ -605,7 +607,6 @@ use constant ABSTRACT_SCHEMA => {
                           REFERENCES => {TABLE  => 'keyworddefs',
                                          COLUMN => 'id',
                                          DELETE => 'CASCADE'}},
-
         ],
         INDEXES => [
             keywords_bug_id_idx    => {FIELDS => [qw(bug_id keywordid)],
index ab02fe41db355cef59ce22cfa6082ab074e6d710..ddd127be2ee49bf5e4dea05b6c5d0bf864d9cd70 100644 (file)
@@ -730,6 +730,10 @@ sub update_table_definitions {
     $dbh->bz_add_column('longdescs', 'is_markdown',
                         {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
 
+    # 2014-11-18 dylan@mozilla.com - Bug 69267
+    $dbh->bz_add_column('keyworddefs', 'is_active',
+                        {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+
     ################################################################
     # New --TABLE-- changes should go *** A B O V E *** this point #
     ################################################################
index afa93e1e9ad2d155ff57bc16b4ae3dcc533bbe2a..ef044a0c544ebaf63c68d41258fa8fa6a90dd11e 100644 (file)
@@ -26,6 +26,7 @@ use constant DB_COLUMNS => qw(
    keyworddefs.id
    keyworddefs.name
    keyworddefs.description
+   keyworddefs.is_active
 );
 
 use constant DB_TABLE => 'keyworddefs';
@@ -33,11 +34,13 @@ use constant DB_TABLE => 'keyworddefs';
 use constant VALIDATORS => {
     name        => \&_check_name,
     description => \&_check_description,
+    is_active   => \&_check_is_active,
 };
 
 use constant UPDATE_COLUMNS => qw(
     name
     description
+    is_active
 );
 
 ###############################
@@ -62,6 +65,7 @@ sub bug_count {
 
 sub set_name        { $_[0]->set('name', $_[1]); }
 sub set_description { $_[0]->set('description', $_[1]); }
+sub set_is_active   { $_[0]->set('is_active', $_[1]); }
 
 ###############################
 ####      Subroutines    ######
@@ -125,6 +129,10 @@ sub _check_description {
     return $desc;
 }
 
+sub _check_is_active { return $_[1] ? 1 : 0 }
+
+sub is_active { return $_[0]->{is_active} }
+
 1;
 
 __END__
@@ -145,13 +153,13 @@ Bugzilla::Keyword - A Keyword that can be added to a bug.
 
 Bugzilla::Keyword represents a keyword that can be added to a bug.
 
-This implements all standard C<Bugzilla::Object> methods. See 
+This implements all standard C<Bugzilla::Object> methods. See
 L<Bugzilla::Object> for more details.
 
-=head1 SUBROUTINES
+=head1 METHODS
 
-This is only a list of subroutines specific to C<Bugzilla::Keyword>.
-See L<Bugzilla::Object> for more subroutines that this object 
+This is only a list of methods specific to C<Bugzilla::Keyword>.
+See L<Bugzilla::Object> for more methods that this object
 implements.
 
 =over
@@ -166,6 +174,18 @@ implements.
  Returns:     A reference to an array of Keyword objects, or an empty
               arrayref if there are no keywords.
 
+=item C<is_active>
+
+ Description: Indicates if the keyword may be used on a bug
+ Params:      none
+ Returns:     a boolean value that is true if the keyword can be applied to bugs.
+
+=item C<set_is_active($is_active)>
+
+ Description: Set the is_active property to a boolean value
+ Params:      the new value of the is_active property.
+ Returns:     nothing
+
 =back
 
 =cut
index de72cd71a04c280cac17fa40efb8bcd16f5ae63d..70a8197b51ebe80707dc41812d5945088aa27616 100644 (file)
@@ -1106,11 +1106,16 @@ sub create {
             # Whether or not keywords are enabled, in this Bugzilla.
             'use_keywords' => sub { return Bugzilla::Keyword->any_exist; },
 
-            # All the keywords.
+            # All the keywords
             'all_keywords' => sub {
                 return [map { $_->name } Bugzilla::Keyword->get_all()];
             },
 
+            # All the active keywords
+            'active_keywords' => sub {
+                return [map { $_->name } grep { $_->is_active } Bugzilla::Keyword->get_all()];
+            },
+
             'feature_enabled' => sub { return Bugzilla->feature(@_); },
 
             # field_descs can be somewhat slow to generate, so we generate
index fd01afb1b2088c24bba24313c3b0a530fe815636..f034d90d5d692603c52c11281fe89da748285450 100644 (file)
@@ -245,6 +245,7 @@ sub _legal_field_values {
     elsif ($field_name eq 'keywords') {
         my @legal_keywords = Bugzilla::Keyword->get_all;
         foreach my $value (@legal_keywords) {
+            next unless $value->is_active;
             push (@result, {
                name     => $self->type('string', $value->name),
                description => $self->type('string', $value->description),
index 245bcbe4c8dd1f44508e5ce45d24bedec084e9f5..d636e752c9690f1d8ff702f691eb13c4bd7688e7 100644 (file)
@@ -9,8 +9,6 @@ A company might have a policy stating all regressions
 must be fixed by the next release—this keyword can make tracking those
 bugs much easier. Keywords are global, rather than per product. 
 
-Keywords can be created, edited, or deleted by clicking the "Keywords"
+Keywords can be created, edited, deactivated, or deleted by clicking the "Keywords"
 link in the admin page. There are two fields for each keyword—the keyword
-itself and a brief description. Currently keywords cannot be marked obsolete
-to prevent future usage.
-
+itself and a brief description.
index 41496f3622956f675300861e1a8220b10e0e8882..06e28b79a820301c1683ef69bc2dad668c4efacc 100755 (executable)
@@ -71,11 +71,12 @@ if ($action eq 'add') {
 #
 if ($action eq 'new') {
     check_token_data($token, 'add_keyword');
-    my $name = $cgi->param('name') || '';
-    my $desc = $cgi->param('description')  || '';
+    my $name      = $cgi->param('name') || '';
+    my $is_active = $cgi->param('is_active');
+    my $desc      = $cgi->param('description')  || '';
 
     my $keyword = Bugzilla::Keyword->create(
-        { name => $name, description => $desc });
+        { name => $name, is_active => $is_active, description => $desc });
 
     delete_token($token);
 
@@ -123,6 +124,7 @@ if ($action eq 'update') {
     $keyword->set_all({
         name        => scalar $cgi->param('name'),
         description => scalar $cgi->param('description'),
+        is_active   => scalar $cgi->param('is_active'),
     });
     my $changes = $keyword->update();
 
index 23158d36fc60c6ce5e8930317754b45d2f51fb70..7e6617a848a615d1544383f6111e99d7ac8bca09 100644 (file)
 <form method="post" action="editkeywords.cgi">
   <table id="admin_table_edit">
     <tr>
-      <th>Name:</th>
-      <td><input size="64" maxlength="64" name="name" 
+      <th><label for="name">Name:</label></th>
+      <td><input size="64" maxlength="64" name="name" id="name"
                  value="[% keyword.name FILTER html %]" required></td>
     </tr>
     <tr>
-      <th>Description:</th>
+      <th><label for="is_active">Enabled For [% terms.Bugs %]</label></th>
+      <td><input id="is_active" name="is_active" type="checkbox" [% "checked" IF keyword.is_active %]></td>
+    </tr>
+    <tr>
+      <th><label for="decription">Description:</label></th>
       <td>
         [% INCLUDE global/textarea.html.tmpl
+          id             = 'description'
           name           = 'description'
           minrows        = 4
           cols           = 64
index c3f4a5292094cabd9cb2f7b8e838fcba38e7a06c..9d920036eb1a964c0a47bafdfee641ec2e474c86 100644 (file)
@@ -10,6 +10,7 @@
   # keywords: array keyword objects having the properties:
   #   - id: number. The ID of the keyword.
   #   - name: string. The name of the keyword.
+  #   - is_active: boolean. true if the keyword can be used.
   #   - description: string. The description of the keyword.
   #   - bug_count: number. The number of bugs with the keyword.
   #%]
 %]
 
 [% columns = [
-     { 
-       name => "name"
-       heading => "Edit keyword..."
-       contentlink => "editkeywords.cgi?action=edit&amp;id=%%id%%" 
-     },
-     { 
-       name => "description"
-       heading => "Description"
-       allow_html_content => 1
-     },
-     { 
-       name => "bug_count"
-       heading => "$terms.Bugs"
-       class => "right"
-       contentlink => "buglist.cgi?keywords=%%name%%"
-     },
-     { 
-       heading => "Action" 
-       content => "Delete"
-       contentlink => "editkeywords.cgi?action=del&amp;id=%%id%%"
-     }
-   ]
+    {
+        name        => "name"
+        heading     => "Edit keyword..."
+        contentlink => "editkeywords.cgi?action=edit&amp;id=%%id%%"
+    },
+    {
+        name        => "description"
+        heading     => "Description"
+        allow_html_content => 1
+    },
+    {
+        name        => "is_active",
+        heading     => "Active",
+        yesno_field => 1
+    },
+    {
+        name         => "bug_count"
+        heading      => "$terms.Bugs"
+        class        => "right"
+        contentlink  => "buglist.cgi?keywords=%%name%%"
+    },
+    {
+        heading     => "Action"
+        content     => "Delete"
+        contentlink => "editkeywords.cgi?action=del&amp;id=%%id%%"
+    }
+]
 %]
 
 [% PROCESS admin/table.html.tmpl
-     columns = columns
-     data = keywords
-     footer = footer_row
+    columns = columns
+    data    = keywords
+    footer  = footer_row
 %]
 
 <p><a href="editkeywords.cgi?action=add">Add a new keyword</a></p>
index 29b17d41017fd7d91284dee78d6c5af24426fc30..c9a7c7db99e596a4275e9ef0ed7a61fae32a24c2 100644 (file)
@@ -537,7 +537,7 @@ TUI_hide_default('attachment_text_field');
     <tr>
       [% INCLUDE bug/field.html.tmpl
         bug = default, field = bug_fields.keywords, editable = 1,
-        value = keywords, possible_values = all_keywords,
+        value = keywords, possible_values = active_keywords,
         desc_url = "describekeywords.cgi", value_span = 3
       %]
     </tr>
index c5cf88f04399c1ba864b5f8f0b1527fdcfb5bebe..5402624f66412e84d0fb18b5eee330aa25de1daa 100644 (file)
         [% INCLUDE bug/field.html.tmpl
           bug = bug, field = bug_fields.keywords, value = bug.keywords
           editable = bug.check_can_change_field("keywords", 0, 1),
-          desc_url = "describekeywords.cgi", possible_values = all_keywords
+          desc_url = "describekeywords.cgi", possible_values = active_keywords
         %]
     </tr>
   [% END %]
index c74ba1efce794ea9875a0723fdb9eeb16dd04c78..8306657e3c8a133dba892ad3759cc50a94394beb 100644 (file)
       Either you mis-typed the name or that user has not yet registered
       for a [% terms.Bugzilla %] account.
     [% ELSIF class == "Bugzilla::Keyword" %]
-      See the list of available <a href="describekeywords.cgi">keywords</a>.
+      See the list of available <a href="describekeywords.cgi?show_inactive_keywords=1">keywords</a>.
     [% END %]
 
   [% ELSIF error == "old_password_incorrect" %]
index 598979d339783128d6cd8e99ecdb8a58fcb1ed3b..6e7ad0c50aa9989540a5b3337decc5c409aa1222 100644 (file)
   title = "$terms.Bugzilla Keyword Descriptions"
   style_urls = ['skins/standard/admin.css']
 %]
+[% cgi = Bugzilla.cgi %]
+[% show_inactive_keywords = cgi.param("show_inactive_keywords") %]
 
-<table id="admin_table">
+<script>
+ $(document).ready(function () {
+     var show_inactive_keywords = [% show_inactive_keywords ? "true" : "false" FILTER none %];
+         link = $("#keywords_show_hide"),
+         rows = $("tr.keyword_inactive");
+
+     link.click(function (event) {
+         if (show_inactive_keywords) {
+             show_inactive_keywords = false;
+             rows.show();
+             link.html("Hide inactive keywords");
+         }
+         else {
+             show_inactive_keywords = true;
+             rows.hide();
+             link.html("Show inactive keywords");
+         }
+         event.preventDefault();
+     }).click();
+ });
+</script>
+
+<p>
+  <a href="[% urlbase FILTER html %]?show_inactive_keywords=[% show_inactive_keywords ? "1" : "0" FILTER none %]"
+     id="keywords_show_hide">[% show_inactive_keywords ? "Show" : "Hide" FILTER html %] inactive keywords</a>
+</p>
+
+<table id="admin_table" class="describe_keywords">
   <tr class="column_header">
     <th>Name</th>
     <th>Description</th>
+    <th>Active</th>
     <th>Open [% terms.Bugs %]</th>
     <th>Total [% terms.Bugs %]</th>
   </tr>
 
   [% FOREACH keyword = keywords %]
-  <tr id="[% keyword.name FILTER html %]">
-    <td>[% keyword.name FILTER html %]</td>
-    <td>[% keyword.description FILTER html_light %]</td>
-    <td class="center">
-      [% IF keyword.bug_count > 0 %]
-        <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]&amp;resolution=---">
-          Search</a>
-      [% ELSE %]
-        none
-      [% END %]
-    </td>
-    <td class="right">
-      [% IF keyword.bug_count > 0 %]
-        <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]">
-          [% keyword.bug_count %]</a>
-      [% ELSE %]
-        none
-      [% END %]
-    </td>
-  </tr>
+    <tr id="[% keyword.name FILTER html %]" class="[% keyword.is_active ? "keyword_active" : "keyword_inactive" FILTER html %]">
+      <td>[% keyword.name FILTER html %]</td>
+      <td>[% keyword.description FILTER html_light %]</td>
+      <td>[% keyword.is_active ? "Yes" : "No" FILTER html %]</td>
+      <td class="center">
+        [% IF keyword.bug_count > 0 %]
+          <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]&amp;resolution=---">
+            Search</a>
+        [% ELSE %]
+          none
+        [% END %]
+      </td>
+      <td class="right">
+        [% IF keyword.bug_count > 0 %]
+          <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]">
+            [% keyword.bug_count %]</a>
+        [% ELSE %]
+          none
+        [% END %]
+      </td>
+    </tr>
   [% END %]
 </table>