forest_admin_datasource_customizer 1.0.0.pre.beta.71 → 1.0.0.pre.beta.72
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/forest_admin_datasource_customizer/decorators/action/action_collection_decorator.rb +47 -11
- data/lib/forest_admin_datasource_customizer/decorators/action/base_action.rb +12 -74
- data/lib/forest_admin_datasource_customizer/decorators/action/form_factory.rb +87 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/form_layout_element.rb +36 -2
- data/lib/forest_admin_datasource_customizer/decorators/action/types/field_type.rb +2 -0
- data/lib/forest_admin_datasource_customizer/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 658c563d6a1a05ba3895d6ee03f130816566313ca15c3db156d729bac9c6f309
|
4
|
+
data.tar.gz: 67b1718e466dde2ec435a41d5a86f98d3265cd1ee0208336c7e5cc469875e1e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7198979d8381dd56cce59bbe447fb51a9132d4d635d6fa4673b5b6cbee55eab1e0d65ff0c249b2fa6f6706a2cb4e2079401f10c001352fe0f17735a36b6ce4ac
|
7
|
+
data.tar.gz: b9296fc4ed968c4d42c0b978e772807f758f0a81ec09a6662c5bb49dd97b2364b64a6ff5fd3265870e965779a0b08a32cacb4dd8f61c5876cd82890fd7aa2127
|
data/lib/forest_admin_datasource_customizer/decorators/action/action_collection_decorator.rb
CHANGED
@@ -10,6 +10,7 @@ module ForestAdminDatasourceCustomizer
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def add_action(name, action)
|
13
|
+
ensure_form_is_correct(action.form, name)
|
13
14
|
action.build_elements
|
14
15
|
action.validate_fields_ids
|
15
16
|
@actions[name] = action
|
@@ -41,15 +42,13 @@ module ForestAdminDatasourceCustomizer
|
|
41
42
|
context = get_context(caller, action, form_values, filter, used, metas[:change_field])
|
42
43
|
|
43
44
|
dynamic_fields = action.form
|
44
|
-
if metas[:search_field]
|
45
|
-
# in the case of a search hook,
|
46
|
-
# we don't want to rebuild all the fields. only the one searched
|
47
|
-
dynamic_fields = dynamic_fields.select { |field| field.id == metas[:search_field] }
|
48
|
-
end
|
45
|
+
dynamic_fields = select_in_form_fields(dynamic_fields, metas[:search_field]) if metas[:search_field]
|
49
46
|
dynamic_fields = drop_defaults(context, dynamic_fields, form_values)
|
50
47
|
dynamic_fields = drop_ifs(context, dynamic_fields) unless metas[:include_hidden_fields]
|
51
48
|
|
52
|
-
fields = drop_deferred(context, metas[:search_values], dynamic_fields)
|
49
|
+
fields = drop_deferred(context, metas[:search_values], dynamic_fields)
|
50
|
+
|
51
|
+
fields.compact
|
53
52
|
|
54
53
|
set_watch_changes_on_fields(form_values, used, fields)
|
55
54
|
|
@@ -64,6 +63,31 @@ module ForestAdminDatasourceCustomizer
|
|
64
63
|
|
65
64
|
private
|
66
65
|
|
66
|
+
def ensure_form_is_correct(form, action_name)
|
67
|
+
return if form.nil? || form.empty?
|
68
|
+
|
69
|
+
is_page_component = ->(element) { element[:type] == 'Layout' && element[:component] == 'Page' }
|
70
|
+
pages = is_page_component.call(form.first)
|
71
|
+
|
72
|
+
form.each do |element|
|
73
|
+
if pages != is_page_component.call(element)
|
74
|
+
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
|
75
|
+
"You cannot mix pages and other form elements in smart action '#{action_name}' form"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def select_in_form_fields(fields, search_field)
|
81
|
+
fields.select do |field|
|
82
|
+
if nested_layout_element?(field)
|
83
|
+
key = field.component == 'Page' ? :elements : :fields
|
84
|
+
select_in_form_fields(field.public_send(:"#{key}"), search_field)
|
85
|
+
else
|
86
|
+
field.id == search_field
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
67
91
|
def set_watch_changes_on_fields(form_values, used, fields)
|
68
92
|
fields.each do |field|
|
69
93
|
if field.type != 'Layout'
|
@@ -77,14 +101,20 @@ module ForestAdminDatasourceCustomizer
|
|
77
101
|
field.watch_changes = used.include?(field.id)
|
78
102
|
elsif field.component == 'Row'
|
79
103
|
set_watch_changes_on_fields(form_values, used, field.fields)
|
104
|
+
elsif field.component == 'Page'
|
105
|
+
set_watch_changes_on_fields(form_values, used, field.elements)
|
80
106
|
end
|
81
107
|
end
|
82
108
|
end
|
83
109
|
|
84
110
|
def execute_on_sub_fields(field)
|
85
|
-
return unless field
|
111
|
+
return unless nested_layout_element?(field)
|
86
112
|
|
87
|
-
field.
|
113
|
+
if field.component == 'Page'
|
114
|
+
field.elements = yield(field.elements)
|
115
|
+
elsif field.component == 'Row'
|
116
|
+
field.fields = yield(field.fields)
|
117
|
+
end
|
88
118
|
end
|
89
119
|
|
90
120
|
def drop_defaults(context, fields, data)
|
@@ -110,10 +140,12 @@ module ForestAdminDatasourceCustomizer
|
|
110
140
|
if_values = fields.map do |field|
|
111
141
|
if evaluate(context, field.if_condition) == false
|
112
142
|
false
|
113
|
-
elsif field
|
114
|
-
|
143
|
+
elsif nested_layout_element?(field)
|
144
|
+
key = field.component == 'Page' ? :elements : :fields
|
145
|
+
field.public_send(:"#{key}=", drop_ifs(context, field.public_send(:"#{key}") || []))
|
146
|
+
|
147
|
+
true unless field.public_send(:"#{key}").empty?
|
115
148
|
|
116
|
-
true unless field.fields.empty?
|
117
149
|
else
|
118
150
|
true
|
119
151
|
end
|
@@ -170,6 +202,10 @@ module ForestAdminDatasourceCustomizer
|
|
170
202
|
|
171
203
|
Context::ActionContext.new(self, caller, form_values, filter, used, change_field)
|
172
204
|
end
|
205
|
+
|
206
|
+
def nested_layout_element?(field)
|
207
|
+
field.type == 'Layout' && %w[Page Row].include?(field.component)
|
208
|
+
end
|
173
209
|
end
|
174
210
|
end
|
175
211
|
end
|
@@ -14,21 +14,22 @@ module ForestAdminDatasourceCustomizer
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def build_elements
|
17
|
-
@form =
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
17
|
+
@form = FormFactory.build_elements(form)
|
18
|
+
end
|
19
|
+
|
20
|
+
def static_form?
|
21
|
+
return form&.all?(&:static?) && form&.none? { |field| field.type == 'Layout' } if form
|
22
|
+
|
23
|
+
true
|
26
24
|
end
|
27
25
|
|
28
26
|
def validate_fields_ids(form = @form, used = [])
|
29
27
|
form&.each do |element|
|
30
|
-
if element.type == 'Layout'
|
31
|
-
|
28
|
+
if element.type == 'Layout'
|
29
|
+
if %w[Page Row].include?(element.component)
|
30
|
+
key = element.component == 'Page' ? :elements : :fields
|
31
|
+
validate_fields_ids(element.public_send(key), used)
|
32
|
+
end
|
32
33
|
else
|
33
34
|
if used.include?(element.id)
|
34
35
|
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
|
@@ -38,69 +39,6 @@ module ForestAdminDatasourceCustomizer
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
41
|
-
|
42
|
-
def build_widget(field)
|
43
|
-
case field[:widget]
|
44
|
-
when 'AddressAutocomplete'
|
45
|
-
WidgetField::AddressAutocompleteField.new(**field)
|
46
|
-
when 'Checkbox'
|
47
|
-
WidgetField::CheckboxField.new(**field)
|
48
|
-
when 'CheckboxGroup'
|
49
|
-
WidgetField::CheckboxGroupField.new(**field)
|
50
|
-
when 'ColorPicker'
|
51
|
-
WidgetField::ColorPickerField.new(**field)
|
52
|
-
when 'CurrencyInput'
|
53
|
-
WidgetField::CurrencyInputField.new(**field)
|
54
|
-
when 'DatePicker'
|
55
|
-
WidgetField::DatePickerField.new(**field)
|
56
|
-
when 'Dropdown'
|
57
|
-
WidgetField::DropdownField.new(**field)
|
58
|
-
when 'FilePicker'
|
59
|
-
WidgetField::FilePickerField.new(**field)
|
60
|
-
when 'JsonEditor'
|
61
|
-
WidgetField::JsonEditorField.new(**field)
|
62
|
-
when 'NumberInput'
|
63
|
-
WidgetField::NumberInputField.new(**field)
|
64
|
-
when 'NumberInputList'
|
65
|
-
WidgetField::NumberInputListField.new(**field)
|
66
|
-
when 'RadioGroup'
|
67
|
-
WidgetField::RadioGroupField.new(**field)
|
68
|
-
when 'RichText'
|
69
|
-
WidgetField::RichTextField.new(**field)
|
70
|
-
when 'TextArea'
|
71
|
-
WidgetField::TextAreaField.new(**field)
|
72
|
-
when 'TextInput'
|
73
|
-
WidgetField::TextInputField.new(**field)
|
74
|
-
when 'TextInputList'
|
75
|
-
WidgetField::TextInputListField.new(**field)
|
76
|
-
when 'TimePicker'
|
77
|
-
WidgetField::TimePickerField.new(**field)
|
78
|
-
when 'UserDropdown'
|
79
|
-
WidgetField::UserDropdownField.new(**field)
|
80
|
-
else
|
81
|
-
raise ForestAdminDatasourceToolkit::Exceptions::ForestException, "Unknow widget type: #{field[:widget]}"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def build_layout_element(field)
|
86
|
-
case field[:component]
|
87
|
-
when 'Separator'
|
88
|
-
FormLayoutElement::SeparatorElement.new(**field)
|
89
|
-
when 'HtmlBlock'
|
90
|
-
FormLayoutElement::HtmlBlockElement.new(**field)
|
91
|
-
when 'Row'
|
92
|
-
FormLayoutElement::RowElement.new(**field)
|
93
|
-
else
|
94
|
-
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
|
95
|
-
"Unknow component type: #{field[:component]}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def static_form?
|
100
|
-
return form&.all?(&:static?) && form&.none? { |field| field.type == 'Layout' } if form
|
101
|
-
|
102
|
-
true
|
103
|
-
end
|
104
42
|
end
|
105
43
|
end
|
106
44
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ForestAdminDatasourceCustomizer
|
2
|
+
module Decorators
|
3
|
+
module Action
|
4
|
+
class FormFactory
|
5
|
+
def self.build_elements(form)
|
6
|
+
form&.map do |field|
|
7
|
+
case field
|
8
|
+
when Hash
|
9
|
+
if field.key?(:widget)
|
10
|
+
build_widget(field)
|
11
|
+
elsif field[:type] == 'Layout'
|
12
|
+
build_layout_element(field)
|
13
|
+
else
|
14
|
+
DynamicField.new(**field)
|
15
|
+
end
|
16
|
+
when FormLayoutElement::RowElement
|
17
|
+
build_elements(field.fields)
|
18
|
+
when FormLayoutElement::PageElement
|
19
|
+
build_elements(field.elements)
|
20
|
+
else
|
21
|
+
field
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.build_widget(field)
|
27
|
+
case field[:widget]
|
28
|
+
when 'AddressAutocomplete'
|
29
|
+
WidgetField::AddressAutocompleteField.new(**field)
|
30
|
+
when 'Checkbox'
|
31
|
+
WidgetField::CheckboxField.new(**field)
|
32
|
+
when 'CheckboxGroup'
|
33
|
+
WidgetField::CheckboxGroupField.new(**field)
|
34
|
+
when 'ColorPicker'
|
35
|
+
WidgetField::ColorPickerField.new(**field)
|
36
|
+
when 'CurrencyInput'
|
37
|
+
WidgetField::CurrencyInputField.new(**field)
|
38
|
+
when 'DatePicker'
|
39
|
+
WidgetField::DatePickerField.new(**field)
|
40
|
+
when 'Dropdown'
|
41
|
+
WidgetField::DropdownField.new(**field)
|
42
|
+
when 'FilePicker'
|
43
|
+
WidgetField::FilePickerField.new(**field)
|
44
|
+
when 'JsonEditor'
|
45
|
+
WidgetField::JsonEditorField.new(**field)
|
46
|
+
when 'NumberInput'
|
47
|
+
WidgetField::NumberInputField.new(**field)
|
48
|
+
when 'NumberInputList'
|
49
|
+
WidgetField::NumberInputListField.new(**field)
|
50
|
+
when 'RadioGroup'
|
51
|
+
WidgetField::RadioGroupField.new(**field)
|
52
|
+
when 'RichText'
|
53
|
+
WidgetField::RichTextField.new(**field)
|
54
|
+
when 'TextArea'
|
55
|
+
WidgetField::TextAreaField.new(**field)
|
56
|
+
when 'TextInput'
|
57
|
+
WidgetField::TextInputField.new(**field)
|
58
|
+
when 'TextInputList'
|
59
|
+
WidgetField::TextInputListField.new(**field)
|
60
|
+
when 'TimePicker'
|
61
|
+
WidgetField::TimePickerField.new(**field)
|
62
|
+
when 'UserDropdown'
|
63
|
+
WidgetField::UserDropdownField.new(**field)
|
64
|
+
else
|
65
|
+
raise ForestAdminDatasourceToolkit::Exceptions::ForestException, "Unknow widget type: #{field[:widget]}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.build_layout_element(field)
|
70
|
+
case field[:component]
|
71
|
+
when 'Separator'
|
72
|
+
FormLayoutElement::SeparatorElement.new(**field)
|
73
|
+
when 'HtmlBlock'
|
74
|
+
FormLayoutElement::HtmlBlockElement.new(**field)
|
75
|
+
when 'Row'
|
76
|
+
FormLayoutElement::RowElement.new(**field)
|
77
|
+
when 'Page'
|
78
|
+
FormLayoutElement::PageElement.new(**field)
|
79
|
+
else
|
80
|
+
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
|
81
|
+
"Unknow component type: #{field[:component]}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -58,10 +58,44 @@ module ForestAdminDatasourceCustomizer
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def instantiate_subfields(fields)
|
61
|
-
fields
|
62
|
-
|
61
|
+
FormFactory.build_elements(fields)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class PageElement < LayoutElement
|
66
|
+
include ForestAdminDatasourceToolkit::Exceptions
|
67
|
+
|
68
|
+
attr_accessor :elements, :next_button_label, :previous_button_label
|
69
|
+
|
70
|
+
def initialize(options)
|
71
|
+
super(component: 'Page', **options)
|
72
|
+
|
73
|
+
validate_elements_presence!(options)
|
74
|
+
validate_no_page_elements!(options[:elements])
|
75
|
+
@next_button_label = options[:next_button_label]
|
76
|
+
@previous_button_label = options[:previous_button_label]
|
77
|
+
@elements = instantiate_elements(options[:elements] || [])
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def validate_elements_presence!(options)
|
83
|
+
return if options.key?(:elements)
|
84
|
+
|
85
|
+
raise ForestException, "Using 'elements' in a 'Page' configuration is mandatory"
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_no_page_elements!(elements)
|
89
|
+
elements&.each do |element|
|
90
|
+
if element[:component] == 'Page'
|
91
|
+
raise ForestException, "'Page' component cannot be used within 'elements'"
|
92
|
+
end
|
63
93
|
end
|
64
94
|
end
|
95
|
+
|
96
|
+
def instantiate_elements(elements)
|
97
|
+
FormFactory.build_elements(elements)
|
98
|
+
end
|
65
99
|
end
|
66
100
|
end
|
67
101
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forest_admin_datasource_customizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.beta.
|
4
|
+
version: 1.0.0.pre.beta.72
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthieu
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-10-
|
12
|
+
date: 2024-10-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/forest_admin_datasource_customizer/decorators/action/context/action_context.rb
|
86
86
|
- lib/forest_admin_datasource_customizer/decorators/action/context/action_context_single.rb
|
87
87
|
- lib/forest_admin_datasource_customizer/decorators/action/dynamic_field.rb
|
88
|
+
- lib/forest_admin_datasource_customizer/decorators/action/form_factory.rb
|
88
89
|
- lib/forest_admin_datasource_customizer/decorators/action/form_layout_element.rb
|
89
90
|
- lib/forest_admin_datasource_customizer/decorators/action/result_builder.rb
|
90
91
|
- lib/forest_admin_datasource_customizer/decorators/action/types/action_scope.rb
|