[Rt-commit] rt branch 5.0/asset-search-filter created. rt-5.0.5-70-gb04d7fe9d3
BPS Git Server
git at git.bestpractical.com
Thu Nov 30 21:12:37 UTC 2023
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".
The branch, 5.0/asset-search-filter has been created
at b04d7fe9d34ca510c2712c1e2e8755ddd6bac224 (commit)
- Log -----------------------------------------------------------------
commit b04d7fe9d34ca510c2712c1e2e8755ddd6bac224
Author: sunnavy <sunnavy at bestpractical.com>
Date: Thu Nov 30 15:40:49 2023 -0500
Add search filter support to assets
diff --git a/share/html/Elements/CollectionAsTable/Header b/share/html/Elements/CollectionAsTable/Header
index 9b4ac06fff..c5b50a46e6 100644
--- a/share/html/Elements/CollectionAsTable/Header
+++ b/share/html/Elements/CollectionAsTable/Header
@@ -218,12 +218,19 @@ foreach my $col ( @Format ) {
$m->out( qq{<span class="title">$loc_title</span>} );
}
- if ( $AllowFiltering && $Class eq 'RT::Tickets' ) {
+ if ( $AllowFiltering ) {
my $attr = ProcessColumnMapValue( $attribute, Arguments => [ $col->{'attribute'} ], Escape => 1 );
- my $field;
- my %supported = map { $_ => 1 }
- qw/id Subject Status Queue Owner Type Creator LastUpdatedBy SLA InitialPriority FinalPriority Priority TimeLeft TimeWorked TimeEstimated Created LastUpdated Told Starts Started Due Resolved Requestors Requestor Cc AdminCc/;
+ my %supported;
+ if ( $Class eq 'RT::Tickets' ) {
+ %supported = map { $_ => 1 }
+ qw/id Subject Status Queue Owner Type Creator LastUpdatedBy SLA InitialPriority FinalPriority Priority TimeLeft TimeWorked TimeEstimated Created LastUpdated Told Starts Started Due Resolved Requestors Requestor Cc AdminCc/;
+ }
+ elsif ( $Class eq 'RT::Assets' ) {
+ %supported = map { $_ => 1 }
+ qw/id Name Description Status Catalog Created LastUpdated Creator LastUpdatedBy Owner HeldBy Contact Contacts/;
+ }
+ my $field;
if ( ( $attr || '' ) =~ /^(\w+)/ && $supported{$1} ) {
$field = $1;
}
@@ -253,109 +260,218 @@ foreach my $col ( @Format ) {
<%INIT>
my %filter_data;
-if ( $AllowFiltering && $Class eq 'RT::Tickets' && $ARGS{Query} && $ARGS{BaseQuery} ) {
-
- my $tickets = RT::Tickets->new( $session{CurrentUser} );
- my ($ok) = $tickets->FromSQL( $ARGS{Query} );
- return unless $ok && ( $ARGS{BaseQuery} || $tickets->Count );
-
- my @queues;
-
- my $tree = RT::Interface::Web::QueryBuilder::Tree->new;
- $tree->ParseSQL( Query => $ARGS{BaseQuery} || $ARGS{Query}, CurrentUser => $session{'CurrentUser'} );
- my $referenced_queues = $tree->GetReferencedQueues;
- for my $name_or_id ( keys %$referenced_queues ) {
- my $queue = RT::Queue->new( $session{CurrentUser} );
- $queue->Load($name_or_id);
- if ( $queue->id ) {
- push @queues, $queue;
+if ( $AllowFiltering && $ARGS{Query} && $ARGS{BaseQuery} ) {
+
+ if ( $Class eq 'RT::Tickets' ) {
+ my $tickets = RT::Tickets->new( $session{CurrentUser} );
+ my ($ok) = $tickets->FromSQL( $ARGS{Query} );
+ return unless $ok && ( $ARGS{BaseQuery} || $tickets->Count );
+
+ my @queues;
+
+ my $tree = RT::Interface::Web::QueryBuilder::Tree->new;
+ $tree->ParseSQL( Query => $ARGS{BaseQuery} || $ARGS{Query}, CurrentUser => $session{'CurrentUser'} );
+ my $referenced_queues = $tree->GetReferencedQueues;
+ for my $name_or_id ( keys %$referenced_queues ) {
+ my $queue = RT::Queue->new( $session{CurrentUser} );
+ $queue->Load($name_or_id);
+ if ( $queue->id ) {
+ push @queues, $queue;
+ }
}
- }
- my %status;
- my @lifecycles;
+ my %status;
+ my @lifecycles;
- if (@queues) {
- my %lifecycle;
- for my $queue (@queues) {
- next if $lifecycle{ $queue->Lifecycle }++;
- push @lifecycles, $queue->LifecycleObj;
+ if (@queues) {
+ my %lifecycle;
+ for my $queue (@queues) {
+ next if $lifecycle{ $queue->Lifecycle }++;
+ push @lifecycles, $queue->LifecycleObj;
+ }
+ }
+ else {
+ @lifecycles = map { RT::Lifecycle->Load( Type => 'ticket', Name => $_ ) } RT::Lifecycle->List('ticket');
}
- }
- else {
- @lifecycles = map { RT::Lifecycle->Load( Type => 'ticket', Name => $_ ) } RT::Lifecycle->List('ticket');
- }
- for my $lifecycle (@lifecycles) {
- $status{$_} = 1 for $lifecycle->Valid;
- }
- delete $status{deleted};
+ for my $lifecycle (@lifecycles) {
+ $status{$_} = 1 for $lifecycle->Valid;
+ }
+ delete $status{deleted};
- if ( !@queues ) {
- my $queues = RT::Queues->new( $session{CurrentUser} );
- $queues->UnLimit;
+ if ( !@queues ) {
+ my $queues = RT::Queues->new( $session{CurrentUser} );
+ $queues->UnLimit;
- while ( my $queue = $queues->Next ) {
- push @queues, $queue;
- last if @queues == 100; # TODO make a config for it
+ while ( my $queue = $queues->Next ) {
+ push @queues, $queue;
+ last if @queues == 100; # TODO make a config for it
+ }
+ }
+
+ my %filter;
+
+ if ( $ARGS{BaseQuery} && $ARGS{BaseQuery} ne $ARGS{Query} ) {
+ my $query = $ARGS{Query};
+ $query =~ s!^\s*\(?\s*\Q$ARGS{BaseQuery}\E\s*\)? AND !!;
+ my $tree = RT::Interface::Web::QueryBuilder::Tree->new;
+ $tree->ParseSQL( Query => $query, CurrentUser => $session{'CurrentUser'} );
+ $tree->traverse(
+ sub {
+ my $node = shift;
+
+ return if $node->isRoot;
+ return unless $node->isLeaf;
+
+ my $clause = $node->getNodeValue();
+ if ( $clause->{Key} =~ /^Queue/ ) {
+ my $queue = RT::Queue->new( $session{CurrentUser} );
+ $queue->Load( $clause->{Value} );
+ if ( $queue->id ) {
+ $filter{ $clause->{Key} }{ $queue->id } = 1;
+ }
+ }
+ elsif ( $clause->{Key} =~ /^(?:Status|SLA|Type)/ ) {
+ $filter{ $clause->{Key} }{ $clause->{Value} } = 1;
+ }
+ elsif ( $clause->{Key}
+ =~ /^(?:(?:Initial|Final)?Priority|Time(?:Worked|Estimated|Left)|id|Told|Starts|Started|Due|Resolved|Created|LastUpdated\b)/
+ )
+ {
+ $filter{ $clause->{Key} }{ $clause->{Op} } = $clause->{Value};
+ }
+ else {
+ my $value = $clause->{Value};
+ $value =~ s!\\([\\"])!$1!g;
+ my $key = $clause->{Key};
+ my $cf;
+ if ( $key eq 'CustomField' ) {
+ $key .= ".$clause->{Subkey}";
+ my ($cf_name) = $clause->{Subkey} =~ /{(.+)}/;
+ $cf = RT::CustomField->new( RT->SystemUser );
+ $cf->Load($cf_name);
+ }
+ elsif ( $key eq 'CustomRole' ) {
+ $key .= ".$1" if $clause->{Subkey} =~ /(\{.+?\})/;
+ }
+ if ( $cf && $cf->id && $cf->Type eq 'Select' ) {
+ $filter{$key}{$value} = 1;
+ }
+ else {
+ $filter{$key} = $value;
+ }
+ }
+ }
+ );
+ $filter{Requestors} = $filter{Requestor} if $filter{Requestor};
}
+ %filter_data = ( status => \%status, queues => \@queues, filter => \%filter );
}
+ elsif ( $Class eq 'RT::Assets' ) {
+ my $assets = RT::Assets->new( $session{CurrentUser} );
+ my ($ok) = $assets->FromSQL( $ARGS{Query} );
+ return unless $ok && ( $ARGS{BaseQuery} || $assets->Count );
- my %filter;
+ my @catalogs;
- if ( $ARGS{BaseQuery} && $ARGS{BaseQuery} ne $ARGS{Query} ) {
- my $query = $ARGS{Query};
- $query =~ s!^\s*\(?\s*\Q$ARGS{BaseQuery}\E\s*\)? AND !!;
my $tree = RT::Interface::Web::QueryBuilder::Tree->new;
- $tree->ParseSQL( Query => $query, CurrentUser => $session{'CurrentUser'} );
- $tree->traverse(
- sub {
- my $node = shift;
-
- return if $node->isRoot;
- return unless $node->isLeaf;
-
- my $clause = $node->getNodeValue();
- if ( $clause->{Key} =~ /^Queue/ ) {
- my $queue = RT::Queue->new( $session{CurrentUser} );
- $queue->Load( $clause->{Value} );
- if ( $queue->id ) {
- $filter{ $clause->{Key} }{ $queue->id } = 1;
- }
- }
- elsif ( $clause->{Key} =~ /^(?:Status|SLA|Type)/ ) {
- $filter{ $clause->{Key} }{ $clause->{Value} } = 1;
- }
- elsif ( $clause->{Key}
- =~ /^(?:(?:Initial|Final)?Priority|Time(?:Worked|Estimated|Left)|id|Told|Starts|Started|Due|Resolved|Created|LastUpdated\b)/
- )
- {
- $filter{ $clause->{Key} }{ $clause->{Op} } = $clause->{Value};
- }
- else {
- my $value = $clause->{Value};
- $value =~ s!\\([\\"])!$1!g;
- my $key = $clause->{Key};
- my $cf;
- if ( $key eq 'CustomField' ) {
- $key .= ".$clause->{Subkey}";
- my ($cf_name) = $clause->{Subkey} =~ /{(.+)}/;
- $cf = RT::CustomField->new( RT->SystemUser );
- $cf->Load($cf_name);
+ $tree->ParseSQL(
+ Query => $ARGS{BaseQuery} || $ARGS{Query},
+ CurrentUser => $session{'CurrentUser'},
+ Class => 'RT::Assets',
+ );
+ my $referenced_catalogs = $tree->GetReferencedCatalogs;
+ for my $name_or_id ( keys %$referenced_catalogs ) {
+ my $catalog = RT::Catalog->new( $session{CurrentUser} );
+ $catalog->Load($name_or_id);
+ if ( $catalog->id ) {
+ push @catalogs, $catalog;
+ }
+ }
+
+ my %status;
+ my @lifecycles;
+
+ if (@catalogs) {
+ my %lifecycle;
+ for my $catalog (@catalogs) {
+ next if $lifecycle{ $catalog->Lifecycle }++;
+ push @lifecycles, $catalog->LifecycleObj;
+ }
+ }
+ else {
+ @lifecycles = map { RT::Lifecycle->Load( Type => 'asset', Name => $_ ) } RT::Lifecycle->List('asset');
+ }
+
+ for my $lifecycle (@lifecycles) {
+ $status{$_} = 1 for $lifecycle->Valid;
+ }
+ delete $status{deleted};
+
+ if ( !@catalogs ) {
+ my $catalogs = RT::Catalogs->new( $session{CurrentUser} );
+ $catalogs->UnLimit;
+
+ while ( my $catalog = $catalogs->Next ) {
+ push @catalogs, $catalog;
+ last if @catalogs == 100; # TODO make a config for it
+ }
+ }
+
+ my %filter;
+
+ if ( $ARGS{BaseQuery} && $ARGS{BaseQuery} ne $ARGS{Query} ) {
+ my $query = $ARGS{Query};
+ $query =~ s!^\s*\(?\s*\Q$ARGS{BaseQuery}\E\s*\)? AND !!;
+ my $tree = RT::Interface::Web::QueryBuilder::Tree->new;
+ $tree->ParseSQL( Query => $query, CurrentUser => $session{'CurrentUser'}, Class => 'RT::Assets' );
+ $tree->traverse(
+ sub {
+ my $node = shift;
+
+ return if $node->isRoot;
+ return unless $node->isLeaf;
+
+ my $clause = $node->getNodeValue();
+ if ( $clause->{Key} =~ /^Catalog/ ) {
+ my $catalog = RT::Catalog->new( $session{CurrentUser} );
+ $catalog->Load( $clause->{Value} );
+ if ( $catalog->id ) {
+ $filter{ $clause->{Key} }{ $catalog->id } = 1;
+ }
}
- elsif ( $key eq 'CustomRole' ) {
- $key .= ".$1" if $clause->{Subkey} =~ /(\{.+?\})/;
+ elsif ( $clause->{Key} eq 'Status' ) {
+ $filter{ $clause->{Key} }{ $clause->{Value} } = 1;
}
- if ( $cf && $cf->id && $cf->Type eq 'Select' ) {
- $filter{$key}{$value} = 1;
+ elsif ( $clause->{Key} =~ /^(?:id|Created|LastUpdated\b)/ ) {
+ $filter{ $clause->{Key} }{ $clause->{Op} } = $clause->{Value};
}
else {
- $filter{$key} = $value;
+ my $value = $clause->{Value};
+ $value =~ s!\\([\\"])!$1!g;
+ my $key = $clause->{Key};
+ my $cf;
+ if ( $key eq 'CustomField' ) {
+ $key .= ".$clause->{Subkey}";
+ my ($cf_name) = $clause->{Subkey} =~ /{(.+)}/;
+ $cf = RT::CustomField->new( RT->SystemUser );
+ $cf->Load($cf_name);
+ }
+ elsif ( $key eq 'CustomRole' ) {
+ $key .= ".$1" if $clause->{Subkey} =~ /(\{.+?\})/;
+ }
+ if ( $cf && $cf->id && $cf->Type eq 'Select' ) {
+ $filter{$key}{$value} = 1;
+ }
+ else {
+ $filter{$key} = $value;
+ }
}
}
- }
- );
+ );
+ $filter{Contacts} = $filter{Contact} if $filter{Contact};
+ }
+ %filter_data = ( status => \%status, catalogs => \@catalogs, filter => \%filter );
}
- %filter_data = ( status => \%status, queues => \@queues, filter => \%filter );
}
</%INIT>
diff --git a/share/html/Elements/SearchFilter b/share/html/Elements/SearchFilter
index 24172b75d2..f9c8e46e1e 100644
--- a/share/html/Elements/SearchFilter
+++ b/share/html/Elements/SearchFilter
@@ -46,7 +46,7 @@
%#
%# END BPS TAGGED BLOCK }}}
<div class="modal search-results-filter">
- <div class="modal-dialog <% $Attribute eq 'Owner' ? '' : 'modal-dialog-scrollable' %> <% $modal_class %>" role="document">
+ <div class="modal-dialog <% $Class eq 'RT::Tickets' && $Attribute eq 'Owner' ? '' : 'modal-dialog-scrollable' %> <% $modal_class %>" role="document">
<form name="search-results-filter">
<div class="modal-content">
<div class="modal-header">
@@ -56,7 +56,8 @@
</a>
</div>
<div class="modal-body">
-% if ( $Attribute eq 'Subject' ) {
+% if ( $Class eq 'RT::Tickets' ) {
+% if ( $Attribute eq 'Subject' ) {
<div class="form-row">
<div class="label col-3">
<&|/l&>Subject</&>:
@@ -65,25 +66,7 @@
<input class="form-control" name="Subject" value="<% $filter->{Subject} // '' %>" />
</div>
</div>
-% } elsif ( $Attribute eq 'Status' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Status</&>:
- </div>
- <div class="value col-9">
- <ul class="list-group list-group-compact">
-% for my $status ( sort { lc $a cmp lc $b } keys %$status ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" id="Status-<% $status %>" name="Status" class="custom-control-input" value="<% $status %>" <% $filter->{Status}{$status} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="Status-<% $status %>"><% $status %></label>
- </div>
- </li>
-% }
- </ul>
- </div>
- </div>
-% } elsif ( $Attribute eq 'Queue' ) {
+% } elsif ( $Attribute eq 'Queue' ) {
<div class="form-row">
<div class="label col-3">
<&|/l&>Queue</&>:
@@ -101,7 +84,7 @@
</ul>
</div>
</div>
-% } elsif ( $Attribute eq 'Owner' ) {
+% } elsif ( $Attribute eq 'Owner' ) {
<div class="form-row">
<div class="label col-3">
<&|/l&>Owner</&>:
@@ -110,7 +93,7 @@
<& /Elements/SelectOwner, Name => 'Owner', Default => $filter->{Owner}, Size => 6 &>
</div>
</div>
-% } elsif ( $Attribute eq 'SLA' ) {
+% } elsif ( $Attribute eq 'SLA' ) {
<div class="form-row">
<div class="label col-3">
<&|/l&>SLA</&>:
@@ -128,16 +111,7 @@
</ul>
</div>
</div>
-% } elsif ( $Attribute =~ /^(?:Creator|LastUpdatedBy)$/) {
- <div class="form-row">
- <div class="label col-3">
- <% loc(join ' ', split /(?=[A-Z])/, $Attribute) %>:
- </div>
- <div class="value col-9">
- <input class="form-control" data-autocomplete="Users" name="<% $Attribute %>" value="<% $filter->{$Attribute} %>" data-autocomplete-return="Name" />
- </div>
- </div>
-% } elsif ( $Attribute eq 'Type' ) {
+% } elsif ( $Attribute eq 'Type' ) {
<div class="form-row">
<div class="label col-3">
<&|/l&>Type</&>:
@@ -155,7 +129,7 @@
</ul>
</div>
</div>
-% } elsif ( $Attribute =~ /(?:Initial|Final)?Priority/ ) {
+% } elsif ( $Attribute =~ /(?:Initial|Final)?Priority/ ) {
<div class="form-row">
<div class="label col-6">
<% loc('[_1] equal to', join ' ', split /(?=[A-Z])/, $Attribute) %>:
@@ -180,32 +154,7 @@
<& /Elements/SelectPriority, Name => "${Attribute}LessThan", Default => $filter->{$Attribute}{'<'}, Queues => { map { $_->Id => 1 } @$queues }, ValueAsString => 1, ShowEmptyOption => 1 &>
</div>
</div>
-% } elsif ( $Attribute eq 'id' ) {
- <div class="form-row">
- <div class="label col-6">
- <% loc('[_1] equal to', $Attribute) %>:
- </div>
- <div class="value col-6">
- <input type="text" class="form-control" name="<% $Attribute %>EqualTo" size="5" value="<% $filter->{$Attribute}{'='} %>" />
- </div>
- </div>
- <div class="form-row">
- <div class="label col-6">
- <% loc('[_1] greater than', $Attribute) %>:
- </div>
- <div class="value col-6">
- <input type="text" class="form-control" name="<% $Attribute %>GreaterThan" size="5" value="<% $filter->{$Attribute}{'>'} %>" />
- </div>
- </div>
- <div class="form-row">
- <div class="label col-6">
- <% loc('[_1] less than', $Attribute) %>:
- </div>
- <div class="value col-6">
- <input type="text" class="form-control" name="<% $Attribute %>LessThan" size="5" value="<% $filter->{$Attribute}{'<'} %>" />
- </div>
- </div>
-% } elsif ( $Attribute =~ /^(?:Told|Starts|Started|Due|Resolved|Created|LastUpdated)/ ) {
+% } elsif ( $Attribute =~ /^(?:Told|Starts|Started|Due|Resolved)/ ) {
<div class="form-row">
<div class="label col-6">
<% loc('[_1] equal to', join ' ', split /(?=[A-Z])/, $Attribute) %>:
@@ -230,7 +179,7 @@
<& /Elements/SelectDate, Name => "${Attribute}LessThan", Default => $filter->{$Attribute}{'<'} || '', ShowTime => 0 &>
</div>
</div>
-% } elsif ( $Attribute =~ /^Time/ ) {
+% } elsif ( $Attribute =~ /^Time/ ) {
<div class="form-row">
<div class="label col-6">
<% loc('[_1] equal to', join ' ', split /(?=[A-Z])/, $Attribute) %>:
@@ -264,7 +213,46 @@
<&|/l&>Minutes</&>
</div>
</div>
-% } elsif ( $Attribute =~ /^(Requestor|Cc|AdminCc)s?$/) {
+% } elsif ( $Attribute =~ /^(Requestor|Cc|AdminCc)s?$/ ) {
+% my $name = $1;
+ <div class="form-row">
+ <div class="label col-4">
+ <% loc($name) %>:
+ </div>
+ <div class="value col-8">
+ <input class="form-control" data-autocomplete="Users" name="<% $name %>" value="<% $filter->{$name} %>" />
+ </div>
+ </div>
+% }
+% } elsif ( $Class eq 'RT::Assets' ) {
+% if ( $Attribute =~ /^(Name|Description)$/ ) {
+ <div class="form-row">
+ <div class="label col-3">
+ <% loc($Attribute) %>:
+ </div>
+ <div class="value col-9">
+ <input class="form-control" name="<% $Attribute %>" value="<% $filter->{$Attribute} // '' %>" />
+ </div>
+ </div>
+% } elsif ( $Attribute eq 'Catalog' ) {
+ <div class="form-row">
+ <div class="label col-3">
+ <&|/l&>Catalog</&>:
+ </div>
+ <div class="value col-9">
+ <ul class="list-group list-group-compact">
+% for my $catalog ( sort { lc $a->Name cmp lc $b->Name } @$catalogs ) {
+ <li class="list-group-item">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="Catalog-<% $catalog->Id %>" name="Catalog" class="custom-control-input" value="<% $catalog->Id %>" <% $filter->{Catalog}{$catalog->Id} ? 'checked="checked"' : '' |n %> />
+ <label class="custom-control-label" for="Catalog-<% $catalog->Id %>"><% $catalog->Name %></label>
+ </div>
+ </li>
+% }
+ </ul>
+ </div>
+ </div>
+% } elsif ( $Attribute =~ /^(Contact|Owner|HeldBy)s?$/ ) {
% my $name = $1;
<div class="form-row">
<div class="label col-4">
@@ -274,6 +262,86 @@
<input class="form-control" data-autocomplete="Users" name="<% $name %>" value="<% $filter->{$name} %>" />
</div>
</div>
+% }
+% }
+
+% if ( $Attribute eq 'Status' ) {
+ <div class="form-row">
+ <div class="label col-3">
+ <&|/l&>Status</&>:
+ </div>
+ <div class="value col-9">
+ <ul class="list-group list-group-compact">
+% for my $status ( sort { lc $a cmp lc $b } keys %$status ) {
+ <li class="list-group-item">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="Status-<% $status %>" name="Status" class="custom-control-input" value="<% $status %>" <% $filter->{Status}{$status} ? 'checked="checked"' : '' |n %> />
+ <label class="custom-control-label" for="Status-<% $status %>"><% $status %></label>
+ </div>
+ </li>
+% }
+ </ul>
+ </div>
+ </div>
+% } elsif ( $Attribute eq 'id' ) {
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] equal to', $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <input type="text" class="form-control" name="<% $Attribute %>EqualTo" size="5" value="<% $filter->{$Attribute}{'='} %>" />
+ </div>
+ </div>
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] greater than', $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <input type="text" class="form-control" name="<% $Attribute %>GreaterThan" size="5" value="<% $filter->{$Attribute}{'>'} %>" />
+ </div>
+ </div>
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] less than', $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <input type="text" class="form-control" name="<% $Attribute %>LessThan" size="5" value="<% $filter->{$Attribute}{'<'} %>" />
+ </div>
+ </div>
+% } elsif ( $Attribute =~ /^(?:Creator|LastUpdatedBy)$/) {
+ <div class="form-row">
+ <div class="label col-3">
+ <% loc(join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ </div>
+ <div class="value col-9">
+ <input class="form-control" data-autocomplete="Users" name="<% $Attribute %>" value="<% $filter->{$Attribute} %>" data-autocomplete-return="Name" />
+ </div>
+ </div>
+% } elsif ( $Attribute =~ /^(?:Created|LastUpdated)/ ) {
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] equal to', join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <& /Elements/SelectDate, Name => "${Attribute}EqualTo", Default => $filter->{$Attribute}{'='} || '', ShowTime => 0 &>
+ </div>
+ </div>
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] greater than', join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <& /Elements/SelectDate, Name => "${Attribute}GreaterThan", Default => $filter->{$Attribute}{'>'} || '', ShowTime => 0 &>
+ </div>
+ </div>
+ <div class="form-row">
+ <div class="label col-6">
+ <% loc('[_1] less than', join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ </div>
+ <div class="value col-6">
+ <& /Elements/SelectDate, Name => "${Attribute}LessThan", Default => $filter->{$Attribute}{'<'} || '', ShowTime => 0 &>
+ </div>
+ </div>
% } elsif ( $Attribute =~ /^CustomRole\.\{(.+)\}$/) {
% my $name = $1;
<div class="form-row">
@@ -319,7 +387,7 @@
<input type="button" class="button btn btn-primary" data-dismiss="modal" name="Apply" value="<% loc('Cancel') %>" />
</div>
<div class="col-auto">
- <input type="button" class="button btn btn-primary" onclick="filterSearchResults()" name="Apply" value="<% loc('Apply') %>" />
+ <input type="button" class="button btn btn-primary" onclick="filterSearchResults('<% $Class %>')" name="Apply" value="<% loc('Apply') %>" />
</div>
</div>
</div>
@@ -332,10 +400,11 @@ return unless $ARGS{Query};
my $status = $FilterData{status};
my $queues = $FilterData{queues};
+my $catalogs = $FilterData{catalogs};
my $filter = $FilterData{filter};
my $modal_class;
-if ( $Attribute =~ /^(?:Time|(?:Initial|Final)Priority|LastUpdated)/ ) {
+if ( $Attribute =~ /^(?:Time|(?:Initial|Final)Priority|LastUpdated|Description)/ ) {
$modal_class = 'modal-md';
}
else {
@@ -346,4 +415,5 @@ else {
<%ARGS>
$Attribute => ''
%FilterData => ()
+$Class => 'RT::Tickets'
</%ARGS>
diff --git a/share/static/js/util.js b/share/static/js/util.js
index d349bd6dcc..79e21316c7 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -1023,66 +1023,121 @@ jQuery(function() {
});
});
-function filterSearchResults () {
+function filterSearchResults (type) {
var clauses = [];
- var queue_clauses = [];
- jQuery('.search-results-filter input[name=Queue]:checked').each(function() {
- queue_clauses.push( 'Queue = ' + '"' + jQuery(this).val() + '"' );
- });
+ if ( type === 'RT::Tickets' ) {
- if ( queue_clauses.length ) {
- clauses.push( '( ' + queue_clauses.join( ' OR ' ) + ' )' );
- }
+ var queue_clauses = [];
+ jQuery('.search-results-filter input[name=Queue]:checked').each(function() {
+ queue_clauses.push( 'Queue = ' + '"' + jQuery(this).val() + '"' );
+ });
- var status_clauses = [];
- jQuery('.search-results-filter input[name=Status]:checked').each(function() {
- status_clauses.push('Status = ' + '"' + jQuery(this).val() + '"' );
- });
+ if ( queue_clauses.length ) {
+ clauses.push( '( ' + queue_clauses.join( ' OR ' ) + ' )' );
+ }
- if ( status_clauses.length ) {
- clauses.push( '( ' + status_clauses.join( ' OR ' ) + ' )' );
- }
+ var sla_clauses = [];
+ jQuery('.search-results-filter input[name=SLA]:checked').each(function() {
+ var value = jQuery(this).val();
+ if ( value == 'NULL' ) {
+ sla_clauses.push( 'SLA IS NULL' );
+ }
+ else {
+ sla_clauses.push( 'SLA = ' + '"' + value + '"' );
+ }
+ });
- var sla_clauses = [];
- jQuery('.search-results-filter input[name=SLA]:checked').each(function() {
- var value = jQuery(this).val();
- if ( value == 'NULL' ) {
- sla_clauses.push( 'SLA IS NULL' );
+ var type_clauses = [];
+ jQuery('.search-results-filter input[name=Type]:checked').each(function() {
+ type_clauses.push('Type = ' + '"' + jQuery(this).val() + '"' );
+ });
+
+ if ( type_clauses.length ) {
+ clauses.push( '( ' + type_clauses.join( ' OR ' ) + ' )' );
}
- else {
- sla_clauses.push( 'SLA = ' + '"' + value + '"' );
+
+ var subject = jQuery('.search-results-filter input[name=Subject]').val();
+ if ( subject && subject.match(/\S/) ) {
+ clauses.push( '( Subject LIKE "' + subject.replace(/(["\\])/g, "\\$1") + '" )' );
}
- });
- var type_clauses = [];
- jQuery('.search-results-filter input[name=Type]:checked').each(function() {
- type_clauses.push('Type = ' + '"' + jQuery(this).val() + '"' );
- });
+ jQuery('.search-results-filter :input[name=Owner]').each(function() {
+ var value = jQuery(this).val();
+ if ( value && value.match(/\S/) ) {
+ clauses.push( 'Owner.Name = ' + '"' + value + '"' );
+ }
+ });
- if ( type_clauses.length ) {
- clauses.push( '( ' + type_clauses.join( ' OR ' ) + ' )' );
- }
+ [ 'Requestors', 'Requestor', 'Cc', 'AdminCc' ].forEach( function(role) {
+ var value = jQuery('.search-results-filter input[name=' + role + ']').val();
+ if ( value && value.match(/\S/) ) {
+ clauses.push( role + '.EmailAddress = ' + "'" + value + "'" );
+ }
+ });
+
+
+ [ 'Told', 'Starts', 'Started', 'Due', 'Resolved', 'Priority', 'InitialPriority', 'FinalPriority', 'TimeWorked', 'TimeEstimated', 'TimeLeft' ].forEach(function(type) {
+ var subs = [];
+ [ 'EqualTo', 'GreaterThan', 'LessThan' ].forEach( function(op) {
+ var value = jQuery('.search-results-filter :input[name=' + type + op + ']').val();
+ if ( value && value.match(/\S/) ) {
+ if ( value.match(/\D/) ) {
+ value = "'" + value + "'";
+ }
- var subject = jQuery('.search-results-filter input[name=Subject]').val();
- if ( subject && subject.match(/\S/) ) {
- clauses.push( '( Subject LIKE "' + subject.replace(/(["\\])/g, "\\$1") + '" )' );
+ if ( op == 'EqualTo' ) {
+ subs.push( type + ' = ' + value );
+ }
+ else if ( op == 'GreaterThan' ) {
+ subs.push( type + ' > ' + value );
+ }
+ else {
+ subs.push( type + ' < ' + value );
+ }
+ }
+ });
+ if ( subs.length ) {
+ clauses.push( '( ' + subs.join( ' AND ' ) + ' )' );
+ }
+ });
}
+ else if ( type === 'RT::Assets' ) {
- [ 'Requestors', 'Requestor', 'Cc', 'AdminCc', ].forEach( function(role) {
- var value = jQuery('.search-results-filter input[name=' + role + ']').val();
- if ( value && value.match(/\S/) ) {
- clauses.push( role + '.EmailAddress = ' + "'" + value + "'" );
- }
- });
+ var catalog_clauses = [];
+ jQuery('.search-results-filter input[name=Catalog]:checked').each(function() {
+ catalog_clauses.push( 'Catalog = ' + '"' + jQuery(this).val() + '"' );
+ });
- jQuery('.search-results-filter :input[name=Owner]').each(function() {
- var value = jQuery(this).val();
- if ( value && value.match(/\S/) ) {
- clauses.push( 'Owner.Name = ' + '"' + value + '"' );
+ if ( catalog_clauses.length ) {
+ clauses.push( '( ' + catalog_clauses.join( ' OR ' ) + ' )' );
}
+
+ [ 'Owner', 'HeldBy', 'Contact' ].forEach( function(role) {
+ var value = jQuery('.search-results-filter input[name=' + role + ']').val();
+ if ( value && value.match(/\S/) ) {
+ clauses.push( role + '.EmailAddress = ' + "'" + value + "'" );
+ }
+ });
+
+ [ 'Name', 'Description' ].forEach( function(item) {
+ var value = jQuery('.search-results-filter input[name=' + item + ']').val();
+ if ( value && value.match(/\S/) ) {
+ clauses.push( '( ' + item + ' LIKE "' + value.replace(/(["\\])/g, "\\$1") + '" )' );
+ }
+ });
+ }
+
+
+ var status_clauses = [];
+ jQuery('.search-results-filter input[name=Status]:checked').each(function() {
+ status_clauses.push('Status = ' + '"' + jQuery(this).val() + '"' );
});
+ if ( status_clauses.length ) {
+ clauses.push( '( ' + status_clauses.join( ' OR ' ) + ' )' );
+ }
+
jQuery('.search-results-filter input[name^=CustomRole]').each(function() {
var role = jQuery(this).attr('name');
var value = jQuery(this).val();
@@ -1099,7 +1154,7 @@ function filterSearchResults () {
}
});
- [ 'id', 'Told', 'Starts', 'Started', 'Due', 'Resolved', 'Created', 'LastUpdated', 'Priority', 'InitialPriority', 'FinalPriority', 'TimeWorked', 'TimeEstimated', 'TimeLeft' ].forEach(function(type) {
+ [ 'id', 'Created', 'LastUpdated' ].forEach(function(type) {
var subs = [];
[ 'EqualTo', 'GreaterThan', 'LessThan' ].forEach( function(op) {
var value = jQuery('.search-results-filter :input[name=' + type + op + ']').val();
-----------------------------------------------------------------------
hooks/post-receive
--
rt
More information about the rt-commit
mailing list