1 package SL::Controller::TopQuickSearch;
4 use parent qw(SL::Controller::Base);
8 use SL::Locale::String qw(t8);
9 use SL::Helper::UserPreferences;
11 use Rose::Object::MakeMethods::Generic (
12 'scalar --get_set_init' => [ qw(module js) ],
15 my @available_modules = (
16 'SL::Controller::TopQuickSearch::Article',
17 'SL::Controller::TopQuickSearch::Part',
18 'SL::Controller::TopQuickSearch::Service',
19 'SL::Controller::TopQuickSearch::Assembly',
20 'SL::Controller::TopQuickSearch::Assortment',
21 'SL::Controller::TopQuickSearch::Contact',
22 'SL::Controller::TopQuickSearch::SalesQuotation',
23 'SL::Controller::TopQuickSearch::SalesOrder',
24 'SL::Controller::TopQuickSearch::RequestForQuotation',
25 'SL::Controller::TopQuickSearch::PurchaseOrder',
26 'SL::Controller::TopQuickSearch::GLTransaction',
27 'SL::Controller::TopQuickSearch::Customer',
28 'SL::Controller::TopQuickSearch::Vendor',
32 sub action_query_autocomplete {
35 my $hashes = $self->module->query_autocomplete;
37 $self->render(\ SL::JSON::to_json($hashes), { layout => 0, type => 'json', process => 0 });
40 sub action_select_autocomplete {
43 my $redirect_url = $self->module->select_autocomplete;
45 $self->js->redirect_to($redirect_url)->render;
48 sub action_do_search {
51 my $redirect_url = $self->module->do_search;
54 $self->js->redirect_to($redirect_url)
60 sub available_modules {
63 $self->require_modules;
65 map { $_->new } @available_modules;
69 my $user_prefs = SL::Helper::UserPreferences->new(
70 namespace => 'TopQuickSearch',
75 my $prefs_val = $user_prefs->get('quick_search_modules');
76 my @quick_search_modules = split ',', $prefs_val;
78 %enabled_names = map {
80 } @quick_search_modules ;
82 %enabled_names = map {
84 } @{ $::instance_conf->get_quick_search_modules };
88 $enabled_names{$_->name}
89 } $_[0]->available_modules
94 $::auth->assert($_->auth, 1)
95 } $_[0]->enabled_modules
101 $self->require_modules;
103 die 'Need module' unless $::form->{module};
105 die 'Unknown module ' . $::form->{module} unless my $class = $modules_by_name{$::form->{module}};
107 $::auth->assert($class->auth);
113 SL::ClientJS->new(controller => $_[0])
116 sub require_modules {
119 if (!$self->{__modules_required}) {
120 for my $class (@available_modules) {
121 eval "require $class" or die $@;
122 $modules_by_name{ $class->name } = $class;
124 $self->{__modules_required} = 1;
136 SL::Controller::TopQuickSearch - Framework for pluggable quicksearch fields in the layout top header.
140 use SL::Controller::TopQuickSearch;
141 my $search = SL::Controller::TopQuickSearch->new;
142 $::request->layout->add_javascripts('kivi.QuickSearch.js');
145 [%- FOREACH module = search.enabled_modules %]
146 <input type='text' id='top-search-[% module.name %]'>
151 This controller provides abstraction for different search plugins, and ensures
152 that all follow a common useability scheme.
154 Modules should be configurable per user, but currently are not. Disabling
155 modules can be done by removing them from available_modules or in client_config.
157 =head1 BEHAVIOUR REQUIREMENTS
163 A single text input field with the html5 placeholder containing a small
164 description of the target will be rendered from the plugin information.
168 On typing, the autocompletion must be enabled.
172 On C<Enter>, the search should redirect to an appropriate listing of matching
175 If only one item matches the result, the plugin should instead redirect
176 directly to the matched item.
180 Search terms should accept the broadest possible matching, and if possible with
185 In case nothing is found, a visual indicator should be given, but no actual
186 redirect should occur.
190 Each search must check rights and must not present a backdoor into data that
191 the user should not see.
195 By design the search must not try to guess C<exact matches>.
201 The full interface is described in L<SL::Controller::TopQuickSeach::Base>
213 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>