diff options
18 files changed, 246 insertions, 240 deletions
diff --git a/lib/Reaction/UI/ViewPort/Action.pm b/lib/Reaction/UI/ViewPort/Action.pm index 6a2ac58..b198c99 100644 --- a/lib/Reaction/UI/ViewPort/Action.pm +++ b/lib/Reaction/UI/ViewPort/Action.pm @@ -2,27 +2,46 @@ package Reaction::UI::ViewPort::Action; use Reaction::Class; +use aliased 'Reaction::UI::ViewPort::Object'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Text'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Array'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::String'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Number'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Integer'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Boolean'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::Password'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::DateTime'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::ChooseOne'; +use aliased 'Reaction::UI::ViewPort::Field::Mutable::ChooseMany'; + +use aliased 'Reaction::UI::ViewPort::Field::Mutable::File'; +#use aliased 'Reaction::UI::ViewPort::Field::Mutable::TimeRange'; + use MooseX::Types::Moose qw/Int/; use Reaction::Types::Core qw/NonEmptySimpleStr/; use namespace::clean -except => [ qw(meta) ]; - -extends 'Reaction::UI::ViewPort::Object::Mutable'; with 'Reaction::UI::ViewPort::Action::Role::OK'; -#this has to fucking go. it BLOWS. -has method => ( - is => 'rw', - isa => NonEmptySimpleStr, - default => sub { 'post' } -); +has model => ( + is => 'ro', + isa => 'Reaction::InterfaceModel::Action', + required => 1 + ); has changed => ( is => 'rw', isa => Int, reader => 'is_changed', default => sub{0} -); + ); + +#this has to fucking go. it BLOWS. +has method => ( + is => 'rw', + isa => NonEmptySimpleStr, + default => sub { 'post' } + ); sub can_apply { my ($self) = @_; @@ -56,6 +75,75 @@ sub sync_action_from_fields { } } +sub _build_fields_for_type_Num { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => Number, %$args); +} + +sub _build_fields_for_type_Int { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => Integer, %$args); +} + +sub _build_fields_for_type_Bool { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => Boolean, %$args); +} + +sub _build_fields_for_type_Reaction_Types_Core_SimpleStr { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => String, %$args); +} + +sub _build_fields_for_type_Reaction_Types_File_File { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => File, %$args); +} + +sub _build_fields_for_type_Str { + my ($self, $attr, $args) = @_; + if ($attr->has_valid_values) { # There's probably a better way to do this + $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args); + } else { + $self->_build_simple_field(attribute => $attr, class => Text, %$args); + } +} + +sub _build_fields_for_type_Reaction_Types_Core_Password { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => Password, %$args); +} + +sub _build_fields_for_type_Reaction_Types_DateTime_DateTime { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => DateTime, %$args); +} + +sub _build_fields_for_type_Enum { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args); +} + +#this needs to be fixed. somehow. beats the shit our of me. really. +#implements build_fields_for_type_Reaction_InterfaceModel_Object => as { +sub _build_fields_for_type_DBIx_Class_Row { + my ($self, $attr, $args) = @_; + $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args); +} + +sub _build_fields_for_type_ArrayRef { + my ($self, $attr, $args) = @_; + if ($attr->has_valid_values) { + $self->_build_simple_field(attribute => $attr, class => ChooseMany, %$args); + } else { + $self->_build_simple_field + ( + attribute => $attr, + class => Array, + layout => 'field/mutable/hidden_array', + %$args); + } +} __PACKAGE__->meta->make_immutable; @@ -65,10 +153,22 @@ __END__; =head1 NAME -Reaction::UI::ViewPort::Action +Reaction::UI::ViewPort::Object::Mutable =head1 SYNOPSIS + use aliased 'Reaction::UI::ViewPort::Object::Mutable'; + + $self->push_viewport(Mutable, + layout => 'register', + model => $action, + next_action => [ $self, 'redirect_to', 'accounts', $c->req->captures ], + ctx => $c, + field_order => [ + qw / contact_title company_name email address1 address2 address3 + city country post_code telephone mobile fax/ ], + ); + =head1 DESCRIPTION This subclass of L<Reaction::UI::ViewPort::Object::Mutable> is used for diff --git a/lib/Reaction/UI/ViewPort/Action/Role/Apply.pm b/lib/Reaction/UI/ViewPort/Action/Role/Apply.pm index e65b9e7..4138dde 100644 --- a/lib/Reaction/UI/ViewPort/Action/Role/Apply.pm +++ b/lib/Reaction/UI/ViewPort/Action/Role/Apply.pm @@ -27,45 +27,3 @@ sub apply { around accept_events => sub { ( 'apply', shift->(@_) ) }; 1; - -__END__ - -=head1 NAME - -Reaction::UI::ViewPort::Action::Role::Apply - -=head1 ATTRIBUTES - -=head2 apply_label - -Default: 'apply' - -=head2 on_apply_callback - -CodeRef. - -=head1 METHODS - -=head2 can_apply - -=head2 apply - -Calls a user-supplied C<do_apply> and if it is successful runs the -C<on_apply_callback> passing C<$self> and the result of C<do_apply> as args. - -=head1 SEE ALSO - -L<Reaction::UI::ViewPort::Action::Role::Close> - -L<Reaction::UI::ViewPort::Action::Role::OK> - -=head1 AUTHORS - -See L<Reaction::Class> for authors. - -=head1 LICENSE - -See L<Reaction::Class> for the license. - -=cut - diff --git a/lib/Reaction/UI/ViewPort/Action/Role/Close.pm b/lib/Reaction/UI/ViewPort/Action/Role/Close.pm index f236a9d..ad31722 100644 --- a/lib/Reaction/UI/ViewPort/Action/Role/Close.pm +++ b/lib/Reaction/UI/ViewPort/Action/Role/Close.pm @@ -37,51 +37,3 @@ around accept_events => sub { }; 1; - -__END__ - -=head1 NAME - -Reaction::UI::ViewPort::Action::Role::Close - -=head1 ATTRIBUTES - -=head2 close_label - -Default: C<close_label_close> - -=head2 close_label_close - -Default: 'close' - -=head2 close_label_cancel - -This label is only shown when C<changed> is true. - -Default: 'cancel' - -=head2 on_close_callback - -CodeRef. - -=head1 METHODS - -=head2 close - -=head2 can_close - -=head1 SEE ALSO - -L<Reaction::UI::ViewPort::Action::Role::Apply> - -L<Reaction::UI::ViewPort::Action::Role::OK> - -=head1 AUTHORS - -See L<Reaction::Class> for authors. - -=head1 LICENSE - -See L<Reaction::Class> for the license. - -=cut diff --git a/lib/Reaction/UI/ViewPort/Action/Role/OK.pm b/lib/Reaction/UI/ViewPort/Action/Role/OK.pm index 38001f8..59e96c7 100644 --- a/lib/Reaction/UI/ViewPort/Action/Role/OK.pm +++ b/lib/Reaction/UI/ViewPort/Action/Role/OK.pm @@ -20,37 +20,3 @@ around accept_events => sub { }; 1; - -__END__ - -=head1 NAME - -Reaction::UI::ViewPort::Action::Role::Close - -=head1 ATTRIBUTES - -=head2 ok_label - -Default: 'ok' - -=head1 METHODS - -=head2 ok - -Calls C<apply>, and then C<close> if successful. - -=head1 SEE ALSO - -L<Reaction::UI::ViewPort::Action::Role::Apply> - -L<Reaction::UI::ViewPort::Action::Role::Close> - -=head1 AUTHORS - -See L<Reaction::Class> for authors. - -=head1 LICENSE - -See L<Reaction::Class> for the license. - -=cut diff --git a/lib/Reaction/UI/ViewPort/Object.pm b/lib/Reaction/UI/ViewPort/Object.pm index e7a2e3a..7fb01d5 100644 --- a/lib/Reaction/UI/ViewPort/Object.pm +++ b/lib/Reaction/UI/ViewPort/Object.pm @@ -39,53 +39,10 @@ sub BUILD { if( my $field_args = delete $args->{Field} ){ $self->field_args( $field_args ); } -} - -sub _build_builder_cache { {} } -sub _build_excluded_fields { [] } - -sub _build_containers { - my $self = shift; - - my @container_layouts; - if( $self->has_container_layouts ){ - #make sure we don't accidentally modify the original - @container_layouts = map { {%$_} }@{ $self->container_layouts }; - } #we should always have a '_' container; - unless (grep {$_->{name} eq '_'} @container_layouts ){ - unshift(@container_layouts, {name => '_'}); - } - - my %fields; - my $ordered_field_names = $self->computed_field_order; - @fields{ @$ordered_field_names } = @{ $self->fields }; - - my %containers; - my @container_order; - for my $layout ( @container_layouts ){ - my @container_fields; - my $name = $layout->{name}; - push(@container_order, $name); - if( my $field_names = delete $layout->{fields} ){ - map{ push(@container_fields, $_) } grep { defined } - map { delete $fields{$_} } @$field_names; - } - $containers{$name} = Container->new( - ctx => $self->ctx, - location => join( '-', $self->location, 'container', $name ), - fields => \@container_fields, - %$layout, - ); - } - if( keys %fields ){ - my @leftovers = grep { exists $fields{$_} } @$ordered_field_names; - push(@{ $containers{_}->fields }, @fields{@leftovers} ); - } - - #only return containers with at least one field - return [ grep { scalar(@{ $_->fields }) } @containers{@container_order} ]; -} +}; +sub _build_excluded_fields { [] }; +sub _build_builder_cache { {} }; sub _build_fields { my ($self) = @_; my $obj = $self->model; @@ -102,6 +59,7 @@ sub _build_fields { return \@fields; } + sub _build_computed_field_order { my ($self) = @_; my %excluded = map { $_ => undef } @{ $self->excluded_fields }; diff --git a/lib/Reaction/UI/Widget/Field/Mutable.pm b/lib/Reaction/UI/Widget/Field/Mutable.pm index 1364b39..0e670e5 100644 --- a/lib/Reaction/UI/Widget/Field/Mutable.pm +++ b/lib/Reaction/UI/Widget/Field/Mutable.pm @@ -22,11 +22,7 @@ extends 'Reaction::UI::Widget::Field'; }; implements fragment message_fragment { - my $vp = $_{viewport}; - my $message = $_{viewport}->message; - $message ||= $vp->name.' is required' - if $vp->value_is_required && !$vp->value_string; - if ($message) { + if (my $message = $_{viewport}->message) { arg message => localized $message; render 'message'; } diff --git a/lib/Reaction/UI/WidgetClass.pm b/lib/Reaction/UI/WidgetClass.pm index e1a797b..622eec4 100644 --- a/lib/Reaction/UI/WidgetClass.pm +++ b/lib/Reaction/UI/WidgetClass.pm @@ -47,7 +47,7 @@ override exports_for_package => sub { my $sig = "should be: render 'name' or render 'name' => over \$coll"; if (!defined $name) { confess "name undefined: $sig"; } - if (ref $name) { confess "name not string: $sig"; } + if (ref $name) { confess "name is a ${\ref $name} ref, not a plain string: $sig"; } if (defined $over && !(blessed($over) && $over->isa(_OVER))) { confess "invalid args after name, $sig"; } diff --git a/share/skin/base/layout/action/link.tt b/share/skin/base/layout/action/link.tt index 41cee96..bd5013c 100644 --- a/share/skin/base/layout/action/link.tt +++ b/share/skin/base/layout/action/link.tt @@ -1,7 +1,5 @@ =for layout widget -<span class="action_link"> - <a href="[% uri %]">[% label %]</a> -</span> +<a href="[% uri %]">[% label %]</a> =cut diff --git a/share/skin/base/layout/collection/grid.tt b/share/skin/base/layout/collection/grid.tt index bfde10d..4042652 100644 --- a/share/skin/base/layout/collection/grid.tt +++ b/share/skin/base/layout/collection/grid.tt @@ -1,26 +1,20 @@ =for layout widget -<table> - [% header %] - [% body %] - [% footer %] -</table> +[% header %] +[% body %] +[% footer %] =for layout header -<thead> - [% header_row %] -</thead> +[% header_row %] =for layout header_row -<tr> - [% header_cells %] -</tr> +[% header_cells %] =for layout header_cell -<th> [% header_cell_contents %] </th> +[% header_cell_contents %] =for layout header_cell_contents @@ -28,10 +22,6 @@ =for layout body -<tbody> - - [% members %] - -</tbody> +[% members %] =cut diff --git a/share/skin/base/layout/collection/grid/member.tt b/share/skin/base/layout/collection/grid/member.tt index 9cf24e2..377f97c 100644 --- a/share/skin/base/layout/collection/grid/member.tt +++ b/share/skin/base/layout/collection/grid/member.tt @@ -1,11 +1,9 @@ =for layout widget -<tr> - [% field_list %] -</tr> +[% field_list %] =for layout field -<td>[% call_next %]</td> +[% call_next %] =cut diff --git a/share/skin/base/layout/collection/grid/member/with_actions.tt b/share/skin/base/layout/collection/grid/member/with_actions.tt index a0bca88..e7ba750 100644 --- a/share/skin/base/layout/collection/grid/member/with_actions.tt +++ b/share/skin/base/layout/collection/grid/member/with_actions.tt @@ -7,6 +7,6 @@ =for layout action -<td>[% call_next %]</td> +[% call_next %] =cut diff --git a/share/skin/base/layout/list_view.tt b/share/skin/base/layout/list_view.tt index e1cf3a4..8a0197d 100644 --- a/share/skin/base/layout/list_view.tt +++ b/share/skin/base/layout/list_view.tt @@ -12,7 +12,7 @@ =for layout header_action_cell -<th colspan="[% col_count %]"> Actions </th> +Actions =for layout header_cell_contents @@ -20,42 +20,34 @@ =for layout actions -<div class="list_view_actions"> -<ul> - [% call_next %] -</ul> -</div> +[% call_next %] =for layout action -<li>[% call_next %]</li> +[% call_next %] =for layout pager -<div class="list_view_pager"> -<ul> - [% first_page %] - [% previous_page %] - [% page_list %] - [% next_page %] - [% last_page %] -</ul> -</div> +[% first_page %] +[% previous_page %] +[% page_list %] +[% next_page %] +[% last_page %] =for layout numbered_page_this_page -<li> [% page_number %] </li> +[% page_number %] =for layout numbered_page -<li> <a href="[% page_uri %]">[% page_number %]</a> </li> +<a href="[% page_uri %]">[% page_number %]</a> =for layout named_page -<li> <a href="[% page_uri %]">[% page_name %]</a> </li> +<a href="[% page_uri %]">[% page_name %]</a> =for layout named_page_no_page -<li> [% page_name %] </li> +[% page_name %] =cut diff --git a/share/skin/base/layout/site_layout.tt b/share/skin/base/layout/site_layout.tt index 90c916f..4ab1cf2 100644 --- a/share/skin/base/layout/site_layout.tt +++ b/share/skin/base/layout/site_layout.tt @@ -37,8 +37,6 @@ =for layout head_style -=for layout doctype - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> =for layout body diff --git a/share/skin/componentui/web/componentui-basic.css b/share/skin/componentui/web/componentui-basic.css index 1f25ddb..c8be739 100644 --- a/share/skin/componentui/web/componentui-basic.css +++ b/share/skin/componentui/web/componentui-basic.css @@ -172,19 +172,19 @@ input{ border: 1px solid #369; } -.collection_actions ul { +.collection_actions { display: inline margin: 0px; padding: 0px; list-style-type: none; } -.collection_actions ul li { +.collection_actions li { display: inline; margin: 0.2em; } -.collection_actions ul li a { +.collection_actions li a { /* background-color #9CF; */ /* padding: 0.2em .2em; */ /* text-decoration: none; */ diff --git a/share/skin/default/layout/collection/grid.tt b/share/skin/default/layout/collection/grid.tt new file mode 100644 index 0000000..ecfc7d6 --- /dev/null +++ b/share/skin/default/layout/collection/grid.tt @@ -0,0 +1,33 @@ +=extends NEXT + +=for layout widget + +<table> + [% call_next %] +</table> + +=for layout header + +<thead> + [% call_next %] +</thead> + +=for layout header_row + +<tr> + [% call_next %] +</tr> + +=for layout header_cell + +<th> [% call_next %] </th> + +=for layout body + +<tbody> + + [% call_next %] + +</tbody> + +=cut diff --git a/share/skin/default/layout/collection/grid/member.tt b/share/skin/default/layout/collection/grid/member.tt new file mode 100644 index 0000000..f0583d7 --- /dev/null +++ b/share/skin/default/layout/collection/grid/member.tt @@ -0,0 +1,13 @@ +=extends NEXT + +=for layout widget + +<tr> + [% call_next %] +</tr> + +=for layout field + +<td>[% call_next %]</td> + +=cut diff --git a/share/skin/default/layout/collection/grid/member/with_actions.tt b/share/skin/default/layout/collection/grid/member/with_actions.tt new file mode 100644 index 0000000..a0bca88 --- /dev/null +++ b/share/skin/default/layout/collection/grid/member/with_actions.tt @@ -0,0 +1,12 @@ +=extends collection/grid/member + +=for layout field_list + +[% call_next %] +[% actions %] + +=for layout action + +<td>[% call_next %]</td> + +=cut diff --git a/share/skin/default/layout/list_view.tt b/share/skin/default/layout/list_view.tt index 78ab34f..f1a72b1 100644 --- a/share/skin/default/layout/list_view.tt +++ b/share/skin/default/layout/list_view.tt @@ -1,15 +1,57 @@ -=extends NEXT +=extends collection/grid + +=for layout widget + +[% pager_fragment %] + +[% call_next %] + +[% pager_fragment %] + +[% actions %] + +=for layout header_action_cell + +<th colspan="[% col_count %]"> Actions </th> + +=for layout header_cell_contents + +<a href="[% order_uri %]">[% call_next %]</a> + +=for layout actions + +<ul class="collection_actions"> + [% call_next %] +</ul> + +=for layout action + +<li>[% call_next %]</li> =for layout pager -<div class="pager"> -<ul> +<ul class="pager"> [% first_page %] [% previous_page %] [% page_list %] [% next_page %] [% last_page %] </ul> -</div> + +=for layout numbered_page_this_page + +<li> [% page_number %] </li> + +=for layout numbered_page + +<li> <a href="[% page_uri %]">[% page_number %]</a> </li> + +=for layout named_page + +<li> <a href="[% page_uri %]">[% page_name %]</a> </li> + +=for layout named_page_no_page + +<li> [% page_name %] </li> =cut |