active_element 0.0.19 → 0.0.20
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/app/controllers/active_element/application_controller.rb +2 -2
- data/app/views/active_element/components/form.html.erb +16 -6
- data/app/views/active_element/components/table/_collection_row.html.erb +1 -1
- data/app/views/active_element/components/table/collection.html.erb +6 -1
- data/app/views/active_element/default_views/edit.html.erb +2 -2
- data/app/views/active_element/default_views/index.html.erb +13 -2
- data/app/views/active_element/default_views/show.html.erb +2 -2
- data/app/views/layouts/active_element.html.erb +9 -1
- data/config/routes.rb +1 -0
- data/lib/active_element/components/button.rb +18 -3
- data/lib/active_element/components/collection_table.rb +4 -2
- data/lib/active_element/components/form.rb +19 -3
- data/lib/active_element/components/util/default_display_value.rb +4 -0
- data/lib/active_element/components/util/form_field_mapping.rb +5 -2
- data/lib/active_element/components/util/record_mapping.rb +10 -1
- data/lib/active_element/controller_interface.rb +2 -1
- data/lib/active_element/controller_state.rb +1 -1
- data/lib/active_element/default_controller/controller.rb +37 -3
- data/lib/active_element/default_controller/search.rb +15 -1
- data/lib/active_element/field_options.rb +3 -3
- data/lib/active_element/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 667ecfa2f26f661d4c0f760529fdc4ae944e242fdefecba10d6cc5b194b1e822
|
4
|
+
data.tar.gz: 28f0326bb18b3bf7fb402a5b89e82c796621825779fdaa2a754817e5028fe8e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d7a79658f6ec7d58e2aac0492fe952d7df2c6d4873f2a4ad9390735b3f5c868947bb9722c92ec4bb640bf2909c3ad064e3ecaf7fccd5c07992810d9ee3344ee
|
7
|
+
data.tar.gz: d48338e4f22be093bf6b3c6ef3ca2acce3150a3db3fde1b715408b4f8de3ce41f2c6a3074982b4426fc53de6f5609b5de443f8192c5b602008f37abe1cbf0621
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
active_element (0.0.
|
4
|
+
active_element (0.0.20)
|
5
5
|
bootstrap (~> 5.3.0alpha3)
|
6
6
|
kaminari (~> 1.2)
|
7
7
|
paintbrush (~> 0.1.2)
|
@@ -83,7 +83,7 @@ GEM
|
|
83
83
|
autoprefixer-rails (10.4.16.0)
|
84
84
|
execjs (~> 2)
|
85
85
|
bcrypt (3.1.18)
|
86
|
-
bootstrap (5.3.
|
86
|
+
bootstrap (5.3.3)
|
87
87
|
autoprefixer-rails (>= 9.1.0)
|
88
88
|
popper_js (>= 2.11.8, < 3)
|
89
89
|
brakeman (5.4.1)
|
@@ -150,7 +150,7 @@ GEM
|
|
150
150
|
mini_mime (1.1.5)
|
151
151
|
mini_portile2 (2.8.2)
|
152
152
|
minitest (5.18.1)
|
153
|
-
net-imap (0.4.
|
153
|
+
net-imap (0.4.11)
|
154
154
|
date
|
155
155
|
net-protocol
|
156
156
|
net-pop (0.1.2)
|
@@ -159,7 +159,7 @@ GEM
|
|
159
159
|
timeout
|
160
160
|
net-smtp (0.5.0)
|
161
161
|
net-protocol
|
162
|
-
nio4r (2.7.
|
162
|
+
nio4r (2.7.3)
|
163
163
|
nokogiri (1.15.2)
|
164
164
|
mini_portile2 (~> 2.8.2)
|
165
165
|
racc (~> 1.4)
|
@@ -27,8 +27,8 @@ module ActiveElement
|
|
27
27
|
helper_method :active_element
|
28
28
|
helper_method :render_active_element_hook
|
29
29
|
|
30
|
-
def render_active_element_hook(hook)
|
31
|
-
render_to_string partial: hook
|
30
|
+
def render_active_element_hook(hook, locals: {})
|
31
|
+
render_to_string partial: hook, locals: locals
|
32
32
|
rescue ActionView::MissingTemplate
|
33
33
|
nil
|
34
34
|
end
|
@@ -59,13 +59,23 @@
|
|
59
59
|
<% fields.each_slice(columns) do |field_group| %>
|
60
60
|
<div class="row form-fields mb-3">
|
61
61
|
<% field_group.each do |field, type, options| %>
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
<% if type != :hidden_field %>
|
63
|
+
<div class="col-sm-3">
|
64
|
+
<%= render partial: 'active_element/components/form/label',
|
65
|
+
locals: {
|
66
|
+
component: component,
|
67
|
+
id: id,
|
68
|
+
type: type,
|
69
|
+
form: form,
|
70
|
+
field: field,
|
71
|
+
options: options
|
72
|
+
} %>
|
73
|
+
</div>
|
74
|
+
<% end %>
|
66
75
|
|
67
76
|
|
68
|
-
|
77
|
+
|
78
|
+
<% if type != :hidden_field %><div class="col"><% end %>
|
69
79
|
<%= render partial: 'active_element/components/form/field',
|
70
80
|
locals: {
|
71
81
|
id: id,
|
@@ -76,7 +86,7 @@
|
|
76
86
|
component: component,
|
77
87
|
record: record }
|
78
88
|
%>
|
79
|
-
|
89
|
+
<% if type != :hidden_field %></div><% end %>
|
80
90
|
<% end %>
|
81
91
|
</div>
|
82
92
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<tr class="<%= (index % 2).zero? ? 'even' : 'odd' %> <%= row_class_mapper.call(item) %>">
|
2
2
|
<% fields.each do |field, class_mapper, label, value_mapper| %>
|
3
|
-
<td class="align-
|
3
|
+
<td class="align-top <%= class_mapper.call(item) %>">
|
4
4
|
<% if component.secret_field?(field) %>
|
5
5
|
<%= controller.helpers.render partial: 'active_element/components/secret/field',
|
6
6
|
locals: { secret: value_mapper.call(item), label: label } %>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%= active_element.component.page_title record.model_name.to_s.titleize %>
|
2
2
|
|
3
|
-
<%= render_active_element_hook "#{controller_path}/before_edit" %>
|
3
|
+
<%= render_active_element_hook "#{controller_path}/before_edit", locals: { record: record } %>
|
4
4
|
|
5
5
|
<%= active_element.component.form model: [namespace, record].compact,
|
6
6
|
destroy: active_element.state.deletable?,
|
7
7
|
fields: active_element.state.editable_fields %>
|
8
8
|
|
9
|
-
<%= render_active_element_hook "#{controller_path}/after_edit" %>
|
9
|
+
<%= render_active_element_hook "#{controller_path}/after_edit", locals: { record: record } %>
|
@@ -7,7 +7,17 @@
|
|
7
7
|
fields: active_element.state.searchable_fields %>
|
8
8
|
<% end %>
|
9
9
|
|
10
|
-
<%= render_active_element_hook "#{controller_path}/before_index" %>
|
10
|
+
<%= render_active_element_hook "#{controller_path}/before_index", locals: { collection: collection } %>
|
11
|
+
|
12
|
+
<% if nested_for.present? %>
|
13
|
+
<%=
|
14
|
+
active_element.component.page_section_title(
|
15
|
+
nested_for.map do |nested_for_record|
|
16
|
+
ActiveElement::Components::Util::DefaultDisplayValue.new(object: nested_for_record).value
|
17
|
+
end.join(', ')
|
18
|
+
)
|
19
|
+
%>
|
20
|
+
<% end %>
|
11
21
|
|
12
22
|
<% if active_element.state.search_required && search_filters.compact_blank.blank? %>
|
13
23
|
<% if active_element.state.creatable? %>
|
@@ -20,8 +30,9 @@
|
|
20
30
|
show: active_element.state.viewable?,
|
21
31
|
edit: active_element.state.editable?,
|
22
32
|
destroy: active_element.state.deletable?,
|
33
|
+
nested_for: nested_for,
|
23
34
|
collection: collection,
|
24
35
|
fields: active_element.state.listable_fields %>
|
25
36
|
<% end %>
|
26
37
|
|
27
|
-
<%= render_active_element_hook "#{controller_path}/after_index" %>
|
38
|
+
<%= render_active_element_hook "#{controller_path}/after_index", locals: { collection: collection } %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%= active_element.component.page_title record.model_name.to_s.titleize %>
|
2
2
|
|
3
|
-
<%= render_active_element_hook "#{controller_path}/before_show" %>
|
3
|
+
<%= render_active_element_hook "#{controller_path}/before_show", locals: { record: record } %>
|
4
4
|
|
5
5
|
<%= active_element.component.table item: record,
|
6
6
|
edit: active_element.state.editable?,
|
7
7
|
destroy: active_element.state.deletable?,
|
8
8
|
fields: active_element.state.viewable_fields %>
|
9
9
|
|
10
|
-
<%= render_active_element_hook "#{controller_path}/after_show" %>
|
10
|
+
<%= render_active_element_hook "#{controller_path}/after_show", locals: { record: record } %>
|
@@ -19,6 +19,15 @@
|
|
19
19
|
</script>
|
20
20
|
<% end %>
|
21
21
|
|
22
|
+
<% if respond_to?(:javascript_pack_tag) && defined? Webpacker %>
|
23
|
+
<%= begin
|
24
|
+
javascript_pack_tag 'application'
|
25
|
+
rescue Webpacker::Manifest::MissingEntryError
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
%>
|
29
|
+
<% end %>
|
30
|
+
|
22
31
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
23
32
|
<link rel="stylesheet"
|
24
33
|
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
|
@@ -116,6 +125,5 @@
|
|
116
125
|
<%= javascript_include_tag 'active_element/active_element', 'data-turbo-track': 'reload', 'data-turbolinks-track': 'reload' %>
|
117
126
|
<%= javascript_include_tag 'application', 'data-turbo-track': 'reload', 'data-turbolinks-track': 'reload' %>
|
118
127
|
<% end %>
|
119
|
-
|
120
128
|
</body>
|
121
129
|
</html>
|
data/config/routes.rb
CHANGED
@@ -6,7 +6,7 @@ module ActiveElement
|
|
6
6
|
class Button
|
7
7
|
# rubocop:disable Metrics/MethodLength
|
8
8
|
def initialize(controller, record, flag_or_options, confirm: false, type: :primary, method: nil,
|
9
|
-
float: nil, icon: nil, tooltip: false, **kwargs, &block)
|
9
|
+
float: nil, icon: nil, tooltip: false, nested_for: nil, **kwargs, &block)
|
10
10
|
@controller = controller
|
11
11
|
@record = record.is_a?(ActiveRecord::Relation) ? record.klass.new : record
|
12
12
|
@flag_or_options = flag_or_options
|
@@ -20,6 +20,7 @@ module ActiveElement
|
|
20
20
|
@block_given = block_given?
|
21
21
|
@content = block.call if block_given?
|
22
22
|
@tooltip = tooltip
|
23
|
+
@nested_for = nested_for
|
23
24
|
end
|
24
25
|
# rubocop:enable Metrics/MethodLength
|
25
26
|
|
@@ -49,7 +50,7 @@ module ActiveElement
|
|
49
50
|
private
|
50
51
|
|
51
52
|
attr_reader :controller, :record, :flag_or_options, :float, :kwargs, :kwargs_class, :type, :method, :icon,
|
52
|
-
:block_given, :content, :confirm, :tooltip
|
53
|
+
:block_given, :content, :confirm, :tooltip, :nested_for
|
53
54
|
|
54
55
|
def link_method
|
55
56
|
return method if method.present?
|
@@ -116,7 +117,21 @@ module ActiveElement
|
|
116
117
|
def record_path
|
117
118
|
return nil unless record.class.is_a?(ActiveModel::Naming)
|
118
119
|
|
119
|
-
Util::RecordPath.new(record: record, controller: controller, type: type).path
|
120
|
+
Util::RecordPath.new(record: record, controller: controller, type: type).path(**nested_args)
|
121
|
+
end
|
122
|
+
|
123
|
+
def nested_args
|
124
|
+
case type
|
125
|
+
when :new
|
126
|
+
nested_params
|
127
|
+
else
|
128
|
+
{}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def nested_params
|
133
|
+
route = controller.request.routes.recognize_path(controller.request.path)
|
134
|
+
route.reject { |key, _value| %w[controller action].include?(key.to_s) }
|
120
135
|
end
|
121
136
|
end
|
122
137
|
end
|
@@ -15,7 +15,7 @@ module ActiveElement
|
|
15
15
|
# rubocop:disable Metrics/MethodLength
|
16
16
|
def initialize(controller, class_name:, collection:, fields:, params:, model_name: nil, style: nil,
|
17
17
|
show: false, new: false, edit: false, destroy: false, paginate: true, group: nil,
|
18
|
-
group_title: false, row_class: nil, title: nil, **_kwargs)
|
18
|
+
group_title: false, nested_for: nil, row_class: nil, title: nil, **_kwargs)
|
19
19
|
@controller = controller
|
20
20
|
@class_name = class_name
|
21
21
|
@model_name = model_name
|
@@ -32,6 +32,7 @@ module ActiveElement
|
|
32
32
|
@group_title = group_title
|
33
33
|
@row_class = row_class
|
34
34
|
@title = title
|
35
|
+
@nested_for = nested_for
|
35
36
|
verify_paginate_and_group
|
36
37
|
end
|
37
38
|
# rubocop:enable Metrics/MethodLength
|
@@ -54,6 +55,7 @@ module ActiveElement
|
|
54
55
|
destroy: destroy,
|
55
56
|
group: group,
|
56
57
|
group_title: group_title,
|
58
|
+
nested_for: nested_for,
|
57
59
|
display_pagination: display_pagination?,
|
58
60
|
page_sizes: [5, 10, 25, 50, 75, 100, 200],
|
59
61
|
page_size: page_size,
|
@@ -78,7 +80,7 @@ module ActiveElement
|
|
78
80
|
|
79
81
|
attr_reader :class_name, :collection, :fields, :style, :row_class,
|
80
82
|
:new, :show, :edit, :destroy,
|
81
|
-
:paginate, :params, :group, :group_title, :title
|
83
|
+
:paginate, :params, :group, :group_title, :title, :nested_for
|
82
84
|
|
83
85
|
def paginated_collection
|
84
86
|
return collection unless paginate && collection.respond_to?(:page) && !limit?
|
@@ -190,14 +190,30 @@ module ActiveElement
|
|
190
190
|
end
|
191
191
|
|
192
192
|
def base_options_for_select(field, field_options)
|
193
|
-
return normalized_options(field_options.fetch(:options)) if field_options.key?(:options)
|
193
|
+
return normalized_options(field_options.fetch(:options), field_options) if field_options.key?(:options)
|
194
194
|
return default_options_for_select(field, field_options) if record.class.is_a?(ActiveModel::Naming)
|
195
195
|
|
196
196
|
raise ArgumentError, "Must provide select options `[:#{field}, { options: [...] }]` or a record instance."
|
197
197
|
end
|
198
198
|
|
199
|
-
def normalized_options(options)
|
200
|
-
options.map
|
199
|
+
def normalized_options(options, field_options)
|
200
|
+
options.map do |option|
|
201
|
+
next option if option.is_a?(Array)
|
202
|
+
next active_record_option(option, field_options) if option.is_a?(ActiveRecord::Base)
|
203
|
+
[option, option] if option.is_a?(String)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def active_record_option(option, field_options)
|
208
|
+
[active_record_display_value(option, field_options), option.send(option.class.primary_key)]
|
209
|
+
end
|
210
|
+
|
211
|
+
def active_record_display_value(option, field_options)
|
212
|
+
if field_options[:display_value].is_a?(Proc) && record.present?
|
213
|
+
field_options[:display_value].call(option)
|
214
|
+
else
|
215
|
+
Util::DefaultDisplayValue.new(object: option).value
|
216
|
+
end
|
201
217
|
end
|
202
218
|
|
203
219
|
def default_class_name
|
@@ -12,6 +12,10 @@ module ActiveElement
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def value
|
15
|
+
if object.respond_to?(:default_display_attribute)
|
16
|
+
return object.public_send(object.default_display_attribute)
|
17
|
+
end
|
18
|
+
|
15
19
|
DEFAULT_FIELDS.each do |field|
|
16
20
|
return object.public_send(field) if active_record_value?(field)
|
17
21
|
return object[field] if hash_key(field) if hash_value?(field)
|
@@ -59,10 +59,12 @@ module ActiveElement
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def inline_configured_field(field)
|
62
|
-
field_options = FieldOptions.from_state(
|
62
|
+
field_options = FieldOptions.from_state(
|
63
|
+
field, controller.active_element.state, record, controller
|
64
|
+
)
|
63
65
|
return nil if field_options.blank?
|
64
66
|
|
65
|
-
[field, field_options.type, field_options.options]
|
67
|
+
[field, field_options.type, field_options.options.reverse_merge({ value: field_options.value })]
|
66
68
|
end
|
67
69
|
|
68
70
|
def field_with_provided_type_and_provided_options(field)
|
@@ -201,6 +203,7 @@ module ActiveElement
|
|
201
203
|
json: :json_field,
|
202
204
|
jsonb: :json_field,
|
203
205
|
geometry: :text_area,
|
206
|
+
text: :text_area,
|
204
207
|
datetime: :datetime_field,
|
205
208
|
date: :date_field,
|
206
209
|
time: :time_field,
|
@@ -80,13 +80,22 @@ module ActiveElement
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def value_from_config
|
83
|
-
field_options =
|
83
|
+
field_options = field_options_from_state
|
84
84
|
return nil if field_options.blank?
|
85
85
|
return nil unless DATABASE_TYPES.include?(field_options.type.to_sym)
|
86
86
|
|
87
87
|
send("#{field_options.type}_value")
|
88
88
|
end
|
89
89
|
|
90
|
+
def field_options_from_state
|
91
|
+
FieldOptions.from_state(
|
92
|
+
field,
|
93
|
+
component.controller.active_element.state,
|
94
|
+
record,
|
95
|
+
component.controller
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
90
99
|
# Override these methods as required in a class that includes this module:
|
91
100
|
|
92
101
|
def mapped_association_from_record
|
@@ -25,8 +25,9 @@ module ActiveElement
|
|
25
25
|
@authorize
|
26
26
|
end
|
27
27
|
|
28
|
-
def listable_fields(*args, order: nil)
|
28
|
+
def listable_fields(*args, order: nil, scope: nil)
|
29
29
|
state.list_order = order
|
30
|
+
state.list_scope = scope
|
30
31
|
state.listable_fields.concat(args.map(&:to_sym)).uniq!
|
31
32
|
end
|
32
33
|
|
@@ -8,7 +8,7 @@ module ActiveElement
|
|
8
8
|
attr_reader :permissions, :listable_fields, :viewable_fields, :editable_fields, :searchable_fields,
|
9
9
|
:field_options
|
10
10
|
attr_accessor :sign_in_path, :sign_in, :sign_in_method, :sign_out_path, :sign_out_method,
|
11
|
-
:deletable, :authorizor, :authenticator, :list_order, :search_required, :model
|
11
|
+
:deletable, :authorizor, :authenticator, :list_order, :list_scope, :search_required, :model
|
12
12
|
|
13
13
|
def initialize(controller:)
|
14
14
|
@controller = controller
|
@@ -15,7 +15,8 @@ module ActiveElement
|
|
15
15
|
controller.render 'active_element/default_views/index',
|
16
16
|
locals: {
|
17
17
|
collection: ordered(collection),
|
18
|
-
search_filters: default_text_search.search_filters
|
18
|
+
search_filters: default_text_search.search_filters,
|
19
|
+
nested_for: nested_relations
|
19
20
|
}
|
20
21
|
end
|
21
22
|
|
@@ -124,9 +125,12 @@ module ActiveElement
|
|
124
125
|
end
|
125
126
|
|
126
127
|
def collection
|
127
|
-
return model.
|
128
|
+
return model.public_send(list_scope).where(nested_scope) unless default_text_search.text_search?
|
128
129
|
|
129
|
-
model.
|
130
|
+
model.public_send(list_scope)
|
131
|
+
.left_outer_joins(default_text_search.search_relations)
|
132
|
+
.where(nested_scope)
|
133
|
+
.where(*default_text_search.text_search)
|
130
134
|
end
|
131
135
|
|
132
136
|
def render_range_error(error:, action:)
|
@@ -140,6 +144,36 @@ module ActiveElement
|
|
140
144
|
|
141
145
|
I18n.t('active_element.unexpected_error')
|
142
146
|
end
|
147
|
+
|
148
|
+
def list_scope
|
149
|
+
return :all if state.list_scope.blank?
|
150
|
+
return state.list_scope.call(request) if state.list_scope.is_a?(Proc)
|
151
|
+
|
152
|
+
state.list_scope
|
153
|
+
end
|
154
|
+
|
155
|
+
def nested_scope
|
156
|
+
nested_params.presence || noop
|
157
|
+
end
|
158
|
+
|
159
|
+
def noop
|
160
|
+
Arel::Nodes::True.new.eq(Arel::Nodes::True.new)
|
161
|
+
end
|
162
|
+
|
163
|
+
def nested_params
|
164
|
+
route = controller.request.routes.recognize_path(controller.request.path)
|
165
|
+
route.reject { |key, _value| %w[controller action].include?(key.to_s) }
|
166
|
+
end
|
167
|
+
|
168
|
+
def nested_relations
|
169
|
+
return [] if nested_params.blank?
|
170
|
+
|
171
|
+
nested_params.map do |key, value|
|
172
|
+
collection.model.reflections.values.find do |reflection|
|
173
|
+
reflection.foreign_key.to_s == key.to_s
|
174
|
+
end&.klass&.find(value)
|
175
|
+
end.compact
|
176
|
+
end
|
143
177
|
end
|
144
178
|
end
|
145
179
|
end
|
@@ -25,6 +25,7 @@ module ActiveElement
|
|
25
25
|
conditions = search_filters.to_h.map do |key, value|
|
26
26
|
next relation_matches(key, value) if relation?(key)
|
27
27
|
next datetime_between(key, value) if datetime?(key)
|
28
|
+
next join(key, value) if key.to_s.include?('.')
|
28
29
|
next model.arel_table[key].matches("#{value}%") if string_like_column?(key)
|
29
30
|
|
30
31
|
model.arel_table[key].eq(value)
|
@@ -36,7 +37,15 @@ module ActiveElement
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def search_relations
|
39
|
-
search_filters.to_h.keys.map { |key| relation?(key) ? key.to_sym : nil }.compact
|
40
|
+
relation_joins = search_filters.to_h.keys.map { |key| relation?(key) ? key.to_sym : nil }.compact
|
41
|
+
(relation_joins + shorthand_joins).uniq
|
42
|
+
end
|
43
|
+
|
44
|
+
def shorthand_joins
|
45
|
+
search_filters.to_h
|
46
|
+
.keys
|
47
|
+
.select { |key| key.to_s.include?('.') }
|
48
|
+
.map { |key| key.partition('.').first.to_sym }
|
40
49
|
end
|
41
50
|
|
42
51
|
private
|
@@ -66,6 +75,11 @@ module ActiveElement
|
|
66
75
|
end.compact
|
67
76
|
end
|
68
77
|
|
78
|
+
def join(key, value)
|
79
|
+
table, _, column = key.to_s.partition('.')
|
80
|
+
relation(table).klass.arel_table[column].eq(value)
|
81
|
+
end
|
82
|
+
|
69
83
|
def noop
|
70
84
|
Arel::Nodes::True.new.eq(Arel::Nodes::True.new)
|
71
85
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActiveElement
|
2
2
|
class FieldOptions
|
3
|
-
attr_accessor :type, :options
|
3
|
+
attr_accessor :type, :options, :value
|
4
4
|
attr_reader :field
|
5
5
|
|
6
|
-
def self.from_state(field, state, record)
|
6
|
+
def self.from_state(field, state, record, controller)
|
7
7
|
block = state.field_options[field]
|
8
8
|
return nil if block.blank?
|
9
9
|
|
10
10
|
field_options = new(field)
|
11
|
-
block.call(field_options, record)
|
11
|
+
block.call(field_options, record, controller)
|
12
12
|
field_options
|
13
13
|
end
|
14
14
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_element
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bootstrap
|