shallow copying req->params
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Action.pm
CommitLineData
ddccc6a2 1package Reaction::UI::ViewPort::Action;
2
3use Reaction::Class;
4
e29819c4 5use MooseX::Types::Moose qw/Int Str/;
08451970 6use Reaction::Types::Core qw/NonEmptySimpleStr/;
7
8use namespace::clean -except => [ qw(meta) ];
b343a983 9
10extends 'Reaction::UI::ViewPort::Object::Mutable';
08451970 11with 'Reaction::UI::ViewPort::Action::Role::OK';
12
e29819c4 13has message => (is => 'rw', isa => Str);
eb52e595 14has '+model' => (handles => [qw/error_message has_error_message/]);
e29819c4 15
b343a983 16#this has to fucking go. it BLOWS.
17has method => (
18 is => 'rw',
19 isa => NonEmptySimpleStr,
20 default => sub { 'post' }
21);
08451970 22
23has changed => (
24 is => 'rw',
25 isa => Int,
26 reader => 'is_changed',
27 default => sub{0}
b343a983 28);
08451970 29
30sub can_apply {
31 my ($self) = @_;
32 foreach my $field ( @{ $self->fields } ) {
33 return 0 if $field->needs_sync;
34 # if e.g. a datetime field has an invalid value that can't be re-assembled
35 # into a datetime object, the action may be in a consistent state but
36 # not synchronized from the fields; in this case, we must not apply
37 }
38 return $self->model->can_apply;
39}
40
41sub do_apply {
42 shift->model->do_apply;
43}
44
45after apply_child_events => sub {
46 # interrupt here because fields will have been updated
47 my ($self) = @_;
48 $self->sync_action_from_fields;
49};
50
51sub sync_action_from_fields {
52 my ($self) = @_;
53 foreach my $field (@{$self->fields}) {
54 $field->sync_to_action; # get the field to populate the $action if possible
55 }
56 $self->model->sync_all;
57 foreach my $field (@{$self->fields}) {
58 $field->sync_from_action; # get errors from $action if applicable
59 }
60}
61
81393881 62
63__PACKAGE__->meta->make_immutable;
64
114916fc 651;
ddccc6a2 66
114916fc 67__END__;
ddccc6a2 68
08451970 69=head1 NAME
70
63bb30b4 71Reaction::UI::ViewPort::Action - Provide user with a form with OK, Apply and Close.
08451970 72
73=head1 SYNOPSIS
74
63bb30b4 75 $controller->push_viewport('Reaction::UI::ViewPort::Action',
76 model => $interface_model_action,
77 field_order => [qw( firstname lastname )],
78 excluded_fields => [qw( password )],
79 );
80
08451970 81=head1 DESCRIPTION
82
599c1172 83This subclass of L<Reaction::UI::ViewPort::Object::Mutable> is used for
84rendering a complete form supporting Apply, Close and OK.
08451970 85
86=head1 ATTRIBUTES
87
63bb30b4 88=head2 message
89
90=head2 model
91
92Inherited from L<Reaction::UI::ViewPort::Object::Mutable>. Must be a
93L<Reaction::InterfaceModel::Action>.
94
95Also handles C<error_message> and C<has_error_message> methods.
96
599c1172 97=head2 method
08451970 98
599c1172 99post / get
08451970 100
101=head2 changed
102
103Returns true if a field has been edited.
104
08451970 105=head1 METHODS
106
599c1172 107=head2 can_apply
08451970 108
63bb30b4 109Returns true if no field C<needs_sync> and the L</model> C<can_apply>.
110
599c1172 111=head2 do_apply
08451970 112
63bb30b4 113Delegates to C<do_apply> on the L</model>, which is a
114L<Reaction::InterfaceModel::Action>.
115
599c1172 116=head2 sync_action_from_fields
08451970 117
63bb30b4 118Firstly calls C<sync_to_action> on every L<Reaction::UI::ViewPort::Field::Mutable>
119in L<fields|Reaction::UI::ViewPort::Object/fields>. Then it calls C<sync_all> on
120the L<Reaction::InterfaceModel::Action> in L</model>. Next it will call
121C<sync_from_action> on every field to repopulate them from the L</model>.
122
123=head1 SUBCLASSING
124
125 package MyApp::UI::ViewPort::Action;
126 use Reaction::Class;
127 use MooseX::Types::Moose qw( Int );
128
129 use namespace::clean -except => 'meta';
130
131 extends 'Reaction::UI::ViewPort::Action';
132
133 has render_timestamp => (
134 is => 'ro',
135 isa => Int,
136 default => sub { time },
137 required => 1,
138 );
139
140 has '+field_order' => (default => sub {[qw( firstname lastname )]});
141
142 1;
143
599c1172 144=head1 SEE ALSO
08451970 145
599c1172 146L<Reaction::UI::ViewPort>
08451970 147
599c1172 148L<Reaction::UI::ViewPort::Object>
08451970 149
599c1172 150L<Reaction::UI::ViewPort::Object::Mutable>
08451970 151
599c1172 152L<Reaction::InterfaceModel::Action::Role::Apply>
08451970 153
599c1172 154L<Reaction::InterfaceModel::Action::Role::Close>
08451970 155
599c1172 156L<Reaction::InterfaceModel::Action::Role::OK>
08451970 157
158=head1 AUTHORS
159
160See L<Reaction::Class> for authors.
161
162=head1 LICENSE
163
164See L<Reaction::Class> for the license.
165
166=cut
167