Skip to content

Commit

Permalink
Fixes #36711 - Add search by description in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
girijaasoni committed Aug 31, 2023
1 parent e30c9d5 commit 02d2040
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
1 change: 0 additions & 1 deletion app/controllers/api/v2/settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class SettingsController < V2::BaseController

api :GET, "/settings/", N_("List all settings")
param_group :search_and_pagination, ::Api::V2::BaseController
add_scoped_search_description_for(Setting)
returns desc: N_('List of all settings') do
property :results, Array
end
Expand Down
8 changes: 5 additions & 3 deletions app/models/setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ def validate(record)

scope :order_by, ->(attr) { except(:order).order(attr) }

scoped_search :on => :id, :complete_enabled => false, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
scoped_search on: :name, complete_value: :true, operators: ['=', '~']


delegate :settings_type, :encrypted, :encrypted?, :default, to: :setting_definition, allow_nil: true

def self.config_file
Expand All @@ -68,6 +66,10 @@ def self.per_page
20
end

def self.complete_for(search_query, opts = {})
Foreman.settings.complete_for(search_query, opts)
end

def self.[](name)
Foreman.settings[name]
end
Expand Down
62 changes: 62 additions & 0 deletions app/services/setting_registry.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,68 @@
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
return if (last_token_is(NULL_PREFIX_OPERATORS, 2) && !(query =~ /(\s|\)|,)$/))
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
return complete_set(field) if field.set?
return complete_key_value(field, token, val) if field.key_field

special_values = field.special_values.select { |v| v =~ /\A#{val}/ }
special_values + complete_value_from_db(field, special_values, val)
end

def complete_key(name, field, val)
raise ::Foreman::Exception.new N_('Unsupported completion, only name and description are supported')
end

def complete_value_from_db(field, special_values, val)
count = 20 - special_values.count
if field.field == :name
results = @registry.map { |set| set.full_name if set.name.starts_with?(val) || set.full_name&.starts_with?(val) }
elsif field.field == :description
results = @registry.map { |set| set.description if set.description.starts_with?(val) }
else
raise ::Foreman::Exception.new N_('Unsupported completion, only name and description are supported')
end

results.first(count)
end
end

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: ['~']

def complete_for(query, opts = {})
SettingCompleter.auto_complete(self, scoped_search_definition, query, opts)
end

def self.subset_registry(subset)
new(subset)
Expand Down

0 comments on commit 02d2040

Please sign in to comment.