diff --git a/app/assets/javascripts/pages/agent-edit-page.js b/app/assets/javascripts/pages/agent-edit-page.js index 56edc7f164..77b9a101cd 100644 --- a/app/assets/javascripts/pages/agent-edit-page.js +++ b/app/assets/javascripts/pages/agent-edit-page.js @@ -16,9 +16,9 @@ // Validate agents_options Json on form submit $("form.agent-form").submit(function (e) { - if ($("textarea#agent_options").length) { + for (const textarea of $("textarea.live-json-editor").toArray()) { try { - JSON.parse($("#agent_options").val()); + JSON.parse($(textarea).val()); } catch (err) { e.preventDefault(); alert( diff --git a/app/concerns/form_configurable.rb b/app/concerns/form_configurable.rb index 259c3d9b0f..b84fada2d0 100644 --- a/app/concerns/form_configurable.rb +++ b/app/concerns/form_configurable.rb @@ -3,7 +3,7 @@ module FormConfigurable included do class_attribute :_form_configurable_fields - self._form_configurable_fields = HashWithIndifferentAccess.new { |h,k| h[k] = [] } + self._form_configurable_fields = HashWithIndifferentAccess.new { |h, k| h[k] = [] } end delegate :form_configurable_attributes, to: :class @@ -31,8 +31,8 @@ module ClassMethods def form_configurable(name, *args) options = args.extract_options!.reverse_merge(roles: [], type: :string) - if args.all? { |arg| arg.is_a?(Symbol) } - options.assert_valid_keys([:type, :roles, :values, :ace, :cache_response]) + if args.all?(Symbol) + options.assert_valid_keys([:type, :roles, :values, :ace, :cache_response, :html_options]) end if options[:type] == :array && (options[:values].blank? || !options[:values].is_a?(Array)) @@ -43,13 +43,30 @@ def form_configurable(name, *args) options[:roles] = [options[:roles]] end - if options[:type] == :array + case options[:type] + when :array options[:roles] << :completable - class_eval <<-EOF + class_eval <<-EOF, __FILE__, __LINE__ + 1 def complete_#{name} #{options[:values]}.map { |v| {text: v, id: v} } end EOF + when :json + class_eval <<-EOF, __FILE__, __LINE__ + 1 + before_validation :decode_#{name}_json + + private def decode_#{name}_json + case value = options[:#{name}] + when String + options[:#{name}] = + begin + JSON.parse(value) + rescue StandardError + value + end + end + end + EOF end _form_configurable_fields[name] = options diff --git a/app/models/agents/delay_agent.rb b/app/models/agents/delay_agent.rb index ffd9543dae..e1c2de6445 100644 --- a/app/models/agents/delay_agent.rb +++ b/app/models/agents/delay_agent.rb @@ -15,6 +15,10 @@ class DelayAgent < Agent that you anticipate passing without this Agent receiving an incoming Event. `max_emitted_events` is used to limit the number of the maximum events which should be created. If you omit this DelayAgent will create events for every event stored in the memory. + + # Ordering Events + + #{description_events_order("events in which buffered events are emitted")} MD def default_options @@ -22,14 +26,16 @@ def default_options 'expected_receive_period_in_days' => '10', 'max_events' => '100', 'keep' => 'newest', - 'max_emitted_events' => '' + 'max_emitted_events' => '', + 'events_order' => [], } end - form_configurable :expected_receive_period_in_days, type: :string - form_configurable :max_events, type: :string + form_configurable :expected_receive_period_in_days, type: :number, html_options: { min: 1 } + form_configurable :max_events, type: :number, html_options: { min: 1 } form_configurable :keep, type: :array, values: %w[newest oldest] - form_configurable :max_emitted_events, type: :string + form_configurable :max_emitted_events, type: :number, html_options: { min: 0 } + form_configurable :events_order, type: :json def validate_options unless options['expected_receive_period_in_days'].present? && options['expected_receive_period_in_days'].to_i > 0 @@ -71,11 +77,16 @@ def receive(incoming_events) end def check - if memory['event_ids'] && memory['event_ids'].length > 0 + if memory['event_ids'].present? events = received_events.where(id: memory['event_ids']).reorder('events.id asc') - if interpolated['max_emitted_events'].present? - events = events.limit(interpolated['max_emitted_events'].to_i) + limit = interpolated['max_emitted_events'].to_i + events = + if options[SortableEvents::EVENTS_ORDER_KEY].present? + sort_events(events).first(limit) + else + events.limit(limit) + end end events.each do |event| diff --git a/app/presenters/form_configurable_agent_presenter.rb b/app/presenters/form_configurable_agent_presenter.rb index 6d40d63fe1..d48127b1f7 100644 --- a/app/presenters/form_configurable_agent_presenter.rb +++ b/app/presenters/form_configurable_agent_presenter.rb @@ -16,7 +16,10 @@ def initialize(agent, view) def option_field_for(attribute) data = @agent.form_configurable_fields[attribute] value = @agent.options[attribute.to_s] || @agent.default_options[attribute.to_s] - html_options = { role: (data[:roles] + ['form-configurable']).join(' '), data: { attribute: } } + html_options = data.fetch(:html_options, {}).deep_merge({ + role: (data[:roles] + ['form-configurable']).join(' '), + data: { attribute: }, + }) case data[:type] when :text @@ -56,6 +59,12 @@ def option_field_for(attribute) when :string @view.text_field_tag "agent[options][#{attribute}]", value, html_options.deep_merge(class: 'form-control', data: { cache_response: data[:cache_response] != false }) + when :number + @view.number_field_tag "agent[options][#{attribute}]", value, + html_options.deep_merge(class: 'form-control', data: { cache_response: data[:cache_response] != false }) + when :json + @view.text_area_tag "agent[options][#{attribute}]", value, + html_options.deep_merge(class: 'form-control live-json-editor', rows: 10) end end end diff --git a/spec/presenters/form_configurable_agent_presenter_spec.rb b/spec/presenters/form_configurable_agent_presenter_spec.rb index 64ece21ed3..837d6f2279 100644 --- a/spec/presenters/form_configurable_agent_presenter_spec.rb +++ b/spec/presenters/form_configurable_agent_presenter_spec.rb @@ -6,9 +6,11 @@ class FormConfigurableAgentPresenterAgent < Agent include FormConfigurable form_configurable :string, roles: :validatable + form_configurable :number, type: :number, html_options: { min: 0 } form_configurable :text, type: :text, roles: :completable form_configurable :boolean, type: :boolean form_configurable :array, type: :array, values: [1, 2, 3] + form_configurable :json, type: :json end before(:all) do @@ -30,6 +32,21 @@ class FormConfigurableAgentPresenterAgent < Agent ) end + it "works for the type :number" do + expect(@presenter.option_field_for(:number)).to( + have_tag( + 'input', + with: { + 'data-attribute': 'number', + role: 'form-configurable', + type: 'number', + name: 'agent[options][number]', + min: '0', + } + ) + ) + end + it "works for the type :text" do expect(@presenter.option_field_for(:text)).to( have_tag( @@ -69,4 +86,18 @@ class FormConfigurableAgentPresenterAgent < Agent ) ) end + + it "works for the type :json" do + expect(@presenter.option_field_for(:json)).to( + have_tag( + 'textarea', + with: { + 'data-attribute': 'json', + role: 'form-configurable', + name: 'agent[options][json]', + class: 'live-json-editor', + } + ) + ) + end end