Skip to content

Commit

Permalink
Add search filter support to assets
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnavy committed Jan 23, 2024
1 parent 3042d82 commit 53c3f33
Show file tree
Hide file tree
Showing 4 changed files with 559 additions and 135 deletions.
299 changes: 209 additions & 90 deletions share/html/Elements/CollectionAsTable/Header
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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>');
Expand All @@ -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>
Loading

0 comments on commit 53c3f33

Please sign in to comment.