phlexi-display 0.0.1 → 0.0.2
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/lib/phlexi/display/base.rb +35 -158
- data/lib/phlexi/display/components/base.rb +1 -14
- data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
- data/lib/phlexi/display/components/date_time.rb +49 -0
- data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
- data/lib/phlexi/display/components/hint.rb +1 -1
- data/lib/phlexi/display/components/label.rb +3 -15
- data/lib/phlexi/display/components/number.rb +37 -0
- data/lib/phlexi/display/components/placeholder.rb +15 -0
- data/lib/phlexi/display/components/string.rb +17 -0
- data/lib/phlexi/display/components/wrapper.rb +4 -18
- data/lib/phlexi/display/field_options/associations.rb +2 -2
- data/lib/phlexi/display/field_options/attachments.rb +21 -0
- data/lib/phlexi/display/field_options/description.rb +22 -0
- data/lib/phlexi/display/field_options/hints.rb +1 -1
- data/lib/phlexi/display/field_options/inferred_types.rb +26 -52
- data/lib/phlexi/display/field_options/{placeholder.rb → placeholders.rb} +2 -2
- data/lib/phlexi/display/field_options/themes.rb +45 -120
- data/lib/phlexi/display/structure/dom.rb +7 -27
- data/lib/phlexi/display/structure/field_builder.rb +75 -151
- data/lib/phlexi/display/structure/field_collection.rb +5 -20
- data/lib/phlexi/display/structure/namespace.rb +22 -34
- data/lib/phlexi/display/structure/namespace_collection.rb +1 -9
- data/lib/phlexi/display/structure/node.rb +9 -3
- data/lib/phlexi/display/version.rb +1 -1
- data/lib/phlexi/display.rb +0 -1
- metadata +11 -31
- data/lib/phlexi/display/components/checkbox.rb +0 -48
- data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
- data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
- data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
- data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
- data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
- data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
- data/lib/phlexi/display/components/file_input.rb +0 -32
- data/lib/phlexi/display/components/full_error.rb +0 -21
- data/lib/phlexi/display/components/input.rb +0 -84
- data/lib/phlexi/display/components/input_array.rb +0 -45
- data/lib/phlexi/display/components/radio_button.rb +0 -41
- data/lib/phlexi/display/components/select.rb +0 -69
- data/lib/phlexi/display/components/submit_button.rb +0 -41
- data/lib/phlexi/display/components/textarea.rb +0 -34
- data/lib/phlexi/display/field_options/autofocus.rb +0 -18
- data/lib/phlexi/display/field_options/collection.rb +0 -54
- data/lib/phlexi/display/field_options/disabled.rb +0 -18
- data/lib/phlexi/display/field_options/errors.rb +0 -92
- data/lib/phlexi/display/field_options/length.rb +0 -53
- data/lib/phlexi/display/field_options/limit.rb +0 -66
- data/lib/phlexi/display/field_options/min_max.rb +0 -92
- data/lib/phlexi/display/field_options/multiple.rb +0 -65
- data/lib/phlexi/display/field_options/pattern.rb +0 -38
- data/lib/phlexi/display/field_options/readonly.rb +0 -18
- data/lib/phlexi/display/field_options/required.rb +0 -37
- data/lib/phlexi/display/field_options/validators.rb +0 -48
@@ -1,92 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Errors
|
7
|
-
def custom_error(error)
|
8
|
-
options[:error] = error
|
9
|
-
self
|
10
|
-
end
|
11
|
-
|
12
|
-
def error
|
13
|
-
error_text if has_errors?
|
14
|
-
end
|
15
|
-
|
16
|
-
def full_error
|
17
|
-
full_error_text if has_errors?
|
18
|
-
end
|
19
|
-
|
20
|
-
def has_errors?
|
21
|
-
object_with_errors? || !object && has_custom_error?
|
22
|
-
end
|
23
|
-
|
24
|
-
def show_errors?
|
25
|
-
options[:error] != false
|
26
|
-
end
|
27
|
-
|
28
|
-
def valid?
|
29
|
-
!has_errors? && has_value?
|
30
|
-
end
|
31
|
-
|
32
|
-
protected
|
33
|
-
|
34
|
-
def error_text
|
35
|
-
text = has_custom_error? ? options[:error] : errors.send(error_method)
|
36
|
-
|
37
|
-
"#{options[:error_prefix]} #{text}".lstrip
|
38
|
-
end
|
39
|
-
|
40
|
-
def full_error_text
|
41
|
-
has_custom_error? ? options[:error] : full_errors.send(error_method)
|
42
|
-
end
|
43
|
-
|
44
|
-
def object_with_errors?
|
45
|
-
object&.respond_to?(:errors) && errors.present?
|
46
|
-
end
|
47
|
-
|
48
|
-
def error_method
|
49
|
-
options[:error_method] || :first
|
50
|
-
end
|
51
|
-
|
52
|
-
def errors
|
53
|
-
@errors ||= (errors_on_attribute + errors_on_association).compact
|
54
|
-
end
|
55
|
-
|
56
|
-
def full_errors
|
57
|
-
@full_errors ||= (full_errors_on_attribute + full_errors_on_association).compact
|
58
|
-
end
|
59
|
-
|
60
|
-
def errors_on_attribute
|
61
|
-
object.errors[key] || []
|
62
|
-
end
|
63
|
-
|
64
|
-
def full_errors_on_attribute
|
65
|
-
object.errors.full_messages_for(key)
|
66
|
-
end
|
67
|
-
|
68
|
-
def errors_on_association
|
69
|
-
reflection ? object.errors[reflection.name] : []
|
70
|
-
end
|
71
|
-
|
72
|
-
def full_errors_on_association
|
73
|
-
reflection ? object.errors.full_messages_for(reflection.name) : []
|
74
|
-
end
|
75
|
-
|
76
|
-
def has_custom_error?
|
77
|
-
options[:error].is_a?(String)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Determines if the associated object is in a valid state
|
81
|
-
#
|
82
|
-
# An object is considered valid if it is persisted and has no errors.
|
83
|
-
#
|
84
|
-
# @return [Boolean] true if the object is persisted and has no errors, false otherwise
|
85
|
-
def object_valid?
|
86
|
-
object.respond_to?(:persisted?) && object.persisted? &&
|
87
|
-
object.respond_to?(:errors) && !object.errors.empty?
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Length
|
7
|
-
def minlength(minlength = nil)
|
8
|
-
if minlength.nil?
|
9
|
-
options[:minlength] = options.fetch(:minlength) { calculate_minlength }
|
10
|
-
else
|
11
|
-
options[:minlength] = minlength
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def maxlength(maxlength = nil)
|
17
|
-
if maxlength.nil?
|
18
|
-
options[:maxlength] = options.fetch(:maxlength) { calculate_maxlength }
|
19
|
-
else
|
20
|
-
options[:maxlength] = maxlength
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def calculate_minlength
|
28
|
-
minimum_length_value_from(find_length_validator)
|
29
|
-
end
|
30
|
-
|
31
|
-
def minimum_length_value_from(length_validator)
|
32
|
-
if length_validator
|
33
|
-
length_validator.options[:is] || length_validator.options[:minimum]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def calculate_maxlength
|
38
|
-
maximum_length_value_from(find_length_validator)
|
39
|
-
end
|
40
|
-
|
41
|
-
def maximum_length_value_from(length_validator)
|
42
|
-
if length_validator
|
43
|
-
length_validator.options[:is] || length_validator.options[:maximum]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def find_length_validator
|
48
|
-
find_validator(:length)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Limit
|
7
|
-
def limit(limit = nil)
|
8
|
-
if limit.nil?
|
9
|
-
options[:limit] = options.fetch(:limit) { calculate_limit }
|
10
|
-
else
|
11
|
-
options[:limit] = limit
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def calculate_limit
|
19
|
-
return unless multiple?
|
20
|
-
|
21
|
-
limit_from_validators = [
|
22
|
-
limit_from_length_validator,
|
23
|
-
limit_from_inclusion_validator
|
24
|
-
].compact.min
|
25
|
-
|
26
|
-
limit_from_validators || limit_from_db_column
|
27
|
-
end
|
28
|
-
|
29
|
-
def limit_from_length_validator
|
30
|
-
length_validator = find_validator(:length)
|
31
|
-
return unless length_validator
|
32
|
-
|
33
|
-
length_validator.options[:maximum]
|
34
|
-
end
|
35
|
-
|
36
|
-
def limit_from_inclusion_validator
|
37
|
-
return unless has_validators?
|
38
|
-
|
39
|
-
inclusion_validator = find_validator(:inclusion)
|
40
|
-
return unless inclusion_validator
|
41
|
-
|
42
|
-
in_option = inclusion_validator.options[:in]
|
43
|
-
in_option.is_a?(Array) ? in_option.size : nil
|
44
|
-
end
|
45
|
-
|
46
|
-
def limit_from_db_column
|
47
|
-
return unless object.class.respond_to?(:columns_hash)
|
48
|
-
|
49
|
-
column = object.class.columns_hash[key.to_s]
|
50
|
-
return unless column
|
51
|
-
|
52
|
-
case object.class.connection.adapter_name.downcase
|
53
|
-
when "postgresql"
|
54
|
-
if column.array?
|
55
|
-
# Check if there's a limit on the array size
|
56
|
-
column.limit
|
57
|
-
elsif column.type == :string && column.sql_type.include?("[]")
|
58
|
-
# For string arrays, extract the limit if specified
|
59
|
-
column.sql_type.match(/\[(\d+)\]/)&.captures&.first&.to_i
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module MinMax
|
7
|
-
def min(min_value = nil)
|
8
|
-
if min_value.nil?
|
9
|
-
options[:min] = options.fetch(:min) { calculate_min }
|
10
|
-
else
|
11
|
-
options[:min] = min_value
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def max(max_value = nil)
|
17
|
-
if max_value.nil?
|
18
|
-
options[:max] = options.fetch(:max) { calculate_max }
|
19
|
-
else
|
20
|
-
options[:max] = max_value
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def step
|
26
|
-
1 if min || max
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def calculate_min
|
32
|
-
if (numericality_validator = find_numericality_validator)
|
33
|
-
get_min_from_validator(numericality_validator)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def calculate_max
|
38
|
-
if (numericality_validator = find_numericality_validator)
|
39
|
-
get_max_from_validator(numericality_validator)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def find_numericality_validator
|
44
|
-
find_validator(:numericality)
|
45
|
-
end
|
46
|
-
|
47
|
-
def get_min_from_validator(validator)
|
48
|
-
options = validator.options
|
49
|
-
min = if options.key?(:greater_than)
|
50
|
-
{value: options[:greater_than], exclusive: true}
|
51
|
-
elsif options.key?(:greater_than_or_equal_to)
|
52
|
-
{value: options[:greater_than_or_equal_to], exclusive: false}
|
53
|
-
end
|
54
|
-
evaluate_and_adjust_min(min)
|
55
|
-
end
|
56
|
-
|
57
|
-
def get_max_from_validator(validator)
|
58
|
-
options = validator.options
|
59
|
-
max = if options.key?(:less_than)
|
60
|
-
{value: options[:less_than], exclusive: true}
|
61
|
-
elsif options.key?(:less_than_or_equal_to)
|
62
|
-
{value: options[:less_than_or_equal_to], exclusive: false}
|
63
|
-
end
|
64
|
-
evaluate_and_adjust_max(max)
|
65
|
-
end
|
66
|
-
|
67
|
-
def evaluate_and_adjust_min(min)
|
68
|
-
return nil unless min
|
69
|
-
|
70
|
-
value = evaluate_numericality_validator_option(min[:value])
|
71
|
-
min[:exclusive] ? value + 1 : value
|
72
|
-
end
|
73
|
-
|
74
|
-
def evaluate_and_adjust_max(max)
|
75
|
-
return nil unless max
|
76
|
-
|
77
|
-
value = evaluate_numericality_validator_option(max[:value])
|
78
|
-
max[:exclusive] ? value - 1 : value
|
79
|
-
end
|
80
|
-
|
81
|
-
def evaluate_numericality_validator_option(option)
|
82
|
-
case option
|
83
|
-
when Proc
|
84
|
-
option.arity.zero? ? option.call : option.call(object)
|
85
|
-
else
|
86
|
-
option
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Multiple
|
7
|
-
def multiple?
|
8
|
-
options[:multiple] = options.fetch(:multiple) { calculate_multiple_field_value }
|
9
|
-
end
|
10
|
-
|
11
|
-
def multiple!(multiple = true)
|
12
|
-
options[:multiple] = multiple
|
13
|
-
self
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def calculate_multiple_field_value
|
19
|
-
return true if reflection&.macro == :has_many
|
20
|
-
return true if multiple_field_array_attribute?
|
21
|
-
|
22
|
-
check_multiple_field_from_validators
|
23
|
-
end
|
24
|
-
|
25
|
-
def multiple_field_array_attribute?
|
26
|
-
return false unless object.class.respond_to?(:columns_hash)
|
27
|
-
|
28
|
-
column = object.class.columns_hash[key.to_s]
|
29
|
-
return false unless column
|
30
|
-
|
31
|
-
case object.class.connection.adapter_name.downcase
|
32
|
-
when "postgresql"
|
33
|
-
column.array? || (column.type == :string && column.sql_type.include?("[]"))
|
34
|
-
end # || object.class.attribute_types[key.to_s].is_a?(ActiveRecord::Type::Serialized)
|
35
|
-
rescue
|
36
|
-
# Rails.logger.warn("Error checking multiple field array attribute: #{e.message}")
|
37
|
-
false
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_multiple_field_from_validators
|
41
|
-
inclusion_validator = find_validator(:inclusion)
|
42
|
-
length_validator = find_validator(:length)
|
43
|
-
|
44
|
-
return false unless inclusion_validator || length_validator
|
45
|
-
|
46
|
-
check_multiple_field_inclusion_validator(inclusion_validator) ||
|
47
|
-
check_multiple_field_length_validator(length_validator)
|
48
|
-
end
|
49
|
-
|
50
|
-
def check_multiple_field_inclusion_validator(validator)
|
51
|
-
return false unless validator
|
52
|
-
in_option = validator.options[:in]
|
53
|
-
return false unless in_option.is_a?(Array)
|
54
|
-
|
55
|
-
validator.options[:multiple] == true || (multiple_field_array_attribute? && in_option.size > 1)
|
56
|
-
end
|
57
|
-
|
58
|
-
def check_multiple_field_length_validator(validator)
|
59
|
-
return false unless validator
|
60
|
-
validator.options[:maximum].to_i > 1 if validator.options[:maximum]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Pattern
|
7
|
-
def pattern(pattern = nil)
|
8
|
-
if pattern.nil?
|
9
|
-
options[:pattern] = options.fetch(:pattern) { calculate_pattern }
|
10
|
-
else
|
11
|
-
options[:pattern] = pattern
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def calculate_pattern
|
19
|
-
if (pattern_validator = find_pattern_validator) && (with = pattern_validator.options[:with])
|
20
|
-
evaluate_format_validator_option(with).source
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def find_pattern_validator
|
25
|
-
find_validator(:format)
|
26
|
-
end
|
27
|
-
|
28
|
-
def evaluate_format_validator_option(option)
|
29
|
-
if option.respond_to?(:call)
|
30
|
-
option.call(object)
|
31
|
-
else
|
32
|
-
option
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Readonly
|
7
|
-
def readonly?
|
8
|
-
options[:readonly] == true
|
9
|
-
end
|
10
|
-
|
11
|
-
def readonly!(readonly = true)
|
12
|
-
options[:readonly] = readonly
|
13
|
-
self
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Required
|
7
|
-
def required?
|
8
|
-
options[:required] = options.fetch(:required) { calculate_required }
|
9
|
-
end
|
10
|
-
|
11
|
-
def required!(required = true)
|
12
|
-
options[:required] = required
|
13
|
-
self
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def calculate_required
|
19
|
-
if has_validators?
|
20
|
-
required_by_validators?
|
21
|
-
else
|
22
|
-
required_by_default?
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def required_by_validators?
|
27
|
-
(attribute_validators + reflection_validators).any? { |v| v.kind == :presence && valid_validator?(v) }
|
28
|
-
end
|
29
|
-
|
30
|
-
def required_by_default?
|
31
|
-
# TODO: get this from configuration
|
32
|
-
false
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module FieldOptions
|
6
|
-
module Validators
|
7
|
-
private
|
8
|
-
|
9
|
-
def has_validators?
|
10
|
-
@has_validators ||= object.class.respond_to?(:validators_on)
|
11
|
-
end
|
12
|
-
|
13
|
-
def attribute_validators
|
14
|
-
object.class.validators_on(key)
|
15
|
-
end
|
16
|
-
|
17
|
-
def reflection_validators
|
18
|
-
reflection ? object.class.validators_on(reflection.name) : []
|
19
|
-
end
|
20
|
-
|
21
|
-
def valid_validator?(validator)
|
22
|
-
!conditional_validators?(validator) && action_validator_match?(validator)
|
23
|
-
end
|
24
|
-
|
25
|
-
def conditional_validators?(validator)
|
26
|
-
validator.options.include?(:if) || validator.options.include?(:unless)
|
27
|
-
end
|
28
|
-
|
29
|
-
def action_validator_match?(validator)
|
30
|
-
return true unless validator.options.include?(:on)
|
31
|
-
|
32
|
-
case validator.options[:on]
|
33
|
-
when :save
|
34
|
-
true
|
35
|
-
when :create
|
36
|
-
!object.persisted?
|
37
|
-
when :update
|
38
|
-
object.persisted?
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def find_validator(kind)
|
43
|
-
attribute_validators.find { |v| v.kind == kind && valid_validator?(v) } if has_validators?
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|