]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1533717 - Add a search keyword "Whatever"
authorKohei Yoshino <kohei.yoshino@gmail.com>
Tue, 16 Jul 2019 20:06:41 +0000 (16:06 -0400)
committerGitHub <noreply@github.com>
Tue, 16 Jul 2019 20:06:41 +0000 (16:06 -0400)
Bugzilla/Field.pm
Bugzilla/Search.pm
js/advanced-search.js
template/en/default/global/field-descs.none.tmpl

index a12cf2e868f27649da61d79f60cd70efcfb8a482..5aedef21ba0251a222170cf30b4e37b78b2c9e1e 100644 (file)
@@ -487,6 +487,9 @@ use constant DEFAULT_FIELDS => (
     type    => FIELD_TYPE_USER,
     buglist => 1,
   },
+
+  # Special field that allows to search everything with Custom Search queries
+  {name => 'anything', desc => 'Any field'},
 );
 
 ################
index e856838198c1f9e4741847d0a1f30e6eeccd0180..eb58602c23575439c313decde68377625c7101ab 100644 (file)
@@ -3476,30 +3476,34 @@ sub _changedbefore_changedafter {
     = @$args{qw(chart_id joins field operator value)};
   my $dbh = Bugzilla->dbh;
 
-  my $field_object = $self->_chart_fields->{$field}
-    || ThrowCodeError("invalid_field_name", {field => $field});
+  my $table;
+  my $join = {table => 'bugs_activity', extra => []};
 
-  # Asking when creation_ts changed is just asking when the bug was created.
-  if ($field_object->name eq 'creation_ts') {
-    $args->{operator}
-      = $operator eq 'changedbefore' ? 'lessthaneq' : 'greaterthaneq';
-    return $self->_do_operator_function($args);
-  }
+  if ($field eq 'anything') {
+    # Handle special field name to find changes in any field
+    $table = $join->{as} = "act_x_$chart_id";
+  } else {
+    my $field_object = $self->_chart_fields->{$field}
+      || ThrowCodeError("invalid_field_name", {field => $field});
+
+    # Asking when creation_ts changed is just asking when the bug was created.
+    if ($field_object->name eq 'creation_ts') {
+      $args->{operator}
+        = $operator eq 'changedbefore' ? 'lessthaneq' : 'greaterthaneq';
+      return $self->_do_operator_function($args);
+    }
 
-  my $sql_operator = ($operator =~ /before/) ? '<=' : '>=';
-  my $field_id = $field_object->id;
+    my $field_id = $field_object->id;
 
-  # Charts on changed* fields need to be field-specific. Otherwise,
-  # OR chart rows make no sense if they contain multiple fields.
-  my $table = "act_${field_id}_$chart_id";
+    # Charts on changed* fields need to be field-specific. Otherwise,
+    # OR chart rows make no sense if they contain multiple fields.
+    $table = $join->{as} = "act_${field_id}_$chart_id";
+    push(@{$join->{extra}}, "$table.fieldid = $field_id");
+  }
 
+  my $sql_operator = ($operator =~ /before/) ? '<=' : '>=';
   my $sql_date = $dbh->quote(SqlifyDate($value));
-  my $join     = {
-    table => 'bugs_activity',
-    as    => $table,
-    extra =>
-      ["$table.fieldid = $field_id", "$table.bug_when $sql_operator $sql_date"],
-  };
+  push(@{$join->{extra}}, "$table.bug_when $sql_operator $sql_date");
 
   $args->{term} = "$table.bug_when IS NOT NULL";
   $self->_changed_security_check($args, $join);
@@ -3511,16 +3515,22 @@ sub _changedfrom_changedto {
   my ($chart_id, $joins, $field, $operator, $quoted)
     = @$args{qw(chart_id joins field operator quoted)};
 
+  my $table;
+  my $join = {table => 'bugs_activity', extra => []};
   my $column = ($operator =~ /from/) ? 'removed' : 'added';
-  my $field_object = $self->_chart_fields->{$field}
-    || ThrowCodeError("invalid_field_name", {field => $field});
-  my $field_id = $field_object->id;
-  my $table    = "act_${field_id}_$chart_id";
-  my $join     = {
-    table => 'bugs_activity',
-    as    => $table,
-    extra => ["$table.fieldid = $field_id", "$table.$column = $quoted"],
-  };
+
+  if ($field eq 'anything') {
+    # Handle special field name to find changes in any field
+    $table = $join->{as} = "act_x_$chart_id";
+  } else {
+    my $field_object = $self->_chart_fields->{$field}
+      || ThrowCodeError("invalid_field_name", {field => $field});
+    my $field_id = $field_object->id;
+    $table = $join->{as} = "act_${field_id}_$chart_id";
+    push(@{$join->{extra}}, "$table.fieldid = $field_id");
+  }
+
+  push(@{$join->{extra}}, "$table.$column = $quoted");
 
   $args->{term} = "$table.bug_when IS NOT NULL";
   $self->_changed_security_check($args, $join);
@@ -3532,16 +3542,22 @@ sub _changedby {
   my ($chart_id, $joins, $field, $operator, $value)
     = @$args{qw(chart_id joins field operator value)};
 
-  my $field_object = $self->_chart_fields->{$field}
-    || ThrowCodeError("invalid_field_name", {field => $field});
-  my $field_id = $field_object->id;
-  my $table    = "act_${field_id}_$chart_id";
-  my $user_id  = login_to_id($value, THROW_ERROR);
-  my $join     = {
-    table => 'bugs_activity',
-    as    => $table,
-    extra => ["$table.fieldid = $field_id", "$table.who = $user_id"],
-  };
+  my $table;
+  my $join = {table => 'bugs_activity', extra => []};
+
+  if ($field eq 'anything') {
+    # Handle special field name to find changes in any field
+    $table = $join->{as} = "act_x_$chart_id";
+  } else {
+    my $field_object = $self->_chart_fields->{$field}
+      || ThrowCodeError("invalid_field_name", {field => $field});
+    my $field_id = $field_object->id;
+    $table = $join->{as} = "act_${field_id}_$chart_id";
+    push(@{$join->{extra}}, "$table.fieldid = $field_id");
+  }
+
+  my $user_id = login_to_id($value, THROW_ERROR);
+  push(@{$join->{extra}}, "$table.who = $user_id");
 
   $args->{term} = "$table.bug_when IS NOT NULL";
   $self->_changed_security_check($args, $join);
index 8f32148152bafadb0944a5a29e349090c02253e7..d1d8462fbf57522e3c0c0a737a710604f4f2cf67 100644 (file)
@@ -593,12 +593,31 @@ Bugzilla.CustomSearch.Row = class CustomSearchRow extends Bugzilla.CustomSearch.
     this.$element = $placeholder.firstElementChild;
     this.$action_grab = this.$element.querySelector('[data-action="grab"]');
     this.$action_remove = this.$element.querySelector('[data-action="remove"]');
+    this.$select_field = this.$element.querySelector('select.field');
+    this.$select_operator = this.$element.querySelector('select.operator');
+    this.$input_value = this.$element.querySelector('input.value');
 
     this.$element.addEventListener('dragstart', event => this.handle_drag(event));
     this.$element.addEventListener('dragend', event => this.handle_drag(event));
     this.$action_grab.addEventListener('mousedown', () => this.enable_drag());
     this.$action_grab.addEventListener('mouseup', () => this.disable_drag());
     this.$action_remove.addEventListener('click', () => this.remove());
+    this.$select_field.addEventListener('change', () => this.field_onchange());
+  }
+
+  /**
+   * Called whenever a field option is selected.
+   */
+  field_onchange() {
+    const is_anything = this.$select_field.value === 'anything';
+
+    // Add support for the "anything" special field that allows to search the bug history. When it's selected, disable
+    // search types other than "changed before", "changed after", "changed from", "changed to", "changed by", and make
+    // "changed by" selected for convenience.
+    for (const $option of this.$select_operator.options) {
+      $option.disabled = is_anything ? !$option.value.match(/changed\w+/) : false;
+      $option.selected = $option.value === (is_anything ? 'changedby' : 'noop');
+    }
   }
 };
 
index 4ee255e4c81cef268c44788bd9dbea98b39223a4..4a7bf48f6a17be09846956e09fcbc1ee24ea8959 100644 (file)
@@ -94,6 +94,7 @@ if ( $stash->get("in_template_var") ) {
         "[Bug creation]"          => "[$terms->{Bug} creation]",
         "actual_time"             => "Actual Hours",
         "alias"                   => "Alias",
+        "anything"                => "Any field",
         "assigned_to"             => "Assignee",
         "assigned_to_realname"    => "Assignee Real Name",
         "assignee_last_login"     => "Assignee Last Login Date",