Class: Compony::Intent
- Inherits:
-
Object
- Object
- Compony::Intent
- Defined in:
- lib/compony/intent.rb
Overview
An Intent is a a gateway to a component, along with relevant context, such as the comp and family, perhaps a resource, standalone name, feasibility etc.
The class provides tooling used by various Compony helpers used to point to other components in some way.
Note: The arguments label and style are not part of the button: hash, because they are processed by the Intent before affecting the button.
Instance Attribute Summary collapse
- #comp_class ⇒ Object readonly
- #data ⇒ Object readonly
Instance Method Summary collapse
-
#button_comp_opts ⇒ Object
Returns the options that are given to the initializer when creating a button from this intent.
-
#comp ⇒ Object
Instanciates the component and returns the instance.
- #feasibility_action ⇒ Object
- #feasibility_target ⇒ Object
-
#feasible? ⇒ Boolean
Returns whether this intent is feasible (no prevention).
-
#initialize(comp_name_or_cst_or_class, model_or_family_name_or_cst = nil, standalone_name: nil, name: nil, label: nil, style: nil, button: {}, path: nil, method: nil, data: nil, data_class: nil, feasibility_target: nil, feasibility_action: nil) ⇒ Intent
constructor
A new instance of Intent.
-
#label(model = nil, **label_opt_overrides) ⇒ Object
Returns the label of buttons produced by this intent.
- #method ⇒ Object
-
#model? ⇒ Boolean
Returns true for things like User.first, but false for things like :users or User.
-
#name ⇒ Object
Returns a name for this intent, consisting of comp and family name.
-
#path(model = nil, standalone_name: nil, **path_opt_overrides) ⇒ Object
Returns the path to the component.
-
#render(controller, parent_comp = nil, style: nil, **button_arg_overrides) ⇒ Object
Renders this intent into a button defined by
style.
Constructor Details
#initialize(comp_name_or_cst_or_class, model_or_family_name_or_cst = nil, standalone_name: nil, name: nil, label: nil, style: nil, button: {}, path: nil, method: nil, data: nil, data_class: nil, feasibility_target: nil, feasibility_action: nil) ⇒ Intent
Returns a new instance of Intent.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/compony/intent.rb', line 26 def initialize(comp_name_or_cst_or_class, model_or_family_name_or_cst = nil, standalone_name: nil, name: nil, label: nil, style: nil, button: {}, path: nil, method: nil, data: nil, data_class: nil, feasibility_target: nil, feasibility_action: nil) # Check for model / data @data = data @data ||= model_or_family_name_or_cst if model_or_family_name_or_cst.respond_to?(:model_name) @data_class = data_class # Figure out comp_class if comp_name_or_cst_or_class.is_a?(Class) && (comp_name_or_cst_or_class <= Compony::Component) # A class was given as the first argument @comp_class = comp_name_or_cst_or_class else # Build the constant from the first two arguments family_underscore_str = @data.respond_to?(:model_name) ? @data.model_name.plural : model_or_family_name_or_cst.to_s.underscore constant_str = "::Components::#{family_underscore_str.camelize}::#{comp_name_or_cst_or_class.to_s.camelize}" @comp_class = constant_str.constantize end # Store further arguments @name = name&.to_sym @standalone_name = standalone_name @label = label.is_a?(String) ? label : nil @label_opts = label.is_a?(Hash) ? label : {} @style = style&.to_sym @button_opts = @path = path.is_a?(String) ? path : nil @path_opts = path.is_a?(Hash) ? path : {} @method = method&.to_sym @feasibility_target = feasibility_target @feasibility_action = feasibility_action end |
Instance Attribute Details
#comp_class ⇒ Object (readonly)
7 8 9 |
# File 'lib/compony/intent.rb', line 7 def comp_class @comp_class end |
#data ⇒ Object (readonly)
8 9 10 |
# File 'lib/compony/intent.rb', line 8 def data @data end |
Instance Method Details
#button_comp_opts ⇒ Object
Returns the options that are given to the initializer when creating a button from this intent.
121 122 123 124 125 126 127 128 129 |
# File 'lib/compony/intent.rb', line 121 def return { label:, href: feasible? ? path : nil, method:, class: feasible? ? nil : 'disabled', title: feasible? ? nil : feasibility_target.(feasibility_action).presence }.deep_merge(@button_opts) end |
#comp ⇒ Object
Instanciates the component and returns the instance. If data and/or data_class were specified when instantiating this intent, they are passed.
All given arguments will be given to the component's initializer, also overriding data and data_class if present.
77 78 79 |
# File 'lib/compony/intent.rb', line 77 def comp(*, **) return @comp ||= @comp_class.new(*, data: @data, data_class: @data_class, **) end |
#feasibility_action ⇒ Object
110 111 112 |
# File 'lib/compony/intent.rb', line 110 def feasibility_action @feasibility_action.presence || comp_class.comp_name.to_sym end |
#feasibility_target ⇒ Object
106 107 108 |
# File 'lib/compony/intent.rb', line 106 def feasibility_target @feasibility_target.presence || model? ? @data : nil end |
#feasible? ⇒ Boolean
Returns whether this intent is feasible (no prevention)
115 116 117 118 |
# File 'lib/compony/intent.rb', line 115 def feasible? return true if feasibility_target.blank? || feasibility_action.blank? return feasibility_target.feasible?(feasibility_action) end |
#label(model = nil, **label_opt_overrides) ⇒ Object
Returns the label of buttons produced by this intent.
97 98 99 100 |
# File 'lib/compony/intent.rb', line 97 def label(model = nil, *, **label_opt_overrides) label_opts = @label_opts.deep_merge(label_opt_overrides) @label.presence || comp.label(model || (model? ? @data : nil), *, **label_opts) end |
#method ⇒ Object
102 103 104 |
# File 'lib/compony/intent.rb', line 102 def method @method || :get end |
#model? ⇒ Boolean
Returns true for things like User.first, but false for things like :users or User
70 71 72 73 |
# File 'lib/compony/intent.rb', line 70 def model? @model = @data.respond_to?(:model_name) && !@data.is_a?(Class) if @model.nil? return @model end |
#name ⇒ Object
Returns a name for this intent, consisting of comp and family name. Can be overriden in the constructor. Example: :show_users, :destroy_sessions
92 93 94 |
# File 'lib/compony/intent.rb', line 92 def name @name.presence || :"#{comp_class.comp_name}_#{comp_class.family_name}" end |
#path(model = nil, standalone_name: nil, **path_opt_overrides) ⇒ Object
Returns the path to the component. Additional arguments are passed to the component's path block, which typically passes them to the Rails path helper.
85 86 87 88 |
# File 'lib/compony/intent.rb', line 85 def path(model = nil, *, standalone_name: nil, **path_opt_overrides) path_opts = @path_opts.deep_merge(path_opt_overrides) comp.path(model || (model? ? @data : nil), standalone_name: standalone_name || @standalone_name, **path_opts) end |
#render(controller, parent_comp = nil, style: nil, **button_arg_overrides) ⇒ Object
Renders this intent into a button defined by style.
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/compony/intent.rb', line 136 def render(controller, parent_comp = nil, style: nil, **) # Abort if not authorized return nil unless comp.standalone_access_permitted_for?(controller, standalone_name: @standalone_name, verb: method) # Prepare opts ||= Compony.(*[style || @style].compact) = .merge() # Perform render if parent_comp return parent_comp.sub_comp(, **).render(controller) else .new(**).render(controller) end end |