diff options
author | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2008-10-31 21:10:33 +0000 |
---|---|---|
committer | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2008-10-31 21:10:33 +0000 |
commit | 336b3bb0ca6893e856f82865521d599dd1596538 (patch) | |
tree | 5fa544b096de10bad69fdfb2ec8cbecc87117166 /lib | |
parent | 1c601a7646d5da9d4ca4c21a2734455ba184de1f (diff) | |
download | reaction-336b3bb0ca6893e856f82865521d599dd1596538.tar.gz reaction-336b3bb0ca6893e856f82865521d599dd1596538.zip |
checking in more pod, some fixes for weird bugs, a manual for migration, an extra ComponentUI example and a new ResultSet base class for IM actions
Diffstat (limited to 'lib')
8 files changed, 265 insertions, 11 deletions
diff --git a/lib/ComponentUI/Controller/TestModel/Foo.pm b/lib/ComponentUI/Controller/TestModel/Foo.pm index e8e2318..99f33c1 100644 --- a/lib/ComponentUI/Controller/TestModel/Foo.pm +++ b/lib/ComponentUI/Controller/TestModel/Foo.pm @@ -10,6 +10,7 @@ __PACKAGE__->config( base => { Chained => '/base', PathPart => 'testmodel/foo' }, list => { ViewPort => { + action_prototypes => { delete_all => 'Delete all records' }, excluded_fields => [qw/id/], action_order => [qw/delete_all create/], Member => { diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/Result.pm b/lib/Reaction/InterfaceModel/Action/DBIC/Result.pm index 405209e..3b172c6 100644 --- a/lib/Reaction/InterfaceModel/Action/DBIC/Result.pm +++ b/lib/Reaction/InterfaceModel/Action/DBIC/Result.pm @@ -7,11 +7,40 @@ use Reaction::Class; use namespace::clean -except => [ qw(meta) ]; extends 'Reaction::InterfaceModel::Action'; - - has '+target_model' => (isa => Row); __PACKAGE__->meta->make_immutable; - 1; + +__END__; + +=head1 NAME + +Reaction::InterfaceModel::Action::DBIC::Result + +=head1 DESCRIPTION + +Base class for actions that apply to DBIC row objects. Extends +L<InterfaceModel::Action|Reaction::InterfaceModel::Action> + +=head1 ATTRIBUTES + +=head2 target_model + +Extends C<target_model> by assigning it a type constraint of +L<Row|Reaction::Types::DBIC>. + +=head1 SEE ALSO + +L<Action::DBIC::ResultSet|Reaction::InterfaceModel::Action::DBIC::ResultSet>, + +=head1 AUTHORS + +See L<Reaction::Class> for authors. + +=head1 LICENSE + +See L<Reaction::Class> for the license. + +=cut diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/Result/Delete.pm b/lib/Reaction/InterfaceModel/Action/DBIC/Result/Delete.pm index dddf6b4..7b6aaba 100644 --- a/lib/Reaction/InterfaceModel/Action/DBIC/Result/Delete.pm +++ b/lib/Reaction/InterfaceModel/Action/DBIC/Result/Delete.pm @@ -1,9 +1,8 @@ package Reaction::InterfaceModel::Action::DBIC::Result::Delete; -use Reaction::Types::DBIC 'Row'; use Reaction::Class; - use namespace::clean -except => [ qw(meta) ]; + extends 'Reaction::InterfaceModel::Action::DBIC::Result'; with 'Reaction::InterfaceModel::Action::Role::SimpleMethodCall'; diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/Result/Update.pm b/lib/Reaction/InterfaceModel/Action/DBIC/Result/Update.pm index 03ac9c1..b5068cc 100644 --- a/lib/Reaction/InterfaceModel/Action/DBIC/Result/Update.pm +++ b/lib/Reaction/InterfaceModel/Action/DBIC/Result/Update.pm @@ -1,10 +1,9 @@ package Reaction::InterfaceModel::Action::DBIC::Result::Update; -use Reaction::Types::DBIC 'Row'; use Reaction::Class; - use namespace::clean -except => [ qw(meta) ]; -extend 'Reaction::InterfaceModel::Action::DBIC::Result'; + +extends 'Reaction::InterfaceModel::Action::DBIC::Result'; with 'Reaction::InterfaceModel::Action::DBIC::Role::CheckUniques'; sub BUILD { diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet.pm b/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet.pm new file mode 100644 index 0000000..90bc429 --- /dev/null +++ b/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet.pm @@ -0,0 +1,48 @@ +package Reaction::InterfaceModel::Action::DBIC::ResultSet; + +use Reaction::InterfaceModel::Action; +use Reaction::Types::DBIC 'ResultSet'; +use Reaction::Class; + +use namespace::clean -except => [ qw(meta) ]; +extends 'Reaction::InterfaceModel::Action'; + +has '+target_model' => (isa => ResultSet); + +__PACKAGE__->meta->make_immutable; + +1; + +__END__; + + +=head1 NAME + +Reaction::InterfaceModel::Action::DBIC::ResultSet + +=head1 DESCRIPTION + +Base class for actions that apply to DBIC resultset objects. Extends +L<InterfaceModel::Action|Reaction::InterfaceModel::Action> + +=head1 ATTRIBUTES + +=head2 target_model + +Extends C<target_model> by assigning it a type constraint of +L<ResultSet|Reaction::Types::DBIC>. + +=head1 SEE ALSO + +L<Action::DBIC::Result|Reaction::InterfaceModel::Action::DBIC::Result>, + +=head1 AUTHORS + +See L<Reaction::Class> for authors. + +=head1 LICENSE + +See L<Reaction::Class> for the license. + +=cut + diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet/Create.pm b/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet/Create.pm index 6076570..c6e6dd1 100644 --- a/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet/Create.pm +++ b/lib/Reaction/InterfaceModel/Action/DBIC/ResultSet/Create.pm @@ -6,11 +6,10 @@ use Reaction::InterfaceModel::Action; use Reaction::InterfaceModel::Action::DBIC::Role::CheckUniques; use namespace::clean -except => [ qw(meta) ]; -extends 'Reaction::InterfaceModel::Action'; +extends 'Reaction::InterfaceModel::Action::DBIC::ResultSet'; with 'Reaction::InterfaceModel::Action::DBIC::Role::CheckUniques'; -has '+target_model' => (isa => ResultSet); sub do_apply { my $self = shift; my $args = $self->parameter_hashref; diff --git a/lib/Reaction/Manual/ActionPrototypes.pod b/lib/Reaction/Manual/ActionPrototypes.pod new file mode 100644 index 0000000..abf3a2d --- /dev/null +++ b/lib/Reaction/Manual/ActionPrototypes.pod @@ -0,0 +1,179 @@ +=head1 Changes to the Action Prototype Mechanism + +=head1 DESCRIPTION + +After Reaction 0.001001 the API used to create links for different actions in +the L<ViewPort::Collection::Grid|Reaction::UI::ViewPort::Collection::Grid> +changed significantly. The aim of the changes was to create a simpler API that +was more concise, flexible, and didn't tie unneccessary controller logic in the +ViewPort layer. + +=head1 Major Changes + +=head2 Controller Layer + +=head3 L<Reaction::UI::Controller::Collection> + +=over 4 + +=item The default display class for the C<list> action is now +L<Grid|Reaction::UI::ViewPort::Collection::Grid>. + +=item Addition of the C<default_member_actions> and C<default_collection_actions> + +=item Addition of the C<_build_member_action_prototype> and +C<_build_collection_action_prototype> methods. These are used by +C<_build_action_viewport_args> to create prototypes for collection and member +actions. + +=back + +=head3 L<Reaction::UI::Controller::Collection::CRUD> + +By default, enable C<create>, C<update>, C<delete>, C<delete_all>, actions. + +=head2 ViewPort Layer + +=head3 L<Reaction::UI::ViewPort::Collection::Grid> + +=over 4 + +=item Add the C<member_action_count> attribute. It allows the controller to +know how many actions to expect to lay out the UI properly. + +=item Default to member-class +L<Grid::Member::WithActions|Reaction::UI::ViewPort::Collection::Grid::Member::WithActions> + +=back + +=head2 L<Reaction::UI::ViewPort::Role::Actions> + +Completely revamped the action-prototypes, added ordering support and moved to +using the new C<ViewPort::URI|Reaction::UI::ViewPort::URI>. + +Most notably C<action_prototypes> is now a HASH ref. + +=head1 Migration + +In most cases, you shouldn't need to change much for migration, but if you had +custom actions in your controllers that were linked to by the CRUD system, or +you had excluded certain classes, you'll need to create some minor updates. + +=head2 A custom collection action in your controller. + + #old code + sub custom_action { ... } + sub _build_action_viewport_map { + my $map = shift->next::method(@_); + $map->{custom_action} = 'Reaction::UI::ViewPort::Action'; + return $map; + } + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + my $custom_proto = { + label => 'Create', + action => sub { [ '', 'create', $_[1]->req->captures ] } + }; + my $protos = $args->{list}->{action_prototypes}; + push(@$protos, $custom_proto); + return $args; + } + + #new code: + sub custom_action { ... } + sub _build_action_viewport_map { + my $map = shift->next::method(@_); + $map->{custom_action} = 'Reaction::UI::ViewPort::Action'; + return $map; + } + sub _build_default_collection_actions { + [ @{shift->next::method(@_)}, 'custom_action']; + } + +=head2 A custom member action in your controller. + + #old code + sub custom_action { ... } + sub _build_action_viewport_map { + my $map = shift->next::method(@_); + $map->{custom_action} = 'Reaction::UI::ViewPort::Action'; + return $map; + } + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + my $custom_proto = { + label => 'Create', + action => sub { [ '', 'create', $_[1]->req->captures ] } + }; + my $protos = $args->{list}->{Member}->{action_prototypes}; + push(@$protos, $custom_proto); + return $args; + } + + #new code: + sub custom_action { ... } + sub _build_action_viewport_map { + my $map = shift->next::method(@_); + $map->{custom_action} = 'Reaction::UI::ViewPort::Action'; + return $map; + } + sub _build_default_member_actions { + [ @{shift->next::method(@_)}, 'custom_action']; + } + + +=head2 Disabling a default collection action + + #old code + sub delete_all {} + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + #remove the delete all action + my $protos = $args->{list}->{action_prototypes}; + @$protos = grep { $_->{label} !~ /Delete all/i } @$protos; + return $args; + } + + #new code + sub delete_all {} + sub _build_default_collection_actions { + [ grep {$_ ne 'delete_all'} @{ shift->next::method(@_) } ]; + } + + #or ... + sub delete_all {} + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + my $protos = $args->{list}->{action_prototypes}; + delete $protos->{delete_all}; + return $args; + } + + +=head2 Changing the label of a collection action + + #old code + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + my $protos = $args->{list}->{action_prototypes}; + $proto = grep { $_->{label} eq 'Delete all' } @$protos; + $proto->{label} = 'New Label'; + return $args; + } + + #new code + sub delete_all {} + sub _build_action_viewport_args { + my $args = shift->next::method(@_); + my $protos = $args->{list}->{action_prototypes}; + $proto->{delete_all}->{label} = 'New Label'; + return $args; + } + + #or ... + __PACKAGE__->config(action => { list => { ViewPort => { + action_prototypes => { delete_all => {label => 'New Label'} } + }, + ); + +=cut diff --git a/lib/Reaction/UI/Controller/Collection/CRUD.pm b/lib/Reaction/UI/Controller/Collection/CRUD.pm index 1141826..1813e05 100644 --- a/lib/Reaction/UI/Controller/Collection/CRUD.pm +++ b/lib/Reaction/UI/Controller/Collection/CRUD.pm @@ -15,7 +15,7 @@ sub _build_action_viewport_map { #my %allowed = map { $_ => undef } # ( @{$self->default_member_actions}, @{$self->default_collection_actions} ); - #my @local_actions = qw/create update delete delete_all/; + my @local_actions = qw/create update delete delete_all/; #$map->{$_} = Action for grep { exists $allowed{$_} } @local_actions; $map->{$_} = Action for @local_actions; |