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