Commit | Line | Data |
89b70ba7 |
1 | package Reaction::UI::Controller::Collection::CRUD; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | use base 'Reaction::UI::Controller::Collection'; |
6 | use Reaction::Class; |
7 | |
c8fbb8ad |
8 | use aliased 'Reaction::UI::ViewPort::Action'; |
89b70ba7 |
9 | |
10 | sub _build_action_viewport_map { |
11 | my $map = shift->next::method(@_); |
c8fbb8ad |
12 | map{ $map->{$_} = Action } qw/create update delete delete_all/; |
89b70ba7 |
13 | return $map; |
14 | } |
15 | |
16 | sub _build_action_viewport_args { |
17 | my $args = shift->next::method(@_); |
18 | $args->{list} = |
19 | { action_prototypes => |
20 | [ { label => 'Create', action => sub { |
21 | [ '', 'create', $_[1]->req->captures ] } }, |
22 | { label => 'Delete all', action => sub { |
23 | [ '', 'delete_all', $_[1]->req->captures ] } }, |
24 | ], |
c8fbb8ad |
25 | Member => |
89b70ba7 |
26 | { action_prototypes => |
27 | [ { label => 'View', action => sub { |
28 | [ '', 'view', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } }, |
29 | { label => 'Edit', action => sub { |
30 | [ '', 'update', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } }, |
31 | { label => 'Delete', action => sub { |
32 | [ '', 'delete', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } }, |
33 | ], |
34 | }, |
35 | }; |
36 | return $args; |
37 | } |
38 | |
39 | sub get_model_action { |
40 | my ($self, $c, $name, $target) = @_; |
41 | |
42 | if ($target->can('action_for')) { |
43 | return $target->action_for($name, ctx => $c); |
44 | } |
45 | |
46 | #can we please kill this already? |
47 | my $model_name = "Action::${name}".$self->model_name; |
48 | my $model = $c->model($model_name); |
49 | confess "no such Model $model_name" unless $model; |
50 | return $model->new(target_model => $target, ctx => $c); |
51 | } |
52 | |
53 | sub create :Chained('base') :PathPart('create') :Args(0) { |
54 | my ($self, $c) = @_; |
55 | my $vp_args = { |
56 | next_action => 'list', |
57 | on_apply_callback => sub { $self->after_create_callback($c => @_); }, |
58 | }; |
59 | $c->forward( basic_model_action => [$vp_args]); |
60 | } |
61 | |
62 | sub delete_all :Chained('base') :PathPart('delete_all') :Args(0) { |
63 | my ($self, $c) = @_; |
64 | $c->forward(basic_model_action => [{ next_action => 'list'}]); |
65 | } |
66 | |
67 | sub after_create_callback { |
68 | my ($self, $c, $vp, $result) = @_; |
69 | return $self->redirect_to |
70 | ( $c, 'update', [ @{$c->req->captures}, $result->id ] ); |
71 | } |
72 | |
73 | sub update :Chained('object') :Args(0) { |
74 | my ($self, $c) = @_; |
75 | #this needs a better solution. currently thinking about it |
76 | my @cap = @{$c->req->captures}; |
77 | pop(@cap); # object id |
78 | my $vp_args = { next_action => [ $self, 'redirect_to', 'list', \@cap ]}; |
79 | $c->forward(basic_model_action => [$vp_args]); |
80 | } |
81 | |
82 | sub delete :Chained('object') :Args(0) { |
83 | my ($self, $c) = @_; |
84 | #this needs a better solution. currently thinking about it |
85 | my @cap = @{$c->req->captures}; |
86 | pop(@cap); # object id |
87 | my $vp_args = { next_action => [ $self, 'redirect_to', 'list', \@cap ]}; |
88 | $c->forward(basic_model_action => [$vp_args]); |
89 | } |
90 | |
91 | sub basic_model_action :Private { |
92 | my ($self, $c, $vp_args) = @_; |
93 | |
94 | my $target = exists $c->stash->{object} ? |
95 | $c->stash->{object} : $self->get_collection($c); |
96 | |
97 | my $cat_action_name = $c->stack->[-2]->name; |
98 | my $im_action_name = join('', (map{ ucfirst } split('_', $cat_action_name))); |
99 | $c->log->debug($cat_action_name); |
100 | $c->log->debug($self->action_viewport_map->{$cat_action_name}); |
101 | $c->log->debug(keys %{$self->action_viewport_map}); |
102 | return $self->push_viewport |
103 | ( |
104 | $self->action_viewport_map->{$cat_action_name}, |
c8fbb8ad |
105 | model => $self->get_model_action($c, $im_action_name, $target), |
89b70ba7 |
106 | %{ $vp_args || {} }, |
107 | %{ $self->action_viewport_args->{$cat_action_name} || {} }, |
108 | ); |
109 | } |
110 | |
111 | 1; |