active_element 0.0.12 → 0.0.13

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +3 -3
  4. data/app/assets/javascripts/active_element/highlight.js +311 -0
  5. data/app/assets/javascripts/active_element/json_field.js +51 -20
  6. data/app/assets/javascripts/active_element/popover.js +6 -4
  7. data/app/assets/stylesheets/active_element/_dark.scss +1 -1
  8. data/app/assets/stylesheets/active_element/application.scss +39 -1
  9. data/app/controllers/concerns/active_element/default_controller_actions.rb +7 -7
  10. data/app/views/active_element/components/fields/_json.html.erb +3 -2
  11. data/app/views/active_element/components/form/_field.html.erb +2 -1
  12. data/app/views/active_element/components/form/_json.html.erb +2 -0
  13. data/app/views/active_element/components/form/_label.html.erb +7 -0
  14. data/app/views/active_element/components/form.html.erb +2 -2
  15. data/app/views/layouts/active_element.html.erb +25 -4
  16. data/example_app/Gemfile.lock +1 -1
  17. data/lib/active_element/components/form.rb +1 -8
  18. data/lib/active_element/components/util/display_value_mapping.rb +0 -2
  19. data/lib/active_element/components/util/form_field_mapping.rb +2 -1
  20. data/lib/active_element/components/util.rb +7 -0
  21. data/lib/active_element/controller_interface.rb +2 -1
  22. data/lib/active_element/controller_state.rb +1 -1
  23. data/lib/active_element/default_controller/actions.rb +3 -0
  24. data/lib/active_element/default_controller/controller.rb +145 -0
  25. data/lib/active_element/default_controller/json_params.rb +48 -0
  26. data/lib/active_element/default_controller/params.rb +97 -0
  27. data/lib/active_element/default_controller/search.rb +112 -0
  28. data/lib/active_element/default_controller.rb +10 -132
  29. data/lib/active_element/version.rb +1 -1
  30. data/lib/active_element.rb +0 -2
  31. data/rspec-documentation/_head.html.erb +2 -0
  32. data/rspec-documentation/pages/000-Introduction.md +8 -5
  33. data/rspec-documentation/pages/005-Setup.md +21 -28
  34. data/rspec-documentation/pages/010-Components/Form Fields.md +35 -0
  35. data/rspec-documentation/pages/015-Custom Controllers.md +32 -0
  36. data/rspec-documentation/pages/016-Default Controller.md +132 -0
  37. data/rspec-documentation/pages/Themes.md +3 -0
  38. metadata +11 -4
  39. data/lib/active_element/default_record_params.rb +0 -62
  40. data/lib/active_element/default_search.rb +0 -110
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveElement
4
- # Provides params for ActiveRecord models when using the default boilerplate controller
5
- # actions. Navigates input parameters and maps them to appropriate relations as needed.
6
- class DefaultRecordParams
7
- def initialize(controller:, model:)
8
- @controller = controller
9
- @model = model
10
- end
11
-
12
- def params
13
- with_transformed_relations(
14
- controller.params.require(controller.controller_name.singularize)
15
- .permit(controller.active_element.state.editable_fields)
16
- )
17
- end
18
-
19
- private
20
-
21
- attr_reader :controller, :model
22
-
23
- def with_transformed_relations(params)
24
- params.to_h.to_h do |key, value|
25
- next [key, value] unless relation?(key)
26
-
27
- relation_param(key, value)
28
- end
29
- end
30
-
31
- def relation_param(key, value)
32
- case relation(key).macro
33
- when :belongs_to
34
- belongs_to_param(key, value)
35
- when :has_one
36
- has_one_param(key, value)
37
- when :has_many
38
- has_many_param(key, value)
39
- end
40
- end
41
-
42
- def belongs_to_param(key, value)
43
- [relation(key).foreign_key, value]
44
- end
45
-
46
- def has_one_param(key, value) # rubocop:disable Naming/PredicateName
47
- [relation(key).name, relation(key).klass.find_by(relation(key).klass.primary_key => value)]
48
- end
49
-
50
- def has_many_param(key, _value) # rubocop:disable Naming/PredicateName
51
- [relation(key).name, relation(key).klass.where(relation(key).klass.primary_key => relation(key).value)]
52
- end
53
-
54
- def relation?(attribute)
55
- relation(attribute.to_sym).present?
56
- end
57
-
58
- def relation(attribute)
59
- model.reflect_on_association(attribute.to_sym)
60
- end
61
- end
62
- end
@@ -1,110 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveElement
4
- # Full text search and datetime querying for DefaultController, provides full text search
5
- # filters for all controllers with configured searchable fields. Includes support for querying
6
- # across relations.
7
- class DefaultSearch
8
- def initialize(controller:, model:)
9
- @controller = controller
10
- @model = model
11
- end
12
-
13
- def search_filters
14
- @search_filters ||= controller.params.permit(*searchable_fields).transform_values do |value|
15
- value.try(:compact_blank) || value
16
- end.compact_blank
17
- end
18
-
19
- def text_search?
20
- search_filters.present?
21
- end
22
-
23
- def text_search
24
- conditions = search_filters.to_h.map do |key, value|
25
- next relation_matches(key, value) if relation?(key)
26
- next datetime_between(key, value) if datetime?(key)
27
-
28
- model.arel_table[key].matches("#{value}%")
29
- end
30
- conditions[1..].reduce(conditions.first) do |accumulated, condition|
31
- accumulated.and(condition)
32
- end
33
- end
34
-
35
- def search_relations
36
- search_filters.to_h.keys.map { |key| relation?(key) ? key.to_sym : nil }.compact
37
- end
38
-
39
- private
40
-
41
- attr_reader :controller, :model
42
-
43
- def searchable_fields
44
- controller.active_element.state.searchable_fields.map do |field|
45
- next field unless field.to_s.end_with?('_at')
46
-
47
- { field => %i[from to] }
48
- end
49
- end
50
-
51
- def noop
52
- Arel::Nodes::True.new.eq(Arel::Nodes::True.new)
53
- end
54
-
55
- def datetime?(key)
56
- model.columns.find { |column| column.name.to_s == key.to_s }&.type == :datetime
57
- end
58
-
59
- def datetime_between(key, value)
60
- return noop if value[:from].blank? && value[:to].blank?
61
-
62
- model.arel_table[key].between(range_begin(value)...range_end(value))
63
- end
64
-
65
- def range_begin(value)
66
- value[:from].present? ? Time.zone.parse(value[:from]) + timezone_offset : -Float::INFINITY
67
- end
68
-
69
- def range_end(value)
70
- value[:to].present? ? Time.zone.parse(value[:to]) + timezone_offset : Float::INFINITY
71
- end
72
-
73
- def timezone_offset
74
- controller.request.cookies['timezone_offset'].to_i.minutes
75
- end
76
-
77
- def relation_matches(key, value)
78
- fields = searchable_relation_fields(key)
79
- relation_model = relation(key).klass
80
- fields.select! do |field|
81
- relation_model.columns.find { |column| column.name.to_s == field.to_s }&.type == :string
82
- end
83
-
84
- return noop if fields.empty?
85
-
86
- relation_conditions(fields, value, relation_model)
87
- end
88
-
89
- def relation_conditions(fields, value, relation_model)
90
- fields[1..].reduce(relation_model.arel_table[fields.first].matches("#{value}%")) do |condition, field|
91
- condition.or(relation_model.arel_table[field].matches("#{value}%"))
92
- end
93
- end
94
-
95
- def searchable_relation_fields(key)
96
- Components::Util.relation_controller(model, controller, key)
97
- &.active_element
98
- &.state
99
- &.fetch(:searchable_fields, []) || []
100
- end
101
-
102
- def relation?(attribute)
103
- relation(attribute.to_sym).present?
104
- end
105
-
106
- def relation(attribute)
107
- model.reflect_on_association(attribute.to_sym)
108
- end
109
- end
110
- end