changed search api to less magic but working version
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Collection / Grid.pm
CommitLineData
ddccc6a2 1package Reaction::UI::ViewPort::Collection::Grid;
2
3use Reaction::Class;
4
5use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection';
f46fa4fd 6use aliased 'Reaction::UI::ViewPort::Collection::Grid::Member::WithActions';
ddccc6a2 7
81393881 8use namespace::clean -except => [ qw(meta) ];
9extends 'Reaction::UI::ViewPort::Collection';
ddccc6a2 10
f46fa4fd 11has field_order => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1);
81393881 12has excluded_fields => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1);
f5e2ab69 13has included_fields => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1);
f46fa4fd 14has computed_field_order => (is => 'ro', isa => 'ArrayRef', lazy_build => 1);
15
e113d857 16has _raw_field_labels => (
f46fa4fd 17 is => 'rw',
18 isa => 'HashRef',
e113d857 19 init_arg => 'field_labels',
f46fa4fd 20 default => sub { {} },
e113d857 21);
f46fa4fd 22
e113d857 23has field_labels => (
f46fa4fd 24 is => 'ro',
25 isa => 'HashRef',
26 lazy_build => 1,
27 init_arg => undef,
e113d857 28);
81393881 29
f46fa4fd 30has member_action_count => (
31 is => 'rw',
32 isa => 'Int',
33 required => 1,
34 lazy => 1,
35 default => sub {
36 my $self = shift;
37 for (@{ $self->members }) {
38 my $protos = $_->action_prototypes;
37728bba 39 return scalar(keys(%$protos));
f46fa4fd 40 }
41 return 1;
42 },
43);
81393881 44
45####################################
f46fa4fd 46sub _build_member_class { WithActions };
47
81393881 48sub _build_field_labels {
49 my $self = shift;
e113d857 50 my %labels = %{$self->_raw_field_labels};
51 for my $field ( @{$self->computed_field_order}) {
642eb116 52 next if defined $labels{$field};
81393881 53 $labels{$field} = join(' ', map{ ucfirst } split('_', $field));
54 }
55 return \%labels;
f46fa4fd 56}
57
58sub _build_field_order { []; }
59
60sub _build_excluded_fields { []; }
61
f5e2ab69 62sub _build_included_fields { [] }
63
f46fa4fd 64#this is a total clusterfuck and it sucks we should just eliminate it and have
65# the grid members not render ArrayRef or Collection fields
81393881 66sub _build_computed_field_order {
67 my ($self) = @_;
68 my %excluded = map { $_ => undef } @{ $self->excluded_fields };
f5e2ab69 69 my %included = map { $_ => undef } @{ $self->included_fields };
81393881 70 #treat _$field_name as private and exclude fields with no reader
f5e2ab69 71 my @names = grep { $_ !~ /^_/ && (!%included || exists( $included{$_}) )
72 && !exists($excluded{$_})} map { $_->name }
81393881 73 grep {
74 !($_->has_type_constraint &&
75 ($_->type_constraint->is_a_type_of('ArrayRef') ||
76 eval {$_->type_constraint->name->isa('Reaction::InterfaceModel::Collection')} ||
77 eval { $_->_isa_metadata->isa('Reaction::InterfaceModel::Collection') }
78 )
79 ) }
80 grep { defined $_->get_read_method }
81 $self->current_collection->member_type->parameter_attributes;
82
83 return $self->sort_by_spec($self->field_order, \@names);
f46fa4fd 84}
ddccc6a2 85
f46fa4fd 86around _build_members => sub {
87 my $orig = shift;
88 my $self = shift;
81393881 89 $self->member_args->{computed_field_order} ||= $self->computed_field_order;
37728bba 90 $self->member_args->{computed_action_order} ||= [];
f46fa4fd 91 my $members = $self->$orig(@_);
92
93 # cache everything yo
37728bba 94 for my $member (@$members){
95 $member->clear_computed_action_order;
96 my $order = $member->computed_action_order;
97 @{ $self->member_args->{computed_action_order} } = @$order;
98 last;
99 }
f46fa4fd 100
101 return $members;
81393881 102};
103
104__PACKAGE__->meta->make_immutable;
105
106
2dba7201 1071;
ddccc6a2 108
2dba7201 109__END__;
ddccc6a2 110
2dba7201 111=head1 NAME
112
113Reaction::UI::ViewPort::Collection
114
115=head1 DESCRIPTION
116
117This subclass of L<Reaction::UI::ViewPort::Collection> allows you to display a
118homogenous collection of Reaction::InterfaceModel::Objects as a grid.
119
120=head1 ATTRIBUTES
121
122=head2 field_order
123
124=head2 excluded_fields
125
f5e2ab69 126List of field names to exclude.
127
128=head2 included_fields
129
130List of field names to include. If both C<included_fields> and
131C<excluded_fields> are specified the result is those fields which
132are in C<included_fields> and not in C<excluded_fields>.
133
134=head2 included_fields
135
136List of field names to include. If both C<included_fields> and
137C<excluded_fields> are specified the result is those fields which
138are in C<included_fields> and not in C<excluded_fields>.
139
140
2dba7201 141=head2 field_labels
142
7460b544 143=head2 _raw_field_labels
144
2dba7201 145=head2 computed_field_order
146
7460b544 147=head2 member_action_count
148
2dba7201 149=head1 INTERNAL METHODS
150
151These methods, although stable, are subject to change without notice. These are meant
152to be used only by developers. End users should refrain from using these methods to
153avoid potential breakages.
154
155=head1 SEE ALSO
156
157L<Reaction::UI::ViewPort::Collection>
158
159=head1 AUTHORS
160
161See L<Reaction::Class> for authors.
162
163=head1 LICENSE
164
165See L<Reaction::Class> for the license.
166
167=cut