aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Reaction/UI/ViewPort/TimeRangeCollection.pm781
1 files changed, 393 insertions, 388 deletions
diff --git a/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm b/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm
index ac61f3e..985cf47 100644
--- a/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm
+++ b/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm
@@ -1,390 +1,395 @@
-package Reaction::UI::ViewPort::TimeRangeCollection;
-
-use Reaction::Class;
-use Reaction::Types::DateTime;
-use Moose::Util::TypeConstraints ();
-use DateTime::Event::Recurrence;
-use aliased 'Reaction::UI::ViewPort::Field::String';
-use aliased 'Reaction::UI::ViewPort::Field::DateTime';
-use aliased 'Reaction::UI::ViewPort::Field::HiddenArray';
-use aliased 'Reaction::UI::ViewPort::Field::TimeRange';
-
-class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
-
- #has '+layout' => (default => 'timerangecollection');
-
- has '+column_order' => (
- default => sub{[ qw/ time_from time_to pattern repeat_from repeat_to / ]},
- );
-
- has time_from => (
- isa => 'Reaction::UI::ViewPort::Field::DateTime',
- is => 'rw', lazy_build => 1,
- );
-
- has time_to => (
- isa => 'Reaction::UI::ViewPort::Field::DateTime',
- is => 'rw', lazy_build => 1,
- );
-
- has repeat_from => (
- isa => 'Reaction::UI::ViewPort::Field::DateTime',
- is => 'rw', lazy_build => 1,
- );
-
- has repeat_to => (
- isa => 'Reaction::UI::ViewPort::Field::DateTime',
- is => 'rw', lazy_build => 1,
- );
-
- has pattern => (
- isa => 'Reaction::UI::ViewPort::Field::String',
- # valid_values => [ qw/none daily weekly monthly/ ],
- is => 'rw', lazy_build => 1,
- );
-
- has range_vps => (isa => 'ArrayRef', is => 'rw', lazy_build => 1,);
-
- has max_range_vps => (isa => 'Int', is => 'rw', lazy_build => 1,);
-
- has error => (
- isa => 'Str',
- is => 'rw',
- required => 0,
- );
-
- has field_names => (
- isa => 'ArrayRef', is => 'rw',
- lazy_build => 1, clearer => 'clear_field_names',
- );
-
- has _field_map => (
- isa => 'HashRef', is => 'rw', init_arg => 'fields',
- clearer => '_clear_field_map',
- predicate => '_has_field_map',
- lazy_build => 1,
- );
-
- has on_next_callback => (
- isa => 'CodeRef',
- is => 'rw',
- predicate => 'has_on_next_callback',
- );
-
- implements fields => as { shift->_field_map };
-
- implements _build_range_vps => as { [] };
-
- implements spanset => as {
- my ($self) = @_;
- my $spanset = DateTime::SpanSet->empty_set;
- $spanset = $spanset->union($_->value) for @{$self->range_vps};
- return $spanset;
- };
-
- implements range_strings => as {
- my ($self) = @_;
- return [ map { $_->value_string } @{$self->range_vps} ];
- };
-
- implements remove_range_vp => as {
- my ($self, $to_remove) = @_;
- $self->range_vps([ grep { $_ != $to_remove } @{$self->range_vps} ]);
- $self->_clear_field_map;
- $self->clear_field_names;
- };
-
- implements add_range_vp => as {
- my ($self) = @_;
- if ($self->can_add) {
- $self->_clear_field_map;
- $self->clear_field_names;
- my @span_info = (
- $self->time_from->value,
- $self->time_to->value,
- (map { $_->has_value ? $_->value : '' }
- map { $self->$_ } qw/repeat_from repeat_to/),
- $self->pattern->value,
- );
- my $encoded_spanset = join ',', @span_info;
- my $args = {
- value_string => $encoded_spanset,
- parent => $self
- };
- my $count = scalar(@{$self->range_vps});
- my $field = $self->_build_simple_field(TimeRange, 'range-'.$count, $args);
- my $d = DateTime::Format::Duration->new( pattern => '%s' );
- if ($d->format_duration( $self->spanset->intersection($field->value)->duration ) > 0) {
- # XXX - Stop using the stash here?
- $self->ctx->stash->{warning} = 'Warning: Most recent time range overlaps '.
- 'with existing time range in this booking.';
- }
- #warn "encoded spanset = $encoded_spanset\n";
- #warn "current range = ".join(', ', (@{$self->range_vps}))."\n";
- push(@{$self->range_vps}, $field);
- }
- };
-
- implements _build_field_map => as {
- my ($self) = @_;
- my %map;
- foreach my $field (@{$self->range_vps}) {
- $map{$field->name} = $field;
- }
- foreach my $name (@{$self->column_order}) {
- $map{$name} = $self->$name;
- }
- return \%map;
- };
-
- implements _build_field_names => as {
- my ($self) = @_;
- return [
- (map { $_->name } @{$self->range_vps}),
- @{$self->column_order}
- ];
- };
-
- implements can_add => as {
- my ($self) = @_;
- my $error;
- if ($self->time_to->has_value && $self->time_from->has_value) {
- my $time_to = $self->time_to->value;
- my $time_from = $self->time_from->value;
-
- my ($pattern, $repeat_from, $repeat_to) = ('','','');
- $pattern = $self->pattern->value if $self->pattern->has_value;
- $repeat_from = $self->repeat_from->value if $self->repeat_from->has_value;
- $repeat_to = $self->repeat_to->value if $self->repeat_to->has_value;
-
- my $duration = $time_to - $time_from;
- if ($time_to < $time_from) {
- $error = 'Please make sure that the Time To is after the Time From.';
- } elsif ($time_to == $time_from) {
- $error = 'Your desired booking slot is too small.';
- } elsif ($pattern && $pattern ne 'none') {
- my %pattern = (hourly => [ hours => 1 ],
- daily => [ days => 1 ],
- weekly => [ days => 7 ],
- monthly => [ months => 1 ]);
- my $pattern_comp = DateTime::Duration->compare(
- $duration, DateTime::Duration->new( @{$pattern{$pattern}} )
- );
- if (!$repeat_to || !$repeat_from) {
- $error = 'Please make sure that you enter a valid range for the '.
- 'repetition period.';
- } elsif ($time_to == $time_from) {
- $error = 'Your desired repetition period is too short.';
- } elsif ($repeat_to && ($repeat_to < $repeat_from)) {
- $error = 'Please make sure that the Repeat To is after the Repeat From.';
- } elsif ( ( ($pattern eq 'hourly') && ($pattern_comp > 0) ) ||
- ( ($pattern eq 'daily') && ($pattern_comp > 0) ) ||
- ( ($pattern eq 'weekly') && ($pattern_comp > 0) ) ||
- ( ($pattern eq 'monthly') && ($pattern_comp > 0) ) ) {
- $error = "Your repetition pattern ($pattern) is too short for your ".
- "desired booking length.";
- }
- }
- } else {
- $error = 'Please complete both the Time To and Time From fields.';
- }
- $self->error($error);
- return !defined($error);
- };
-
- implements _build_simple_field => as {
- my ($self, $class, $name, $args) = @_;
- return $class->new(
- name => $name,
- location => join('-', $self->location, 'field', $name),
- ctx => $self->ctx,
- %$args
- );
- };
-
- implements _build_time_to => as {
- my ($self) = @_;
- return $self->_build_simple_field(DateTime, 'time_to', {});
- };
-
- implements _build_time_from => as {
- my ($self) = @_;
- return $self->_build_simple_field(DateTime, 'time_from', {});
- };
-
- implements _build_repeat_to => as {
- my ($self) = @_;
- return $self->_build_simple_field(DateTime, 'repeat_to', {});
- };
-
- implements _build_repeat_from => as {
- my ($self) = @_;
- return $self->_build_simple_field(DateTime, 'repeat_from', {});
- };
-
- implements _build_pattern => as {
- my ($self) = @_;
- return $self->_build_simple_field(String, 'pattern', {});
- };
-
- implements next => as {
- $_[0]->on_next_callback->(@_);
- };
-
- override accept_events => sub {
- my $self = shift;
- ('add_range_vp', ($self->has_on_next_callback ? ('next') : ()), super());
- };
-
- override child_event_sinks => sub {
- my ($self) = @_;
- return ((grep { ref($_) =~ 'Hidden' } values %{$self->_field_map}),
- (grep { ref($_) !~ 'Hidden' } values %{$self->_field_map}),
- super());
- };
-
- override apply_events => sub {
- my ($self, $ctx, $events) = @_;
-
- # auto-inflate range fields based on number from hidden field
-
- my $max = $events->{$self->location.':max_range_vps'};
- my @range_vps = map {
- TimeRange->new(
- name => "range-$_",
- location => join('-', $self->location, 'field', 'range', $_),
- ctx => $self->ctx,
- parent => $self,
- )
- } ($max ? (0 .. $max - 1) : ());
- $self->range_vps(\@range_vps);
- $self->_clear_field_map;
- $self->clear_field_names;
-
- # call original event handling
-
- super();
-
- # repack range VPs in case of deletion
-
- my $prev_idx = -1;
-
- foreach my $vp (@{$self->range_vps}) {
- my $cur_idx = ($vp->name =~ m/range-(\d+)/);
- if (($cur_idx - $prev_idx) > 1) {
- $cur_idx--;
- my $name = "range-${cur_idx}";
- $vp->name($name);
- $vp->location(join('-', $self->location, 'field', $name));
- }
- $prev_idx = $cur_idx;
- }
- };
-
-};
+#package Reaction::UI::ViewPort::TimeRangeCollection;
+#
+# Marked commented out because unused and unmaintained. Should probably
+# be turned into a complex viewport example later instead --mst
+#
+#use Reaction::Class;
+#use Reaction::Types::DateTime;
+#use Moose::Util::TypeConstraints ();
+#use DateTime::Event::Recurrence;
+#use aliased 'Reaction::UI::ViewPort::Field::String';
+#use aliased 'Reaction::UI::ViewPort::Field::DateTime';
+#use aliased 'Reaction::UI::ViewPort::Field::HiddenArray';
+#use aliased 'Reaction::UI::ViewPort::Field::TimeRange';
+#
+#class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
+#
+# #has '+layout' => (default => 'timerangecollection');
+#
+# has '+column_order' => (
+# default => sub{[ qw/ time_from time_to pattern repeat_from repeat_to / ]},
+# );
+#
+# has time_from => (
+# isa => 'Reaction::UI::ViewPort::Field::DateTime',
+# is => 'rw', lazy_build => 1,
+# );
+#
+# has time_to => (
+# isa => 'Reaction::UI::ViewPort::Field::DateTime',
+# is => 'rw', lazy_build => 1,
+# );
+#
+# has repeat_from => (
+# isa => 'Reaction::UI::ViewPort::Field::DateTime',
+# is => 'rw', lazy_build => 1,
+# );
+#
+# has repeat_to => (
+# isa => 'Reaction::UI::ViewPort::Field::DateTime',
+# is => 'rw', lazy_build => 1,
+# );
+#
+# has pattern => (
+# isa => 'Reaction::UI::ViewPort::Field::String',
+# # valid_values => [ qw/none daily weekly monthly/ ],
+# is => 'rw', lazy_build => 1,
+# );
+#
+# has range_vps => (isa => 'ArrayRef', is => 'rw', lazy_build => 1,);
+#
+# has max_range_vps => (isa => 'Int', is => 'rw', lazy_build => 1,);
+#
+# has error => (
+# isa => 'Str',
+# is => 'rw',
+# required => 0,
+# );
+#
+# has field_names => (
+# isa => 'ArrayRef', is => 'rw',
+# lazy_build => 1, clearer => 'clear_field_names',
+# );
+#
+# has _field_map => (
+# isa => 'HashRef', is => 'rw', init_arg => 'fields',
+# clearer => '_clear_field_map',
+# predicate => '_has_field_map',
+# lazy_build => 1,
+# );
+#
+# has on_next_callback => (
+# isa => 'CodeRef',
+# is => 'rw',
+# predicate => 'has_on_next_callback',
+# );
+#
+# implements fields => as { shift->_field_map };
+#
+# implements _build_range_vps => as { [] };
+#
+# implements spanset => as {
+# my ($self) = @_;
+# my $spanset = DateTime::SpanSet->empty_set;
+# $spanset = $spanset->union($_->value) for @{$self->range_vps};
+# return $spanset;
+# };
+#
+# implements range_strings => as {
+# my ($self) = @_;
+# return [ map { $_->value_string } @{$self->range_vps} ];
+# };
+#
+# implements remove_range_vp => as {
+# my ($self, $to_remove) = @_;
+# $self->range_vps([ grep { $_ != $to_remove } @{$self->range_vps} ]);
+# $self->_clear_field_map;
+# $self->clear_field_names;
+# };
+#
+# implements add_range_vp => as {
+# my ($self) = @_;
+# if ($self->can_add) {
+# $self->_clear_field_map;
+# $self->clear_field_names;
+# my @span_info = (
+# $self->time_from->value,
+# $self->time_to->value,
+# (map { $_->has_value ? $_->value : '' }
+# map { $self->$_ } qw/repeat_from repeat_to/),
+# $self->pattern->value,
+# );
+# my $encoded_spanset = join ',', @span_info;
+# my $args = {
+# value_string => $encoded_spanset,
+# parent => $self
+# };
+# my $count = scalar(@{$self->range_vps});
+# my $field = $self->_build_simple_field(TimeRange, 'range-'.$count, $args);
+# my $d = DateTime::Format::Duration->new( pattern => '%s' );
+# if ($d->format_duration( $self->spanset->intersection($field->value)->duration ) > 0) {
+# # XXX - Stop using the stash here?
+# $self->ctx->stash->{warning} = 'Warning: Most recent time range overlaps '.
+# 'with existing time range in this booking.';
+# }
+# #warn "encoded spanset = $encoded_spanset\n";
+# #warn "current range = ".join(', ', (@{$self->range_vps}))."\n";
+# push(@{$self->range_vps}, $field);
+# }
+# };
+#
+# implements _build_field_map => as {
+# my ($self) = @_;
+# my %map;
+# foreach my $field (@{$self->range_vps}) {
+# $map{$field->name} = $field;
+# }
+# foreach my $name (@{$self->column_order}) {
+# $map{$name} = $self->$name;
+# }
+# return \%map;
+# };
+#
+# implements _build_field_names => as {
+# my ($self) = @_;
+# return [
+# (map { $_->name } @{$self->range_vps}),
+# @{$self->column_order}
+# ];
+# };
+#
+# implements can_add => as {
+# my ($self) = @_;
+# my $error;
+# if ($self->time_to->has_value && $self->time_from->has_value) {
+# my $time_to = $self->time_to->value;
+# my $time_from = $self->time_from->value;
+#
+# my ($pattern, $repeat_from, $repeat_to) = ('','','');
+# $pattern = $self->pattern->value if $self->pattern->has_value;
+# $repeat_from = $self->repeat_from->value if $self->repeat_from->has_value;
+# $repeat_to = $self->repeat_to->value if $self->repeat_to->has_value;
+#
+# my $duration = $time_to - $time_from;
+# if ($time_to < $time_from) {
+# $error = 'Please make sure that the Time To is after the Time From.';
+# } elsif ($time_to == $time_from) {
+# $error = 'Your desired booking slot is too small.';
+# } elsif ($pattern && $pattern ne 'none') {
+# my %pattern = (hourly => [ hours => 1 ],
+# daily => [ days => 1 ],
+# weekly => [ days => 7 ],
+# monthly => [ months => 1 ]);
+# my $pattern_comp = DateTime::Duration->compare(
+# $duration, DateTime::Duration->new( @{$pattern{$pattern}} )
+# );
+# if (!$repeat_to || !$repeat_from) {
+# $error = 'Please make sure that you enter a valid range for the '.
+# 'repetition period.';
+# } elsif ($time_to == $time_from) {
+# $error = 'Your desired repetition period is too short.';
+# } elsif ($repeat_to && ($repeat_to < $repeat_from)) {
+# $error = 'Please make sure that the Repeat To is after the Repeat From.';
+# } elsif ( ( ($pattern eq 'hourly') && ($pattern_comp > 0) ) ||
+# ( ($pattern eq 'daily') && ($pattern_comp > 0) ) ||
+# ( ($pattern eq 'weekly') && ($pattern_comp > 0) ) ||
+# ( ($pattern eq 'monthly') && ($pattern_comp > 0) ) ) {
+# $error = "Your repetition pattern ($pattern) is too short for your ".
+# "desired booking length.";
+# }
+# }
+# } else {
+# $error = 'Please complete both the Time To and Time From fields.';
+# }
+# $self->error($error);
+# return !defined($error);
+# };
+#
+# implements _build_simple_field => as {
+# my ($self, $class, $name, $args) = @_;
+# return $class->new(
+# name => $name,
+# location => join('-', $self->location, 'field', $name),
+# ctx => $self->ctx,
+# %$args
+# );
+# };
+#
+# implements _build_time_to => as {
+# my ($self) = @_;
+# return $self->_build_simple_field(DateTime, 'time_to', {});
+# };
+#
+# implements _build_time_from => as {
+# my ($self) = @_;
+# return $self->_build_simple_field(DateTime, 'time_from', {});
+# };
+#
+# implements _build_repeat_to => as {
+# my ($self) = @_;
+# return $self->_build_simple_field(DateTime, 'repeat_to', {});
+# };
+#
+# implements _build_repeat_from => as {
+# my ($self) = @_;
+# return $self->_build_simple_field(DateTime, 'repeat_from', {});
+# };
+#
+# implements _build_pattern => as {
+# my ($self) = @_;
+# return $self->_build_simple_field(String, 'pattern', {});
+# };
+#
+# implements next => as {
+# $_[0]->on_next_callback->(@_);
+# };
+#
+# override accept_events => sub {
+# my $self = shift;
+# ('add_range_vp', ($self->has_on_next_callback ? ('next') : ()), super());
+# };
+#
+# override child_event_sinks => sub {
+# my ($self) = @_;
+# return ((grep { ref($_) =~ 'Hidden' } values %{$self->_field_map}),
+# (grep { ref($_) !~ 'Hidden' } values %{$self->_field_map}),
+# super());
+# };
+#
+# override apply_events => sub {
+# my ($self, $ctx, $events) = @_;
+#
+# # auto-inflate range fields based on number from hidden field
+#
+# my $max = $events->{$self->location.':max_range_vps'};
+# my @range_vps = map {
+# TimeRange->new(
+# name => "range-$_",
+# location => join('-', $self->location, 'field', 'range', $_),
+# ctx => $self->ctx,
+# parent => $self,
+# )
+# } ($max ? (0 .. $max - 1) : ());
+# $self->range_vps(\@range_vps);
+# $self->_clear_field_map;
+# $self->clear_field_names;
+#
+# # call original event handling
+#
+# super();
+#
+# # repack range VPs in case of deletion
+#
+# my $prev_idx = -1;
+#
+# foreach my $vp (@{$self->range_vps}) {
+# my $cur_idx = ($vp->name =~ m/range-(\d+)/);
+# if (($cur_idx - $prev_idx) > 1) {
+# $cur_idx--;
+# my $name = "range-${cur_idx}";
+# $vp->name($name);
+# $vp->location(join('-', $self->location, 'field', $name));
+# }
+# $prev_idx = $cur_idx;
+# }
+# };
+#
+#};
+#
+#1;
+#
+#=head1 NAME
+#
+#Reaction::UI::ViewPort::TimeRangeCollection
+#
+#=head1 SYNOPSIS
+#
+# my $trc = $self->push_viewport(TimeRangeCollection,
+# layout => 'avail_search_form',
+# on_apply_callback => $search_callback,
+# name => 'TRC',
+# );
+#
+#=head1 DESCRIPTION
+#
+#=head1 ATTRIBUTES
+#
+#=head2 can_add
+#
+#=head2 column_order
+#
+#=head2 error
+#
+#=head2 field_names
+#
+#=head2 fields
+#
+#=head2 layout
+#
+#=head2 pattern
+#
+#Typically either: none, daily, weekly or monthly
+#
+#=head2 max_range_vps
+#
+#=head2 range_vps
+#
+#=head2 repeat_from
+#
+#A DateTime field.
+#
+#=head2 repeat_to
+#
+#A DateTime field.
+#
+#=head2 time_from
+#
+#A DateTime field.
+#
+#=head2 time_to
+#
+#A DateTime field.
+#
+#=head1 METHODS
+#
+#=head2 spanset
+#
+#Returns: $spanset consisting of all the TimeRange spans combined
+#
+#=head2 range_strings
+#
+#Returns: ArrayRef of Str consisting of the value_strings of all TimeRange
+#VPs
+#
+#=head2 remove_range_vp
+#
+#Arguments: $to_remove
+#
+#=head2 add_range_vp
+#
+#Arguments: $to_add
+#
+#=head2 _build_simple_field
+#
+#Arguments: $class, $name, $args
+#where $class is an object, $name is a scalar and $args is a hashref
+#
+#=head2 next
+#
+#=head2 on_next_callback
+#
+#=head2 clear_field_names
+#
+#=head2 child_event_sinks
+#
+#=head1 SEE ALSO
+#
+#=head2 L<Reaction::UI::ViewPort>
+#
+#=head2 L<Reaction::UI::ViewPort::Field::TimeRange>
+#
+#=head2 L<Reaction::UI::ViewPort::Field::DateTime>
+#
+#=head2 L<DateTime::Event::Recurrence>
+#
+#=head1 AUTHORS
+#
+#See L<Reaction::Class> for authors.
+#
+#=head1 LICENSE
+#
+#See L<Reaction::Class> for the license.
+#
+#=cut
1;
-
-=head1 NAME
-
-Reaction::UI::ViewPort::TimeRangeCollection
-
-=head1 SYNOPSIS
-
- my $trc = $self->push_viewport(TimeRangeCollection,
- layout => 'avail_search_form',
- on_apply_callback => $search_callback,
- name => 'TRC',
- );
-
-=head1 DESCRIPTION
-
-=head1 ATTRIBUTES
-
-=head2 can_add
-
-=head2 column_order
-
-=head2 error
-
-=head2 field_names
-
-=head2 fields
-
-=head2 layout
-
-=head2 pattern
-
-Typically either: none, daily, weekly or monthly
-
-=head2 max_range_vps
-
-=head2 range_vps
-
-=head2 repeat_from
-
-A DateTime field.
-
-=head2 repeat_to
-
-A DateTime field.
-
-=head2 time_from
-
-A DateTime field.
-
-=head2 time_to
-
-A DateTime field.
-
-=head1 METHODS
-
-=head2 spanset
-
-Returns: $spanset consisting of all the TimeRange spans combined
-
-=head2 range_strings
-
-Returns: ArrayRef of Str consisting of the value_strings of all TimeRange
-VPs
-
-=head2 remove_range_vp
-
-Arguments: $to_remove
-
-=head2 add_range_vp
-
-Arguments: $to_add
-
-=head2 _build_simple_field
-
-Arguments: $class, $name, $args
-where $class is an object, $name is a scalar and $args is a hashref
-
-=head2 next
-
-=head2 on_next_callback
-
-=head2 clear_field_names
-
-=head2 child_event_sinks
-
-=head1 SEE ALSO
-
-=head2 L<Reaction::UI::ViewPort>
-
-=head2 L<Reaction::UI::ViewPort::Field::TimeRange>
-
-=head2 L<Reaction::UI::ViewPort::Field::DateTime>
-
-=head2 L<DateTime::Event::Recurrence>
-
-=head1 AUTHORS
-
-See L<Reaction::Class> for authors.
-
-=head1 LICENSE
-
-See L<Reaction::Class> for the license.
-
-=cut