TopQuickSearch: qw() -> liste, zum einfachen auskommentieren
[kivitendo-erp.git] / SL / Controller / TopQuickSearch.pm
1 package SL::Controller::TopQuickSearch;
2
3 use strict;
4 use parent qw(SL::Controller::Base);
5
6 use SL::ClientJS;
7 use SL::JSON;
8 use SL::Locale::String qw(t8);
9
10 use Rose::Object::MakeMethods::Generic (
11  'scalar --get_set_init' => [ qw(module js) ],
12 );
13
14 my @available_modules = (
15   'SL::Controller::TopQuickSearch::Article',
16   'SL::Controller::TopQuickSearch::Part',
17   'SL::Controller::TopQuickSearch::Service',
18   'SL::Controller::TopQuickSearch::Assembly',
19   'SL::Controller::TopQuickSearch::Contact',
20   'SL::Controller::TopQuickSearch::GLTransaction',
21 );
22 my %modules_by_name;
23
24 sub action_query_autocomplete {
25   my ($self) = @_;
26
27   my $hashes = $self->module->query_autocomplete;
28
29   $self->render(\ SL::JSON::to_json($hashes), { layout => 0, type => 'json', process => 0 });
30 }
31
32 sub action_select_autocomplete {
33   my ($self) = @_;
34
35   my $redirect_url = $self->module->select_autocomplete;
36
37   $self->js->redirect_to($redirect_url)->render;
38 }
39
40 sub action_do_search {
41   my ($self) = @_;
42
43   my $redirect_url = $self->module->do_search;
44
45   if ($redirect_url) {
46     $self->js->redirect_to($redirect_url)
47   }
48
49   $self->js->render;
50 }
51
52 sub available_modules {
53   my ($self) = @_;
54
55   $self->require_modules;
56
57   map { $_->new } @available_modules;
58 }
59
60 sub active_modules {
61   grep {
62     $::auth->assert($_->auth, 1)
63   } $_[0]->available_modules
64 }
65
66 sub init_module {
67   my ($self) = @_;
68
69   $self->require_modules;
70
71   die 'Need module' unless $::form->{module};
72
73   die 'Unknown module ' . $::form->{module} unless my $class = $modules_by_name{$::form->{module}};
74
75   $::auth->assert($class->auth);
76
77   return $class->new;
78 }
79
80 sub init_js {
81   SL::ClientJS->new(controller => $_[0])
82 }
83
84 sub require_modules {
85   my ($self) = @_;
86
87   if (!$self->{__modules_required}) {
88     for my $class (@available_modules) {
89       eval "require $class" or die $@;
90       $modules_by_name{ $class->name } = $class;
91     }
92     $self->{__modules_required} = 1;
93   }
94 }
95
96 1;
97
98 __END__
99
100 =encoding utf-8
101
102 =head1 NAME
103
104 SL::Controller::TopQuickSearch - Framework for pluggable quicksearch fields in the layout top header.
105
106 =head1 SYNOPSIS
107
108 use SL::Controller::TopQuickSearch;
109 my $search = SL::Controller::TopQuickSearch->new;
110
111 # in layout
112 [%- FOREACH module = search.available_modules %]
113 <input type='text' id='top-search-[% module.name %]'>
114 [%- END %]
115
116 =head1 DESCRIPTION
117
118 This controller provides abstraction for different search plugins, and ensures
119 that all follow a common useability scheme.
120
121 Modules should be configurable, but currently are not. Diabling modules can be
122 done by removing them from available_modules.
123
124 =head1 BEHAVIOUR REQUIREMENTS
125
126 =over 4
127
128 =item *
129
130 A single text input field with the html5 placeholder containing a small
131 description of the target will be rendered from the plugin information.
132
133 =item *
134
135 On typing, the autocompletion must be enabled.
136
137 =item *
138
139 On C<Enter>, the search should redirect to an appropriate listing of matching
140 results.
141
142 If only one item matches the result, the plugin should instead redirect
143 directly to the matched item.
144
145 =item *
146
147 Search terms should accept the broadest possible matching, and if possible with
148 C<multi> parsing.
149
150 =item *
151
152 In case nothing is found, a visual indicator should be given, but no actual
153 redirect should occur.
154
155 =item *
156
157 Each search must check rights and must not present a backdoor into data that
158 the user should not see.
159
160 =back
161
162 =head1 INTERFACE
163
164 Plugins need to provide:
165
166  - name
167  - localized description for config
168  - localized description for textfield
169  - autocomplete callback
170  - redirect callback
171
172 the frontend will only generate urls of the forms:
173   action=TopQuickSearch/autocomplete&module=<module>&term=<term>
174   action=TopQuickSearch/search&module=<module>&term=<term>
175
176 =head1 TODO
177
178  - filter available searches with auth
179  - toggling with cofiguration doesn't work yet
180
181 =head1 BUGS
182
183 None yet :)
184
185 =head1 AUTHOR
186
187 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
188
189 =cut