Mailing List Archive

rt branch 5.0/search-chart-sort-axis-labels created. rt-5.0.5-185-g0c5e8d2a8c
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/search-chart-sort-axis-labels has been created
at 0c5e8d2a8c159579609349bb74dce4d6278d2bb9 (commit)

- Log -----------------------------------------------------------------
commit 0c5e8d2a8c159579609349bb74dce4d6278d2bb9
Author: sunnavy <sunnavy@bestpractical.com>
Date: Thu Mar 28 11:41:17 2024 -0400

Test sorting/limiting axis labels of search charts

diff --git a/t/charts/basics.t b/t/charts/basics.t
index 0f93e5a243..390666ea0b 100644
--- a/t/charts/basics.t
+++ b/t/charts/basics.t
@@ -12,7 +12,7 @@ my @tickets = add_tix_from_data(
{ Subject => 'n', Status => 'new' },
{ Subject => 'o', Status => 'open' },
{ Subject => 'o', Status => 'open' },
- { Subject => 'r', Status => 'resolved' },
+ { Subject => 'o', Status => 'open' },
{ Subject => 'r', Status => 'resolved' },
{ Subject => 'r', Status => 'resolved' },
);
@@ -28,6 +28,19 @@ use_ok 'RT::Report::Tickets';
);
$report->SortEntries;

+ my $new_cell = [.
+ { 'value' => 'new', 'type' => 'label' },
+ { 'query' => '(Status = \'new\')', 'value' => '1', 'type' => 'value' },
+ ];
+ my $open_cell = [.
+ { 'value' => 'open', 'type' => 'label' },
+ { 'query' => '(Status = \'open\')', 'value' => '3', 'type' => 'value' }
+ ];
+ my $resolved_cell = [.
+ { 'value' => 'resolved', 'type' => 'label' },
+ { 'query' => '(Status = \'resolved\')', 'value' => '2', 'type' => 'value' }
+ ];
+
my @colors = RT->Config->Get("ChartColors");
my $expected = {
'thead' => [ {
@@ -45,24 +58,15 @@ use_ok 'RT::Report::Tickets';
} ],
'tbody' => [.
{
- 'cells' => [.
- { 'value' => 'new', 'type' => 'label' },
- { 'query' => '(Status = \'new\')', 'value' => '1', 'type' => 'value' },
- ],
+ 'cells' => $new_cell,
'even' => 1
},
{
- 'cells' => [.
- { 'value' => 'open', 'type' => 'label' },
- { 'query' => '(Status = \'open\')', 'value' => '2', 'type' => 'value' }
- ],
+ 'cells' => $open_cell,
'even' => 0
},
{
- 'cells' => [.
- { 'value' => 'resolved', 'type' => 'label' },
- { 'query' => '(Status = \'resolved\')', 'value' => '3', 'type' => 'value' }
- ],
+ 'cells' => $resolved_cell,
'even' => 1
},
]
@@ -70,6 +74,45 @@ use_ok 'RT::Report::Tickets';

my %table = $report->FormatTable( %columns );
is_deeply( \%table, $expected, "basic table" );
+
+ $report->SortEntries( ChartOrderBy => 'label', ChartOrder => 'ASC' );
+ %table = $report->FormatTable( %columns );
+ is_deeply( \%table, $expected, "basic table sorted by label ASC" );
+
+ $report->SortEntries( ChartOrderBy => 'label', ChartOrder => 'DESC' );
+ %table = $report->FormatTable( %columns );
+ @{$expected->{'tbody'}} = reverse @{$expected->{'tbody'}};
+ is_deeply( \%table, $expected, "basic table sorted by label DESC" );
+
+ $report->SortEntries( ChartOrderBy => 'value', ChartOrder => 'ASC' );
+ %table = $report->FormatTable( %columns );
+ $expected->{'tbody'} = [.
+ {
+ 'cells' => $new_cell,
+ 'even' => 1
+ },
+ {
+ 'cells' => $resolved_cell,
+ 'even' => 0,
+ },
+ {
+ 'cells' => $open_cell,
+ 'even' => 1
+ },
+ ];
+ is_deeply( \%table, $expected, "basic table sorted by value ASC" );
+
+ $report->SortEntries( ChartOrderBy => 'value', ChartOrder => 'DESC' );
+ %table = $report->FormatTable( %columns );
+ @{$expected->{'tbody'}} = reverse @{$expected->{'tbody'}};
+ is_deeply( \%table, $expected, "basic table sorted by value DESC" );
+
+ $report->SortEntries( ChartOrderBy => 'value', ChartOrder => 'DESC', ChartLimit => 2 );
+ %table = $report->FormatTable( %columns );
+ pop @{$expected->{'tbody'}};
+ $expected->{'tfoot'}[0]{'even'} = 1;
+ $expected->{'tfoot'}[0]{'cells'}[1]{'value'} = 5;
+ is_deeply( \%table, $expected, "basic table sorted by value DESC" );
}

done_testing;

commit 0c8ef9f896751f219c3e18654062ecf1fc88423f
Author: sunnavy <sunnavy@bestpractical.com>
Date: Wed Mar 27 20:16:23 2024 -0400

Support to sort/limit axis labels in search charts

Previously charts were always sorted by labels in ascending order, this
commit enhances it to support descending order too, as well as sorting by
values(i.e. asset/ticket/transaction count).

Limiting the number of results is also implemented in this commit, with
which users can easily get a more friendly chart that contains significant
data only.

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 6fe866f97f..dc90a31294 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -84,7 +84,7 @@ use RT::Interface::Web::ReportsRegistry;

our @SHORTENER_SEARCH_FIELDS
= qw/Class ObjectType BaseQuery Query Format RowsPerPage Order OrderBy ExtraQueryParams ResultPage/;
-our @SHORTENER_CHART_FIELDS = qw/Width Height ChartStyle GroupBy ChartFunction StackedGroupBy/;
+our @SHORTENER_CHART_FIELDS = qw/Width Height ChartStyle GroupBy ChartFunction StackedGroupBy ChartOrderBy ChartOrder ChartLimit/;

=head2 SquishedCSS $style

diff --git a/lib/RT/Report.pm b/lib/RT/Report.pm
index 5e76fa29ed..6cea047123 100644
--- a/lib/RT/Report.pm
+++ b/lib/RT/Report.pm
@@ -759,6 +759,12 @@ sub _FieldToFunction {

sub SortEntries {
my $self = shift;
+ my %args = (
+ ChartOrderBy => 'label',
+ ChartOrder => 'ASC',
+ ChartLimit => undef,
+ @_,
+ );

$self->_DoSearch if $self->{'must_redo_search'};
return unless $self->{'items'} && @{ $self->{'items'} };
@@ -772,16 +778,21 @@ sub SortEntries {
my @SORT_OPS;
my $by_multiple = sub ($$) {
for my $f ( @SORT_OPS ) {
- my $r = $f->($_[0], $_[1]);
+ my $r = uc $f->($args{ChartOrder} eq 'ASC' ? ( $_[0], $_[1] ) : ( $_[1], $_[0] ) );
return $r if $r;
}
};
+
my @data = map [$_], @{ $self->{'items'} };

- for ( my $i = 0; $i < @groups; $i++ ) {
- my $group_by = $groups[$i];
- my $idx = $i+1;
+ if ( $args{ChartOrderBy} eq 'value' && grep { $_ eq 'id' } $self->ColumnsList ) {
+ $_->[1] = $_->[0]->RawValue('id') for @data;
+ push @SORT_OPS, sub { $_[0][1] <=> $_[1][1] };
+ }

+ # Even if charts are sorted by value, it's still good to sort by labels next, to sort items with the same value.
+ for my $group_by ( @groups ) {
+ my $idx = @SORT_OPS + 1;
my $order = $group_by->{'META'}{Sort} || 'label';
my $method = $order =~ /label$/ ? 'LabelValue' : 'RawValue';

@@ -834,6 +845,10 @@ sub SortEntries {
map $_->[0],
sort $by_multiple @data
];
+
+ if ( $args{ChartLimit} ) {
+ $self->{'items'} = [ splice @{ $self->{'items'} }, 0, $args{ChartLimit} ];
+ }
}

sub PostProcessRecords {
diff --git a/share/html/Search/Chart b/share/html/Search/Chart
index 5b3a19afcc..516eb2b232 100644
--- a/share/html/Search/Chart
+++ b/share/html/Search/Chart
@@ -119,7 +119,7 @@ if ( $Cache and my $data = delete $session{'charts_cache'}{ $Cache } ) {
Function => \@ChartFunction,
);

- $report->SortEntries;
+ $report->SortEntries( map { $_ => $ARGS{$_} } grep { $ARGS{$_} } qw(ChartOrderBy ChartOrder ChartLimit) );
}

my @data = ([],[]);
diff --git a/share/html/Search/Chart.html b/share/html/Search/Chart.html
index 14774cdb37..667d5d1344 100644
--- a/share/html/Search/Chart.html
+++ b/share/html/Search/Chart.html
@@ -56,13 +56,16 @@ my $default_value = {
GroupBy => [ $report->DefaultGroupBy ],
ChartStyle => 'bar+table+sql',
ChartFunction => ['COUNT'],
+ ChartOrderBy => 'label',
+ ChartOrder => 'ASC',
+ ChartLimit => '',
};

$m->callback( ARGSRef => \%ARGS, CallbackName => 'Initial' );

my $title = loc( "Grouped search results");

-my @search_fields = ( qw(Query GroupBy StackedGroupBy ChartStyle ChartFunction Width Height Class ExtraQueryParams), grep $_, @ExtraQueryParams );
+my @search_fields = ( qw(Query GroupBy StackedGroupBy ChartStyle ChartFunction Width Height Class ExtraQueryParams ChartOrderBy ChartOrder ChartLimit), grep $_, @ExtraQueryParams );
my $saved_search = $m->comp( '/Widgets/SavedSearch:new',
SearchType => 'Chart',
SearchFields => [@search_fields],
@@ -273,6 +276,37 @@ $m->callback( ARGSRef => \%ARGS, QueryArgsRef => \%query );
<input type="checkbox" id="ChartStyleIncludeSQL" name="ChartStyleIncludeSQL" class="custom-control-input" <% $query{ChartStyle} =~ /\bsql\b/ ? 'checked="checked"' : '' |n %>>
<label class="custom-control-label" for="ChartStyleIncludeSQL"><&|/l&>Include TicketSQL query</&></label>
</div>
+
+ <div class="form-row sorting">
+ <div class="label col-auto">
+ <span class="far fa-question-circle icon-helper" data-toggle="tooltip" data-placement="top" data-original-title="<&|/l&>Value only works for count calculations</&>"></span>
+ <&|/l&>Order by</&>:
+ </div>
+ <div class="value col-auto">
+ <select name="ChartOrderBy" class="form-control selectpicker">
+ <option value="label" <% $query{ChartOrderBy} eq 'label' ? 'selected="selected"' : '' |n %>><&|/l&>Label</&></option>
+ <option value="value" <% $query{ChartOrderBy} eq 'value' ? 'selected="selected"' : '' |n %>><&|/l&>Value</&></option>
+ </select>
+ </div>
+ <div class="value col-auto">
+ <select name="ChartOrder" class="form-control selectpicker">
+ <option value="ASC" <% $query{ChartOrder} eq 'ASC' ? 'selected="selected"' : '' |n %>><&|/l&>ASC</&></option>
+ <option value="DESC" <% $query{ChartOrder} eq 'DESC' ? 'selected="selected"' : '' |n %>><&|/l&>DESC</&></option>
+ </select>
+ </div>
+ <div class="label col-auto"><&|/l&>Limit</&>:</div>
+ <div class="value col-auto">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text"><&|/l&>top</&></span>
+ </div>
+ <input name="ChartLimit" size="3" class="form-control" value="<% $query{ChartLimit} // '' %>" />
+ <div class="input-group-append">
+ <span class="input-group-text"><&|/l&>items</&></span>
+ </div>
+ </div>
+ </div>
+ </div>
</&>

<script type="text/javascript">
diff --git a/share/html/Search/Elements/Chart b/share/html/Search/Elements/Chart
index 7079551846..1c260788f8 100644
--- a/share/html/Search/Elements/Chart
+++ b/share/html/Search/Elements/Chart
@@ -65,7 +65,7 @@ my %columns = $report->SetupGroupings(
Function => \@ChartFunction,
);

-$report->SortEntries;
+$report->SortEntries(map { $_ => $ARGS{$_} } grep { $ARGS{$_} } qw(ChartOrderBy ChartOrder ChartLimit));

my $query_string = $m->comp('/Elements/QueryString', %ARGS, GroupBy => \@GroupBy );

diff --git a/share/html/Search/JSChart b/share/html/Search/JSChart
index dc72c4cddf..14e3024a49 100644
--- a/share/html/Search/JSChart
+++ b/share/html/Search/JSChart
@@ -208,7 +208,7 @@ if ( $Cache and my $data = delete $session{'charts_cache'}{ $Cache } ) {
Function => \@ChartFunction,
);

- $report->SortEntries;
+ $report->SortEntries( map { $_ => $ARGS{$_} } grep { $ARGS{$_} } qw(ChartOrderBy ChartOrder ChartLimit) );
}

my @data = ([],[]);

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


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