]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
ug 1268317 - Add Triage Contact to Components as an Editable Field (everything else)
authorDavid Lawrence <dkl@mozilla.com>
Tue, 27 Sep 2016 13:55:12 +0000 (13:55 +0000)
committerDavid Lawrence <dkl@mozilla.com>
Tue, 27 Sep 2016 13:55:12 +0000 (13:55 +0000)
12 files changed:
Bugzilla/Component.pm
Bugzilla/Field.pm
Bugzilla/Search.pm
editcomponents.cgi
extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
extensions/BugModal/web/bug_modal.js
template/en/default/admin/components/confirm-delete.html.tmpl
template/en/default/admin/components/edit-common.html.tmpl
template/en/default/bug/edit.html.tmpl
template/en/default/global/confirm-user-match.html.tmpl
template/en/default/global/field-descs.none.tmpl
template/en/default/global/messages.html.tmpl

index b44f787334667cfbc9dc82cfcd6c0339f0c6bd0d..68024c2fa81541ca0e9a5287fb270e8c403981cf 100644 (file)
@@ -38,6 +38,7 @@ use constant DB_COLUMNS => qw(
     initialqacontact
     description
     isactive
+    triage_owner_id
 );
 
 use constant UPDATE_COLUMNS => qw(
@@ -46,6 +47,7 @@ use constant UPDATE_COLUMNS => qw(
     initialqacontact
     description
     isactive
+    triage_owner_id
 );
 
 use constant REQUIRED_FIELD_MAP => {
@@ -61,6 +63,7 @@ use constant VALIDATORS => {
     initial_cc       => \&_check_cc_list,
     name             => \&_check_name,
     isactive         => \&Bugzilla::Object::check_boolean,
+    triage_owner_id  => \&_check_triage_owner,
 };
 
 use constant VALIDATOR_DEPENDENCIES => {
@@ -242,6 +245,13 @@ sub _check_cc_list {
     return [keys %cc_ids];
 }
 
+sub _check_triage_owner {
+    my ($invocant, $triage_owner) = @_;
+    my $triage_owner_id;
+    $triage_owner_id = Bugzilla::User->check($triage_owner)->id if $triage_owner;
+    return $triage_owner_id;
+}
+
 ###############################
 ####       Methods         ####
 ###############################
@@ -317,6 +327,12 @@ sub set_cc_list {
     # Reset the list of CC user objects.
     delete $self->{initial_cc};
 }
+sub set_triage_owner {
+    my ($self, $triage_owner) = @_;
+    $self->set('triage_owner_id', $triage_owner);
+    # Reset the triage owner object
+    delete $self->{triage_owner};
+}
 
 sub bug_count {
     my $self = shift;
@@ -360,6 +376,17 @@ sub default_qa_contact {
     return $self->{'default_qa_contact'};
 }
 
+sub triage_owner {
+    my $self = shift;
+    if (!defined $self->{'triage_owner'}) {
+        my $params = $self->{'triage_owner_id'}
+                     ? { id => $self->{'triage_owner_id'}, cache => 1 }
+                     : $self->{'triage_owner_id'};
+        $self->{'triage_owner'} = Bugzilla::User->new($params);
+    }
+    return $self->{'triage_owner'};
+}
+
 sub flag_types {
     my ($self, $params) = @_;
     $params ||= {};
@@ -454,6 +481,7 @@ Bugzilla::Component - Bugzilla product component class.
     my $default_assignee   = $component->default_assignee;
     my $default_qa_contact = $component->default_qa_contact;
     my $initial_cc         = $component->initial_cc;
+    my $triage_owner       = $component->triage_owner;
     my $product            = $component->product;
     my $bug_flag_types     = $component->flag_types->{'bug'};
     my $attach_flag_types  = $component->flag_types->{'attachment'};
@@ -465,6 +493,7 @@ Bugzilla::Component - Bugzilla product component class.
                                     product          => $product,
                                     initialowner     => $user_login1,
                                     initialqacontact => $user_login2,
+                                    triage_owner     => $user_login3,
                                     description      => $description});
 
     $component->set_name($new_name);
@@ -472,6 +501,7 @@ Bugzilla::Component - Bugzilla product component class.
     $component->set_default_assignee($new_login_name);
     $component->set_default_qa_contact($new_login_name);
     $component->set_cc_list(\@new_login_names);
+    $component->set_triage_owner($new_triage_owner);
     $component->update();
 
     $component->remove_from_db;
@@ -542,6 +572,15 @@ Component.pm represents a Product Component object.
 
  Returns:     An arrayref of L<Bugzilla::User> objects.
 
+=item C<triage_owner>
+
+ Description: Returns the user responsible for performing triage on
+              bugs for this component.
+
+ Params:      none
+
+ Returns:     A Bugzilla::User object.
+
 =item C<flag_types()>
 
  Description: Returns all bug and attachment flagtypes available for
@@ -605,6 +644,12 @@ Component.pm represents a Product Component object.
 
  Returns:     Nothing.
 
+=item C<set_triage_owner>
+
+ Description: Changes the triage owner of the component.
+
+ Params:      $new_triage_owner - login name of the new triage owner (string).
+
 =item C<update()>
 
  Description: Write changes made to the component into the DB.
@@ -644,6 +689,7 @@ Component.pm represents a Product Component object.
                                 or an empty string to clear it.
               initial_cc      - an arrayref of login names to add to the
                                 CC list by default.
+              triage_owner    - login name of the default triage owner
 
  Returns:     A Bugzilla::Component object.
 
index a9e12411557732d1d42d548cf4f1d0efebf8a787..c468959245cb22f240bf1b8d2dd800408bce656a 100644 (file)
@@ -265,6 +265,7 @@ use constant DEFAULT_FIELDS => (
     {name => 'bug_interest_ts',       desc => 'Bug Interest', buglist => 1,
      type => FIELD_TYPE_DATETIME},
     {name => 'comment_tag',           desc => 'Comment Tag'},
+    {name => 'triage_owner',          desc => 'Triage Owner', buglist => 1},
 );
 
 ################
index 19419817a56c54739f23993fb0745a65a34b0ab0..cddedb3f03b05a38d77f1e18e5c566be35504318 100644 (file)
@@ -336,6 +336,9 @@ use constant OPERATOR_FIELD_OVERRIDE => {
         _non_changed => \&_bug_interest_ts,
         _default     => \&_invalid_operator,
     },
+    triage_owner => {
+        _non_changed => \&_triage_owner_nonchanged,
+    },
     # Custom Fields
     FIELD_TYPE_FREETEXT, { _non_changed => \&_nullable },
     FIELD_TYPE_BUG_ID,   { _non_changed => \&_nullable_int },
@@ -371,6 +374,9 @@ sub SPECIAL_PARSING {
 
         # BMO - Add ability to use pronoun for bug mentors field
         bug_mentor => \&_commenter_pronoun,
+
+        # BMO - add ability to use pronoun for triage owners
+        triage_owner => \&_triage_owner_pronoun,
     };
     foreach my $field (Bugzilla->active_custom_fields) {
         if ($field->type == FIELD_TYPE_DATETIME) {
@@ -447,6 +453,7 @@ use constant SPECIAL_ORDER => {
 use constant COLUMN_DEPENDS => {
     classification      => ['product'],
     percentage_complete => ['actual_time', 'remaining_time'],
+    triage_owner        => ['component'],
 };
 
 # This describes tables that must be joined when you want to display
@@ -515,6 +522,13 @@ sub COLUMN_JOINS {
                 to    => 'id',
             },
         },
+        'triage_owner' => {
+            table => 'profiles',
+            as    => 'map_triage_owner',
+            from  => 'map_component.triage_owner_id',
+            to    => 'userid',
+            join  => 'LEFT',
+        },
         keywords => {
             table => 'keywords',
             then_to => {
@@ -625,6 +639,13 @@ sub COLUMNS {
         assignee_last_login => 'assignee.last_seen_date',
     );
 
+    if ($user->id) {
+        $special_sql{triage_owner} = 'map_triage_owner.login_name';
+    }
+    else {
+        $special_sql{triage_owner} = 'map_triage_owner.realname';
+    }
+
     # Backward-compatibility for old field names. Goes new_name => old_name.
     # These are here and not in _translate_old_column because the rest of the
     # code actually still uses the old names, while the fielddefs table uses
@@ -2444,6 +2465,22 @@ sub _commenter_pronoun {
     }
 }
 
+# XXX only works with %user% currently
+sub _triage_owner_pronoun {
+    my ($self, $args) = @_;
+    my $value = $args->{value};
+    my $user = $self->_user;
+    if ($value eq "%user%") {
+        if ($user->id) {
+            $args->{value} = $user->id;
+            $args->{quoted} = $args->{value};
+            $args->{value_is_id} = 1;
+        } else {
+            ThrowUserError('login_required_for_pronoun');
+        }
+    }
+}
+
 #####################################################################
 # Search Functions
 #####################################################################
@@ -2855,6 +2892,16 @@ sub _classification_nonchanged {
         "classifications.id", "classifications", $term);
 }
 
+sub _triage_owner_nonchanged {
+    my ($self, $args) = @_;
+    $self->_add_extra_column('triage_owner');
+    $args->{full_field} = $args->{value_is_id} ? 'profiles.userid' : 'profiles.login_name';
+    $self->_do_operator_function($args);
+    my $term = $args->{term};
+    $args->{term} = build_subselect('bugs.component_id', 'components.id',
+        'profiles JOIN components ON components.triage_owner_id = profiles.userid', $term);
+}
+
 sub _nullable {
     my ($self, $args) = @_;
     my $field = $args->{full_field};
index 9f59cda8fda05e9d5aa2bdc24d2f66457b8f8caa..6846fb4d9ff7a63b5bc6938f32035085d1f58b1c 100755 (executable)
@@ -107,12 +107,14 @@ if ($action eq 'new') {
     Bugzilla::User::match_field ({
         'initialowner'     => { 'type' => 'single' },
         'initialqacontact' => { 'type' => 'single' },
+        'triage_owner'     => { 'type' => 'single' },
         'initialcc'        => { 'type' => 'multi'  },
     });
 
     my $default_assignee   = trim($cgi->param('initialowner')     || '');
     my $default_qa_contact = trim($cgi->param('initialqacontact') || '');
     my $description        = trim($cgi->param('description')      || '');
+    my $triage_owner       = trim($cgi->param('triage_owner')     || '');
     my @initial_cc         = $cgi->param('initialcc');
     my $isactive           = $cgi->param('isactive');
 
@@ -123,6 +125,7 @@ if ($action eq 'new') {
         initialowner     => $default_assignee,
         initialqacontact => $default_qa_contact,
         initial_cc       => \@initial_cc,
+        triage_owner_id  => $triage_owner,
         # XXX We should not be creating series for products that we
         # didn't create series for.
         create_series    => 1,
@@ -209,6 +212,7 @@ if ($action eq 'update') {
     Bugzilla::User::match_field ({
         'initialowner'     => { 'type' => 'single' },
         'initialqacontact' => { 'type' => 'single' },
+        'triage_owner'     => { 'type' => 'single' },
         'initialcc'        => { 'type' => 'multi'  },
     });
 
@@ -216,6 +220,7 @@ if ($action eq 'update') {
     my $default_assignee      = trim($cgi->param('initialowner')     || '');
     my $default_qa_contact    = trim($cgi->param('initialqacontact') || '');
     my $description           = trim($cgi->param('description')      || '');
+    my $triage_owner          = trim($cgi->param('triage_owner')     || '');
     my @initial_cc            = $cgi->param('initialcc');
     my $isactive              = $cgi->param('isactive');
   
@@ -226,6 +231,7 @@ if ($action eq 'update') {
     $component->set_description($description);
     $component->set_default_assignee($default_assignee);
     $component->set_default_qa_contact($default_qa_contact);
+    $component->set_triage_owner($triage_owner);
     $component->set_cc_list(\@initial_cc);
     $component->set_is_active($isactive);
     my $changes = $component->update();
index d9e970fe05d168133506fe11ebfb0bc6fc9ad717..c7bdefbdc83329be0207d04524295d71d8b0f310 100644 (file)
         view_only = 1
     %]
 
+    [%# triage owner %]
+    [% INCLUDE bug_modal/field.html.tmpl
+        field = bug_fields.triage_owner
+        field_type = constants.FIELD_TYPE_USER
+        value = bug.component_obj.triage_owner
+        view_only = 1
+    %]
+
+
     [%# needinfo %]
     [% WRAPPER bug_modal/field.html.tmpl
         container = 1
index 12d64c58003b5752da64062a254583f0839bcc54..1282ff838b44078fb31e743f937adb938cb18d2f 100644 (file)
@@ -865,7 +865,7 @@ $(function() {
             $('#top-save-btn').show();
             $('#resolve-as').hide();
             $('#bottom-status').show();
-           $('#bottom-dup_id').focus();
+            $('#bottom-dup_id').focus();
         });
     $('.status-btn')
         .click(function(event) {
index da934f4200ef57dc0c070891da8ae7100a5c2e85..a3dae68bbf128e6a41340584bdc4f3b133a1efde 100644 (file)
@@ -56,7 +56,10 @@ from '[% product.name FILTER html %]' product
   <td valign="top">Default QA contact:</td>
   <td valign="top">[% comp.default_qa_contact.login FILTER html %]</td>
 [% END %]
-  
+ </tr>
+<tr>
+  <td valign="top">Triage Owner:</td>
+  <td valign="top">[% comp.triage_owner.login FILTER html %]</td>
 </tr>
 <tr>
   <td valign="top">Component of Product:</td>
index 3e489af74889d68f4601b1b42e5b4de650acf0d1..ffb67bbf778f4fc103a429a0eb67af58a55ff873 100644 (file)
     </td>
   </tr>
 [% END %]
+<tr>
+  <td class="field_label"><label for="triage_owner">Triage Owner:</label></th>
+   <td>
+      [% INCLUDE global/userselect.html.tmpl
+         name    => "triage_owner"
+         id      => "triage_owner"
+         value   => comp.triage_owner.login
+         size    => 64
+         emptyok => 1
+       %]
+    </td>
+</tr>
 <tr>
   <th class="field_label"><label for="initialcc">Default CC List:</label></th>
   <td>
index 93c137073ee8404a641d99ad1f31508cf094209c..723753ae005b298ebed2e7d8f48919c75a2e1651 100644 (file)
     </tr>
     [% END %]
 
+    <tr>
+      <th class="field_label">
+        <label for="triage_owner">
+        <a href="page.cgi?id=fields.html#triage_owner">
+        Triage&nbsp;Owner</a></label>:
+      </th>
+      <td>
+        [% INCLUDE global/user.html.tmpl who = bug.component_obj.triage_owner %]
+      </td>
+    </tr>
+
+
     [%# BMO - hook for adding mentors %]
     [% Hook.process("after_people", "bug/edit.html.tmpl") %]
 
index 971bf2f347dae0bbc6d19df4252321934cfe1f8c..b74dd5ded219b01fd1dcef5ce003719c7b421477 100644 (file)
@@ -44,6 +44,7 @@
                     "initialcc"               => "Default CC List",
                     "initialowner"            => "Default Assignee",
                     "initialqacontact"        => "Default QA Contact",
+                    "triage_owner"            => "Triage Owner",
                     # Used by process_bug.cgi
                     "masscc"                  => "CC List",
                     # Used by request.cgi
index 1b8b765bf9255a07e9fdc708c616e70181208408..ff29ff184efd0e021d58197c36a02158cbc44d7c 100644 (file)
      "status_whiteboard"       => "Whiteboard",
      "tag.name"                => "Tags",
      "target_milestone"        => "Target Milestone",
+     "triage_owner"            => "Triage Owner",
      "version"                 => "Version",
      "work_time"               => "Hours Worked",
   } %]
index b5c75bcc35e1ed6a6304c137abe3994f4ce65340..b2430b7ed27f0d9c200eab4fcdb5fa88bc35adb4 100644 (file)
           <li>Default QA contact deleted</li>
         [% END %]
       [% END %]
+      [% IF changes.triage_owner_id.defined %]
+        [% IF comp.triage_owner.id %]
+          <li>Triage owner updated to '[% comp.triage_owner.login FILTER html %]'</li>
+        [% ELSE %]
+          <li>Triage owner deleted</li>
+        [% END %]
+      [% END %]
       [% IF changes.cc_list.defined %]
         [% IF comp.initial_cc.size %]
           [% cc_list = [] %]