Commit | Line | Data |
e22de101 |
1 | package Reaction::UI::ViewPort::GridView; |
2 | |
3 | use Reaction::Class; |
4 | |
e716714f |
5 | use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection'; |
b8faba69 |
6 | use aliased 'Reaction::UI::ViewPort::GridView::Entity'; |
e22de101 |
7 | |
8 | class GridView is 'Reaction::UI::ViewPort', which { |
9 | |
b8faba69 |
10 | has exclude_fields => ( isa => 'ArrayRef', is => 'ro' ); |
11 | has field_order => ( isa => 'ArrayRef', is => 'ro', lazy_build => 1); |
12 | has field_labels => ( isa => 'HashRef', is => 'ro', lazy_build => 1); |
13 | |
14 | |
15 | has entities => ( isa => 'ArrayRef', is => 'rw', lazy_build => 1); |
e22de101 |
16 | |
e716714f |
17 | has collection => (isa => IM_Collection, is => 'ro', required => 1); |
18 | has current_collection => (isa => IM_Collection, is => 'rw', lazy_build => 1); |
e22de101 |
19 | |
b8faba69 |
20 | has entity_class => ( isa => 'Str', is => 'rw', lazy_build => 1); |
21 | has entity_args => ( is => 'rw' ); |
22 | |
23 | implements BUILD => as { |
24 | my ($self, $args) = @_; |
25 | my $entity_args = delete $args->{Entity}; |
26 | $self->entity_args( $entity_args ) if ref $entity_args; |
27 | }; |
28 | |
29 | after clear_current_collection => sub{ |
30 | shift->clear_entities; #clear the entitiesis the current collection changes, duh |
31 | }; |
e22de101 |
32 | |
89939ff9 |
33 | implements _build_entity_class => as { Entity }; |
b8faba69 |
34 | |
89939ff9 |
35 | implements _build_field_order => as { |
e22de101 |
36 | my ($self) = @_; |
37 | my %excluded = map { $_ => undef } |
b8faba69 |
38 | @{ $self->has_exclude_fields ? $self->exclude_fields : [] }; |
e22de101 |
39 | #XXX this abuse of '_im_class' needs to be fixed ASAP |
40 | my $object_class = $self->collection->_im_class; |
e716714f |
41 | my @fields = $object_class->meta->parameter_attributes; |
42 | #obviously only get fields with readers. |
43 | @fields = grep { $_->get_read_method } @fields; |
e22de101 |
44 | #eliminate excluded fields & treat names that start with an underscore as private |
45 | @fields = grep {$_->name !~ /^_/ && !exists $excluded{$_->name} } @fields; |
e716714f |
46 | |
e22de101 |
47 | #eliminate fields marked as collections, or fields that are arrayrefs |
48 | @fields = grep { |
49 | !($_->has_type_constraint && |
50 | ($_->type_constraint->is_a_type_of('ArrayRef') || |
51 | eval {$_->type_constraint->name->isa('Reaction::InterfaceModel::Collection')} || |
52 | eval { $_->_isa_metadata->isa('Reaction::InterfaceModel::Collection') } |
53 | ) |
54 | ) } @fields; |
55 | |
56 | #order the columns all nice and pretty, and only get fields with readers, duh |
e716714f |
57 | my $ordered = $self->sort_by_spec |
58 | ( $self->column_order, [ map { (($_->name) || ()) } @fields] ); |
59 | |
60 | return $ordered; |
e22de101 |
61 | }; |
62 | |
89939ff9 |
63 | implements _build_current_collection => as { |
e22de101 |
64 | shift->collection; |
65 | }; |
66 | |
89939ff9 |
67 | implements _build_field_labels => as { |
e716714f |
68 | my $self = shift; |
b8faba69 |
69 | my %labels; |
70 | for my $field ( @{$self->field_order}){ |
71 | $labels{$field} = join(' ', map{ ucfirst } split('_', $field)); |
e716714f |
72 | } |
b8faba69 |
73 | return \%labels; |
e716714f |
74 | }; |
75 | |
89939ff9 |
76 | implements _build_entities => as { |
b8faba69 |
77 | my ($self) = @_; |
78 | my (@entities, $i); |
79 | my $args = $self->has_entity_args ? $self->entity_args : {}; |
80 | my $builders = {}; |
81 | my $ctx = $self->ctx; |
82 | my $loc = $self->location; |
83 | my $order = $self->field_order; |
84 | my $class = $self->entity_class; |
85 | for my $obj ( $self->current_collection->members ) { |
86 | my $row = $class->new( |
87 | ctx => $ctx, |
88 | object => $obj, |
89 | location => join('-', $loc, 'row', $i++), |
90 | field_order => $order, |
91 | builder_cache => $builders, |
92 | ref $args ? %$args : () |
93 | ); |
94 | push(@entities, $row); |
e716714f |
95 | } |
b8faba69 |
96 | return \@entities; |
e716714f |
97 | }; |
98 | |
e22de101 |
99 | }; |
100 | |
101 | |
102 | |
103 | 1; |