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