more POD
[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);
f46fa4fd 13has computed_field_order => (is => 'ro', isa => 'ArrayRef', lazy_build => 1);
14
e113d857 15has _raw_field_labels => (
f46fa4fd 16 is => 'rw',
17 isa => 'HashRef',
e113d857 18 init_arg => 'field_labels',
f46fa4fd 19 default => sub { {} },
e113d857 20);
f46fa4fd 21
e113d857 22has field_labels => (
f46fa4fd 23 is => 'ro',
24 isa => 'HashRef',
25 lazy_build => 1,
26 init_arg => undef,
e113d857 27);
81393881 28
f46fa4fd 29has member_action_count => (
30 is => 'rw',
31 isa => 'Int',
32 required => 1,
33 lazy => 1,
34 default => sub {
35 my $self = shift;
36 for (@{ $self->members }) {
37 my $protos = $_->action_prototypes;
37728bba 38 return scalar(keys(%$protos));
f46fa4fd 39 }
40 return 1;
41 },
42);
81393881 43
44####################################
f46fa4fd 45sub _build_member_class { WithActions };
46
81393881 47sub _build_field_labels {
48 my $self = shift;
e113d857 49 my %labels = %{$self->_raw_field_labels};
50 for my $field ( @{$self->computed_field_order}) {
51 next if $labels{$field};
81393881 52 $labels{$field} = join(' ', map{ ucfirst } split('_', $field));
53 }
54 return \%labels;
f46fa4fd 55}
56
57sub _build_field_order { []; }
58
59sub _build_excluded_fields { []; }
60
61#this is a total clusterfuck and it sucks we should just eliminate it and have
62# the grid members not render ArrayRef or Collection fields
81393881 63sub _build_computed_field_order {
64 my ($self) = @_;
65 my %excluded = map { $_ => undef } @{ $self->excluded_fields };
66 #treat _$field_name as private and exclude fields with no reader
67 my @names = grep { $_ !~ /^_/ && !exists($excluded{$_})} map { $_->name }
68 grep {
69 !($_->has_type_constraint &&
70 ($_->type_constraint->is_a_type_of('ArrayRef') ||
71 eval {$_->type_constraint->name->isa('Reaction::InterfaceModel::Collection')} ||
72 eval { $_->_isa_metadata->isa('Reaction::InterfaceModel::Collection') }
73 )
74 ) }
75 grep { defined $_->get_read_method }
76 $self->current_collection->member_type->parameter_attributes;
77
78 return $self->sort_by_spec($self->field_order, \@names);
f46fa4fd 79}
ddccc6a2 80
f46fa4fd 81around _build_members => sub {
82 my $orig = shift;
83 my $self = shift;
81393881 84 $self->member_args->{computed_field_order} ||= $self->computed_field_order;
37728bba 85 $self->member_args->{computed_action_order} ||= [];
f46fa4fd 86 my $members = $self->$orig(@_);
87
88 # cache everything yo
37728bba 89 for my $member (@$members){
90 $member->clear_computed_action_order;
91 my $order = $member->computed_action_order;
92 @{ $self->member_args->{computed_action_order} } = @$order;
93 last;
94 }
f46fa4fd 95
96 return $members;
81393881 97};
98
99__PACKAGE__->meta->make_immutable;
100
101
2dba7201 1021;
ddccc6a2 103
2dba7201 104__END__;
ddccc6a2 105
2dba7201 106=head1 NAME
107
108Reaction::UI::ViewPort::Collection
109
110=head1 DESCRIPTION
111
112This subclass of L<Reaction::UI::ViewPort::Collection> allows you to display a
113homogenous collection of Reaction::InterfaceModel::Objects as a grid.
114
115=head1 ATTRIBUTES
116
117=head2 field_order
118
119=head2 excluded_fields
120
121=head2 field_labels
122
123=head2 computed_field_order
124
2dba7201 125=head1 INTERNAL METHODS
126
127These methods, although stable, are subject to change without notice. These are meant
128to be used only by developers. End users should refrain from using these methods to
129avoid potential breakages.
130
131=head1 SEE ALSO
132
133L<Reaction::UI::ViewPort::Collection>
134
135=head1 AUTHORS
136
137See L<Reaction::Class> for authors.
138
139=head1 LICENSE
140
141See L<Reaction::Class> for the license.
142
143=cut