phlexi-display 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/phlexi/display/base.rb +35 -158
  3. data/lib/phlexi/display/components/base.rb +1 -14
  4. data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
  5. data/lib/phlexi/display/components/date_time.rb +49 -0
  6. data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
  7. data/lib/phlexi/display/components/hint.rb +1 -1
  8. data/lib/phlexi/display/components/label.rb +3 -15
  9. data/lib/phlexi/display/components/number.rb +37 -0
  10. data/lib/phlexi/display/components/placeholder.rb +15 -0
  11. data/lib/phlexi/display/components/string.rb +17 -0
  12. data/lib/phlexi/display/components/wrapper.rb +4 -18
  13. data/lib/phlexi/display/field_options/associations.rb +2 -2
  14. data/lib/phlexi/display/field_options/attachments.rb +21 -0
  15. data/lib/phlexi/display/field_options/description.rb +22 -0
  16. data/lib/phlexi/display/field_options/hints.rb +1 -1
  17. data/lib/phlexi/display/field_options/inferred_types.rb +26 -52
  18. data/lib/phlexi/display/field_options/{placeholder.rb → placeholders.rb} +2 -2
  19. data/lib/phlexi/display/field_options/themes.rb +45 -120
  20. data/lib/phlexi/display/structure/dom.rb +7 -27
  21. data/lib/phlexi/display/structure/field_builder.rb +75 -151
  22. data/lib/phlexi/display/structure/field_collection.rb +5 -20
  23. data/lib/phlexi/display/structure/namespace.rb +22 -34
  24. data/lib/phlexi/display/structure/namespace_collection.rb +1 -9
  25. data/lib/phlexi/display/structure/node.rb +9 -3
  26. data/lib/phlexi/display/version.rb +1 -1
  27. data/lib/phlexi/display.rb +0 -1
  28. metadata +11 -31
  29. data/lib/phlexi/display/components/checkbox.rb +0 -48
  30. data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
  31. data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
  32. data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
  33. data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
  34. data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
  35. data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
  36. data/lib/phlexi/display/components/file_input.rb +0 -32
  37. data/lib/phlexi/display/components/full_error.rb +0 -21
  38. data/lib/phlexi/display/components/input.rb +0 -84
  39. data/lib/phlexi/display/components/input_array.rb +0 -45
  40. data/lib/phlexi/display/components/radio_button.rb +0 -41
  41. data/lib/phlexi/display/components/select.rb +0 -69
  42. data/lib/phlexi/display/components/submit_button.rb +0 -41
  43. data/lib/phlexi/display/components/textarea.rb +0 -34
  44. data/lib/phlexi/display/field_options/autofocus.rb +0 -18
  45. data/lib/phlexi/display/field_options/collection.rb +0 -54
  46. data/lib/phlexi/display/field_options/disabled.rb +0 -18
  47. data/lib/phlexi/display/field_options/errors.rb +0 -92
  48. data/lib/phlexi/display/field_options/length.rb +0 -53
  49. data/lib/phlexi/display/field_options/limit.rb +0 -66
  50. data/lib/phlexi/display/field_options/min_max.rb +0 -92
  51. data/lib/phlexi/display/field_options/multiple.rb +0 -65
  52. data/lib/phlexi/display/field_options/pattern.rb +0 -38
  53. data/lib/phlexi/display/field_options/readonly.rb +0 -18
  54. data/lib/phlexi/display/field_options/required.rb +0 -37
  55. 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