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',
74 if (my $prefs_val = $user_prefs->get('quick_search_modules')) {
75 my @quick_search_modules = split ',', $prefs_val;
77 %enabled_names = map {
79 } @quick_search_modules ;
81 %enabled_names = map {
83 } @{ $::instance_conf->get_quick_search_modules };
87 $enabled_names{$_->name}
88 } $_[0]->available_modules
93 $::auth->assert($_->auth, 1)
94 } $_[0]->enabled_modules
100 $self->require_modules;
102 die 'Need module' unless $::form->{module};
104 die 'Unknown module ' . $::form->{module} unless my $class = $modules_by_name{$::form->{module}};
106 $::auth->assert($class->auth);
112 SL::ClientJS->new(controller => $_[0])
115 sub require_modules {
118 if (!$self->{__modules_required}) {
119 for my $class (@available_modules) {
120 eval "require $class" or die $@;
121 $modules_by_name{ $class->name } = $class;
123 $self->{__modules_required} = 1;
135 SL::Controller::TopQuickSearch - Framework for pluggable quicksearch fields in the layout top header.
139 use SL::Controller::TopQuickSearch;
140 my $search = SL::Controller::TopQuickSearch->new;
141 $::request->layout->add_javascripts('kivi.QuickSearch.js');
144 [%- FOREACH module = search.enabled_modules %]
145 <input type='text' id='top-search-[% module.name %]'>
150 This controller provides abstraction for different search plugins, and ensures
151 that all follow a common useability scheme.
153 Modules should be configurable per user, but currently are not. Disabling
154 modules can be done by removing them from available_modules or in client_config.
156 =head1 BEHAVIOUR REQUIREMENTS
162 A single text input field with the html5 placeholder containing a small
163 description of the target will be rendered from the plugin information.
167 On typing, the autocompletion must be enabled.
171 On C<Enter>, the search should redirect to an appropriate listing of matching
174 If only one item matches the result, the plugin should instead redirect
175 directly to the matched item.
179 Search terms should accept the broadest possible matching, and if possible with
184 In case nothing is found, a visual indicator should be given, but no actual
185 redirect should occur.
189 Each search must check rights and must not present a backdoor into data that
190 the user should not see.
194 By design the search must not try to guess C<exact matches>.
200 The full interface is described in L<SL::Controller::TopQuickSeach::Base>
212 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>