Mailing List Archive

rt branch 5.0/asset-search-filter created. rt-5.0.5-72-ga5ca988744
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 a5ca9887448a5bb8ef86215caced7e373245d542 (commit)

- Log -----------------------------------------------------------------
commit a5ca9887448a5bb8ef86215caced7e373245d542
Author: sunnavy <sunnavy@bestpractical.com>
Date: Wed Dec 20 17:27:31 2023 -0500

Add search filter support to assets

diff --git a/share/html/Elements/CollectionAsTable/Header b/share/html/Elements/CollectionAsTable/Header
index e0c0b5c226..ad0225975d 100644
--- a/share/html/Elements/CollectionAsTable/Header
+++ b/share/html/Elements/CollectionAsTable/Header
@@ -218,12 +218,22 @@ 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;
+ my $filter_comp;
+ 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/;
+ $filter_comp = '/Search/Elements/FilterTickets';
+ }
+ elsif ( $Class eq 'RT::Assets' ) {
+ %supported = map { $_ => 1 }
+ qw/id Name Description Status Catalog Created LastUpdated Creator LastUpdatedBy Owner HeldBy Contact Contacts/;
+ $filter_comp = '/Search/Elements/FilterAssets';
+ }

+ my $field;
if ( ( $attr || '' ) =~ /^(\w+)/ && $supported{$1} ) {
$field = $1;
}
@@ -242,7 +252,7 @@ foreach my $col ( @Format ) {
$m->out(
qq{&nbsp;<a href="javascript:void(0)" class="btn btn-primary button search-filter" data-toggle="tooltip" data-placement="bottom" data-original-title="$tooltip">$icon</a>}
);
- $m->out( $m->scomp( '/Search/Elements/FilterTickets', Attribute => $field, FilterData => \%filter_data, %ARGS ) );
+ $m->out( $m->scomp( $filter_comp, Attribute => $field, FilterData => \%filter_data, %ARGS ) );
}
}
$m->out('</th>');
@@ -253,109 +263,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/Search/Elements/FilterTickets b/share/html/Search/Elements/FilterAssets
similarity index 60%
copy from share/html/Search/Elements/FilterTickets
copy to share/html/Search/Elements/FilterAssets
index 2360397dd5..bbaff8689c 100644
--- a/share/html/Search/Elements/FilterTickets
+++ b/share/html/Search/Elements/FilterAssets
@@ -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 modal-dialog-scrollable <% $modal_class %>" role="document">
<form name="search-results-filter">
<div class="modal-content">
<div class="modal-header">
@@ -56,130 +56,61 @@
</a>
</div>
<div class="modal-body">
-% if ( $Attribute eq 'Subject' ) {
+% if ( $Attribute =~ /^(Name|Description)$/ ) {
<div class="form-row">
<div class="label col-3">
- <&|/l&>Subject</&>:
+ <% loc($Attribute) %>:
</div>
<div class="value col-9">
- <input class="form-control" name="Subject" value="<% $filter->{Subject} // '' %>" />
+ <input class="form-control" name="<% $Attribute %>" value="<% $filter->{$Attribute} // '' %>" />
</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 'Catalog' ) {
<div class="form-row">
<div class="label col-3">
- <&|/l&>Queue</&>:
+ <&|/l&>Catalog</&>:
</div>
<div class="value col-9">
<ul class="list-group list-group-compact">
-% for my $queue ( sort { lc $a->Name cmp lc $b->Name } @$queues ) {
+% 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="Queue-<% $queue->Id %>" name="Queue" class="custom-control-input" value="<% $queue->Id %>" <% $filter->{Queue}{$queue->Id} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="Queue-<% $queue->Id %>"><% $queue->Name %></label>
+ <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 eq 'Owner' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Owner</&>:
- </div>
- <div class="value col-9">
- <& /Elements/SelectOwner, Name => 'Owner', Default => $filter->{Owner}, Size => 6 &>
- </div>
- </div>
-% } elsif ( $Attribute eq 'SLA' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>SLA</&>:
- </div>
- <div class="value col-9">
- <ul class="list-group list-group-compact">
-% for my $sla ( sort( keys %{RT->Config->Get('ServiceAgreements')->{'Levels'}} ), 'NULL' ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" class="custom-control-input checkbox" id="SLA_<% $sla %>" name="SLA" value="<% $sla %>" <% $filter->{SLA}{$sla} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="SLA_<% $sla %>"><% $sla eq 'NULL' ? loc('(no value)') : $sla %></label>
- </div>
- </li>
-% }
- </ul>
- </div>
- </div>
-% } elsif ( $Attribute =~ /^(?:Creator|LastUpdatedBy)$/) {
+% } elsif ( $Attribute =~ /^(Contact|Owner|HeldBy)s?$/ ) {
+% my $name = $1;
<div class="form-row">
- <div class="label col-3">
- <% loc(join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ <div class="label col-4">
+ <% loc($name) %>:
</div>
- <div class="value col-9">
- <input class="form-control" data-autocomplete="Users" name="<% $Attribute %>" value="<% $filter->{$Attribute} %>" data-autocomplete-return="Name" />
+ <div class="value col-8">
+ <input class="form-control" data-autocomplete="Users" name="<% $name %>" value="<% $filter->{$name} %>" />
</div>
</div>
-% } elsif ( $Attribute eq 'Type' ) {
+% } elsif ( $Attribute eq 'Status' ) {
<div class="form-row">
<div class="label col-3">
- <&|/l&>Type</&>:
+ <&|/l&>Status</&>:
</div>
<div class="value col-9">
<ul class="list-group list-group-compact">
-% for my $type ( qw/approval reminder ticket/ ) {
+% 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="Type-<% $type %>" name="Type" class="custom-control-input" value="<% $type %>" <% $filter->{Type}{$type} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="Type-<% $type %>"><% $type %></label>
+ <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 =~ /(?:Initial|Final)?Priority/ ) {
- <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/SelectPriority, Name => "${Attribute}EqualTo", Default => $filter->{$Attribute}{'='}, Queues => { map { $_->Id => 1 } @$queues }, ValueAsString => 1, ShowEmptyOption => 1 &>
- </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/SelectPriority, Name => "${Attribute}GreaterThan", Default => $filter->{$Attribute}{'>'}, Queues => { map { $_->Id => 1 } @$queues }, ValueAsString => 1, ShowEmptyOption => 1 &>
- </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/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">
@@ -205,41 +136,22 @@
<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)/ ) {
- <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>
+% } elsif ( $Attribute =~ /^(?:Creator|LastUpdatedBy)$/) {
<div class="form-row">
- <div class="label col-6">
- <% loc('[_1] less than', join ' ', split /(?=[A-Z])/, $Attribute) %>:
+ <div class="label col-3">
+ <% loc(join ' ', split /(?=[A-Z])/, $Attribute) %>:
</div>
- <div class="value col-6">
- <& /Elements/SelectDate, Name => "${Attribute}LessThan", Default => $filter->{$Attribute}{'<'} || '', ShowTime => 0 &>
+ <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 =~ /^Time/ ) {
+% } 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">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>EqualTo" size="5" value="<% $filter->{$Attribute}{'='} %>" />
- </div>
- <&|/l&>Minutes</&>
+ <& /Elements/SelectDate, Name => "${Attribute}EqualTo", Default => $filter->{$Attribute}{'='} || '', ShowTime => 0 &>
</div>
</div>
<div class="form-row">
@@ -247,10 +159,7 @@
<% loc('[_1] greater than', join ' ', split /(?=[A-Z])/, $Attribute) %>:
</div>
<div class="value col-6">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>GreaterThan" size="5" value="<% $filter->{$Attribute}{'>'} %>" />
- </div>
- <&|/l&>Minutes</&>
+ <& /Elements/SelectDate, Name => "${Attribute}GreaterThan", Default => $filter->{$Attribute}{'>'} || '', ShowTime => 0 &>
</div>
</div>
<div class="form-row">
@@ -258,20 +167,7 @@
<% loc('[_1] less than', join ' ', split /(?=[A-Z])/, $Attribute) %>:
</div>
<div class="value col-6">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>LessThan" size="5" value="<% $filter->{$Attribute}{'<'} %>" />
- </div>
- <&|/l&>Minutes</&>
- </div>
- </div>
-% } 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} %>" />
+ <& /Elements/SelectDate, Name => "${Attribute}LessThan", Default => $filter->{$Attribute}{'<'} || '', ShowTime => 0 &>
</div>
</div>
% } elsif ( $Attribute =~ /^CustomRole\.\{(.+)\}$/) {
@@ -319,7 +215,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('RT::Assets')" name="Apply" value="<% loc('Apply') %>" />
</div>
</div>
</div>
@@ -331,11 +227,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|Created|LastUpdated)/ ) {
+if ( $Attribute =~ /^(?:Created|LastUpdated|Description)/ ) {
$modal_class = 'modal-md';
}
else {
diff --git a/share/html/Search/Elements/FilterTickets b/share/html/Search/Elements/FilterTickets
index 2360397dd5..3276aa2d94 100644
--- a/share/html/Search/Elements/FilterTickets
+++ b/share/html/Search/Elements/FilterTickets
@@ -319,7 +319,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('RT::Tickets')" name="Apply" value="<% loc('Apply') %>" />
</div>
</div>
</div>
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();

commit 3042d82a414b20767d2d7a04efefb59cdcd57c0d
Author: sunnavy <sunnavy@bestpractical.com>
Date: Wed Dec 20 17:22:04 2023 -0500

Use a wider modal for Created column just like LastUpdated

Created and LastUpdated have the same modal inputs and should be treated
in the same way.

diff --git a/share/html/Search/Elements/FilterTickets b/share/html/Search/Elements/FilterTickets
index 24172b75d2..2360397dd5 100644
--- a/share/html/Search/Elements/FilterTickets
+++ b/share/html/Search/Elements/FilterTickets
@@ -335,7 +335,7 @@ my $queues = $FilterData{queues};
my $filter = $FilterData{filter};

my $modal_class;
-if ( $Attribute =~ /^(?:Time|(?:Initial|Final)Priority|LastUpdated)/ ) {
+if ( $Attribute =~ /^(?:Time|(?:Initial|Final)Priority|Created|LastUpdated)/ ) {
$modal_class = 'modal-md';
}
else {

commit d7cddf59d6c07b86f86c9a1056434399bedff739
Author: sunnavy <sunnavy@bestpractical.com>
Date: Wed Dec 20 17:12:56 2023 -0500

Move /Elements/SearchFilter to /Search/Elements/FilterTickets

Then it's clear that it's bound to /Search/. Also add "Tickets" suffix
as we are going to support more types.

diff --git a/share/html/Elements/CollectionAsTable/Header b/share/html/Elements/CollectionAsTable/Header
index 9b4ac06fff..e0c0b5c226 100644
--- a/share/html/Elements/CollectionAsTable/Header
+++ b/share/html/Elements/CollectionAsTable/Header
@@ -242,7 +242,7 @@ foreach my $col ( @Format ) {
$m->out(
qq{&nbsp;<a href="javascript:void(0)" class="btn btn-primary button search-filter" data-toggle="tooltip" data-placement="bottom" data-original-title="$tooltip">$icon</a>}
);
- $m->out( $m->scomp( '/Elements/SearchFilter', Attribute => $field, FilterData => \%filter_data, %ARGS ) );
+ $m->out( $m->scomp( '/Search/Elements/FilterTickets', Attribute => $field, FilterData => \%filter_data, %ARGS ) );
}
}
$m->out('</th>');
diff --git a/share/html/Elements/SearchFilter b/share/html/Elements/SearchFilter
index 24172b75d2..ebfe08e4d5 100644
--- a/share/html/Elements/SearchFilter
+++ b/share/html/Elements/SearchFilter
@@ -45,305 +45,11 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<div class="modal search-results-filter">
- <div class="modal-dialog <% $Attribute eq 'Owner' ? '' : 'modal-dialog-scrollable' %> <% $modal_class %>" role="document">
- <form name="search-results-filter">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title"><&|/l&>Filter Results</&></h5>
- <a href="javascript:void(0)" class="close" data-dismiss="modal" aria-label="Close">
- <span aria-hidden="true">&times;</span>
- </a>
- </div>
- <div class="modal-body">
-% if ( $Attribute eq 'Subject' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Subject</&>:
- </div>
- <div class="value col-9">
- <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' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Queue</&>:
- </div>
- <div class="value col-9">
- <ul class="list-group list-group-compact">
-% for my $queue ( sort { lc $a->Name cmp lc $b->Name } @$queues ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" id="Queue-<% $queue->Id %>" name="Queue" class="custom-control-input" value="<% $queue->Id %>" <% $filter->{Queue}{$queue->Id} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="Queue-<% $queue->Id %>"><% $queue->Name %></label>
- </div>
- </li>
-% }
- </ul>
- </div>
- </div>
-% } elsif ( $Attribute eq 'Owner' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Owner</&>:
- </div>
- <div class="value col-9">
- <& /Elements/SelectOwner, Name => 'Owner', Default => $filter->{Owner}, Size => 6 &>
- </div>
- </div>
-% } elsif ( $Attribute eq 'SLA' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>SLA</&>:
- </div>
- <div class="value col-9">
- <ul class="list-group list-group-compact">
-% for my $sla ( sort( keys %{RT->Config->Get('ServiceAgreements')->{'Levels'}} ), 'NULL' ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" class="custom-control-input checkbox" id="SLA_<% $sla %>" name="SLA" value="<% $sla %>" <% $filter->{SLA}{$sla} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="SLA_<% $sla %>"><% $sla eq 'NULL' ? loc('(no value)') : $sla %></label>
- </div>
- </li>
-% }
- </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' ) {
- <div class="form-row">
- <div class="label col-3">
- <&|/l&>Type</&>:
- </div>
- <div class="value col-9">
- <ul class="list-group list-group-compact">
-% for my $type ( qw/approval reminder ticket/ ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" id="Type-<% $type %>" name="Type" class="custom-control-input" value="<% $type %>" <% $filter->{Type}{$type} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="Type-<% $type %>"><% $type %></label>
- </div>
- </li>
-% }
- </ul>
- </div>
- </div>
-% } elsif ( $Attribute =~ /(?:Initial|Final)?Priority/ ) {
- <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/SelectPriority, Name => "${Attribute}EqualTo", Default => $filter->{$Attribute}{'='}, Queues => { map { $_->Id => 1 } @$queues }, ValueAsString => 1, ShowEmptyOption => 1 &>
- </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/SelectPriority, Name => "${Attribute}GreaterThan", Default => $filter->{$Attribute}{'>'}, Queues => { map { $_->Id => 1 } @$queues }, ValueAsString => 1, ShowEmptyOption => 1 &>
- </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/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)/ ) {
- <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 =~ /^Time/ ) {
- <div class="form-row">
- <div class="label col-6">
- <% loc('[_1] equal to', join ' ', split /(?=[A-Z])/, $Attribute) %>:
- </div>
- <div class="value col-6">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>EqualTo" size="5" value="<% $filter->{$Attribute}{'='} %>" />
- </div>
- <&|/l&>Minutes</&>
- </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">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>GreaterThan" size="5" value="<% $filter->{$Attribute}{'>'} %>" />
- </div>
- <&|/l&>Minutes</&>
- </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">
- <div class="d-inline-block">
- <input type="text" class="form-control" name="<% $Attribute %>LessThan" size="5" value="<% $filter->{$Attribute}{'<'} %>" />
- </div>
- <&|/l&>Minutes</&>
- </div>
- </div>
-% } 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 ( $Attribute =~ /^CustomRole\.\{(.+)\}$/) {
-% 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="<% $Attribute %>" value="<% $filter->{$Attribute} %>" />
- </div>
- </div>
-% } elsif ( $Attribute =~ /^CustomField\.\{(.+)\}$/) {
-% my $name = $1;
-% my $cf = RT::CustomField->new($session{CurrentUser});
-% $cf->Load($name);
- <div class="form-row">
- <div class="label col-4">
- <% loc($name) %>:
- </div>
- <div class="value col-8">
-% if ( $cf->Type eq 'Select' ) {
-% my $cfvs = $cf->Values;
- <ul class="list-group list-group-compact">
-% while ( my $cfv = $cfvs->Next ) {
- <li class="list-group-item">
- <div class="custom-control custom-checkbox">
- <input type="checkbox" class="custom-control-input checkbox" id="<% $name . '_' . $cfv->Name %>" name="<% $Attribute %>" value="<% $cfv->Name %>" <% $filter->{$Attribute}{$cfv->Name} ? 'checked="checked"' : '' |n %> />
- <label class="custom-control-label" for="<% $name . '_' . $cfv->Name %>"><% $cfv->Name %></label>
- </div>
- </li>
-% }
- </ul>
-% } else {
- <input type="text" class="form-control" name="<% $Attribute %>" size="5" value="<% $filter->{$Attribute} %>" />
-% }
- </div>
- </div>
-% }
+<& /Search/Elements/FilterTickets, %ARGS &>

- </div>
- <div class="modal-footer">
- <div class="form-row justify-content-end">
- <div class="col-auto">
- <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') %>" />
- </div>
- </div>
- </div>
- </div>
- </form>
- </div>
-</div>
<%INIT>
-return unless $ARGS{Query};
-
-my $status = $FilterData{status};
-my $queues = $FilterData{queues};
-my $filter = $FilterData{filter};
-
-my $modal_class;
-if ( $Attribute =~ /^(?:Time|(?:Initial|Final)Priority|LastUpdated)/ ) {
- $modal_class = 'modal-md';
-}
-else {
- $modal_class = 'modal-sm';
-}
+RT->Deprecated(
+ Instead => '/Search/Elements/FilterTickets',
+ Remove => '5.2',
+);
</%INIT>
-
-<%ARGS>
-$Attribute => ''
-%FilterData => ()
-</%ARGS>
diff --git a/share/html/Elements/SearchFilter b/share/html/Search/Elements/FilterTickets
similarity index 100%
copy from share/html/Elements/SearchFilter
copy to share/html/Search/Elements/FilterTickets

-----------------------------------------------------------------------


hooks/post-receive
--
rt
_______________________________________________
rt-commit mailing list
rt-commit@lists.bestpractical.com
https://lists.bestpractical.com/mailman/listinfo/rt-commit