active_fields 1.1.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -4
  3. data/CHANGELOG.md +32 -2
  4. data/README.md +411 -38
  5. data/app/models/active_fields/field/boolean.rb +3 -0
  6. data/app/models/active_fields/field/date.rb +3 -0
  7. data/app/models/active_fields/field/date_array.rb +3 -0
  8. data/app/models/active_fields/field/date_time.rb +4 -1
  9. data/app/models/active_fields/field/date_time_array.rb +4 -1
  10. data/app/models/active_fields/field/decimal.rb +6 -1
  11. data/app/models/active_fields/field/decimal_array.rb +6 -1
  12. data/app/models/active_fields/field/enum.rb +3 -0
  13. data/app/models/active_fields/field/enum_array.rb +3 -0
  14. data/app/models/active_fields/field/integer.rb +3 -0
  15. data/app/models/active_fields/field/integer_array.rb +3 -0
  16. data/app/models/active_fields/field/text.rb +3 -0
  17. data/app/models/active_fields/field/text_array.rb +3 -0
  18. data/app/models/active_fields/field.rb +5 -0
  19. data/app/models/concerns/active_fields/customizable_concern.rb +89 -5
  20. data/app/models/concerns/active_fields/field_concern.rb +26 -5
  21. data/app/models/concerns/active_fields/value_concern.rb +0 -2
  22. data/db/migrate/20240229230000_create_active_fields_tables.rb +1 -1
  23. data/lib/active_fields/casters/date_time_caster.rb +1 -3
  24. data/lib/active_fields/casters/decimal_caster.rb +2 -5
  25. data/lib/active_fields/constants.rb +55 -0
  26. data/lib/active_fields/engine.rb +2 -1
  27. data/lib/active_fields/finders/array_finder.rb +112 -0
  28. data/lib/active_fields/finders/base_finder.rb +73 -0
  29. data/lib/active_fields/finders/boolean_finder.rb +20 -0
  30. data/lib/active_fields/finders/date_array_finder.rb +65 -0
  31. data/lib/active_fields/finders/date_finder.rb +32 -0
  32. data/lib/active_fields/finders/date_time_array_finder.rb +65 -0
  33. data/lib/active_fields/finders/date_time_finder.rb +32 -0
  34. data/lib/active_fields/finders/decimal_array_finder.rb +65 -0
  35. data/lib/active_fields/finders/decimal_finder.rb +32 -0
  36. data/lib/active_fields/finders/enum_array_finder.rb +41 -0
  37. data/lib/active_fields/finders/enum_finder.rb +20 -0
  38. data/lib/active_fields/finders/integer_array_finder.rb +65 -0
  39. data/lib/active_fields/finders/integer_finder.rb +32 -0
  40. data/lib/active_fields/finders/singular_finder.rb +66 -0
  41. data/lib/active_fields/finders/text_array_finder.rb +47 -0
  42. data/lib/active_fields/finders/text_finder.rb +81 -0
  43. data/lib/active_fields/has_active_fields.rb +3 -4
  44. data/lib/active_fields/registry.rb +38 -0
  45. data/lib/active_fields/version.rb +1 -1
  46. data/lib/active_fields.rb +29 -1
  47. data/lib/generators/active_fields/scaffold/scaffold_generator.rb +9 -0
  48. data/lib/generators/active_fields/scaffold/templates/controllers/active_fields_controller.rb +0 -10
  49. data/lib/generators/active_fields/scaffold/templates/controllers/concerns/active_fields_controller_concern.rb +33 -0
  50. data/lib/generators/active_fields/scaffold/templates/helpers/active_fields_helper.rb +67 -0
  51. data/lib/generators/active_fields/scaffold/templates/javascript/controllers/active_fields_finders_form_controller.js +59 -0
  52. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/_form.html.erb +42 -0
  53. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_array_size.html.erb +16 -0
  54. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_boolean.html.erb +21 -0
  55. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_date.html.erb +16 -0
  56. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_date_array.html.erb +16 -0
  57. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_datetime.html.erb +16 -0
  58. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_datetime_array.html.erb +16 -0
  59. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_decimal.html.erb +16 -0
  60. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_decimal_array.html.erb +16 -0
  61. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_enum.html.erb +16 -0
  62. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_enum_array.html.erb +16 -0
  63. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_integer.html.erb +16 -0
  64. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_integer_array.html.erb +16 -0
  65. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_text.html.erb +16 -0
  66. data/lib/generators/active_fields/scaffold/templates/views/active_fields/finders/inputs/_text_array.html.erb +16 -0
  67. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_boolean.html.erb +1 -1
  68. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_date.html.erb +1 -1
  69. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_date_array.html.erb +1 -1
  70. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_datetime.html.erb +2 -2
  71. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_datetime_array.html.erb +2 -2
  72. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_decimal.html.erb +2 -2
  73. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_decimal_array.html.erb +2 -2
  74. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_enum.html.erb +1 -1
  75. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_enum_array.html.erb +1 -1
  76. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_integer.html.erb +1 -1
  77. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_integer_array.html.erb +1 -1
  78. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_text.html.erb +1 -1
  79. data/lib/generators/active_fields/scaffold/templates/views/active_fields/forms/_text_array.html.erb +1 -1
  80. data/lib/generators/active_fields/scaffold/templates/views/shared/_array_field.html.erb +1 -1
  81. metadata +42 -10
  82. data/lib/active_fields/customizable_config.rb +0 -24
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveFields
4
+ module Finders
5
+ class TextFinder < SingularFinder
6
+ operation :eq, operator: OPS[:eq] do |value|
7
+ scope.where(eq(casted_value_field("text"), cast(value)))
8
+ end
9
+ operation :not_eq, operator: OPS[:not_eq] do |value|
10
+ scope.where(not_eq(casted_value_field("text"), cast(value)))
11
+ end
12
+ operation :start_with, operator: OPS[:start_with] do |value|
13
+ scope.where(like(casted_value_field("text"), "#{escape_pattern(cast(value))}%"))
14
+ end
15
+ operation :end_with, operator: OPS[:end_with] do |value|
16
+ scope.where(like(casted_value_field("text"), "%#{escape_pattern(cast(value))}"))
17
+ end
18
+ operation :contain, operator: OPS[:contain] do |value|
19
+ scope.where(like(casted_value_field("text"), "%#{escape_pattern(cast(value))}%"))
20
+ end
21
+ operation :not_start_with, operator: OPS[:not_start_with] do |value|
22
+ scope.where(not_like(casted_value_field("text"), "#{escape_pattern(cast(value))}%"))
23
+ end
24
+ operation :not_end_with, operator: OPS[:not_end_with] do |value|
25
+ scope.where(not_like(casted_value_field("text"), "%#{escape_pattern(cast(value))}"))
26
+ end
27
+ operation :not_contain, operator: OPS[:not_contain] do |value|
28
+ scope.where(not_like(casted_value_field("text"), "%#{escape_pattern(cast(value))}%"))
29
+ end
30
+ operation :istart_with, operator: OPS[:istart_with] do |value|
31
+ scope.where(ilike(casted_value_field("text"), "#{escape_pattern(cast(value))}%"))
32
+ end
33
+ operation :iend_with, operator: OPS[:iend_with] do |value|
34
+ scope.where(ilike(casted_value_field("text"), "%#{escape_pattern(cast(value))}"))
35
+ end
36
+ operation :icontain, operator: OPS[:icontain] do |value|
37
+ scope.where(ilike(casted_value_field("text"), "%#{escape_pattern(cast(value))}%"))
38
+ end
39
+ operation :not_istart_with, operator: OPS[:not_istart_with] do |value|
40
+ scope.where(not_ilike(casted_value_field("text"), "#{escape_pattern(cast(value))}%"))
41
+ end
42
+ operation :not_iend_with, operator: OPS[:not_iend_with] do |value|
43
+ scope.where(not_ilike(casted_value_field("text"), "%#{escape_pattern(cast(value))}"))
44
+ end
45
+ operation :not_icontain, operator: OPS[:not_icontain] do |value|
46
+ scope.where(not_ilike(casted_value_field("text"), "%#{escape_pattern(cast(value))}%"))
47
+ end
48
+
49
+ private
50
+
51
+ def cast(value)
52
+ Casters::TextCaster.new.deserialize(value)
53
+ end
54
+
55
+ def like(target, value)
56
+ target.matches(value, nil, true)
57
+ end
58
+
59
+ def ilike(target, value)
60
+ target.matches(value, nil, false)
61
+ end
62
+
63
+ def not_like(target, value)
64
+ # We expect NULLs to never match the pattern
65
+ target.does_not_match(value, nil, true).or(target.eq(nil))
66
+ end
67
+
68
+ def not_ilike(target, value)
69
+ # We expect NULLs to never match the pattern
70
+ target.does_not_match(value, nil, false).or(target.eq(nil))
71
+ end
72
+
73
+ # Escape special chars (\, %, _) in LIKE/ILIKE pattern
74
+ def escape_pattern(value)
75
+ return unless value.is_a?(String)
76
+
77
+ value.gsub("\\", "\\\\\\").gsub("%", "\\%").gsub("_", "\\_")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -6,13 +6,12 @@ module ActiveFields
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  class_methods do
9
- attr_reader :active_fields_config
10
-
11
9
  def has_active_fields(types: ActiveFields.config.type_names)
12
10
  include CustomizableConcern
13
11
 
14
- @active_fields_config = CustomizableConfig.new(self)
15
- @active_fields_config.types = types
12
+ types.each do |field_type|
13
+ ActiveFields.registry.add(field_type, name)
14
+ end
16
15
  end
17
16
  end
18
17
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveFields
4
+ # Storage for configured relations between active fields and customizable models
5
+ class Registry
6
+ include Singleton
7
+
8
+ def initialize
9
+ @customizables = {}
10
+ @fields = {}
11
+ end
12
+
13
+ # Add relation between active field type and customizable type
14
+ def add(field_type_name, customizable_type)
15
+ if ActiveFields.config.type_names.exclude?(field_type_name)
16
+ raise ArgumentError, "undefined ActiveFields type provided for #{customizable_type}: #{field_type_name}"
17
+ end
18
+
19
+ @customizables[field_type_name] ||= Set.new
20
+ @customizables[field_type_name] << customizable_type
21
+
22
+ @fields[customizable_type] ||= Set.new
23
+ @fields[customizable_type] << field_type_name
24
+
25
+ nil
26
+ end
27
+
28
+ # Returns customizable types that allow provided active field type name
29
+ def customizable_types_for(field_type_name)
30
+ @customizables[field_type_name]
31
+ end
32
+
33
+ # Returns active field type names, allowed for given customizable type
34
+ def field_type_names_for(customizable_type)
35
+ @fields[customizable_type]
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveFields
4
- VERSION = "1.1.0"
4
+ VERSION = "2.0.1"
5
5
  end
data/lib/active_fields.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "active_fields/version"
4
+ require_relative "active_fields/constants"
4
5
  require_relative "active_fields/engine"
5
6
 
6
7
  module ActiveFields
@@ -11,12 +12,13 @@ module ActiveFields
11
12
  super
12
13
  Casters.eager_load!
13
14
  Validators.eager_load!
15
+ Finders.eager_load!
14
16
  end
15
17
  end
16
18
 
17
19
  eager_autoload do
18
20
  autoload :Config
19
- autoload :CustomizableConfig
21
+ autoload :Registry
20
22
  autoload :HasActiveFields
21
23
  end
22
24
 
@@ -62,6 +64,30 @@ module ActiveFields
62
64
  end
63
65
  end
64
66
 
67
+ module Finders
68
+ extend ActiveSupport::Autoload
69
+
70
+ eager_autoload do
71
+ autoload :BaseFinder
72
+ autoload :SingularFinder
73
+ autoload :ArrayFinder
74
+
75
+ autoload :BooleanFinder
76
+ autoload :DateFinder
77
+ autoload :DateArrayFinder
78
+ autoload :DateTimeFinder
79
+ autoload :DateTimeArrayFinder
80
+ autoload :DecimalFinder
81
+ autoload :DecimalArrayFinder
82
+ autoload :EnumFinder
83
+ autoload :EnumArrayFinder
84
+ autoload :IntegerFinder
85
+ autoload :IntegerArrayFinder
86
+ autoload :TextFinder
87
+ autoload :TextArrayFinder
88
+ end
89
+ end
90
+
65
91
  class << self
66
92
  def config
67
93
  yield Config.instance if block_given?
@@ -69,5 +95,7 @@ module ActiveFields
69
95
  end
70
96
 
71
97
  alias_method :configure, :config
98
+
99
+ def registry = Registry.instance
72
100
  end
73
101
  end
@@ -17,6 +17,15 @@ module ActiveFields
17
17
  end
18
18
  end
19
19
 
20
+ def insert_into_application_controller
21
+ inject_into_class "app/controllers/application_controller.rb", "ApplicationController" do
22
+ optimize_indentation(<<~CODE, 2)
23
+ include ActiveFieldsControllerConcern
24
+ helper ActiveFieldsHelper
25
+ CODE
26
+ end
27
+ end
28
+
20
29
  def add_routes
21
30
  route "resources :active_fields"
22
31
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ActiveFieldsController < ApplicationController
4
- helper ActiveFieldsHelper
5
-
6
4
  before_action :set_active_field, only: %i[show edit update destroy]
7
5
 
8
6
  def index
@@ -59,14 +57,6 @@ class ActiveFieldsController < ApplicationController
59
57
  end
60
58
  end
61
59
 
62
- def compact_array_param(value)
63
- if value.first == ""
64
- value[1..-1]
65
- else
66
- value
67
- end
68
- end
69
-
70
60
  # It is strongly recommended to move it to, for example, policies.
71
61
  def permitted_attributes_for_create(model_class)
72
62
  if model_class == ActiveFields::Field::Boolean
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveFieldsControllerConcern
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ helper_method :active_fields_finders_params
8
+ end
9
+
10
+ def active_fields_finders_params
11
+ @active_fields_finders_params ||=
12
+ params.permit(
13
+ f: [
14
+ :n,
15
+ :name,
16
+ :op,
17
+ :operator,
18
+ :v,
19
+ :value,
20
+ v: [],
21
+ value: [],
22
+ ],
23
+ )[:f] || {}
24
+ end
25
+
26
+ def compact_array_param(value)
27
+ if value.first == ""
28
+ value[1..-1]
29
+ else
30
+ value
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveFieldsHelper
4
+ ARRAY_SIZE_OPERATIONS = %i[size_eq size_not_eq size_gt size_gteq size_lt size_lteq].freeze
5
+ private_constant :ARRAY_SIZE_OPERATIONS
6
+
4
7
  def render_array_field(form:, name:, value:, field_method:, field_opts: {})
5
8
  render partial: "shared/array_field", locals: {
6
9
  form: form,
@@ -23,6 +26,70 @@ module ActiveFieldsHelper
23
26
  render partial: partial, locals: { form: form, active_value: active_value, active_field: active_value.active_field }
24
27
  end
25
28
 
29
+ def render_active_fields_finders_form(active_fields:, url:)
30
+ render partial: "active_fields/finders/form", locals: { active_fields: active_fields, url: url }
31
+ end
32
+
33
+ def active_field_finder_input_types(active_field:)
34
+ return [] if active_field.value_finder_class.nil?
35
+
36
+ types = [active_field.type_name]
37
+ types += [:array_size] if active_field.value_finder_class.operations.intersect?(ARRAY_SIZE_OPERATIONS)
38
+
39
+ types
40
+ end
41
+
42
+ def render_active_field_finder_input(form:, type:, active_field:, template: false, selected: {})
43
+ if type == :array_size
44
+ operations = active_field.value_finder_class.operations & ARRAY_SIZE_OPERATIONS
45
+ partial = "active_fields/finders/inputs/array_size"
46
+ else
47
+ operations = active_field.value_finder_class.operations - ARRAY_SIZE_OPERATIONS
48
+ partial = "active_fields/finders/inputs/#{type}"
49
+ end
50
+
51
+ render partial: partial, locals: {
52
+ form: form,
53
+ active_field: active_field,
54
+ operations: operations,
55
+ template: template,
56
+ selected: selected,
57
+ }
58
+ end
59
+
60
+ def render_selected_active_field_finder_input(form:, active_fields:, finder_params:)
61
+ active_field_name = finder_params[:n] || finder_params[:name]
62
+ active_field = active_fields.find { |active_field| active_field.name == active_field_name }
63
+ return if active_field&.value_finder_class.nil?
64
+
65
+ op = (finder_params[:op] || finder_params[:operator])&.to_sym
66
+ if active_field.value_finder_class.operations.include?(op)
67
+ operation = op
68
+ operator = active_field.value_finder_class.operator_for(op)
69
+ else
70
+ operation = active_field.value_finder_class.operation_for(op)
71
+ operator = op
72
+ end
73
+ return if operation.nil? || operator.nil?
74
+
75
+ value = finder_params[:v] || finder_params[:value]
76
+
77
+ type =
78
+ if ARRAY_SIZE_OPERATIONS.include?(operation)
79
+ :array_size
80
+ else
81
+ active_field.type_name
82
+ end
83
+
84
+ render_active_field_finder_input(
85
+ form: form,
86
+ type: type,
87
+ active_field: active_field,
88
+ template: false,
89
+ selected: { operation: operation, operator: operator, value: value },
90
+ )
91
+ end
92
+
26
93
  def active_field_form(active_field)
27
94
  "active_fields/forms/#{active_field.type_name}"
28
95
  end
@@ -0,0 +1,59 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static targets = [
5
+ "inputTemplatesContainer",
6
+ "inputTemplate",
7
+ "inputsContainer",
8
+ "input",
9
+ ]
10
+
11
+ connect() {
12
+ this.inputTemplatesContainerTarget.style.display = "none"
13
+ }
14
+
15
+ addInput(e) {
16
+ e.preventDefault()
17
+
18
+ const selectedOption = e.target.options[e.target.selectedIndex]
19
+ const selectedName = selectedOption.dataset.activeFieldName
20
+ const selectedType = selectedOption.value
21
+
22
+ if (!selectedName || !selectedType) { return }
23
+
24
+ const templateInput = this.inputTemplateTargets.find((templateInput) => {
25
+ return templateInput.dataset.activeFieldName === selectedName && templateInput.dataset.type === selectedType
26
+ })
27
+
28
+ let newInput = templateInput.cloneNode(true)
29
+ newInput.dataset.activeFieldsFindersFormTarget = "input"
30
+ this.#setInputIndex(newInput)
31
+
32
+ this.inputsContainerTarget.append(newInput)
33
+
34
+ e.target.value = ""
35
+ }
36
+
37
+ removeInput(e) {
38
+ e.preventDefault()
39
+
40
+ e.target.parentElement.remove()
41
+ }
42
+
43
+ #getLastIndex() {
44
+ if (this.inputTargets.length === 0) { return -1 }
45
+
46
+ return Math.max(...this.inputTargets.map((input) => +input.dataset.index))
47
+ }
48
+
49
+ #setInputIndex(input) {
50
+ const newIndex = this.#getLastIndex() + 1
51
+
52
+ input.dataset.index = newIndex.toString()
53
+ Array.from(input.children).forEach((element) => {
54
+ if (element.hasAttribute("name") && element.name.includes("[0]")) {
55
+ element.name = element.name.replace("[0]", `[${newIndex}]`)
56
+ }
57
+ })
58
+ }
59
+ }
@@ -0,0 +1,42 @@
1
+ <div data-controller="active-fields-finders-form">
2
+ <% selector_options = [["-", [["< Add filter >", ""]]]] + active_fields.map do |active_field|
3
+ [
4
+ active_field.name,
5
+ active_field_finder_input_types(active_field: active_field).map do |type|
6
+ [
7
+ "#{active_field.name} [#{type}]",
8
+ type,
9
+ { data: { "active-field-name": active_field.name } },
10
+ ]
11
+ end
12
+ ]
13
+ end
14
+ %>
15
+ <%= select_tag :selector,
16
+ grouped_options_for_select(selector_options),
17
+ data: { "active-fields-finders-form-target": "selector", action: "change->active-fields-finders-form#addInput" }
18
+ %>
19
+
20
+ <div data-active-fields-finders-form-target="inputTemplatesContainer" style="display: none;">
21
+ <% active_fields.each do |active_field| %>
22
+ <%= fields_for :f, nil, index: 0 do |ff| %>
23
+ <% active_field_finder_input_types(active_field: active_field).each do |type| %>
24
+ <%= render_active_field_finder_input(form: ff, type: type, active_field: active_field, template: true) %>
25
+ <% end %>
26
+ <% end %>
27
+ <% end %>
28
+ </div>
29
+
30
+ <%= form_with(url: url, method: :get) do |f| %>
31
+ <div data-active-fields-finders-form-target="inputsContainer">
32
+ <% active_fields_finders_params.each do |index, finder_params| %>
33
+ <%= fields_for :f, nil, index: index do |ff| %>
34
+ <%= render_selected_active_field_finder_input(form: ff, active_fields: active_fields, finder_params: finder_params) %>
35
+ <% end %>
36
+ <% end %>
37
+ </div>
38
+
39
+ <%= f.submit "Filter" %>
40
+ <%= link_to "Reset", url %>
41
+ <% end %>
42
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="array_size"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.number_field :v, { value: selected[:value], min: 0, max: active_field.max_size, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,21 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <% if active_field.nullable? %>
15
+ <% values = { "True" => "true", "False" => "false", "Null" => "" } %>
16
+ <% else %>
17
+ <% values = { "True" => "true", "False" => "false" } %>
18
+ <% end %>
19
+ <%= form.select :v, values, { selected: selected[:value] }, { id: nil } %>
20
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
21
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.date_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.date_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.datetime_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.datetime_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.number_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, step: "any", id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.number_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, step: "any", id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.select :v, active_field.allowed_values, { selected: selected[:value], include_blank: true }, { id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.select :v, active_field.allowed_values, { selected: selected[:value], include_blank: true }, { id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>
@@ -0,0 +1,16 @@
1
+ <div
2
+ data-active-fields-finders-form-target="<%= template ? "inputTemplate" : "input" %>"
3
+ data-type="<%= active_field.type_name %>"
4
+ data-active-field-name="<%= active_field.name %>"
5
+ data-index="<%= form.index %>"
6
+ >
7
+ <%= form.label :n, active_field.name, for: nil %>
8
+ <%= form.hidden_field :n, value: active_field.name, id: nil %>
9
+ <%= form.select :op,
10
+ operations.map { |operation_name| [operation_name, active_field.value_finder_class.operator_for(operation_name)] },
11
+ { selected: selected[:operator] },
12
+ { id: nil }
13
+ %>
14
+ <%= form.number_field :v, { value: selected[:value], min: active_field.min, max: active_field.max, id: nil } %>
15
+ <%= button_tag "Remove", type: "button", data: { action: "click->active-fields-finders-form#removeInput" } %>
16
+ </div>