aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Reaction/UI/ViewPort/Action.pm120
-rw-r--r--lib/Reaction/UI/ViewPort/Action/Role/Apply.pm42
-rw-r--r--lib/Reaction/UI/ViewPort/Action/Role/Close.pm48
-rw-r--r--lib/Reaction/UI/ViewPort/Action/Role/OK.pm34
-rw-r--r--lib/Reaction/UI/ViewPort/Object.pm50
-rw-r--r--lib/Reaction/UI/Widget/Field/Mutable.pm6
-rw-r--r--lib/Reaction/UI/WidgetClass.pm2
-rw-r--r--share/skin/base/layout/action/link.tt4
-rw-r--r--share/skin/base/layout/collection/grid.tt24
-rw-r--r--share/skin/base/layout/collection/grid/member.tt6
-rw-r--r--share/skin/base/layout/collection/grid/member/with_actions.tt2
-rw-r--r--share/skin/base/layout/list_view.tt32
-rw-r--r--share/skin/base/layout/site_layout.tt2
-rw-r--r--share/skin/componentui/web/componentui-basic.css6
-rw-r--r--share/skin/default/layout/collection/grid.tt33
-rw-r--r--share/skin/default/layout/collection/grid/member.tt13
-rw-r--r--share/skin/default/layout/collection/grid/member/with_actions.tt12
-rw-r--r--share/skin/default/layout/list_view.tt50
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