TopQuickSearch: Alle Part Varianten for free
[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 = qw(
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 t8('Need module') unless $::form->{module};
72
73   $::lxdebug->dump(0,  "modules", \%modules_by_name);
74
75   die t8('Unknown module #1', $::form->{module}) unless my $class = $modules_by_name{$::form->{module}};
76
77   $::lxdebug->dump(0,  "auth:", $class->auth);
78
79   $::auth->assert($class->auth);
80
81   return $class->new;
82 }
83
84 sub init_js {
85   SL::ClientJS->new(controller => $_[0])
86 }
87
88 sub require_modules {
89   my ($self) = @_;
90
91   if (!$self->{__modules_required}) {
92     for my $class (@available_modules) {
93       eval "require $class" or die $@;
94       $modules_by_name{ $class->name } = $class;
95     }
96     $self->{__modules_required} = 1;
97   }
98 }
99
100 1;
101
102 __END__
103
104 =encoding utf-8
105
106 =head1 NAME
107
108 SL::Controller::TopQuickSearch - Framework for pluggable quicksearch fields in the layout top header.
109
110 =head1 SYNOPSIS
111
112 use SL::Controller::TopQuickSearch;
113 my $search = SL::Controller::TopQuickSearch->new;
114
115 # in layout
116 [%- FOREACH module = search.available_modules %]
117 <input type='text' id='top-search-[% module.name %]'>
118 [%- END %]
119
120 =head1 DESCRIPTION
121
122 This controller provides abstraction for different search plugins, and ensures
123 that all follow a common useability scheme.
124
125 Modules should be configurable, but currently are not. Diabling modules can be
126 done by removing them from available_modules.
127
128 =head1 BEHAVIOUR REQUIREMENTS
129
130 =over 4
131
132 =item *
133
134 A single text input field with the html5 placeholder containing a small
135 description of the target will be rendered from the plugin information.
136
137 =item *
138
139 On typing, the autocompletion must be enabled.
140
141 =item *
142
143 On C<Enter>, the search should redirect to an appropriate listing of matching
144 results.
145
146 If only one item matches the result, the plugin should instead redirect
147 directly to the matched item.
148
149 =item *
150
151 Search terms should accept the broadest possible matching, and if possible with
152 C<multi> parsing.
153
154 =item *
155
156 In case nothing is found, a visual indicator should be given, but no actual
157 redirect should occur.
158
159 =item *
160
161 Each search must check rights and must not present a backdoor into data that
162 the user should not see.
163
164 =back
165
166 =head1 INTERFACE
167
168 Plugins need to provide:
169
170  - name
171  - localized description for config
172  - localized description for textfield
173  - autocomplete callback
174  - redirect callback
175
176 the frontend will only generate urls of the forms:
177   action=TopQuickSearch/autocomplete&module=<module>&term=<term>
178   action=TopQuickSearch/search&module=<module>&term=<term>
179
180 =head1 TODO
181
182  - filter available searches with auth
183  - toggling with cofiguration doesn't work yet
184
185 =head1 BUGS
186
187 None yet :)
188
189 =head1 AUTHOR
190
191 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
192
193 =cut