From 6f0959163b0a5b274474d72f2b290711104f9fd3 Mon Sep 17 00:00:00 2001 From: Girija Soni Date: Fri, 24 Nov 2023 14:14:28 +0530 Subject: [PATCH] Fixes #36711 - Fix searching in settings --- app/models/setting.rb | 5 ++++ app/presenters/setting_presenter.rb | 2 +- app/services/setting_registry.rb | 43 +++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/models/setting.rb b/app/models/setting.rb index 84ba764e21b..b4c0451751b 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -56,6 +56,7 @@ def validate(record) scoped_search :on => :id, :complete_enabled => false, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER scoped_search on: :name, complete_value: :true, operators: ['=', '~'] + scoped_search on: :description, complete_value: :true, operators: ['~'] delegate :settings_type, :encrypted, :encrypted?, :default, to: :setting_definition, allow_nil: true @@ -68,6 +69,10 @@ def self.per_page 20 end + def self.complete_for(search_query, opts = {}) + SettingRegistry::SettingCompleter.auto_complete(Foreman.settings, scoped_search_definition, search_query, opts) + end + def self.[](name) Foreman.settings[name] end diff --git a/app/presenters/setting_presenter.rb b/app/presenters/setting_presenter.rb index 9e0a6586b31..d3e49d2eca1 100644 --- a/app/presenters/setting_presenter.rb +++ b/app/presenters/setting_presenter.rb @@ -86,7 +86,7 @@ def matches_search_query?(query) end if query =~ /name\s*=\s*(\S+)/ - name == tokenized.last + name == tokenized.last || full_name == tokenized.last elsif query =~ /name\s*~\s*(\S+)/ search_value = tokenized.last name.include?(search_value) || full_name&.include?(search_value) diff --git a/app/services/setting_registry.rb b/app/services/setting_registry.rb index a393e0d0a3a..00c81b7a081 100644 --- a/app/services/setting_registry.rb +++ b/app/services/setting_registry.rb @@ -1,6 +1,49 @@ class SettingRegistry include Singleton include Enumerable + extend ScopedSearch::ClassMethods + + class SettingCompleter < ScopedSearch::AutoCompleteBuilder + def initialize(registry, definition, query, options) + @registry = registry + super(definition, query, options) + end + + def self.auto_complete(registry, definition, query, options) + return [] if (query.nil? || definition.nil? || !definition.respond_to?(:fields)) + + new(registry, definition, query, options).build_autocomplete_options + end + + def is_query_valid + true + end + + def complete_value + if last_token_is(COMPARISON_OPERATORS) + token = tokens[tokens.size - 2] + val = '' + else + token = tokens[tokens.size - 3] + val = tokens[tokens.size - 1] + end + field = definition.field_by_name(token) + return [] unless field&.complete_value + complete_value_from_db(field, val) + end + + def complete_value_from_db(field, val) + count = 20 + if field.field == :name + results = @registry.filter_map { |set| ((set.full_name =~ /\s/) ? "\"#{set.full_name.gsub('"', '\"')}\"" : set.full_name) if set.name.include?(val) || set.full_name&.include?(val) } + results.first(count) + elsif field.field == :description + [] + else + raise ScopedSearch::QueryNotSupported, "Value '#{val}' is not valid for field '#{field.field}'" + end + end + end def self.subset_registry(subset) new(subset)