Commit | Line | Data |
e653a487 |
1 | package Reaction::UI::ViewPort::SearchableListViewContainer; |
2 | use Reaction::Class; |
3 | |
4 | #use aliased 'Reaction::InterfaceModel::Search::Spec', 'SearchSpec'; |
5 | use aliased 'Reaction::InterfaceModel::Action::Search::UpdateSpec', 'UpdateSearchSpec'; |
6 | use aliased 'Reaction::UI::ViewPort::ListViewWithSearch'; |
7 | use aliased 'Reaction::UI::ViewPort::Action' => 'ActionVP'; |
eb09f78b |
8 | use aliased 'Reaction::UI::ViewPort'; |
e653a487 |
9 | use aliased 'Reaction::UI::ViewPort::Collection::Role::Pager', 'PagerRole'; |
10 | |
11 | use Method::Signatures::Simple; |
12 | |
13 | use namespace::clean -except => 'meta'; |
14 | |
15 | extends 'Reaction::UI::ViewPort'; |
16 | |
17 | has 'listview' => ( |
eb09f78b |
18 | isa => ViewPort, |
e653a487 |
19 | is => 'ro', |
20 | required => 1, |
21 | ); |
22 | |
eb09f78b |
23 | has 'search_form' => (isa => ViewPort, is => 'ro', required => 1); |
e653a487 |
24 | |
25 | override BUILDARGS => sub { |
26 | my $args = super; |
27 | my $spec_event_id = $args->{location}.':search-spec'; |
28 | my $spec_class = $args->{spec_class} |
29 | or confess "Argument spec_class is required"; |
eb09f78b |
30 | my $listview_class = $args->{'listview_class'} || ListViewWithSearch; |
31 | my $search_form_class = $args->{'search_form_class'} || ActionVP; |
e653a487 |
32 | my $action_class = $args->{action_class} |
33 | or confess "Argument action_class is required"; |
34 | # TODO: how do we autodiscover spec classes? |
35 | # $spec_class =~ s/^::/${\SearchSpec}::/; |
36 | Class::MOP::load_class($spec_class); |
37 | my $spec = do { |
38 | if (my $string = $args->{ctx}->req->query_params->{$spec_event_id}) { |
39 | $spec_class->from_string($string, $args->{spec}||{}); |
40 | } else { |
41 | $spec_class->new($args->{spec}||{}); |
42 | } |
43 | }; |
44 | my $listview_location = $args->{location}.'-listview'; |
eb09f78b |
45 | my $listview = $args->{listview} = $listview_class->new( |
e653a487 |
46 | %$args, |
eb09f78b |
47 | layout => $args->{'listview_layout'} || 'list_view', |
e653a487 |
48 | search_spec => $spec, |
49 | location => $listview_location, |
50 | ); |
eb09f78b |
51 | $args->{search_form} = $search_form_class->new( |
3cb77ac0 |
52 | model => $action_class->new( |
53 | target_model => $spec, |
54 | %{$args->{search_model}||{}} |
55 | ), |
e653a487 |
56 | location => $args->{location}.'-search_form', |
57 | apply_label => 'search', |
58 | ctx => $args->{ctx}, |
59 | on_apply_callback => sub { |
60 | my ($vp, $spec) = @_; |
61 | my $req = $vp->ctx->req; |
62 | my $new_uri = $req->uri->clone; |
63 | my %query = %{$req->query_parameters}; |
64 | delete @query{grep /^\Q${listview_location}\E/, keys %query}; |
65 | $query{$spec_event_id} = $spec->to_string; |
66 | $new_uri->query_form(\%query); |
67 | $req->uri($new_uri); |
68 | $listview->clear_page; |
69 | $listview->clear_order_by; |
70 | }, |
71 | %{$args->{search}||{}} |
72 | ); |
73 | $args; |
74 | }; |
75 | |
76 | override child_event_sinks => method () { |
77 | ((map $self->$_, 'listview', 'search_form'), super); |
78 | }; |
79 | |
80 | 1; |
81 | |