merge docs for action viewport roles
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Action.pm
CommitLineData
ddccc6a2 1package Reaction::UI::ViewPort::Action;
2
3use Reaction::Class;
4
08451970 5use aliased 'Reaction::UI::ViewPort::Object';
6use aliased 'Reaction::UI::ViewPort::Field::Mutable::Text';
7use aliased 'Reaction::UI::ViewPort::Field::Mutable::Array';
8use aliased 'Reaction::UI::ViewPort::Field::Mutable::String';
9use aliased 'Reaction::UI::ViewPort::Field::Mutable::Number';
10use aliased 'Reaction::UI::ViewPort::Field::Mutable::Integer';
11use aliased 'Reaction::UI::ViewPort::Field::Mutable::Boolean';
12use aliased 'Reaction::UI::ViewPort::Field::Mutable::Password';
13use aliased 'Reaction::UI::ViewPort::Field::Mutable::DateTime';
14use aliased 'Reaction::UI::ViewPort::Field::Mutable::ChooseOne';
15use aliased 'Reaction::UI::ViewPort::Field::Mutable::ChooseMany';
16
17use aliased 'Reaction::UI::ViewPort::Field::Mutable::File';
18#use aliased 'Reaction::UI::ViewPort::Field::Mutable::TimeRange';
19
20use MooseX::Types::Moose qw/Int/;
21use Reaction::Types::Core qw/NonEmptySimpleStr/;
22
23use namespace::clean -except => [ qw(meta) ];
08451970 24with 'Reaction::UI::ViewPort::Action::Role::OK';
25
26has model => (
27 is => 'ro',
28 isa => 'Reaction::InterfaceModel::Action',
29 required => 1
30 );
31
32has changed => (
33 is => 'rw',
34 isa => Int,
35 reader => 'is_changed',
36 default => sub{0}
37 );
38
39#this has to fucking go. it BLOWS.
40has method => (
41 is => 'rw',
42 isa => NonEmptySimpleStr,
43 default => sub { 'post' }
44 );
45
46sub can_apply {
47 my ($self) = @_;
48 foreach my $field ( @{ $self->fields } ) {
49 return 0 if $field->needs_sync;
50 # if e.g. a datetime field has an invalid value that can't be re-assembled
51 # into a datetime object, the action may be in a consistent state but
52 # not synchronized from the fields; in this case, we must not apply
53 }
54 return $self->model->can_apply;
55}
56
57sub do_apply {
58 shift->model->do_apply;
59}
60
61after apply_child_events => sub {
62 # interrupt here because fields will have been updated
63 my ($self) = @_;
64 $self->sync_action_from_fields;
65};
66
67sub sync_action_from_fields {
68 my ($self) = @_;
69 foreach my $field (@{$self->fields}) {
70 $field->sync_to_action; # get the field to populate the $action if possible
71 }
72 $self->model->sync_all;
73 foreach my $field (@{$self->fields}) {
74 $field->sync_from_action; # get errors from $action if applicable
75 }
76}
77
78sub _build_fields_for_type_Num {
79 my ($self, $attr, $args) = @_;
80 $self->_build_simple_field(attribute => $attr, class => Number, %$args);
81}
82
83sub _build_fields_for_type_Int {
84 my ($self, $attr, $args) = @_;
85 $self->_build_simple_field(attribute => $attr, class => Integer, %$args);
86}
87
88sub _build_fields_for_type_Bool {
89 my ($self, $attr, $args) = @_;
90 $self->_build_simple_field(attribute => $attr, class => Boolean, %$args);
91}
92
93sub _build_fields_for_type_Reaction_Types_Core_SimpleStr {
94 my ($self, $attr, $args) = @_;
95 $self->_build_simple_field(attribute => $attr, class => String, %$args);
96}
97
98sub _build_fields_for_type_Reaction_Types_File_File {
99 my ($self, $attr, $args) = @_;
100 $self->_build_simple_field(attribute => $attr, class => File, %$args);
101}
102
103sub _build_fields_for_type_Str {
104 my ($self, $attr, $args) = @_;
105 if ($attr->has_valid_values) { # There's probably a better way to do this
106 $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args);
107 } else {
108 $self->_build_simple_field(attribute => $attr, class => Text, %$args);
109 }
110}
111
112sub _build_fields_for_type_Reaction_Types_Core_Password {
113 my ($self, $attr, $args) = @_;
114 $self->_build_simple_field(attribute => $attr, class => Password, %$args);
115}
116
117sub _build_fields_for_type_Reaction_Types_DateTime_DateTime {
118 my ($self, $attr, $args) = @_;
119 $self->_build_simple_field(attribute => $attr, class => DateTime, %$args);
120}
121
122sub _build_fields_for_type_Enum {
123 my ($self, $attr, $args) = @_;
124 $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args);
125}
126
127#this needs to be fixed. somehow. beats the shit our of me. really.
128#implements build_fields_for_type_Reaction_InterfaceModel_Object => as {
129sub _build_fields_for_type_DBIx_Class_Row {
130 my ($self, $attr, $args) = @_;
131 $self->_build_simple_field(attribute => $attr, class => ChooseOne, %$args);
132}
133
134sub _build_fields_for_type_ArrayRef {
135 my ($self, $attr, $args) = @_;
136 if ($attr->has_valid_values) {
137 $self->_build_simple_field(attribute => $attr, class => ChooseMany, %$args);
138 } else {
139 $self->_build_simple_field
140 (
141 attribute => $attr,
142 class => Array,
143 layout => 'field/mutable/hidden_array',
144 %$args);
145 }
114916fc 146}
81393881 147
148__PACKAGE__->meta->make_immutable;
149
114916fc 1501;
ddccc6a2 151
114916fc 152__END__;
ddccc6a2 153
08451970 154=head1 NAME
155
156Reaction::UI::ViewPort::Object::Mutable
157
158=head1 SYNOPSIS
159
160 use aliased 'Reaction::UI::ViewPort::Object::Mutable';
161
162 $self->push_viewport(Mutable,
163 layout => 'register',
164 model => $action,
165 next_action => [ $self, 'redirect_to', 'accounts', $c->req->captures ],
166 ctx => $c,
167 field_order => [
168 qw / contact_title company_name email address1 address2 address3
169 city country post_code telephone mobile fax/ ],
170 );
171
172=head1 DESCRIPTION
173
599c1172 174This subclass of L<Reaction::UI::ViewPort::Object::Mutable> is used for
175rendering a complete form supporting Apply, Close and OK.
08451970 176
177=head1 ATTRIBUTES
178
599c1172 179=head2 method
08451970 180
599c1172 181post / get
08451970 182
183=head2 changed
184
185Returns true if a field has been edited.
186
08451970 187=head1 METHODS
188
599c1172 189=head2 can_apply
08451970 190
599c1172 191=head2 do_apply
08451970 192
599c1172 193=head2 sync_action_from_fields
08451970 194
599c1172 195=head1 SEE ALSO
08451970 196
599c1172 197L<Reaction::UI::ViewPort>
08451970 198
599c1172 199L<Reaction::UI::ViewPort::Object>
08451970 200
599c1172 201L<Reaction::UI::ViewPort::Object::Mutable>
08451970 202
599c1172 203L<Reaction::InterfaceModel::Action::Role::Apply>
08451970 204
599c1172 205L<Reaction::InterfaceModel::Action::Role::Close>
08451970 206
599c1172 207L<Reaction::InterfaceModel::Action::Role::OK>
08451970 208
209=head1 AUTHORS
210
211See L<Reaction::Class> for authors.
212
213=head1 LICENSE
214
215See L<Reaction::Class> for the license.
216
217=cut
218