]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1541617 - Allow Products to set a default bug type.
authorKohei Yoshino <kohei.yoshino@gmail.com>
Thu, 25 Apr 2019 21:55:58 +0000 (17:55 -0400)
committerGitHub <noreply@github.com>
Thu, 25 Apr 2019 21:55:58 +0000 (17:55 -0400)
12 files changed:
Bugzilla/Component.pm
Bugzilla/DB/Schema.pm
Bugzilla/Install/DB.pm
Bugzilla/Product.pm
Bugzilla/WebService/Product.pm
docs/en/rst/api/core/v1/product.rst
editproducts.cgi
template/en/default/admin/components/edit-common.html.tmpl
template/en/default/admin/default_select.html.tmpl [new file with mode: 0644]
template/en/default/admin/products/edit-common.html.tmpl
template/en/default/admin/products/list.html.tmpl
template/en/default/admin/products/updated.html.tmpl

index 2869e8edaaaee4ed6356f59b42cbdab4efa87df7..73a258d31b4d2a2ccb0ff806d87cecbbfb188a56 100644 (file)
@@ -204,10 +204,14 @@ sub _check_description {
 }
 
 sub _check_default_bug_type {
-  my ($invocant, $type) = @_;
-  return $type if Bugzilla::Config::Common::check_bug_type($type) eq '';
-  # Ignore silently just in case
-  return undef;
+  my ($invocant, $type, undef, $params) = @_;
+  my $product = blessed($invocant) ? $invocant->product : $params->{product};
+
+  # Reset if the specified bug type is the same as the product's default bug
+  # type or if there's any error in validation
+  return undef if $type eq $product->default_bug_type
+    || Bugzilla::Config::Common::check_bug_type($type) ne '';
+  return $type;
 }
 
 sub _check_initialowner {
@@ -385,7 +389,7 @@ sub bug_ids {
 }
 
 sub default_bug_type {
-  return $_[0]->{'default_bug_type'} ||= Bugzilla->params->{'default_bug_type'};
+  return $_[0]->{'default_bug_type'} ||= $_[0]->product->default_bug_type;
 }
 
 sub default_assignee {
@@ -596,8 +600,8 @@ Component.pm represents a Product Component object.
 =item C<default_bug_type()>
 
  Description: Returns the default type for bugs filed under this component.
-              Returns the installation's global default bug type if the
-              component's specific type is not set.
+              Returns the product's default type or the installation's global
+              default type if the component-specific default type is not set.
 
  Params:      none.
 
index 5ecc186cfeea66d204f409d0dca7497c2077b76e..9eb386047148704784d0e8ffc821c580b96063ea 100644 (file)
@@ -1422,6 +1422,7 @@ use constant ABSTRACT_SCHEMA => {
       defaultmilestone   => {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"},
       allows_unconfirmed => {TYPE => 'BOOLEAN',     NOTNULL => 1, DEFAULT => 'TRUE'},
       bug_description_template => {TYPE => 'MEDIUMTEXT'},
+      default_bug_type  => {TYPE => 'varchar(20)'},
     ],
     INDEXES => [products_name_idx => {FIELDS => ['name'], TYPE => 'UNIQUE'},],
   },
index a62fa5eb6b98000b17927da4ead6750aeabf33bd..e5a5e182a23a3c982af98ef251280cbb92fe9f76 100644 (file)
@@ -783,10 +783,10 @@ sub update_table_definitions {
   $dbh->bz_add_column('products', 'bug_description_template',
     {TYPE => 'MEDIUMTEXT'});
 
-  # Bug 1522341 - kohei.yoshino@gmail.com
+  # Bug 1522341, 1541617 - kohei.yoshino@gmail.com
   $dbh->bz_add_column('bugs', 'bug_type', {TYPE => 'varchar(20)'});
-  $dbh->bz_add_column('components', 'default_bug_type',
-    {TYPE => 'varchar(20)'});
+  $dbh->bz_add_column('components', 'default_bug_type', {TYPE => 'varchar(20)'});
+  $dbh->bz_add_column('products',   'default_bug_type', {TYPE => 'varchar(20)'});
 
   _add_oauth2_jwt_support();
 
index 341655c933e444ed155cfec64e87404552505103..2e56c64be038cfeb9e88b18ac1f70846699edca5 100644 (file)
@@ -45,6 +45,7 @@ use constant DB_COLUMNS => qw(
   classification_id
   description
   isactive
+  default_bug_type
   defaultmilestone
   allows_unconfirmed
 );
@@ -52,6 +53,7 @@ use constant DB_COLUMNS => qw(
 use constant UPDATE_COLUMNS => qw(
   name
   description
+  default_bug_type
   defaultmilestone
   isactive
   allows_unconfirmed
@@ -64,6 +66,7 @@ use constant VALIDATORS => {
   name               => \&_check_name,
   description        => \&_check_description,
   version            => \&_check_version,
+  default_bug_type   => \&_check_default_bug_type,
   defaultmilestone   => \&_check_default_milestone,
   isactive           => \&Bugzilla::Object::check_boolean,
   create_series      => \&Bugzilla::Object::check_boolean
@@ -417,6 +420,13 @@ sub _check_version {
   return $version;
 }
 
+sub _check_default_bug_type {
+  my ($invocant, $type) = @_;
+  return $type if Bugzilla::Config::Common::check_bug_type($type) eq '';
+  # Ignore silently just in case
+  return undef;
+}
+
 sub _check_default_milestone {
   my ($invocant, $milestone) = @_;
 
@@ -519,6 +529,7 @@ sub _create_series {
 
 sub set_name               { $_[0]->set('name',               $_[1]); }
 sub set_description        { $_[0]->set('description',        $_[1]); }
+sub set_default_bug_type   { $_[0]->set('default_bug_type',   $_[1]); }
 sub set_default_milestone  { $_[0]->set('defaultmilestone',   $_[1]); }
 sub set_is_active          { $_[0]->set('isactive',           $_[1]); }
 sub set_allows_unconfirmed { $_[0]->set('allows_unconfirmed', $_[1]); }
@@ -914,6 +925,10 @@ sub bug_description_template {
   return $self->{'bug_description_template'};
 }
 
+sub default_bug_type {
+  return $_[0]->{'default_bug_type'} ||= Bugzilla->params->{'default_bug_type'};
+}
+
 ###############################
 ####      Subroutines    ######
 ###############################
@@ -963,6 +978,7 @@ Bugzilla::Product - Bugzilla product class.
     my $name             = $product->name;
     my $description      = $product->description;
     my isactive          = $product->is_active;
+    my $default_bug_type = $product->default_bug_type;
     my $defaultmilestone = $product->default_milestone;
     my $classificationid = $product->classification_id;
     my $allows_unconfirmed = $product->allows_unconfirmed;
@@ -990,6 +1006,17 @@ below.
 
  Returns:     An array of Bugzilla::Component object.
 
+=item C<default_bug_type()>
+
+ Description: Returns the default type for bugs filed under this product.
+              Returns the installation's global default type if the
+              product-specific default type is not set. Each component can
+              override this value.
+
+ Params:      none.
+
+ Returns:     A string.
+
 =item C<group_controls()>
 
  Description: Returns a hash (group id as key) with all product
index 0726c371dcb571b5cd793f7aa3cfd245f11296d2..cc119b2d63d05306c50b2005c3c25c6a4f0b0554 100644 (file)
@@ -154,6 +154,7 @@ sub create {
     name             => $params->{name},
     description      => $params->{description},
     version          => $params->{version},
+    default_bug_type => $params->{default_bug_type},
     defaultmilestone => $params->{default_milestone},
 
     # create_series has no default value.
@@ -182,6 +183,7 @@ sub _product_to_hash {
     default_milestone => $self->type('string',  $product->default_milestone),
     has_unconfirmed   => $self->type('boolean', $product->allows_unconfirmed),
     classification    => $self->type('string',  $product->classification->name),
+    default_bug_type  => $self->type('string',  $product->default_bug_type),
   };
   if (filter_wants($params, 'components')) {
     $field_data->{components}
@@ -221,6 +223,7 @@ sub _component_to_hash {
     sort_key =>    # sort_key is returned to match Bug.fields
       0,
     is_active => $self->type('boolean', $component->is_active),
+    default_bug_type => $self->type('string', $component->default_bug_type),
     },
     undef, 'components';
 
@@ -492,6 +495,10 @@ C<string> A description of the product, which may contain HTML.
 
 C<boolean> A boolean indicating if the product is active.
 
+=item C<default_bug_type>
+
+C<string> The default type for bugs filed under this product.
+
 =item C<default_milestone>
 
 C<string> The name of the default milestone for the product.
@@ -531,6 +538,10 @@ C<string> A description of the component, which may contain HTML.
 C<string> The login name of the user to whom new bugs will be assigned by
 default.
 
+=item C<default_bug_type>
+
+C<string> The default type for bugs filed under this component.
+
 =item C<default_qa_contact>
 
 C<string> The login name of the user who will be set as the QA Contact for
@@ -702,6 +713,11 @@ Default: true.
 
 C<string> The name of the Classification which contains this product.
 
+=item C<default_bug_type>
+
+C<string> The default type for bugs filed under this product. Each component can
+override this value.
+
 =item C<default_milestone>
 
 C<string> The default milestone for this product. Default: '---'.
index a1f5bd3c892a4e4fa6c2a5090141ffc5ef9fc5c3..0b96f782397ba667a9a51eb4cef1d06d37823139 100644 (file)
@@ -101,11 +101,13 @@ type        string  The group of products to return. Valid values are
      "products": [
        {
          "id": 1,
+         "default_bug_type": "defect",
          "default_milestone": "---",
          "components": [
            {
              "is_active": true,
              "default_assigned_to": "admin@bugzilla.org",
+             "default_bug_type": "defect",
              "id": 1,
              "sort_key": 0,
              "name": "TestComponent",
@@ -182,6 +184,7 @@ name               string   The name of the product. This is a unique identifier
                             for the product.
 description        string   A description of the product, which may contain HTML.
 is_active          boolean  A boolean indicating if the product is active.
+default_bug_type   string   The default type for bugs filed under this product.
 default_milestone  string   The name of the default milestone for the product.
 has_unconfirmed    boolean  Indicates whether the UNCONFIRMED bug status is
                             available for this product.
@@ -213,6 +216,8 @@ description          string   A description of the component, which may contain
                               HTML.
 default_assigned_to  string   The login name of the user to whom new bugs
                               will be assigned by default.
+default_bug_type     string   The default type for bugs filed under this
+                              component.
 default_qa_contact   string   The login name of the user who will be set as
                               the QA Contact for new bugs by default. Empty
                               string if the QA contact is not defined.
@@ -300,6 +305,8 @@ has_unconfirmed    boolean  Allow the UNCONFIRMED status to be set on bugs in
                             this product. Default: true.
 classification     string   The name of the Classification which contains this
                             product.
+default_bug_type   string   The default type for bugs filed under this product.
+                            Each component can override this value.
 default_milestone  string   The default milestone for this product. Default
                             '---'.
 is_open            boolean  ``true`` if the product is currently allowing bugs
@@ -385,6 +392,8 @@ name               type     description
 name               string   A new name for this product. If you try to set this
                             while updating more than one product, an error will
                             occur, as product names must be unique.
+default_bug_type   string   The default type for bugs filed under this product.
+                            Each component can override this value.
 default_milestone  string   When a new bug is filed, what milestone does it
                             get by default if the user does not choose one? Must
                             represent a milestone that is valid for this product.
index ad55a47fa1d141215115d07a37552a04c4199c77..97254489249d2699c228aa1cc555262216b7dfb0 100755 (executable)
@@ -166,6 +166,7 @@ if ($action eq 'new') {
     create_series      => scalar $cgi->param('createseries'),
     allows_unconfirmed => scalar $cgi->param('allows_unconfirmed'),
     bug_description_template => scalar $cgi->param('bug_description_template'),
+    default_bug_type   => scalar $cgi->param('default_bug_type'),
   );
   my $product = Bugzilla::Product->create(\%create_params);
 
@@ -285,6 +286,7 @@ if ($action eq 'update') {
     allows_unconfirmed => scalar $cgi->param('allows_unconfirmed'),
     default_milestone  => scalar $cgi->param('defaultmilestone'),
     bug_description_template => scalar $cgi->param('bug_description_template'),
+    default_bug_type   => scalar $cgi->param('default_bug_type'),
   });
 
   my $changes = $product->update();
index 4d9f183b3ec71eb8cb6d7bf80dd05a6d1c570e7e..cbeda3a7b2d4bb66b6f2a6f81eaf1cafda59f4a5 100644 (file)
@@ -43,9 +43,9 @@
 <tr>
   <th class="field_label"><label for="default_bug_type">Default [% terms.Bug %] Type:</label></th>
   <td>
-    [% INCLUDE default_select
+    [% INCLUDE admin/default_select.html.tmpl
         field_name   = 'default_bug_type'
-        field_value  = comp.default_bug_type
+        field_value  = comp.default_bug_type || product.default_bug_type
         field_values = bug_fields.bug_type.legal_values
     %]
   </td>
 </tr>
 
 [% Hook.process('rows') %]
-
-[% BLOCK default_select %]
-  <select name="[% field_name FILTER html %]">
-    [% FOREACH v IN field_values %]
-      <option value="[% v.value FILTER html %]" [% " selected" IF field_value == v.value %]>
-        [% v.value FILTER html %]
-      </option>
-    [% END %]
-  </select>
-[% END %]
diff --git a/template/en/default/admin/default_select.html.tmpl b/template/en/default/admin/default_select.html.tmpl
new file mode 100644 (file)
index 0000000..3fb0d8c
--- /dev/null
@@ -0,0 +1,15 @@
+[%# 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.
+  #%]
+
+<select name="[% field_name FILTER html %]">
+  [% FOREACH v IN field_values %]
+    <option value="[% v.value FILTER html %]" [% " selected" IF field_value == v.value %]>
+      [% v.value FILTER html %]
+    </option>
+  [% END %]
+</select>
index 05ec2864b3eeaede4ecb05126be22475382b2747..ed778bce08a90b39e2e47adadcc941bb64999c3e 100644 (file)
         [% product.bug_description_template FILTER html %]</textarea>
   </td>
 </tr>
+<tr>
+  <th align="right">Default [% terms.Bug %] Type:</th>
+  <td>
+    [% INCLUDE admin/default_select.html.tmpl
+        field_name   = 'default_bug_type'
+        field_value  = product.default_bug_type
+        field_values = bug_fields.bug_type.legal_values
+    %]
+  </td>
+</tr>
 
 [% IF Param('usetargetmilestone') -%]
   <tr>
index c211c65ef38d678667816c67f3905d21b0b112db..295b6750911bb72cfb5009bf3b2611296957f56b 100644 (file)
        heading => "Description"
        allow_html_content => 1
      },
+     {
+       name => "default_bug_type"
+       heading => "Default $terms.Bug Type"
+     },
      {
        name => "is_active"
        heading => "Open For New $terms.Bugs"
index 98d1d7b2763daacec9912b19eb98ac7a3a43c846..ba4c69865f3a1df9dadeebe5462f62489da33704 100644 (file)
   </p>
 [% END %]
 
+[% IF changes.default_bug_type.defined %]
+  <p>
+  Updated default [% terms.bug %] type from '[% changes.default_bug_type.0 FILTER html %]' to
+  '[% product.default_bug_type FILTER html %]'.
+  </p>
+[% END %]
+
 [% IF changes.defaultmilestone.defined %]
   <p>
   Updated default milestone from '[% changes.defaultmilestone.0 FILTER html %]' to