Grid->field_labels as rw attr
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Collection / Grid.pm
1 package Reaction::UI::ViewPort::Collection::Grid;
2
3 use Reaction::Class;
4
5 use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection';
6 use aliased 'Reaction::UI::ViewPort::Collection::Grid::Member';
7
8 use namespace::clean -except => [ qw(meta) ];
9 extends 'Reaction::UI::ViewPort::Collection';
10
11
12
13 has field_order     => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1);
14 has excluded_fields => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1);
15 has _raw_field_labels => (
16   is       => 'rw', isa => 'HashRef',
17   init_arg => 'field_labels',
18 );
19 has field_labels => (
20   is         => 'ro', isa => 'HashRef',
21   lazy_build => 1, init_arg => undef,
22 );
23
24 has computed_field_order => (is => 'ro', isa => 'ArrayRef', lazy_build => 1);
25
26 ####################################
27 sub _build_member_class { Member };
28 sub _build_field_labels {
29   my $self = shift;
30   my %labels = %{$self->_raw_field_labels};
31   for my $field ( @{$self->computed_field_order}) {
32     next if $labels{$field};
33     $labels{$field} = join(' ', map{ ucfirst } split('_', $field));
34   }
35   return \%labels;
36 };
37 sub _build_field_order { []; };
38 sub _build_excluded_fields { []; };
39 sub _build_computed_field_order {
40   my ($self) = @_;
41   my %excluded = map { $_ => undef } @{ $self->excluded_fields };
42   #treat _$field_name as private and exclude fields with no reader
43   my @names = grep { $_ !~ /^_/ && !exists($excluded{$_})} map { $_->name }
44     grep {
45       !($_->has_type_constraint &&
46         ($_->type_constraint->is_a_type_of('ArrayRef') ||
47          eval {$_->type_constraint->name->isa('Reaction::InterfaceModel::Collection')} ||
48          eval { $_->_isa_metadata->isa('Reaction::InterfaceModel::Collection') }
49         )
50        )  }
51       grep { defined $_->get_read_method }
52         $self->current_collection->member_type->parameter_attributes;
53
54   return $self->sort_by_spec($self->field_order, \@names);
55 };
56
57 before _build_members => sub {
58   my ($self) = @_;
59   $self->member_args->{computed_field_order} ||= $self->computed_field_order;
60 };
61
62 __PACKAGE__->meta->make_immutable;
63
64
65 1;
66
67 __END__;
68
69 =head1 NAME
70
71 Reaction::UI::ViewPort::Collection
72
73 =head1 DESCRIPTION
74
75 This subclass of L<Reaction::UI::ViewPort::Collection> allows you to display a
76 homogenous collection of Reaction::InterfaceModel::Objects as a grid.
77
78 =head1 ATTRIBUTES
79
80 =head2 field_order
81
82 =head2 excluded_fields
83
84 =head2 field_labels
85
86 =head2 computed_field_order
87
88 =head1 INTERNAL METHODS
89
90 These methods, although stable, are subject to change without notice. These are meant
91 to be used only by developers. End users should refrain from using these methods to
92 avoid potential breakages.
93
94 =head1 SEE ALSO
95
96 L<Reaction::UI::ViewPort::Collection>
97
98 =head1 AUTHORS
99
100 See L<Reaction::Class> for authors.
101
102 =head1 LICENSE
103
104 See L<Reaction::Class> for the license.
105
106 =cut