[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.4-513-g14af0211a5
Jim Brandt
jbrandt at bestpractical.com
Fri Jun 4 16:29:05 EDT 2021
The branch, 4.4-trunk has been updated
via 14af0211a5d60a66c6b6962a4c921d3e99ce26b2 (commit)
via 19aa86b44020e048ad7c24b28e681dbbdf2a900e (commit)
via 5d7039ff0ddfa6af780c362e6389d2d708b2060a (commit)
via fd29f7e1cf500c9b2b757b012c06f6aa34287b13 (commit)
via 8b5c8d1b28dc06b5259fb7d07b6da0df8efd6731 (commit)
via 7abb7900e4f547c6bea1d2399c6ad07fad9b94d7 (commit)
via d9c9d676486698056ef0e862d08fe1f1b938b4d6 (commit)
via c37090a5b3233324213ca7c29a7250e4bf2513d9 (commit)
from 43acfb645b556e1c3d2d57bc5d7c610517664be4 (commit)
Summary of changes:
docs/UPGRADING-4.4 | 12 +++
etc/upgrade/4.4.5/content | 34 ++++++
lib/RT/Interface/Web.pm | 2 +-
lib/RT/Tickets.pm | 53 ++++++++-
share/html/Elements/ColumnMap | 155 +++++++++++++++++++++------
share/html/Search/Elements/BuildFormatString | 25 ++++-
share/html/Search/Elements/EditSort | 24 +++--
t/ticket/sort-by-user.t | 51 ++++++++-
t/web/cf_access.t | 2 +-
t/web/query_builder.t | 143 +++++++++++++++++++++++-
10 files changed, 452 insertions(+), 49 deletions(-)
- Log -----------------------------------------------------------------
commit c37090a5b3233324213ca7c29a7250e4bf2513d9
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Nov 27 00:55:00 2019 +0800
Support order by watcher's custom fields for ticket search
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index bd71c2c68a..82e32f1b55 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1104,7 +1104,9 @@ Try and turn a custom role descriptor (e.g. C<CustomRole.{Engineer}>) into
sub _CustomRoleDecipher {
my ($self, $string) = @_;
- my ($field, $column) = ($string =~ /^\{(.+)\}(?:\.(\w+))?$/);
+ # $column could be core fields like "EmailAddress" or CFs like
+ # "CustomField.{Department}", the CF format is used in OrderByCols.
+ my ($field, $column) = ($string =~ /^\{(.+?)\}(?:\.(.+))?$/);
my $role;
@@ -1528,7 +1530,54 @@ sub OrderByCols {
$self->{_sql_u_watchers_alias_for_sort}{ $cache_key }
= $users = ( $self->_WatcherJoin( Name => $type, Class => "RT::" . $class ) )[2];
}
- push @res, { %$row, ALIAS => $users, FIELD => $column };
+
+ if ( $column =~ /^CustomField\.\{(.+)\}$/ ) {
+ my $cf_name = $1;
+ my $cf = RT::CustomField->new( $self->CurrentUser );
+ $cf->LoadByCols( LookupType => RT::User->CustomFieldLookupType, Name => $cf_name );
+ if ( $cf->id ) {
+ my $ocfvs = $self->NewAlias('ObjectCustomFieldValues');
+ $self->Join(
+ TYPE => 'LEFT',
+ ALIAS1 => $users,
+ FIELD1 => 'id',
+ ALIAS2 => $ocfvs,
+ FIELD2 => 'ObjectId',
+ );
+
+ $self->Limit(
+ LEFTJOIN => $ocfvs,
+ FIELD => 'CustomField',
+ VALUE => $cf->id,
+ ENTRYAGGREGATOR => 'AND',
+ );
+
+ # The following is copied from RT::SearchBuilder::_OrderByCF
+ my $CFvs = $self->Join(
+ TYPE => 'LEFT',
+ ALIAS1 => $ocfvs,
+ FIELD1 => 'CustomField',
+ TABLE2 => 'CustomFieldValues',
+ FIELD2 => 'CustomField',
+ );
+ $self->Limit(
+ LEFTJOIN => $CFvs,
+ FIELD => 'Name',
+ QUOTEVALUE => 0,
+ VALUE => "$ocfvs.Content",
+ ENTRYAGGREGATOR => 'AND'
+ );
+ push @res, { %$row, ALIAS => $CFvs, FIELD => 'SortOrder' },
+ { %$row, ALIAS => $ocfvs, FIELD => 'Content' };
+ }
+ else {
+ RT->Logger->warning("Couldn't load user custom field $cf_name");
+ next;
+ }
+ }
+ else {
+ push @res, { %$row, ALIAS => $users, FIELD => $column };
+ }
} elsif ( defined $meta->[0] && $meta->[0] eq 'CUSTOMFIELD' ) {
my ($object, $field, $cf, $column) = $self->_CustomFieldDecipher( $subkey );
my $cfkey = $cf ? $cf->id : "$object.$field";
commit d9c9d676486698056ef0e862d08fe1f1b938b4d6
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Nov 27 00:55:45 2019 +0800
Test order by watcher's custom fields for ticket search
diff --git a/t/ticket/sort-by-user.t b/t/ticket/sort-by-user.t
index 42f95fc258..bde06d2ef3 100644
--- a/t/ticket/sort-by-user.t
+++ b/t/ticket/sort-by-user.t
@@ -1,5 +1,5 @@
-use RT::Test nodata => 1, tests => 52;
+use RT::Test nodata => 1, tests => undef;
use strict;
use warnings;
@@ -33,6 +33,7 @@ foreach my $u (qw(Z A)) {
my $user = RT::User->new( RT->SystemUser );
my ($uid) = $user->Create(
Name => $name,
+ EmailAddress => $name . '@localhost',
Privileged => 1,
);
ok $uid, "created user #$uid";
@@ -117,7 +118,7 @@ run_tests();
run_tests();
@data = (
- { Subject => 'RT' },
+ { Subject => 'Nobody' },
{ Subject => 'Z', LastUpdatedBy => $uids[0] },
{ Subject => 'A', LastUpdatedBy => $uids[1] },
);
@@ -127,4 +128,50 @@ run_tests();
);
run_tests();
+my $cf = RT::Test->load_or_create_custom_field(
+ Name => 'Department',
+ Type => 'FreeformSingle',
+ LookupType => RT::User->CustomFieldLookupType,
+);
+my ( $ret, $msg ) = $cf->AddToObject( RT::User->new( RT->SystemUser ) );
+ok( $ret, "Added CF globally: $msg" );
+
+( $ret, $msg ) = $users[0]->AddCustomFieldValue( Field => $cf, Value => 'Bar' );
+ok( $ret, "Added CF value 'Foo' to users[0]: $msg" );
+
+( $ret, $msg ) = $users[1]->AddCustomFieldValue( Field => $cf, Value => 'Foo' );
+ok( $ret, "Added CF value 'Bar' to users[1]: $msg" );
+
+ at data = (
+ { Subject => '-' },
+ { Subject => 'Z', Owner => $uids[1] },
+ { Subject => 'A', Owner => $uids[0] },
+);
+ at tickets = RT::Test->create_tickets( { Queue => $queue->id }, @data );
+ at test = (
+ { Order => "Owner.CustomField.{Department}" },
+);
+run_tests();
+
+my $cr = RT::CustomRole->new( RT->SystemUser );
+( $ret, $msg ) = $cr->Create(
+ Name => 'Engineer',
+ MaxValues => 0,
+);
+ok( $ret, "Created custom role: $msg" );
+
+( $ret, $msg ) = $cr->AddToObject( ObjectId => $queue->id );
+ok( $ret, "Added CR to queue: $msg" );
+
+ at data = (
+ { Subject => '-' },
+ { Subject => 'Z', $cr->GroupType => $uids[1] },
+ { Subject => 'A', $cr->GroupType => $uids[0] },
+);
+ at tickets = RT::Test->create_tickets( { Queue => $queue->id }, @data );
+ at test = ( { Order => "CustomRole.{Engineer}.CustomField.{Department}" }, );
+run_tests();
+
@tickets = ();
+
+done_testing;
commit 7abb7900e4f547c6bea1d2399c6ad07fad9b94d7
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Apr 22 05:38:19 2020 +0800
Support more watcher fields including user cfs in search result format
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 10a4a4192a..41d937ed9a 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -4004,7 +4004,7 @@ sub GetColumnMapEntry {
# complex things
elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.(.+)$/ ) {
- $subkey =~ s/^\{(.*)\}$/$1/;
+ $subkey =~ s/^\{(.*)\}/$1/ unless $mainkey eq 'CustomRole';
return undef unless $args{'Map'}->{$mainkey};
return $args{'Map'}{$mainkey}{ $args{'Attribute'} }
unless ref $args{'Map'}{$mainkey}{ $args{'Attribute'} } eq 'CODE';
diff --git a/share/html/Elements/ColumnMap b/share/html/Elements/ColumnMap
index 836d658d8c..50082ef37d 100644
--- a/share/html/Elements/ColumnMap
+++ b/share/html/Elements/ColumnMap
@@ -54,6 +54,104 @@ $Attr => undef
use Scalar::Util;
+my $role_value = sub {
+ my $role = shift;
+ my $object = shift;
+
+ # $[0] is the index number of current row
+ my $field = $_[1] || '';
+
+ my ( $role_type, $attr, $cf_name );
+
+
+ if ( $role eq 'CustomRole' ) {
+ my $role_name;
+ if ( $field =~ /^\{(.+)\}\.CustomField\.\{(.+)\}/ ) {
+
+ # {test}.CustomField.{foo}
+ $role_name = $1;
+ $cf_name = $2;
+ }
+ elsif ( $field =~ /^\{(.+)\}(?:\.(\w+))?$/ ) {
+
+ # {test}.Name or {test}
+ $role_name = $1;
+ $attr = $2;
+ }
+
+ # Cache the role object on a per-request basis, to avoid
+ # having to load it for every row
+ my $key = "RT::CustomRole-" . $role_name;
+
+ $role_type = $m->notes($key);
+ if ( !$role_type ) {
+ my $role_obj = RT::CustomRole->new( $object->CurrentUser );
+ $role_obj->Load($role_name);
+
+ RT->Logger->notice("Unable to load custom role $role_name")
+ unless $role_obj->Id;
+
+ $role_type = $role_obj->GroupType;
+ $m->notes( $key, $role_type );
+ }
+ }
+ else {
+ if ( $field =~ /^CustomField\.\{(.+)\}/ ) {
+ $cf_name = $1;
+ }
+ elsif ( $field =~ /^(\w+)$/ ) {
+ $attr = $1;
+ }
+ $role_type = $role;
+ }
+
+ return if !$role_type;
+
+ my $role_group = $object->RoleGroup($role_type);
+ if ( $cf_name || $attr ) {
+ # TODO Show direct members only?
+ my $users = $role_group->UserMembersObj;
+ my @values;
+
+ while ( my $user = $users->Next ) {
+ if ($cf_name) {
+ my $key = join( "-", "CF", $user->CustomFieldLookupType, $cf_name );
+ my $cf = $m->notes($key);
+ if ( !$cf ) {
+ $cf = $user->LoadCustomFieldByIdentifier($cf_name);
+ RT->Logger->debug( "Unable to load $cf_name for " . $user->CustomFieldLookupType )
+ unless $cf->Id;
+ $m->notes( $key, $cf );
+ }
+
+ my $ocfvs = $cf->ValuesForObject($user)->ItemsArrayRef;
+ my $comp
+ = $m->comp_exists( "/Elements/ShowCustomField" . $cf->Type )
+ ? "/Elements/ShowCustomField" . $cf->Type
+ : undef;
+
+ push @values, map { $comp ? \( $m->scomp( $comp, Object => $_ ) ) : $_->Content } @$ocfvs;
+
+ }
+ elsif ( $user->_Accessible( $attr, 'read' ) ) {
+ push @values, $user->$attr || ();
+ }
+ }
+ return @values if @values <= 1;
+
+ if ($cf_name) {
+ @values = map { \"<li>", $_, \"</li>" } @values;
+ @values = ( \"<ul class='cf-values'>", @values, \"</ul>" );
+ }
+ else {
+ return join ', ', @values;
+ }
+ }
+ else {
+ return \( $m->scomp( "/Elements/ShowPrincipal", Object => $role_group ) );
+ }
+};
+
my ($COLUMN_MAP, $WCOLUMN_MAP);
$WCOLUMN_MAP = $COLUMN_MAP = {
id => {
@@ -143,34 +241,21 @@ $WCOLUMN_MAP = $COLUMN_MAP = {
},
CustomRole => {
attribute => sub { return shift @_ },
- title => sub { return pop @_ },
- value => sub {
- my $object = shift;
- my $role_name = pop;
-
- my $role_type = do {
- # Cache the role object on a per-request basis, to avoid
- # having to load it for every row
- my $key = "RT::CustomRole-" . $role_name;
-
- my $role_type = $m->notes($key);
- if (!$role_type) {
- my $role_obj = RT::CustomRole->new($object->CurrentUser);
- $role_obj->Load($role_name);
-
- RT->Logger->notice("Unable to load custom role $role_name")
- unless $role_obj->Id;
-
- $role_type = $role_obj->GroupType;
- $m->notes($key, $role_type);
- }
-
- $role_type;
- };
-
- return if !$role_type;
- return \($m->scomp("/Elements/ShowPrincipal", Object => $object->RoleGroup($role_type) ) );
+ title => sub {
+ my $field = pop @_;
+ if ( $field =~ /^\{(.+)\}\.CustomField\.\{(.+)\}/
+ || $field =~ /^\{(.+)\}\.(.+)/ )
+ {
+ return "$1.$2";
+ }
+ elsif ( $field =~ /^\{(.+)\}$/ ) {
+ return $1;
+ }
+ else {
+ return $field;
+ }
},
+ value => sub { return $role_value->('CustomRole', @_) },
},
CheckBox => {
@@ -254,9 +339,19 @@ if ($RecordClass->DOES("RT::Record::Role::Roles")) {
for my $role ($RecordClass->Roles(UserDefined => 0)) {
my $attrs = $RecordClass->Role($role);
$ROLE_MAP->{$RecordClass}{$role} = {
- title => $role,
- attribute => $attrs->{Column} || "$role.EmailAddress",
- value => sub { return \($m->scomp("/Elements/ShowPrincipal", Object => $_[0]->RoleGroup($role) ) ) },
+ attribute => sub { return shift @_ },
+ title => sub {
+ my $field = pop @_;
+ if ( $field =~ /^CustomField\.\{(.+)\}/
+ || $field =~ /^(?!$role)(.+)/ )
+ {
+ return "$role.$1";
+ }
+ else {
+ return $role;
+ }
+ },
+ value => sub { return $role_value->($role, @_, @_ == 2 ? '' : () ) },
};
$ROLE_MAP->{$RecordClass}{$role . "s"} = $ROLE_MAP->{$RecordClass}{$role}
unless $attrs->{Single};
commit 8b5c8d1b28dc06b5259fb7d07b6da0df8efd6731
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Nov 27 02:17:51 2019 +0800
Add more watcher fields including user cfs to OrderBy/Columns in search builder
Besides user cfs, the following core fields are added: id, Name,
EmailAddress, RealName, Organization, City and Country.
The previous ambiguous "Owner" in OrderBy select is renamed to "Owner.Name".
diff --git a/share/html/Search/Elements/BuildFormatString b/share/html/Search/Elements/BuildFormatString
index ce541f889e..d5e8718960 100644
--- a/share/html/Search/Elements/BuildFormatString
+++ b/share/html/Search/Elements/BuildFormatString
@@ -128,8 +128,29 @@ foreach my $id (keys %queues) {
next unless $queue->Id;
$CustomRoles->LimitToObjectId($queue->Id);
}
-while ( my $Role = $CustomRoles->Next ) {
- push @fields, "CustomRole.{" . $Role->Name . "}";
+
+my @user_fields = qw/id Name EmailAddress Organization RealName City Country/;
+my $user_cfs = RT::CustomFields->new( $session{CurrentUser} );
+$user_cfs->Limit( FIELD => 'LookupType', VALUE => RT::User->CustomFieldLookupType );
+while ( my $user_cf = $user_cfs->Next ) {
+ push @user_fields, join '.', 'CustomField', '{' . $user_cf->Name . '}';
+}
+
+for my $watcher (qw/AdminCc Cc Owner Requestor/) {
+ for my $user_field (@user_fields) {
+ my $field = join '.', $watcher, $user_field;
+ push @fields, $field;
+ }
+}
+
+# Add all available CustomRoles to the list of sortable columns.
+while ( my $role = $CustomRoles->Next ) {
+ push @fields, 'CustomRole.{' . $role->Name . '}';
+
+ # Add all available CustomRoles to the list of sortable columns.
+ for my $user_field (@user_fields) {
+ push @fields, join '.', 'CustomRole.{' . $role->Name . '}', $user_field;
+ }
}
$m->callback( Fields => \@fields, ARGSRef => \%ARGS );
diff --git a/share/html/Search/Elements/EditSort b/share/html/Search/Elements/EditSort
index 7b70b923e3..9d9a15aaaf 100644
--- a/share/html/Search/Elements/EditSort
+++ b/share/html/Search/Elements/EditSort
@@ -108,20 +108,26 @@ for my $field (keys %FieldDescriptions) {
$fields{$field} = $field;
}
-$fields{'Owner'} = 'Owner';
-$fields{ $_ . '.EmailAddress' } = $_ . '.EmailAddress'
- for qw(Requestor Cc AdminCc);
-
# Add all available CustomFields to the list of sortable columns.
my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
$fields{$_} = $_ for @cfs;
+# Add all available core roles to the list of sortable columns.
+my @roles = grep /^(?:Owner|Requestor|Cc|AdminCc)\./, @{$ARGS{AvailableColumns}};
+$fields{$_} = $_ for @roles;
+
# Add all available CustomRoles to the list of sortable columns.
-my @roles = grep /^CustomRole/, @{$ARGS{AvailableColumns}};
-for my $role (@roles) {
- my ($label) = $role =~ /^CustomRole.\{(.*)\}$/;
- my $value = $role;
- $fields{$label . '.EmailAddress' } = $value . '.EmailAddress';
+my @custom_roles = grep /^CustomRole\./, @{$ARGS{AvailableColumns}};
+for my $role ( @custom_roles ) {
+ my $label = $role;
+ # In case custom role contains "{}" in name.
+ if ( $label =~ /\.CustomField/ ) {
+ $label =~ s!^CustomRole\.\{(.*)\}(?=\.CustomField\.)!$1!;
+ }
+ else {
+ $label =~ s!^CustomRole\.\{(.*)\}!$1!;
+ }
+ $fields{$label} = $role;
}
# Add PAW sort
commit fd29f7e1cf500c9b2b757b012c06f6aa34287b13
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Nov 27 02:22:14 2019 +0800
Upgrade OrderBy "Owner" to new version "Owner.Name" in saved searchs
As we added more watcher fields to OrderBy, previous ambiguous "Owner"
has been removed.
diff --git a/etc/upgrade/4.4.5/content b/etc/upgrade/4.4.5/content
index 45b13c1eee..68e0a73997 100644
--- a/etc/upgrade/4.4.5/content
+++ b/etc/upgrade/4.4.5/content
@@ -1,6 +1,40 @@
use warnings;
use strict;
+our @Initial = (
+ sub {
+ my $searches = RT::Attributes->new( RT->SystemUser );
+ $searches->Limit( FIELD => 'Name', VALUE => 'SavedSearch' );
+ $searches->OrderBy( FIELD => 'id' );
+
+ while ( my $search = $searches->Next ) {
+ my $content = $search->Content;
+ next unless ref $content eq 'HASH';
+
+ if ( $content->{OrderBy} ) {
+ my @order_by = split /\|/, $content->{OrderBy};
+ my @new_order_by;
+ my $changed;
+ for my $order_by (@order_by) {
+ if ( $order_by eq 'Owner' ) {
+ push @new_order_by, 'Owner.Name';
+ $changed = 1;
+ }
+ else {
+ push @new_order_by, $order_by;
+ }
+ }
+ if ($changed) {
+ $content->{OrderBy} = join '|', @new_order_by;
+ my ( $ok, $msg ) = $search->SetContent($content);
+ RT->Logger->error("Unable to upgrade saved chart #@{[$search->id]}: $msg")
+ unless $ok;
+ }
+ }
+ }
+ }
+);
+
our @ScripConditions = (
{
Name => 'On Create Via Email',
commit 5d7039ff0ddfa6af780c362e6389d2d708b2060a
Author: sunnavy <sunnavy at bestpractical.com>
Date: Wed Nov 27 02:31:26 2019 +0800
Update query builder tests as now we support more watcher fields
diff --git a/t/web/cf_access.t b/t/web/cf_access.t
index aa707f5dc6..505269b599 100644
--- a/t/web/cf_access.t
+++ b/t/web/cf_access.t
@@ -231,7 +231,7 @@ $m->submit_form(
$m->form_name('BuildQuery');
-my $col = ($m->current_form->find_input('SelectDisplayColumns'))[-1];
+my ($col) = grep { ($_->possible_values)[-1] =~ /CustomField/ } $m->find_all_inputs( name => 'SelectDisplayColumns' );
$col->value( ($col->possible_values)[-1] );
$m->click('AddCol');
diff --git a/t/web/query_builder.t b/t/web/query_builder.t
index 89e89f5707..94a167041a 100644
--- a/t/web/query_builder.t
+++ b/t/web/query_builder.t
@@ -326,13 +326,25 @@ diag "make sure skipped order by field doesn't break search";
), "link to the ticket" );
}
-diag "make sure the list of columns available in the 'Order by' dropdowns are complete";
+diag "make sure the list of columns available in the 'Order by'/'Add Columns' dropdowns are complete";
{
$agent->get_ok($url . 'Search/Build.html');
my @orderby = qw(
+ AdminCc.City
+ AdminCc.Country
AdminCc.EmailAddress
+ AdminCc.Name
+ AdminCc.Organization
+ AdminCc.RealName
+ AdminCc.id
+ Cc.City
+ Cc.Country
Cc.EmailAddress
+ Cc.Name
+ Cc.Organization
+ Cc.RealName
+ Cc.id
Created
Creator
Custom.Ownership
@@ -341,10 +353,22 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
InitialPriority
LastUpdated
LastUpdatedBy
- Owner
+ Owner.City
+ Owner.Country
+ Owner.EmailAddress
+ Owner.Name
+ Owner.Organization
+ Owner.RealName
+ Owner.id
Priority
Queue
+ Requestor.City
+ Requestor.Country
Requestor.EmailAddress
+ Requestor.Name
+ Requestor.Organization
+ Requestor.RealName
+ Requestor.id
Resolved
SLA
Started
@@ -370,17 +394,115 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
is ($scraped_orderby, '[none] '.$orderby);
}
+ my @formats = qw(
+ id
+ QueueName
+ Subject
+ Status
+ ExtendedStatus
+ UpdateStatus
+ Type
+ OwnerName
+ Requestors
+ Cc
+ AdminCc
+ CreatedBy
+ LastUpdatedBy
+ Priority
+ InitialPriority
+ FinalPriority
+ TimeWorked
+ TimeLeft
+ TimeEstimated
+ Starts
+ StartsRelative
+ Started
+ StartedRelative
+ Created
+ CreatedRelative
+ LastUpdated
+ LastUpdatedRelative
+ Told
+ ToldRelative
+ Due
+ DueRelative
+ Resolved
+ ResolvedRelative
+ SLA
+ RefersTo
+ ReferredToBy
+ DependsOn
+ DependedOnBy
+ MemberOf
+ Members
+ Parents
+ Children
+ Bookmark
+ Timer
+ NEWLINE
+ NBSP
+ AdminCc.id
+ AdminCc.Name
+ AdminCc.EmailAddress
+ AdminCc.Organization
+ AdminCc.RealName
+ AdminCc.City
+ AdminCc.Country
+ Cc.id
+ Cc.Name
+ Cc.EmailAddress
+ Cc.Organization
+ Cc.RealName
+ Cc.City
+ Cc.Country
+ Owner.id
+ Owner.Name
+ Owner.EmailAddress
+ Owner.Organization
+ Owner.RealName
+ Owner.City
+ Owner.Country
+ Requestor.id
+ Requestor.Name
+ Requestor.EmailAddress
+ Requestor.Organization
+ Requestor.RealName
+ Requestor.City
+ Requestor.Country
+ );
+ my $formats = join(' ', @formats);
+ my $scraped_formats = $agent->scrape_text_by_attr('name', 'SelectDisplayColumns');
+ is( $scraped_formats, $formats, 'Default format' );
+
my $cf = RT::Test->load_or_create_custom_field(
Name => 'Location',
Queue => 'General',
Type => 'FreeformSingle', );
isa_ok( $cf, 'RT::CustomField' );
+ my $user_cf = RT::Test->load_or_create_custom_field(
+ Name => 'Employee ID',
+ LookupType => RT::User->CustomFieldLookupType,
+ Type => 'FreeformSingle',
+ );
+
+ my $cr = RT::CustomRole->new( RT->SystemUser );
+ my ( $ret, $msg ) = $cr->Create(
+ Name => 'Engineer',
+ MaxValues => 0,
+ );
+ ok( $ret, "Created custom role: $msg" );
+
+ ( $ret, $msg ) = $cr->AddToObject( ObjectId => 'General' );
+ ok( $ret, "Added CR to queue: $msg" );
+
ok($agent->form_name('BuildQuery'), "found the form");
$agent->field("ValueOfQueue", "General");
$agent->submit;
push @orderby, 'CustomField.{Location}';
+ push @orderby, 'Engineer', map { "Engineer.$_" } qw/City Country EmailAddress Name Organization RealName id/;
+ push @orderby, map {"$_.CustomField.{Employee ID}"} qw/AdminCc Cc Requestor Owner Engineer/;
$orderby = join(' ', sort @orderby);
@@ -393,6 +515,23 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
is ($scraped_orderby, '[none] '.$orderby);
}
+ # Formats are not sorted, we need to insert new items accordingly
+ my @new_formats;
+ for my $format ( @formats ) {
+ push @new_formats, $format;
+ if ( $format eq 'NBSP' ) {
+ push @new_formats, 'CustomField.{Location}';
+ }
+ elsif ( $format =~ /(\w+)\.Country/ ) {
+ push @new_formats, "$1.CustomField.{Employee ID}";
+ }
+ }
+ push @new_formats, 'CustomRole.{Engineer}',
+ map {"CustomRole.{Engineer}.$_"} qw/id Name EmailAddress Organization RealName City Country/, 'CustomField.{Employee ID}';
+ $formats = join(' ', @new_formats);
+ $scraped_formats = $agent->scrape_text_by_attr('name', 'SelectDisplayColumns');
+ is( $scraped_formats, $formats, 'Format with custom fields and custom roles' );
+
$cf->SetDisabled(1);
}
commit 19aa86b44020e048ad7c24b28e681dbbdf2a900e
Author: Jim Brandt <jbrandt at bestpractical.com>
Date: Fri Jun 4 16:21:04 2021 -0400
Document the database updates for the Owner.Name change
diff --git a/docs/UPGRADING-4.4 b/docs/UPGRADING-4.4
index f7a925d6bb..20aa146ddd 100644
--- a/docs/UPGRADING-4.4
+++ b/docs/UPGRADING-4.4
@@ -678,6 +678,18 @@ so batch runs only once for the outermost updates. All transactions
performed for that batch are available from the C<TransactionBatch> method
as expected.
+=item * Ambigious Owner order by option in search replaced with Owner.Name
+
+RT 4.4.5 adds a bunch of new order by and format options for users and roles
+to the Query Builder. For example, you can order by user fields on a user
+like Owner.EmailAddress, Owner.RealName, or even Owner.Organization.
+As part of this change, the previous Owner entry has been renamed to
+Owner.Name.
+
+The upgrade scripts include a step to make this change in any saved searches
+in the database automatically. If you have Owner as an order by field in
+searches stored elsewhere or as a link, you can update to Owner.Name manually.
+
=back
=cut
commit 14af0211a5d60a66c6b6962a4c921d3e99ce26b2
Merge: 43acfb645b 19aa86b440
Author: Jim Brandt <jbrandt at bestpractical.com>
Date: Fri Jun 4 16:21:25 2021 -0400
Merge branch '4.4/ticket-search-order-by-watcher-cfs' into 4.4-trunk
-----------------------------------------------------------------------
More information about the rt-commit
mailing list