forest_admin_datasource_customizer 1.0.0.pre.beta.21 → 1.0.0.pre.beta.57

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/forest_admin_datasource_customizer.gemspec +3 -2
  3. data/lib/forest_admin_datasource_customizer/collection_customizer.rb +292 -5
  4. data/lib/forest_admin_datasource_customizer/context/agent_customization_context.rb +18 -0
  5. data/lib/forest_admin_datasource_customizer/context/collection_customization_context.rb +15 -0
  6. data/lib/forest_admin_datasource_customizer/context/relaxed_wrappers/relaxed_collection.rb +50 -0
  7. data/lib/forest_admin_datasource_customizer/context/relaxed_wrappers/relaxed_data_source.rb +18 -0
  8. data/lib/forest_admin_datasource_customizer/datasource_customizer.rb +43 -13
  9. data/lib/forest_admin_datasource_customizer/decorators/action/action_collection_decorator.rb +137 -0
  10. data/lib/forest_admin_datasource_customizer/decorators/action/base_action.rb +67 -0
  11. data/lib/forest_admin_datasource_customizer/decorators/action/context/action_context.rb +56 -0
  12. data/lib/forest_admin_datasource_customizer/decorators/action/context/action_context_single.rb +26 -0
  13. data/lib/forest_admin_datasource_customizer/decorators/action/dynamic_field.rb +50 -0
  14. data/lib/forest_admin_datasource_customizer/decorators/action/result_builder.rb +68 -0
  15. data/lib/forest_admin_datasource_customizer/decorators/action/types/action_scope.rb +15 -0
  16. data/lib/forest_admin_datasource_customizer/decorators/action/types/field_type.rb +35 -0
  17. data/lib/forest_admin_datasource_customizer/decorators/action/widget_field.rb +357 -0
  18. data/lib/forest_admin_datasource_customizer/decorators/binary/binary_collection_decorator.rb +215 -0
  19. data/lib/forest_admin_datasource_customizer/decorators/binary/binary_helper.rb +17 -0
  20. data/lib/forest_admin_datasource_customizer/decorators/chart/chart_collection_decorator.rb +41 -0
  21. data/lib/forest_admin_datasource_customizer/decorators/chart/chart_context.rb +33 -0
  22. data/lib/forest_admin_datasource_customizer/decorators/chart/chart_datasource_decorator.rb +46 -0
  23. data/lib/forest_admin_datasource_customizer/decorators/chart/result_builder.rb +148 -0
  24. data/lib/forest_admin_datasource_customizer/decorators/computed/compute_collection_decorator.rb +115 -0
  25. data/lib/forest_admin_datasource_customizer/decorators/computed/computed_definition.rb +21 -0
  26. data/lib/forest_admin_datasource_customizer/decorators/computed/utils/computed_field.rb +74 -0
  27. data/lib/forest_admin_datasource_customizer/decorators/computed/utils/flattener.rb +49 -0
  28. data/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb +33 -4
  29. data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_aggregate_context.rb +18 -0
  30. data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_create_context.rb +18 -0
  31. data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_delete_context.rb +12 -0
  32. data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_list_context.rb +18 -0
  33. data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_update_context.rb +12 -0
  34. data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_aggregate_context.rb +20 -0
  35. data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_create_context.rb +18 -0
  36. data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_delete_context.rb +18 -0
  37. data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_list_context.rb +19 -0
  38. data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_update_context.rb +19 -0
  39. data/lib/forest_admin_datasource_customizer/decorators/hook/context/hook_context.rb +22 -0
  40. data/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator.rb +95 -0
  41. data/lib/forest_admin_datasource_customizer/decorators/hook/hooks.rb +26 -0
  42. data/lib/forest_admin_datasource_customizer/decorators/operators_emulate/operators_emulate_collection_decorator.rb +118 -0
  43. data/lib/forest_admin_datasource_customizer/decorators/operators_equivalence/operators_equivalence_collection_decorator.rb +50 -0
  44. data/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb +16 -0
  45. data/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb +16 -0
  46. data/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb +17 -0
  47. data/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator.rb +49 -0
  48. data/lib/forest_admin_datasource_customizer/decorators/publication/publication_collection_decorator.rb +95 -0
  49. data/lib/forest_admin_datasource_customizer/decorators/publication/publication_datasource_decorator.rb +57 -0
  50. data/lib/forest_admin_datasource_customizer/decorators/relation/relation_collection_decorator.rb +268 -0
  51. data/lib/forest_admin_datasource_customizer/decorators/rename_collection/rename_collection_datasource_decorator.rb +70 -0
  52. data/lib/forest_admin_datasource_customizer/decorators/rename_collection/rename_collection_decorator.rb +37 -0
  53. data/lib/forest_admin_datasource_customizer/decorators/rename_field/rename_field_collection_decorator.rb +190 -0
  54. data/lib/forest_admin_datasource_customizer/decorators/schema/schema_collection_decorator.rb +21 -0
  55. data/lib/forest_admin_datasource_customizer/decorators/search/search_collection_decorator.rb +135 -0
  56. data/lib/forest_admin_datasource_customizer/decorators/segment/segment_collection_decorator.rb +60 -0
  57. data/lib/forest_admin_datasource_customizer/decorators/sort/sort_collection_decorator.rb +127 -0
  58. data/lib/forest_admin_datasource_customizer/decorators/validation/validation_collection_decorator.rb +82 -0
  59. data/lib/forest_admin_datasource_customizer/decorators/write/create_relations/create_relations_collection_decorator.rb +75 -0
  60. data/lib/forest_admin_datasource_customizer/decorators/write/update_relations/update_relations_collection_decorator.rb +96 -0
  61. data/lib/forest_admin_datasource_customizer/decorators/write/write_datasource_decorator.rb +14 -0
  62. data/lib/forest_admin_datasource_customizer/decorators/write/write_replace/write_customization_context.rb +18 -0
  63. data/lib/forest_admin_datasource_customizer/decorators/write/write_replace/write_replace_collection_decorator.rb +125 -0
  64. data/lib/forest_admin_datasource_customizer/plugins/add_external_relation.rb +27 -0
  65. data/lib/forest_admin_datasource_customizer/plugins/import_field.rb +74 -0
  66. data/lib/forest_admin_datasource_customizer/version.rb +1 -1
  67. metadata +84 -5
  68. data/README.md +0 -31
@@ -0,0 +1,67 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ class BaseAction
5
+ attr_reader :scope, :form, :is_generate_file, :execute
6
+
7
+ def initialize(scope:, form: nil, is_generate_file: false, &execute)
8
+ @scope = scope
9
+ @form = form
10
+ @is_generate_file = is_generate_file
11
+ @execute = execute
12
+ end
13
+
14
+ def build_fields
15
+ @form = @form&.map do |field|
16
+ case field[:widget]
17
+ when 'AddressAutocomplete'
18
+ WidgetField::AddressAutocompleteField.new(**field)
19
+ when 'Checkbox'
20
+ WidgetField::CheckboxField.new(**field)
21
+ when 'CheckboxGroup'
22
+ WidgetField::CheckboxGroupField.new(**field)
23
+ when 'ColorPicker'
24
+ WidgetField::ColorPickerField.new(**field)
25
+ when 'CurrencyInput'
26
+ WidgetField::CurrencyInputField.new(**field)
27
+ when 'DatePicker'
28
+ WidgetField::DatePickerField.new(**field)
29
+ when 'Dropdown'
30
+ WidgetField::DropdownField.new(**field)
31
+ when 'FilePicker'
32
+ WidgetField::FilePickerField.new(**field)
33
+ when 'JsonEditor'
34
+ WidgetField::JsonEditorField.new(**field)
35
+ when 'NumberInput'
36
+ WidgetField::NumberInputField.new(**field)
37
+ when 'NumberInputList'
38
+ WidgetField::NumberInputListField.new(**field)
39
+ when 'RadioGroup'
40
+ WidgetField::RadioGroupField.new(**field)
41
+ when 'RichText'
42
+ WidgetField::RichTextField.new(**field)
43
+ when 'TextArea'
44
+ WidgetField::TextAreaField.new(**field)
45
+ when 'TextInput'
46
+ WidgetField::TextInputField.new(**field)
47
+ when 'TextInputList'
48
+ WidgetField::TextInputListField.new(**field)
49
+ when 'TimePicker'
50
+ WidgetField::TimePickerField.new(**field)
51
+ when 'UserDropdown'
52
+ WidgetField::UserDropdownField.new(**field)
53
+ else
54
+ DynamicField.new(**field)
55
+ end
56
+ end
57
+ end
58
+
59
+ def static_form?
60
+ return form&.all?(&:static?) if form
61
+
62
+ true
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,56 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ module Context
5
+ class ActionContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomizationContext
6
+ include ForestAdminDatasourceToolkit
7
+
8
+ attr_reader :filter, :used, :form_values
9
+
10
+ def initialize(collection, caller, form_values, filter, used = [], change_field = nil)
11
+ super(collection, caller)
12
+ @form_values = form_values
13
+ @filter = filter
14
+ @used = used
15
+ @change_field = change_field
16
+ end
17
+
18
+ def field_changed?(field_name)
19
+ @used << field_name
20
+
21
+ @change_field == field_name
22
+ end
23
+
24
+ def get_form_value(key)
25
+ @used << key
26
+
27
+ @form_values[key]
28
+ end
29
+
30
+ def get_records(fields = [])
31
+ Validations::ProjectionValidator.validate?(@real_collection, fields)
32
+
33
+ @real_collection.list(@caller, @filter, Components::Query::Projection.new)
34
+ end
35
+
36
+ def record_ids
37
+ composite_ids = composite_record_ids
38
+
39
+ composite_ids.map { |id| id[0] }
40
+ end
41
+
42
+ def composite_record_ids
43
+ projection = Components::Query::Projection.new.with_pks(@real_collection)
44
+ records = get_records(projection)
45
+
46
+ records.map { |record| Utils::Record.primary_keys(@real_collection, record) }
47
+ end
48
+
49
+ alias get_record_ids record_ids
50
+ alias get_composite_record_ids composite_record_ids
51
+ alias has_field_changed field_changed?
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,26 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ module Context
5
+ class ActionContextSingle < ActionContext
6
+ include ForestAdminDatasourceToolkit
7
+
8
+ def get_record(fields = [])
9
+ get_records(fields)[0]
10
+ end
11
+
12
+ def record_id
13
+ composite_record_id[0]
14
+ end
15
+
16
+ def composite_record_id
17
+ composite_record_ids[0]
18
+ end
19
+
20
+ alias get_record_id record_id
21
+ alias get_composite_record_id composite_record_id
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ class DynamicField
5
+ attr_accessor :type, :label, :description, :is_required, :is_read_only, :if_condition, :value, :default_value,
6
+ :collection_name, :enum_values, :placeholder
7
+
8
+ def initialize(
9
+ type:,
10
+ label:,
11
+ description: nil,
12
+ is_required: false,
13
+ is_read_only: false,
14
+ if_condition: nil,
15
+ value: nil,
16
+ default_value: nil,
17
+ collection_name: nil,
18
+ enum_values: nil,
19
+ placeholder: nil,
20
+ **_kwargs
21
+ )
22
+ @type = type
23
+ @label = label
24
+ @description = description
25
+ @is_required = is_required
26
+ @is_read_only = is_read_only
27
+ @if_condition = if_condition
28
+ @value = value
29
+ @default_value = default_value
30
+ @collection_name = collection_name
31
+ @enum_values = enum_values
32
+ @placeholder = placeholder
33
+ end
34
+
35
+ def static?
36
+ instance_variables.all? { |attribute| !instance_variable_get(attribute).respond_to?(:call) }
37
+ end
38
+
39
+ def to_h
40
+ result = {}
41
+ instance_variables.each do |attribute|
42
+ result[attribute.to_s.delete('@').to_sym] = instance_variable_get(attribute)
43
+ end
44
+
45
+ result
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,68 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ class ResultBuilder
5
+ def initialize
6
+ @headers = {}
7
+ end
8
+
9
+ def set_header(key, value)
10
+ @headers[key] = value
11
+
12
+ self
13
+ end
14
+
15
+ def success(message: 'Success', options: {})
16
+ {
17
+ headers: @headers,
18
+ type: 'Success',
19
+ message: message,
20
+ refresh: { relationships: options.key?(:invalidated) ? options[:invalidated] : [] },
21
+ html: options.key?(:html) ? options[:html] : nil
22
+ }
23
+ end
24
+
25
+ def error(message: 'Error', options: {})
26
+ {
27
+ headers: @headers,
28
+ type: 'Error',
29
+ status: 400,
30
+ message: message,
31
+ html: options.key?(:html) ? options[:html] : nil
32
+ }
33
+ end
34
+
35
+ def webhook(url:, method: 'POST', headers: {}, body: {})
36
+ {
37
+ headers: @headers,
38
+ type: 'Webhook',
39
+ webhook: {
40
+ body: body,
41
+ headers: headers,
42
+ method: method,
43
+ url: url
44
+ }
45
+ }
46
+ end
47
+
48
+ def file(content:, name: 'file', mime_type: 'application/octet-stream')
49
+ {
50
+ headers: @headers,
51
+ type: 'File',
52
+ name: name,
53
+ mime_type: mime_type,
54
+ stream: content
55
+ }
56
+ end
57
+
58
+ def redirect_to(path:)
59
+ {
60
+ headers: @headers,
61
+ type: 'Redirect',
62
+ redirect_to: path
63
+ }
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,15 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ module Types
5
+ module ActionScope
6
+ SINGLE = 'single'.freeze
7
+
8
+ BULK = 'bulk'.freeze
9
+
10
+ GLOBAL = 'global'.freeze
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ module Types
5
+ module FieldType
6
+ BOOLEAN = 'Boolean'.freeze
7
+
8
+ DATE = 'Date'.freeze
9
+
10
+ DATE_ONLY = 'Dateonly'.freeze
11
+
12
+ COLLECTION = 'Collection'.freeze
13
+
14
+ ENUM = 'Enum'.freeze
15
+
16
+ ENUM_LIST = 'EnumList'.freeze
17
+
18
+ FILE = 'File'.freeze
19
+
20
+ FILE_LIST = 'FileList'.freeze
21
+
22
+ JSON = 'Json'.freeze
23
+
24
+ NUMBER = 'Number'.freeze
25
+
26
+ NUMBER_LIST = 'NumberList'.freeze
27
+
28
+ STRING = 'String'.freeze
29
+
30
+ STRING_LIST = 'StringList'.freeze
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,357 @@
1
+ module ForestAdminDatasourceCustomizer
2
+ module Decorators
3
+ module Action
4
+ module WidgetField
5
+ include Types
6
+ def self.validate_arg(options, attribute, rule)
7
+ case rule[attribute]
8
+ when 'contains'
9
+ unless rule[:value].include? options[attribute]
10
+ raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
11
+ "'#{attribute}' must have a value included in [#{rule[:value]}]"
12
+ end
13
+ when 'present'
14
+ unless options.key? attribute
15
+ raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
16
+ "key '#{attribute}' must be defined"
17
+ end
18
+ end
19
+ end
20
+
21
+ class TimePickerField < DynamicField
22
+ attr_accessor :widget
23
+
24
+ def initialize(options)
25
+ super(**options)
26
+ WidgetField.validate_arg(options, :type, { type: 'contains', value: ['Time'] })
27
+ @widget = 'TimePicker'
28
+ end
29
+ end
30
+
31
+ class AddressAutocompleteField < DynamicField
32
+ attr_accessor :widget
33
+
34
+ def initialize(options)
35
+ super(**options)
36
+ WidgetField.validate_arg(options, :type, { type: 'contains', value: ['String'] })
37
+
38
+ @widget = 'AddressAutocomplete'
39
+ end
40
+ end
41
+
42
+ class CheckboxField < DynamicField
43
+ attr_accessor :widget
44
+
45
+ def initialize(options)
46
+ super(**options)
47
+ WidgetField.validate_arg(
48
+ options,
49
+ :type,
50
+ { type: 'contains', value: [Types::FieldType::BOOLEAN] }
51
+ )
52
+
53
+ @widget = 'Checkbox'
54
+ end
55
+ end
56
+
57
+ class CheckboxGroupField < DynamicField
58
+ attr_accessor :widget, :options
59
+
60
+ def initialize(options)
61
+ super(**options)
62
+
63
+ WidgetField.validate_arg(options, :options, { type: 'present' })
64
+ WidgetField.validate_arg(
65
+ options,
66
+ :type,
67
+ { type: 'contains', value: [Types::FieldType::STRING_LIST, Types::FieldType::NUMBER_LIST] }
68
+ )
69
+
70
+ @widget = 'CheckboxGroup'
71
+ @options = options[:options]
72
+ end
73
+ end
74
+
75
+ class ColorPickerField < DynamicField
76
+ attr_accessor :widget, :enable_opacity, :quick_palette
77
+
78
+ def initialize(options)
79
+ super(**options)
80
+
81
+ WidgetField.validate_arg(options, :enable_opacity, { type: 'contains', value: [Types::FieldType::STRING] })
82
+
83
+ @widget = 'ColorPicker'
84
+ @enable_opacity = options[:enable_opacity] || nil
85
+ @quick_palette = options[:quick_palette] || nil
86
+ end
87
+ end
88
+
89
+ class CurrencyInputField < DynamicField
90
+ attr_accessor :widget, :currency, :base, :min, :max, :step
91
+
92
+ def initialize(options)
93
+ super(**options)
94
+
95
+ WidgetField.validate_arg(options, :type, { type: 'contains', value: [Types::FieldType::NUMBER] })
96
+ WidgetField.validate_arg(options, :currency, { type: 'present' })
97
+
98
+ @widget = 'CurrencyInput'
99
+ @currency = options[:currency]
100
+ @base = options[:base] || 'Unit'
101
+ @min = options[:min] || nil
102
+ @max = options[:max] || nil
103
+ @step = options[:step] || nil
104
+ end
105
+ end
106
+
107
+ class DatePickerField < DynamicField
108
+ attr_accessor :widget, :min, :max, :format, :step
109
+
110
+ def initialize(options)
111
+ super(**options)
112
+
113
+ WidgetField.validate_arg(
114
+ options,
115
+ 'type',
116
+ { type: 'contains',
117
+ value: [Types::FieldType::DATE, Types::FieldType::DATE_ONLY, Types::FieldType::STRING] }
118
+ )
119
+
120
+ @widget = 'DatePicker'
121
+ @format = options[:format] || nil
122
+ @min = options[:min] || nil
123
+ @max = options[:max] || nil
124
+ @step = options[:step] || nil
125
+ end
126
+ end
127
+
128
+ class DropdownField < DynamicField
129
+ attr_accessor :widget, :options, :search
130
+
131
+ def initialize(options)
132
+ super(**options)
133
+ WidgetField.validate_arg(options, :options, { type: 'present' })
134
+ WidgetField.validate_arg(
135
+ options,
136
+ 'type',
137
+ {
138
+ type: 'contains',
139
+ value: [Types::FieldType::DATE, Types::FieldType::DATE_ONLY, Types::FieldType::STRING,
140
+ Types::FieldType::STRING_LIST]
141
+ }
142
+ )
143
+
144
+ @widget = 'Dropdown'
145
+ @options = options[:options]
146
+ @search = options[:search] || nil
147
+ end
148
+ end
149
+
150
+ class FilePickerField < DynamicField
151
+ attr_accessor :widget, :extensions, :max_count, :max_size_mb
152
+
153
+ def initialize(options)
154
+ super(**options)
155
+ WidgetField.validate_arg(options, :options, { type: 'present' })
156
+ WidgetField.validate_arg(
157
+ options,
158
+ 'type',
159
+ {
160
+ type: 'contains',
161
+ value: [Types::FieldType::FILE, Types::FieldType::FILE_LIST]
162
+ }
163
+ )
164
+
165
+ @widget = 'FilePicker'
166
+ @extensions = options[:extensions] || nil
167
+ @max_size_mb = options[:max_size_mb] || nil
168
+ @max_count = options[:max_count] || nil
169
+ end
170
+ end
171
+
172
+ class NumberInputField < DynamicField
173
+ attr_accessor :widget, :step, :min, :max
174
+
175
+ def initialize(options)
176
+ super(**options)
177
+ WidgetField.validate_arg(options, :options, { type: 'present' })
178
+ WidgetField.validate_arg(
179
+ options,
180
+ 'type',
181
+ {
182
+ type: 'contains',
183
+ value: [Types::FieldType::NUMBER]
184
+ }
185
+ )
186
+
187
+ @widget = 'NumberInput'
188
+ @step = options[:step] || nil
189
+ @min = options[:min] || nil
190
+ @max = options[:max] || nil
191
+ end
192
+ end
193
+
194
+ class JsonEditorField < DynamicField
195
+ attr_accessor :widget
196
+
197
+ def initialize(options)
198
+ super(**options)
199
+ WidgetField.validate_arg(
200
+ options,
201
+ 'type',
202
+ {
203
+ type: 'contains',
204
+ value: [Types::FieldType::DATE, Types::FieldType::DATE_ONLY, Types::FieldType::STRING,
205
+ Types::FieldType::STRING_LIST]
206
+ }
207
+ )
208
+
209
+ @widget = 'JsonEditor'
210
+ end
211
+ end
212
+
213
+ class NumberInputListField < DynamicField
214
+ attr_accessor :widget, :allow_duplicates, :allow_empty_values, :enable_reorder, :min, :max, :step
215
+
216
+ def initialize(options)
217
+ super(**options)
218
+ WidgetField.validate_arg(options, :options, { type: 'present' })
219
+ WidgetField.validate_arg(
220
+ options,
221
+ 'type',
222
+ {
223
+ type: 'contains',
224
+ value: [Types::FieldType::NUMBER_LIST]
225
+ }
226
+ )
227
+
228
+ @widget = 'NumberInputList'
229
+ @allow_duplicates = options[:allow_duplicates] || nil
230
+ @allow_empty_values = options[:allow_empty_values] || nil
231
+ @enable_reorder = options[:enable_reorder] || nil
232
+ @min = options[:min] || nil
233
+ @max = options[:max] || nil
234
+ @step = options[:step] || nil
235
+ end
236
+ end
237
+
238
+ class RadioGroupField < DynamicField
239
+ attr_accessor :widget, :options
240
+
241
+ def initialize(options)
242
+ super(**options)
243
+ WidgetField.validate_arg(options, :options, { type: 'present' })
244
+ WidgetField.validate_arg(
245
+ options,
246
+ 'type',
247
+ {
248
+ type: 'contains',
249
+ value: [Types::FieldType::DATE, Types::FieldType::DATEONLY, Types::FieldType::NUMBER,
250
+ Types::FieldType::STRING]
251
+ }
252
+ )
253
+
254
+ @widget = 'RadioGroup'
255
+ @options = options[:options]
256
+ end
257
+ end
258
+
259
+ class RichTextField < DynamicField
260
+ attr_accessor :widget
261
+
262
+ def initialize(options)
263
+ super(**options)
264
+ WidgetField.validate_arg(options, :options, { type: 'present' })
265
+ WidgetField.validate_arg(
266
+ options,
267
+ 'type',
268
+ {
269
+ type: 'contains',
270
+ value: [Types::FieldType::STRING]
271
+ }
272
+ )
273
+
274
+ @widget = 'RichText'
275
+ end
276
+ end
277
+
278
+ class TextAreaField < DynamicField
279
+ attr_accessor :widget, :rows
280
+
281
+ def initialize(options)
282
+ super(**options)
283
+ WidgetField.validate_arg(
284
+ options,
285
+ 'type',
286
+ {
287
+ type: 'contains',
288
+ value: [Types::FieldType::STRING]
289
+ }
290
+ )
291
+
292
+ @widget = 'TextArea'
293
+ @rows = options[:rows] || nil
294
+ end
295
+ end
296
+
297
+ class TextInputField < DynamicField
298
+ attr_accessor :widget
299
+
300
+ def initialize(options)
301
+ super(**options)
302
+ WidgetField.validate_arg(
303
+ options,
304
+ 'type',
305
+ {
306
+ type: 'contains',
307
+ value: [Types::FieldType::STRING]
308
+ }
309
+ )
310
+
311
+ @widget = 'TextInput'
312
+ end
313
+ end
314
+
315
+ class TextInputListField < DynamicField
316
+ attr_accessor :widget, :allow_duplicates, :allow_empty_values, :enable_reorder
317
+
318
+ def initialize(options)
319
+ super(**options)
320
+ WidgetField.validate_arg(
321
+ options,
322
+ 'type',
323
+ {
324
+ type: 'contains',
325
+ value: [Types::FieldType::STRING_LIST]
326
+ }
327
+ )
328
+
329
+ @widget = 'TextInput'
330
+ @allow_duplicates = options[:allow_duplicates] || nil
331
+ @allow_empty_values = options[:allow_empty_values] || nil
332
+ @enable_reorder = options[:enable_reorder] || nil
333
+ end
334
+ end
335
+
336
+ class UserDropdownField < DynamicField
337
+ attr_accessor :widget
338
+
339
+ def initialize(options)
340
+ super(**options)
341
+ WidgetField.validate_arg(options, :options, { type: 'present' })
342
+ WidgetField.validate_arg(
343
+ options,
344
+ 'type',
345
+ {
346
+ type: 'contains',
347
+ value: [Types::FieldType::STRING, Types::FieldType::STRING_LIST]
348
+ }
349
+ )
350
+
351
+ @widget = 'UserDropdown'
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end