Skip to content

Commit c3b8d75

Browse files
author
Andy Beverley
committed
Fix timeline group order bug
When a timeline was initially viewed (without specific dates) the ordering is by date order not by the order in the view. This caused the grouping to be in the incorrect order. This commit adds tests for this and fixes it by re-retrieving the items.
1 parent 5be1b69 commit c3b8d75

File tree

2 files changed

+75
-23
lines changed

2 files changed

+75
-23
lines changed

lib/GADS/Records.pm

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,14 +1321,14 @@ sub single
13211321

13221322
my $next_id = $self->_next_single_id;
13231323

1324-
# Check return if limiting to a set number of results
1325-
return if $self->max_results && $self->records_retrieved_count >= $self->max_results;
1326-
13271324
if (!$self->is_group) # Don't retrieve in chunks for group records
13281325
{
13291326
if (
13301327
($next_id == 0 && $self->_single_page == 0) # First run
1331-
|| $next_id >= $chunk # retrieved all of current chunk
1328+
# Retrieved all of current chunk. Make sure there aren't more
1329+
# results than the chunk (possible with
1330+
# separate_records_for_multicol)
1331+
|| ($next_id >= $chunk && $next_id >= @{$self->results})
13321332
)
13331333
{
13341334
$self->_single_page($self->_single_page + 1) # increase to next page
@@ -1561,6 +1561,7 @@ sub clear
15611561
$self->clear_aggregate_results;
15621562
$self->clear_search;
15631563
$self->_set__next_single_id(0);
1564+
$self->_single_page(0);
15641565
$self->_set_current_ids(undef);
15651566
$self->_clear_all_cids_store;
15661567
$self->_clear_cid_search_query_cache
@@ -2510,20 +2511,48 @@ sub data_timeline
25102511
# E.g. if a day is subtracted from 26th March 2018 01:00 London then it will be an
25112512
# invalid time and DateTime will bork.
25122513
$min = min map $_->{dt}, @items;
2513-
$min->set_time_zone('UTC')->subtract(days => 1) if $min;
2514+
if ($min)
2515+
{
2516+
# There is a chance that $min will be the same object as $max.
2517+
# Clone it to ensure we don't change both below
2518+
$min = $min->clone;
2519+
$min->set_time_zone('UTC'); # ->subtract(days => 1);
2520+
}
25142521

25152522
# Fix the max to no longer be where we retrieved to, but actually the
25162523
# max value of the finalised items array. Then add some padding.
25172524
$max = max map $_->{dt}, @items;
2518-
# one day already added to show period to end of day
2519-
$max->set_time_zone('UTC')->add(days => 2) if $max;
2520-
}
2521-
elsif($original_from && $original_to)
2522-
{ @items = @{$timeline->items};
2523-
($min, $max) = ($original_from, $original_to);
2524-
}
2525-
else
2526-
{ @items = @{$timeline->items};
2525+
if ($max)
2526+
{
2527+
$max = $max->clone;
2528+
$max->set_time_zone('UTC');
2529+
}
2530+
2531+
# Set from and to so that a re-retrieval retrieves the same results
2532+
$self->to($max->clone->add(days => 1)) # one day already added to show period to end of day
2533+
if $max;
2534+
$self->from($min->clone)
2535+
if $min;
2536+
2537+
# Set the display range of the timeline
2538+
$original_from = $min && $min->subtract(days => 1);
2539+
$max->add(days => 2) if $max;
2540+
$original_to = $max;
2541+
}
2542+
# If the $limit_qty routine above was used, re-retrieve all of the items to
2543+
# ensure correct sorting (in the case of grouping). XXX This only needs to
2544+
# be done if there was a grouping, but at the moment it is done for all
2545+
# conditions, to ensure they are all fully tested in the tests. What is
2546+
# needed is for the tests to be run twice, once for no re-retrieval and
2547+
# once for re-retrieval. The performance hit is probably quite low, as the
2548+
# above routine is only used when initially looking at the timeline, before
2549+
# a range has been selected by the user.
2550+
if (!$limit_qty || @items)
2551+
{
2552+
@items = @{$timeline->items};
2553+
my $m = min map $_->{dt}, @items;
2554+
($min, $max) = ($original_from, $original_to)
2555+
if $original_from && $original_to;
25272556
}
25282557

25292558
# Remove dt (DateTime) value, otherwise JSON encoding borks

t/013_datatime.t

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -694,18 +694,37 @@ is( @{$records->data_timeline->{items}}, 1, "Filter, single column and limited r
694694

695695
# Multiple items in group field, ordered correctly
696696
{
697-
my $data = [
698-
{
697+
# Create a set of data where a multivalue record is in the middle of the
698+
# right-half of the timeline. The multivalue record contains 2 values that
699+
# are at the top and bottom of the grouped items. All the other values of
700+
# the timeline are in the middle of the grouping. Because the multivalue
701+
# record is in the middle of the date range, both should show on the
702+
# grouping, one at the begninning and one at the end.
703+
my $data = [];
704+
my $date = DateTime->new(year => 2010, month => 1, day => 1);
705+
for my $i (1..100)
706+
{
707+
push @$data, {
708+
string1 => 'foo2',
709+
enum1 => [2],
710+
date1 => $date->add(days => 1)->ymd,
711+
};
712+
}
713+
push @$data,{
699714
string1 => 'foo1',
700715
enum1 => [1,3],
701-
date1 => '2010-06-01',
702-
},
703-
{
716+
date1 => '2010-07-01',
717+
};
718+
$date = DateTime->new(year => 2010, month => 8, day => 1);
719+
for my $i (1..120)
720+
{
721+
push @$data, {
704722
string1 => 'foo2',
705723
enum1 => [2],
706-
date1 => '2010-06-05',
707-
},
708-
];
724+
date1 => $date->add(days => 1)->ymd,
725+
};
726+
}
727+
709728
my $sheet = Test::GADS::DataSheet->new(data => $data, multivalue => 1);
710729

711730
$sheet->create_records;
@@ -728,12 +747,14 @@ is( @{$records->data_timeline->{items}}, 1, "Filter, single column and limited r
728747
view => $view,
729748
user => undef,
730749
layout => $layout,
750+
from => DateTime->new(year => 2010, month => 3, day => 1),
731751
schema => $schema,
732752
);
733753

734754
my $return = $records->data_timeline(group => $enum1->id);
735755

736-
is( @{$return->{items}}, 3, "Correct number of items for group ordering" );
756+
# 149 normal results as per other tests plus 1 extra result for multivalue
757+
is( @{$return->{items}}, 149, "Correct number of items for group ordering" );
737758

738759
# Check that the groups are in the right order. Because we are ordering by
739760
# the enumvals (foo1, foo2, foo3) then number in the value should match the
@@ -1067,6 +1088,8 @@ is( @{$records->data_timeline->{items}}, 1, "Filter, single column and limited r
10671088

10681089
my $layout = $sheet->layout;
10691090
$layout->clear;
1091+
$layout->user($sheet->user_normal1);
1092+
$curval_sheet->layout->user($sheet->user_normal1);
10701093

10711094
my $columns = $sheet->columns;
10721095

0 commit comments

Comments
 (0)