Commit | Line | Data |
7adfd53f |
1 | package Reaction::UI::ViewPort::Field::TimeRange; |
2 | |
3 | use Reaction::Class; |
4 | use Reaction::Types::DateTime; |
5 | use DateTime; |
6 | use DateTime::SpanSet; |
7 | use Time::ParseDate (); |
8 | |
9 | class TimeRange is 'Reaction::UI::ViewPort::Field', which { |
10 | |
11 | has '+value' => (isa => 'DateTime::SpanSet'); |
6ab43711 |
12 | |
13 | #has '+layout' => (default => 'timerange'); |
14 | |
15 | has value_string => |
7adfd53f |
16 | (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string')); |
6ab43711 |
17 | |
7adfd53f |
18 | has delete_label => ( |
19 | isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' }, |
20 | ); |
6ab43711 |
21 | |
7adfd53f |
22 | has parent => ( |
23 | isa => 'Reaction::UI::ViewPort::TimeRangeCollection', |
24 | is => 'ro', |
25 | required => 1, |
26 | is_weak_ref => 1 |
27 | ); |
6ab43711 |
28 | |
89939ff9 |
29 | implements _build_value_string => as { |
7adfd53f |
30 | my $self = shift; |
31 | #return '' unless $self->has_value; |
32 | #return $self->value_string; |
33 | }; |
6ab43711 |
34 | |
7adfd53f |
35 | implements value_array => as { |
36 | my $self = shift; |
37 | return split(',', $self->value_string); |
38 | }; |
6ab43711 |
39 | |
7adfd53f |
40 | implements adopt_value_string => as { |
41 | my ($self) = @_; |
42 | my @values = $self->value_array; |
43 | for my $idx (0 .. 3) { # last value is repeat |
44 | if (length $values[$idx]) { |
45 | my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1); |
46 | $values[$idx] = DateTime->from_epoch( epoch => $epoch ); |
6ab43711 |
47 | } |
7adfd53f |
48 | } |
49 | $self->value($self->range_to_spanset(@values)); |
50 | }; |
6ab43711 |
51 | |
7adfd53f |
52 | implements range_to_spanset => as { |
53 | my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_; |
54 | my $spanset = DateTime::SpanSet->empty_set; |
55 | if (!$pattern || $pattern eq 'none') { |
56 | my $span = DateTime::Span->from_datetimes( |
57 | start => $time_from, end => $time_to |
58 | ); |
59 | $spanset = $spanset->union( $span ); |
60 | } else { |
61 | my $duration = $time_to - $time_from; |
62 | my %args = ( days => $time_from->day + 2, |
63 | hours => $time_from->hour, |
64 | minutes => $time_from->minute, |
65 | seconds => $time_from->second ); |
6ab43711 |
66 | |
7adfd53f |
67 | delete $args{'days'} if ($pattern eq 'daily'); |
68 | delete @args{qw/hours days/} if ($pattern eq 'hourly'); |
69 | $args{'days'} = $time_from->day if ($pattern eq 'monthly'); |
70 | my $start_set = DateTime::Event::Recurrence->$pattern( %args ); |
71 | my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to ); |
72 | while ( my $dt = $iter->next ) { |
73 | my $endtime = $dt + $duration; |
74 | my $new_span = DateTime::Span->from_datetimes( |
75 | start => $dt, |
76 | end => $endtime |
77 | ); |
78 | $spanset = $spanset->union( $new_span ); |
79 | } |
80 | } |
81 | return $spanset; |
82 | }; |
6ab43711 |
83 | |
7adfd53f |
84 | implements delete => as { |
85 | my ($self) = @_; |
86 | $self->parent->remove_range_vp($self); |
87 | }; |
6ab43711 |
88 | |
7adfd53f |
89 | override accept_events => sub { ('value_string', 'delete', super()) }; |
90 | |
91 | }; |
92 | |
6ab43711 |
93 | 1; |
7adfd53f |
94 | |
95 | =head1 NAME |
96 | |
97 | Reaction::UI::ViewPort::Field::TimeRange |
98 | |
99 | =head1 SYNOPSIS |
100 | |
101 | =head1 DESCRIPTION |
102 | |
103 | =head1 METHODS |
104 | |
105 | =head2 value |
106 | |
107 | Accessor for a L<DateTime::SpanSet> object. |
108 | |
109 | =head2 value_string |
110 | |
111 | Returns: Encoded range string representing the value. |
112 | |
113 | =head2 value_array |
114 | |
115 | Returns: Arrayref of the elements of C<value_string>. |
116 | |
117 | =head2 parent |
118 | |
119 | L<Reaction::UI::ViewPort::TimeRangeCollection> object. |
120 | |
121 | =head2 range_to_spanset |
122 | |
123 | Arguments: $self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern |
124 | where $time_from, $time_to, $repeat_from, $repeat_to are L<DateTime> |
125 | objects, and $pattern is a L<DateTime::Event::Recurrence> method name |
126 | |
127 | Returns: $spanset |
128 | |
129 | =head2 delete |
130 | |
131 | Removes TimeRange from C<parent> collection. |
132 | |
133 | =head2 delete_label |
134 | |
135 | Label for the delete option. Default: 'Delete'. |
136 | |
137 | =head1 SEE ALSO |
138 | |
139 | =head2 L<Reaction::UI::ViewPort::Field> |
140 | |
141 | =head2 L<Reaction::UI::ViewPort::TimeRangeCollection> |
142 | |
143 | =head1 AUTHORS |
144 | |
145 | See L<Reaction::Class> for authors. |
146 | |
147 | =head1 LICENSE |
148 | |
149 | See L<Reaction::Class> for the license. |
150 | |
151 | =cut |