forest_admin_datasource_customizer 1.0.0.pre.beta.21 → 1.0.0.pre.beta.58
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/forest_admin_datasource_customizer.gemspec +3 -2
- data/lib/forest_admin_datasource_customizer/collection_customizer.rb +292 -5
- data/lib/forest_admin_datasource_customizer/context/agent_customization_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/context/collection_customization_context.rb +15 -0
- data/lib/forest_admin_datasource_customizer/context/relaxed_wrappers/relaxed_collection.rb +50 -0
- data/lib/forest_admin_datasource_customizer/context/relaxed_wrappers/relaxed_data_source.rb +18 -0
- data/lib/forest_admin_datasource_customizer/datasource_customizer.rb +43 -13
- data/lib/forest_admin_datasource_customizer/decorators/action/action_collection_decorator.rb +137 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/base_action.rb +67 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/context/action_context.rb +56 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/context/action_context_single.rb +26 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/dynamic_field.rb +50 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/result_builder.rb +68 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/types/action_scope.rb +15 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/types/field_type.rb +35 -0
- data/lib/forest_admin_datasource_customizer/decorators/action/widget_field.rb +357 -0
- data/lib/forest_admin_datasource_customizer/decorators/binary/binary_collection_decorator.rb +215 -0
- data/lib/forest_admin_datasource_customizer/decorators/binary/binary_helper.rb +17 -0
- data/lib/forest_admin_datasource_customizer/decorators/chart/chart_collection_decorator.rb +41 -0
- data/lib/forest_admin_datasource_customizer/decorators/chart/chart_context.rb +33 -0
- data/lib/forest_admin_datasource_customizer/decorators/chart/chart_datasource_decorator.rb +46 -0
- data/lib/forest_admin_datasource_customizer/decorators/chart/result_builder.rb +148 -0
- data/lib/forest_admin_datasource_customizer/decorators/computed/compute_collection_decorator.rb +115 -0
- data/lib/forest_admin_datasource_customizer/decorators/computed/computed_definition.rb +21 -0
- data/lib/forest_admin_datasource_customizer/decorators/computed/utils/computed_field.rb +74 -0
- data/lib/forest_admin_datasource_customizer/decorators/computed/utils/flattener.rb +49 -0
- data/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb +33 -4
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_aggregate_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_create_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_delete_context.rb +12 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_list_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_update_context.rb +12 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_aggregate_context.rb +20 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_create_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_delete_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_list_context.rb +19 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/before/hook_before_update_context.rb +19 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/context/hook_context.rb +22 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator.rb +95 -0
- data/lib/forest_admin_datasource_customizer/decorators/hook/hooks.rb +26 -0
- data/lib/forest_admin_datasource_customizer/decorators/operators_emulate/operators_emulate_collection_decorator.rb +118 -0
- data/lib/forest_admin_datasource_customizer/decorators/operators_equivalence/operators_equivalence_collection_decorator.rb +50 -0
- data/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb +16 -0
- data/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb +16 -0
- data/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb +17 -0
- data/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator.rb +49 -0
- data/lib/forest_admin_datasource_customizer/decorators/publication/publication_collection_decorator.rb +95 -0
- data/lib/forest_admin_datasource_customizer/decorators/publication/publication_datasource_decorator.rb +57 -0
- data/lib/forest_admin_datasource_customizer/decorators/relation/relation_collection_decorator.rb +268 -0
- data/lib/forest_admin_datasource_customizer/decorators/rename_collection/rename_collection_datasource_decorator.rb +70 -0
- data/lib/forest_admin_datasource_customizer/decorators/rename_collection/rename_collection_decorator.rb +37 -0
- data/lib/forest_admin_datasource_customizer/decorators/rename_field/rename_field_collection_decorator.rb +190 -0
- data/lib/forest_admin_datasource_customizer/decorators/schema/schema_collection_decorator.rb +21 -0
- data/lib/forest_admin_datasource_customizer/decorators/search/search_collection_decorator.rb +135 -0
- data/lib/forest_admin_datasource_customizer/decorators/segment/segment_collection_decorator.rb +60 -0
- data/lib/forest_admin_datasource_customizer/decorators/sort/sort_collection_decorator.rb +127 -0
- data/lib/forest_admin_datasource_customizer/decorators/validation/validation_collection_decorator.rb +82 -0
- data/lib/forest_admin_datasource_customizer/decorators/write/create_relations/create_relations_collection_decorator.rb +75 -0
- data/lib/forest_admin_datasource_customizer/decorators/write/update_relations/update_relations_collection_decorator.rb +96 -0
- data/lib/forest_admin_datasource_customizer/decorators/write/write_datasource_decorator.rb +14 -0
- data/lib/forest_admin_datasource_customizer/decorators/write/write_replace/write_customization_context.rb +18 -0
- data/lib/forest_admin_datasource_customizer/decorators/write/write_replace/write_replace_collection_decorator.rb +125 -0
- data/lib/forest_admin_datasource_customizer/plugins/add_external_relation.rb +27 -0
- data/lib/forest_admin_datasource_customizer/plugins/import_field.rb +74 -0
- data/lib/forest_admin_datasource_customizer/version.rb +1 -1
- metadata +84 -5
- 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
|
data/lib/forest_admin_datasource_customizer/decorators/action/context/action_context_single.rb
ADDED
@@ -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,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
|