diff options
author | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2007-09-29 20:40:12 +0000 |
---|---|---|
committer | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2007-09-29 20:40:12 +0000 |
commit | 6ab43711ccd779eedce107001b300043e2056a0c (patch) | |
tree | edb162ef7eaaf0aeda8a3e8fac49e4d07a637df8 /lib | |
parent | ff460bc0b2bc0dc060f45cc8ac9e85d275fabcd0 (diff) | |
download | reaction-6ab43711ccd779eedce107001b300043e2056a0c.tar.gz reaction-6ab43711ccd779eedce107001b300043e2056a0c.zip |
It is starting to look like this may actually work after all. Listview is the only one left i think, although the bar tests are still giving me trouble. TODO: add to the collection actions a truncate action. should be useful
Diffstat (limited to 'lib')
46 files changed, 268 insertions, 157 deletions
diff --git a/lib/ComponentUI.pm b/lib/ComponentUI.pm index f1938c5..ae7751f 100644 --- a/lib/ComponentUI.pm +++ b/lib/ComponentUI.pm @@ -13,7 +13,7 @@ use Catalyst::Runtime '5.70'; # Static::Simple: will serve static files from the application's root # directory -use Catalyst qw/-Debug ConfigLoader Static::Simple I18N/; +use Catalyst qw/ ConfigLoader -Debug Static::Simple I18N /; our $VERSION = '0.01'; diff --git a/lib/ComponentUI/Controller/Root.pm b/lib/ComponentUI/Controller/Root.pm index 1d7bd58..567cf3b 100644 --- a/lib/ComponentUI/Controller/Root.pm +++ b/lib/ComponentUI/Controller/Root.pm @@ -12,15 +12,14 @@ use aliased 'Reaction::UI::ViewPort'; # so they function identically to actions created in MyApp.pm # __PACKAGE__->config( - view_name => 'XHTML', + view_name => 'Site', window_title => 'Reaction Test App', - content_type => 'text/html', - namespace => '', + namespace => '' ); sub base :Chained('/') :PathPart('') :CaptureArgs(0) { my ($self, $c) = @_; - $self->push_viewport(ViewPort, layout => 'xhtml'); + $self->push_viewport(ViewPort, layout => 'layout'); } sub root :Chained('base') :PathPart('') :Args(0) { @@ -28,4 +27,16 @@ sub root :Chained('base') :PathPart('') :Args(0) { $self->push_viewport(ViewPort, layout => 'index'); } +sub static :Chained('base') :PathPart('static') :Args { + my ($self, $c, @args) = @_; + return if $c->stash->{window}->view->serve_static_file($c, \@args); + $c->forward('error_404'); +} + +sub error_404 :Private { + my ($self, $c) = @_; + $c->res->body("Error 404"); + $c->res->status(404); +} + 1; diff --git a/lib/ComponentUI/View/Site.pm b/lib/ComponentUI/View/Site.pm new file mode 100644 index 0000000..cbb2d28 --- /dev/null +++ b/lib/ComponentUI/View/Site.pm @@ -0,0 +1,36 @@ +package ComponentUI::View::Site; + +use Reaction::Class; +use aliased 'Reaction::UI::View::TT'; + +class Site is TT, which { + +}; + + +use Class::MOP; + +{ + my @reflect_widgets = qw(ActionForm ObjectView ListView + Field::File + Field::Password + Field::Text DisplayField::Text + Field::Number DisplayField::Number + Field::String DisplayField::String + Field::Boolean DisplayField::Boolean + Field::DateTime DisplayField::DateTime + Field::ChooseOne DisplayField::RelatedObject + Field::ChooseMany DisplayField::Collection + Field::HiddenArray DisplayField::List + ); + + + for (@reflect_widgets){ + my $base = "Reaction::UI::Widget::${_}"; + my $target = "ComponentUI::View::Site::Widget::${_}"; + Class::MOP::load_class( $base ); + $base->meta->create($target, superclasses => [$base]); + } +} + +1; diff --git a/lib/ComponentUI/View/Site/Widget/Index.pm b/lib/ComponentUI/View/Site/Widget/Index.pm new file mode 100644 index 0000000..21175ae --- /dev/null +++ b/lib/ComponentUI/View/Site/Widget/Index.pm @@ -0,0 +1,11 @@ +package ComponentUI::View::Site::Widget::Index; + +use Reaction::UI::WidgetClass; + +class Index which { + + widget renders [ string {"DUMMY"} ]; + +}; + +1; diff --git a/lib/ComponentUI/View/Site/Widget/Layout.pm b/lib/ComponentUI/View/Site/Widget/Layout.pm new file mode 100644 index 0000000..380a03a --- /dev/null +++ b/lib/ComponentUI/View/Site/Widget/Layout.pm @@ -0,0 +1,17 @@ +package ComponentUI::View::Site::Widget::Layout; + +use Reaction::UI::WidgetClass; + +class Layout which { + + widget renders [ qw(menu sidebar header main_content) => + { viewport => func('self', 'viewport') } ]; + + menu renders [ string { "DUMMY" } ]; + sidebar renders [ string { "Sidebar Shit" } ]; + header renders [ string { "DUMMY" } ]; + main_content renders [ viewport over func('viewport', 'inner')]; + +}; + +1; diff --git a/lib/Reaction/UI/LayoutSet.pm b/lib/Reaction/UI/LayoutSet.pm index 60d68d9..1cdb0e9 100644 --- a/lib/Reaction/UI/LayoutSet.pm +++ b/lib/Reaction/UI/LayoutSet.pm @@ -18,6 +18,7 @@ class LayoutSet which { my $found; SEARCH: foreach my $path (@path) { my $cand = $path->file($self->name); + print STDERR $cand,"\n"; if ($cand->stat) { $self->_load_file($cand); $found = 1; @@ -44,7 +45,12 @@ class LayoutSet which { implements 'widget_type' => as { my ($self) = @_; - return join('', map { ucfirst($_) } split('_', $self->name)); + my $widget = join('', map { ucfirst($_) } split('_', $self->name)); + $widget = join('::', map { ucfirst($_) } split('/', $widget)); + + print STDERR "--- ", $self->name, " maps to widget $widget \n"; + + return $widget; }; }; diff --git a/lib/Reaction/UI/LayoutSet/TT.pm b/lib/Reaction/UI/LayoutSet/TT.pm index 72d3fad..02b3cde 100644 --- a/lib/Reaction/UI/LayoutSet/TT.pm +++ b/lib/Reaction/UI/LayoutSet/TT.pm @@ -23,6 +23,7 @@ class TT is LayoutSet, which { || confess "tt_object not provided to new()"; my $tt_args = { data => {} }; my $name = $self->name; + $name =~ s/\//__/g; #slashes are not happy here... my $fragments = $self->fragments; my $tt_source = qq{[% VIEW ${name};\n\n}. join("\n\n", @@ -39,6 +40,6 @@ class TT is LayoutSet, which { return $tt_args->{data}{view}; }; -}; +}; 1; diff --git a/lib/Reaction/UI/View.pm b/lib/Reaction/UI/View.pm index aa30878..987909c 100644 --- a/lib/Reaction/UI/View.pm +++ b/lib/Reaction/UI/View.pm @@ -59,19 +59,23 @@ class View which { my $base = $self->blessed; my $tail = $layout_set->widget_type; my $class = join('::', $base, 'Widget', $tail); - Class::MOP::load_class($class); + eval { Class::MOP::load_class($class) }; + confess "Couldn't load widget '$class': $@" if $@; return $class; }; implements 'layout_set_for' => as { my ($self, $vp) = @_; + print STDERR "Getting layoutset for VP ".(ref($vp) || "SC:".$vp)."\n"; my $lset_name = eval { $vp->layout }; confess "Couldn't call layout method on \$vp arg ${vp}: $@" if $@; unless (length($lset_name)) { - my $last = (split('::', ref($vp)))[-1]; - #previously: join("_", map { lc($_) } split(/(?=[A-Z])/, $last)) - $last =~ s/([a-z0-9])([A-Z])/${1}_${2}/g - $lset_name = lc($last); + my $vp_class = ref($vp) || $vp; + my ($last) = ($vp_class =~ /.*(?:::ViewPort::)(.+?)$/); + my @fragments = split('::', $last); + $_ = join("_", split(/(?=[A-Z])/, $_)) for @fragments; + $lset_name = lc(join('/', @fragments)); + print STDERR "--- $vp_class is rendered as $lset_name\n"; } my $cache = $self->_layout_set_cache; return $cache->{$lset_name} ||= $self->create_layout_set($lset_name); @@ -86,7 +90,7 @@ class View which { implements 'find_related_class' => as { my ($self, $rel) = @_; - my $own_class = ref($self)||$self; + my $own_class = ref($self) || $self; confess View." is abstract, you must subclass it" if $own_class eq View; foreach my $super ($own_class->meta->class_precedence_list) { next if $super eq View; diff --git a/lib/Reaction/UI/ViewPort/ActionForm.pm b/lib/Reaction/UI/ViewPort/ActionForm.pm index bb97bf3..b28c25d 100644 --- a/lib/Reaction/UI/ViewPort/ActionForm.pm +++ b/lib/Reaction/UI/ViewPort/ActionForm.pm @@ -16,45 +16,45 @@ use aliased 'Reaction::UI::ViewPort::Field::TimeRange'; class ActionForm is 'Reaction::UI::ViewPort', which { has action => ( - isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1 - ); + isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1 + ); has ordered_fields => (is => 'rw', isa => 'ArrayRef', lazy_build => 1); has _field_map => ( - isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1, - ); + isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1, + ); has changed => ( - isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 } - ); + isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 } + ); has next_action => ( - isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action' - ); + isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action' + ); has on_apply_callback => ( - isa => 'CodeRef', is => 'rw', required => 0, - predicate => 'has_on_apply_callback' - ); + isa => 'CodeRef', is => 'rw', required => 0, + predicate => 'has_on_apply_callback' + ); has ok_label => ( - isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' } - ); + isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' } + ); has apply_label => ( - isa => 'Str', is => 'rw', required => 1, default => sub { 'apply' } - ); + isa => 'Str', is => 'rw', required => 1, default => sub { 'apply' } + ); has close_label => (isa => 'Str', is => 'rw', lazy_fail => 1); has close_label_close => ( - isa => 'Str', is => 'rw', required => 1, default => sub { 'close' } - ); + isa => 'Str', is => 'rw', required => 1, default => sub { 'close' } + ); has close_label_cancel => ( - isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' } - ); + isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' } + ); sub fields { shift->_field_map } @@ -83,7 +83,7 @@ class ActionForm is 'Reaction::UI::ViewPort', which { my $constraint = $attr->type_constraint; my $base_name = $constraint->name; my $tried_isa = 0; - CONSTRAINT: while (defined($constraint)) { + CONSTRAINT: while (defined($constraint)) { my $name = $constraint->name; if (eval { $name->can('meta') } && !$tried_isa++) { foreach my $class ($name->meta->class_precedence_list) { @@ -125,16 +125,17 @@ class ActionForm is 'Reaction::UI::ViewPort', which { implements build_ordered_fields => as { my $self = shift; - $self->sort_by_spec($self->column_order, [keys %{$self->_field_map_}])}; + my $ordered = $self->sort_by_spec($self->column_order, [keys %{$self->_field_map}]); + return [@{$self->_field_map}{@$ordered}]; }; implements can_apply => as { my ($self) = @_; - foreach my $field (values %{$self->_field_map}) { + foreach my $field ( @{ $self->ordered_fields } ) { return 0 if $field->needs_sync; - # if e.g. a datetime field has an invalid value that can't be re-assembled - # into a datetime object, the action may be in a consistent state but - # not synchronized from the fields; in this case, we must not apply + # if e.g. a datetime field has an invalid value that can't be re-assembled + # into a datetime object, the action may be in a consistent state but + # not synchronized from the fields; in this case, we must not apply } return $self->action->can_apply; }; @@ -212,13 +213,13 @@ class ActionForm is 'Reaction::UI::ViewPort', which { %extra = %$config; } my $field = $class->new( - action => $self->action, - attribute => $attr, - name => $attr->name, - location => join('-', $self->location, 'field', $attr->name), - ctx => $self->ctx, - %extra - ); + action => $self->action, + attribute => $attr, + name => $attr->name, + location => join('-', $self->location, 'field', $attr->name), + ctx => $self->ctx, + %extra + ); return ($attr_name => $field); }; @@ -297,7 +298,7 @@ class ActionForm is 'Reaction::UI::ViewPort', which { }; -1; + 1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/DisplayField/Boolean.pm b/lib/Reaction/UI/ViewPort/DisplayField/Boolean.pm index 9389436..1502fe6 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/Boolean.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/Boolean.pm @@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class Boolean, is DisplayField, which { has '+value' => (isa => 'Bool'); - has '+layout' => (default => 'displayfield/value_string'); + #has '+layout' => (default => 'displayfield/value_string'); has value_string => (isa => 'Str', is => 'rw', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/DisplayField/Collection.pm b/lib/Reaction/UI/ViewPort/DisplayField/Collection.pm index f4cec97..02383cf 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/Collection.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/Collection.pm @@ -5,7 +5,7 @@ use Scalar::Util 'blessed'; class Collection is 'Reaction::UI::ViewPort::DisplayField', which { has '+value' => (isa => 'ArrayRef'); - has '+layout' => (default => 'displayfield/list'); + #has '+layout' => (default => 'displayfield/list'); has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/DisplayField/DateTime.pm b/lib/Reaction/UI/ViewPort/DisplayField/DateTime.pm index 92d5b81..b8e8d89 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/DateTime.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/DateTime.pm @@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class DateTime is DisplayField, which { has '+value' => (isa => 'DateTime'); - has '+layout' => (default => 'displayfield/value_string'); + #has '+layout' => (default => 'displayfield/value_string'); has value_string => (isa => 'Str', is => 'rw', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/DisplayField/List.pm b/lib/Reaction/UI/ViewPort/DisplayField/List.pm index d70f1ed..76fa250 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/List.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/List.pm @@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class List is DisplayField, which { has '+value' => (isa => 'ArrayRef'); - has '+layout' => (default => 'displayfield/list'); + #has '+layout' => (default => 'displayfield/list'); has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/DisplayField/Number.pm b/lib/Reaction/UI/ViewPort/DisplayField/Number.pm index 7c46d06..358154d 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/Number.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/Number.pm @@ -4,7 +4,7 @@ use Reaction::Class; use aliased 'Reaction::UI::ViewPort::DisplayField'; class Number is DisplayField, which { - has '+layout' => (default => 'displayfield/string'); + #has '+layout' => (default => 'displayfield/string'); }; 1; diff --git a/lib/Reaction/UI/ViewPort/DisplayField/RelatedObject.pm b/lib/Reaction/UI/ViewPort/DisplayField/RelatedObject.pm index 3cd217c..9700ac0 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/RelatedObject.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/RelatedObject.pm @@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class RelatedObject is DisplayField, which { - has '+layout' => (default => 'displayfield/value_string'); + #has '+layout' => (default => 'displayfield/value_string'); has value_string => (isa => 'Str', is => 'ro', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/DisplayField/String.pm b/lib/Reaction/UI/ViewPort/DisplayField/String.pm index 3aab498..530cd08 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/String.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/String.pm @@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class String is DisplayField, which { has '+value' => (isa => 'Str'); - has '+layout' => (default => 'displayfield/string'); + #has '+layout' => (default => 'displayfield/string'); }; 1; diff --git a/lib/Reaction/UI/ViewPort/DisplayField/Text.pm b/lib/Reaction/UI/ViewPort/DisplayField/Text.pm index c9e2c27..ea68e8c 100644 --- a/lib/Reaction/UI/ViewPort/DisplayField/Text.pm +++ b/lib/Reaction/UI/ViewPort/DisplayField/Text.pm @@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField'; class Text is DisplayField, which { has '+value' => (isa => 'Str'); - has '+layout' => (default => 'displayfield/text'); + #has '+layout' => (default => 'displayfield/text'); }; 1; diff --git a/lib/Reaction/UI/ViewPort/Field.pm b/lib/Reaction/UI/ViewPort/Field.pm index 41a7c42..06d0598 100644 --- a/lib/Reaction/UI/ViewPort/Field.pm +++ b/lib/Reaction/UI/ViewPort/Field.pm @@ -42,7 +42,9 @@ class Field is 'Reaction::UI::ViewPort', which { implements build_label => as { my ($self) = @_; - return join(' ', map { ucfirst } split('_', $self->name)); + my $label = join(' ', map { ucfirst } split('_', $self->name)); + print STDERR "Field " . $self->name . " has label '$label'\n"; + return $label; }; implements build_value => as { diff --git a/lib/Reaction/UI/ViewPort/Field/Boolean.pm b/lib/Reaction/UI/ViewPort/Field/Boolean.pm index 34f7aae..fb0d886 100644 --- a/lib/Reaction/UI/ViewPort/Field/Boolean.pm +++ b/lib/Reaction/UI/ViewPort/Field/Boolean.pm @@ -5,11 +5,11 @@ use Reaction::Class; class Boolean is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'Bool'); - has '+layout' => (default => 'checkbox'); + #has '+layout' => (default => 'checkbox'); }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/ChooseMany.pm b/lib/Reaction/UI/ViewPort/Field/ChooseMany.pm index 35f6710..9337a3c 100644 --- a/lib/Reaction/UI/ViewPort/Field/ChooseMany.pm +++ b/lib/Reaction/UI/ViewPort/Field/ChooseMany.pm @@ -4,7 +4,7 @@ use Reaction::Class; class ChooseMany is 'Reaction::UI::ViewPort::Field::ChooseOne', which { - has '+layout' => (default => 'dual_select_group'); + #has '+layout' => (default => 'dual_select_group'); has '+value' => (isa => 'ArrayRef'); my $listify = sub { # quick utility function, $listify->($arg) diff --git a/lib/Reaction/UI/ViewPort/Field/ChooseOne.pm b/lib/Reaction/UI/ViewPort/Field/ChooseOne.pm index 0d44fd7..703a26f 100644 --- a/lib/Reaction/UI/ViewPort/Field/ChooseOne.pm +++ b/lib/Reaction/UI/ViewPort/Field/ChooseOne.pm @@ -6,7 +6,7 @@ use Scalar::Util 'blessed'; class ChooseOne is 'Reaction::UI::ViewPort::Field', which { - has '+layout' => (default => 'select'); + #has '+layout' => (default => 'select'); has valid_values => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); has value_choices => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); diff --git a/lib/Reaction/UI/ViewPort/Field/DateTime.pm b/lib/Reaction/UI/ViewPort/Field/DateTime.pm index 2b8509f..6d2958f 100644 --- a/lib/Reaction/UI/ViewPort/Field/DateTime.pm +++ b/lib/Reaction/UI/ViewPort/Field/DateTime.pm @@ -7,18 +7,18 @@ use Time::ParseDate (); class DateTime is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'DateTime'); - - has '+layout' => (default => 'dt_textfield'); - + + #has '+layout' => (default => 'dt_textfield'); + has value_string => ( isa => 'Str', is => 'rw', lazy_build => 1, trigger_adopt('value_string') ); - + has value_string_default_format => ( isa => 'Str', is => 'rw', required => 1, default => sub { "%F %H:%M:%S" } ); - + implements build_value_string => as { my $self = shift; @@ -29,11 +29,11 @@ class DateTime is 'Reaction::UI::ViewPort::Field', which { #<mst> eval { $self->value } ... is probably the best solution atm my $value = eval { $self->value }; return '' unless $self->has_value; - my $format = $self->value_string_default_format; + my $format = $self->value_string_default_format; return $value->strftime($format) if $value; return ''; }; - + implements adopt_value_string => as { my ($self) = @_; my $value = $self->value_string; @@ -47,14 +47,14 @@ class DateTime is 'Reaction::UI::ViewPort::Field', which { $self->needs_sync(1); } }; - + override accept_events => sub { ('value_string', super()); }; }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/File.pm b/lib/Reaction/UI/ViewPort/Field/File.pm index 557826d..a1d181c 100644 --- a/lib/Reaction/UI/ViewPort/Field/File.pm +++ b/lib/Reaction/UI/ViewPort/Field/File.pm @@ -6,9 +6,9 @@ use Reaction::Types::File; class File is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'File', required => 0); - - has '+layout' => (default => 'file'); - + + #has '+layout' => (default => 'file'); + override apply_our_events => sub { my ($self, $ctx, $events) = @_; my $value_key = join(':', $self->location, 'value'); diff --git a/lib/Reaction/UI/ViewPort/Field/Number.pm b/lib/Reaction/UI/ViewPort/Field/Number.pm index e4e925f..f66e03d 100644 --- a/lib/Reaction/UI/ViewPort/Field/Number.pm +++ b/lib/Reaction/UI/ViewPort/Field/Number.pm @@ -4,11 +4,11 @@ use Reaction::Class; class Number is 'Reaction::UI::ViewPort::Field', which { - has '+layout' => (default => 'textfield'); + #has '+layout' => (default => 'textfield'); }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/Password.pm b/lib/Reaction/UI/ViewPort/Field/Password.pm index d70ed62..bc86341 100644 --- a/lib/Reaction/UI/ViewPort/Field/Password.pm +++ b/lib/Reaction/UI/ViewPort/Field/Password.pm @@ -5,11 +5,11 @@ use Reaction::Class; class Password is 'Reaction::UI::ViewPort::Field::String', which { has '+value' => (isa => 'SimpleStr'); - has '+layout' => (default => 'password'); + #has '+layout' => (default => 'password'); }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/String.pm b/lib/Reaction/UI/ViewPort/Field/String.pm index 4be6bdc..6075592 100644 --- a/lib/Reaction/UI/ViewPort/Field/String.pm +++ b/lib/Reaction/UI/ViewPort/Field/String.pm @@ -6,12 +6,12 @@ class String is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'Str'); # accept over 255 chars in case, upstream # constraint from model should catch it - - has '+layout' => (default => 'textfield'); + + #has '+layout' => (default => 'textfield'); }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/Text.pm b/lib/Reaction/UI/ViewPort/Field/Text.pm index d4e89f8..16d4e56 100644 --- a/lib/Reaction/UI/ViewPort/Field/Text.pm +++ b/lib/Reaction/UI/ViewPort/Field/Text.pm @@ -5,11 +5,11 @@ use Reaction::Class; class Text is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'Str'); - has '+layout' => (default => 'textarea'); + #has '+layout' => (default => 'textarea'); }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/Field/TimeRange.pm b/lib/Reaction/UI/ViewPort/Field/TimeRange.pm index 3619b5e..fb11841 100644 --- a/lib/Reaction/UI/ViewPort/Field/TimeRange.pm +++ b/lib/Reaction/UI/ViewPort/Field/TimeRange.pm @@ -9,34 +9,34 @@ use Time::ParseDate (); class TimeRange is 'Reaction::UI::ViewPort::Field', which { has '+value' => (isa => 'DateTime::SpanSet'); - - has '+layout' => (default => 'timerange'); - - has value_string => + + #has '+layout' => (default => 'timerange'); + + has value_string => (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string')); - + has delete_label => ( isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' }, ); - + has parent => ( isa => 'Reaction::UI::ViewPort::TimeRangeCollection', is => 'ro', required => 1, is_weak_ref => 1 ); - + implements build_value_string => as { my $self = shift; #return '' unless $self->has_value; #return $self->value_string; }; - + implements value_array => as { my $self = shift; return split(',', $self->value_string); }; - + implements adopt_value_string => as { my ($self) = @_; my @values = $self->value_array; @@ -44,11 +44,11 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which { if (length $values[$idx]) { my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1); $values[$idx] = DateTime->from_epoch( epoch => $epoch ); - } + } } $self->value($self->range_to_spanset(@values)); }; - + implements range_to_spanset => as { my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_; my $spanset = DateTime::SpanSet->empty_set; @@ -63,7 +63,7 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which { hours => $time_from->hour, minutes => $time_from->minute, seconds => $time_from->second ); - + delete $args{'days'} if ($pattern eq 'daily'); delete @args{qw/hours days/} if ($pattern eq 'hourly'); $args{'days'} = $time_from->day if ($pattern eq 'monthly'); @@ -80,17 +80,17 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which { } return $spanset; }; - + implements delete => as { my ($self) = @_; $self->parent->remove_range_vp($self); }; - + override accept_events => sub { ('value_string', 'delete', super()) }; }; -1; +1; =head1 NAME diff --git a/lib/Reaction/UI/ViewPort/ObjectView.pm b/lib/Reaction/UI/ViewPort/ObjectView.pm index cbb4c7b..7e1cac1 100644 --- a/lib/Reaction/UI/ViewPort/ObjectView.pm +++ b/lib/Reaction/UI/ViewPort/ObjectView.pm @@ -37,7 +37,8 @@ class ObjectView is 'Reaction::UI::ViewPort', which { push(@field_map, $self->build_fields_for($attr => $args)); } - $self->_field_map({ @field_map }); + my %field_map = @field_map; + $self->_field_map( \%field_map ); } }; @@ -94,7 +95,8 @@ class ObjectView is 'Reaction::UI::ViewPort', which { implements build_ordered_fields => as { my $self = shift; - $self->sort_by_spec($self->column_order, [keys %{$self->_field_map_}])}; + my $ordered = $self->sort_by_spec($self->column_order, [keys %{$self->_field_map}]); + return [@{$self->_field_map}{@$ordered}]; }; implements build_simple_field => as { @@ -152,7 +154,6 @@ class ObjectView is 'Reaction::UI::ViewPort', which { return $self->build_simple_field(String, $attr, $args); }; - implements build_fields_for_type_ArrayRef => as { my ($self, $attr, $args) = @_; return $self->build_simple_field(List, $attr, $args) @@ -168,7 +169,6 @@ class ObjectView is 'Reaction::UI::ViewPort', which { return $self->build_simple_field(RelatedObject, $attr, $args); }; - no Moose; no strict 'refs'; diff --git a/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm b/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm index eb1b680..1ebc03b 100644 --- a/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm +++ b/lib/Reaction/UI/ViewPort/TimeRangeCollection.pm @@ -11,89 +11,89 @@ use aliased 'Reaction::UI::ViewPort::Field::TimeRange'; class TimeRangeCollection is 'Reaction::UI::ViewPort', which { - has '+layout' => (default => 'timerangecollection'); - + #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', set_or_lazy_build('field_map'), ); - + 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) = @_; + 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) { @@ -124,7 +124,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { push(@{$self->range_vps}, $field); } }; - + implements build_field_map => as { my ($self) = @_; my %map; @@ -136,7 +136,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { } return \%map; }; - + implements build_field_names => as { my ($self) = @_; return [ @@ -144,19 +144,19 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { @{$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.'; @@ -191,7 +191,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { $self->error($error); return !defined($error); }; - + implements build_simple_field => as { my ($self, $class, $name, $args) = @_; return $class->new( @@ -201,53 +201,53 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { %$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( @@ -260,15 +260,15 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { $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 - + + # 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) { @@ -283,7 +283,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which { }; -1; +1; =head1 NAME @@ -347,11 +347,11 @@ Returns: $spanset consisting of all the TimeRange spans combined 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 diff --git a/lib/Reaction/UI/Widget/ActionForm.pm b/lib/Reaction/UI/Widget/ActionForm.pm index a631130..1f32afb 100644 --- a/lib/Reaction/UI/Widget/ActionForm.pm +++ b/lib/Reaction/UI/Widget/ActionForm.pm @@ -6,9 +6,11 @@ class ActionForm, which { widget renders [qw/header fields buttons footer/ => { viewport => func('self','viewport') } ]; - fields renders [viewport over func('viewport','ordered_fields')]; + fields renders [field over func('viewport','ordered_fields')]; + field renders [ 'viewport' ]; - buttons renders [ string {"DUMMY"} ], {message => func('viewport','message'); + buttons renders [ string {"DUMMY"} ], + {message => sub{ $_{viewport}->can('message') ? $_{viewport}->message : "" } }; header renders [ string {"DUMMY"} ]; footer renders [ string {"DUMMY"} ]; @@ -18,7 +20,6 @@ class ActionForm, which { __END__; - =head1 NAME Reaction::UI::Widget::ActionForm diff --git a/lib/Reaction/UI/Widget/DisplayField.pm b/lib/Reaction/UI/Widget/DisplayField.pm index c454188..2521dd3 100644 --- a/lib/Reaction/UI/Widget/DisplayField.pm +++ b/lib/Reaction/UI/Widget/DisplayField.pm @@ -2,7 +2,7 @@ package Reaction::UI::Widget::DisplayField; use Reaction::UI::WidgetClass; -class Text, which { +class DisplayField, which { widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ]; label renders [ string { $_{viewport}->label } ]; value renders [ string { $_{viewport}->value } ]; @@ -10,6 +10,8 @@ class Text, which { 1; +__END__; + =head1 NAME Reaction::UI::Widget::DisplayField diff --git a/lib/Reaction/UI/Widget/Field.pm b/lib/Reaction/UI/Widget/Field.pm index 6425f15..11f2c67 100644 --- a/lib/Reaction/UI/Widget/Field.pm +++ b/lib/Reaction/UI/Widget/Field.pm @@ -25,6 +25,8 @@ class Field, which { 1; +__END__; + =head1 NAME Reaction::UI::Widget::Field diff --git a/lib/Reaction/UI/Widget/Field/Boolean.pm b/lib/Reaction/UI/Widget/Field/Boolean.pm index 536764c..a4defcd 100644 --- a/lib/Reaction/UI/Widget/Field/Boolean.pm +++ b/lib/Reaction/UI/Widget/Field/Boolean.pm @@ -8,6 +8,8 @@ class Boolean is 'Reaction::UI::Widget::Field', which { 1; +__END__; + =head1 NAME Reaction::UI::Widget::Field::Boolean diff --git a/lib/Reaction/UI/Widget/Field/ChooseMany.pm b/lib/Reaction/UI/Widget/Field/ChooseMany.pm index bd11672..6e9ef47 100644 --- a/lib/Reaction/UI/Widget/Field/ChooseMany.pm +++ b/lib/Reaction/UI/Widget/Field/ChooseMany.pm @@ -12,11 +12,13 @@ class ChooseMany is 'Reaction::UI::Widget::Field', which { available_values renders [ option over func('viewport', 'available_value_choices') ]; selected_values renders [ option over func('viewport', 'current_value_choices') ]; option renders [string {"DUMMY"}], { v_value => sub {$_->{value}}, v_name => sub {$_->{name}} }; + action_buttons renders [ string {"DUMMY"} ]; }; 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/ChooseOne.pm b/lib/Reaction/UI/Widget/Field/ChooseOne.pm index 7ac1898..9754e71 100644 --- a/lib/Reaction/UI/Widget/Field/ChooseOne.pm +++ b/lib/Reaction/UI/Widget/Field/ChooseOne.pm @@ -18,6 +18,7 @@ class ChooseOne is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/DateTime.pm b/lib/Reaction/UI/Widget/Field/DateTime.pm index 9181387..deea805 100644 --- a/lib/Reaction/UI/Widget/Field/DateTime.pm +++ b/lib/Reaction/UI/Widget/Field/DateTime.pm @@ -10,6 +10,7 @@ class DateTime is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/File.pm b/lib/Reaction/UI/Widget/Field/File.pm index aa079c7..ad17c83 100644 --- a/lib/Reaction/UI/Widget/Field/File.pm +++ b/lib/Reaction/UI/Widget/Field/File.pm @@ -8,6 +8,7 @@ class File is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/HiddenArray.pm b/lib/Reaction/UI/Widget/Field/HiddenArray.pm index 05cdd45..7ccead9 100644 --- a/lib/Reaction/UI/Widget/Field/HiddenArray.pm +++ b/lib/Reaction/UI/Widget/Field/HiddenArray.pm @@ -11,6 +11,7 @@ class HiddenArray is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/Number.pm b/lib/Reaction/UI/Widget/Field/Number.pm index 859e7c2..48ef120 100644 --- a/lib/Reaction/UI/Widget/Field/Number.pm +++ b/lib/Reaction/UI/Widget/Field/Number.pm @@ -8,6 +8,7 @@ class Number is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/Password.pm b/lib/Reaction/UI/Widget/Field/Password.pm index 3b53b54..7525530 100644 --- a/lib/Reaction/UI/Widget/Field/Password.pm +++ b/lib/Reaction/UI/Widget/Field/Password.pm @@ -8,6 +8,7 @@ class Password is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/String.pm b/lib/Reaction/UI/Widget/Field/String.pm index eb25c8f..7e64510 100644 --- a/lib/Reaction/UI/Widget/Field/String.pm +++ b/lib/Reaction/UI/Widget/Field/String.pm @@ -8,6 +8,8 @@ class String is 'Reaction::UI::Widget::Field', which { 1; +__END__; + =head1 NAME Reaction::UI::Widget::Field::String diff --git a/lib/Reaction/UI/Widget/Field/Text.pm b/lib/Reaction/UI/Widget/Field/Text.pm index 1066633..9d5e603 100644 --- a/lib/Reaction/UI/Widget/Field/Text.pm +++ b/lib/Reaction/UI/Widget/Field/Text.pm @@ -8,6 +8,7 @@ class Text is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/Field/TimeRange.pm b/lib/Reaction/UI/Widget/Field/TimeRange.pm index f96a2c8..bc2ba05 100644 --- a/lib/Reaction/UI/Widget/Field/TimeRange.pm +++ b/lib/Reaction/UI/Widget/Field/TimeRange.pm @@ -8,6 +8,7 @@ class TimeRange is 'Reaction::UI::Widget::Field', which { 1; +__END__; =head1 NAME diff --git a/lib/Reaction/UI/Widget/ListView.pm b/lib/Reaction/UI/Widget/ListView.pm index ab80d93..7d9801c 100644 --- a/lib/Reaction/UI/Widget/ListView.pm +++ b/lib/Reaction/UI/Widget/ListView.pm @@ -3,24 +3,24 @@ package Reaction::UI::Widget::ListView; use Reaction::UI::WidgetClass; use aliased 'Reaction::UI::ViewPort::ListView' => 'ListView_VP'; -class ListView which { +class ListView, which { has 'viewport' => (isa => ListView_VP, is => 'ro', required => 1); widget renders [ qw(header body) => { viewport => func(self => 'viewport') } ]; - + header renders [ header_entry over func(viewport => 'field_names') ]; - + header_entry renders [ string { $_{viewport}->field_label_map->{ $_ } } ]; - + body renders [ row over func(viewport => 'current_page_collection') ]; - + row renders [ col_entry over func(viewport => 'field_names') => { row => $_ } ]; - + col_entry renders [ string { my $proto = $_{row}->$_; @@ -35,6 +35,8 @@ class ListView which { 1; +__END__; + =head1 NAME Reaction::UI::Widget::ListView diff --git a/lib/Reaction/UI/Widget/ObjectView.pm b/lib/Reaction/UI/Widget/ObjectView.pm index 28614b6..067b73c 100644 --- a/lib/Reaction/UI/Widget/ObjectView.pm +++ b/lib/Reaction/UI/Widget/ObjectView.pm @@ -3,8 +3,9 @@ package Reaction::UI::Widget::ObjectView; use Reaction::UI::WidgetClass; class ObjectView, which { - widget renders [ fields => { viewport => func('self', 'viewport') } ]; - fields renders [ viewport over func('viewport','ordered_fields') } ]; + widget renders [ fields => { viewport => func('self', 'viewport') } ]; + fields renders [ field over func('viewport', 'ordered_fields') ]; + field renders [ 'viewport' ]; }; 1; |