Class: Inquirex::DSL::StepBuilder
- Inherits:
-
Object
- Object
- Inquirex::DSL::StepBuilder
- Includes:
- RuleHelpers
- Defined in:
- lib/inquirex/dsl/step_builder.rb
Overview
Builds a single Node from a step DSL block. Used by FlowBuilder for each verb (ask, say, header, btw, warning, confirm). Includes RuleHelpers for transition conditions and skip_if expressions.
Instance Method Summary collapse
-
#accumulate(target, lookup: nil, per_selection: nil, per_unit: nil, flat: nil) ⇒ Object
Declares how this step's answer contributes to a named accumulator.
-
#build(id) ⇒ Node
Builds the Node for the given step id.
-
#compute {|Answers| ... } ⇒ Object
Registers a compute block: auto-calculates a value from answers, not shown to user.
-
#default(value = nil, &block) ⇒ Object
Sets a default value for this step (shown pre-filled; user can change it).
-
#initialize(verb) ⇒ StepBuilder
constructor
A new instance of StepBuilder.
-
#max(value) ⇒ void
Declares the inclusive upper bound of a numeric step.
-
#min(value) ⇒ void
Declares the inclusive lower bound of a numeric step.
-
#optional(value = true) ⇒ void
Declares this step skippable — the inverse of #required, and the form most flows want.
-
#options(list) ⇒ Object
Sets the list of options for :enum or :multi_enum steps.
-
#price(**kwargs) ⇒ Object
Sugar for the common
:priceaccumulator. -
#question(text) ⇒ Object
Sets the prompt/question text for collecting steps.
-
#required(value = true) ⇒ Object
Declares whether the user must answer this step (true by default).
-
#skip_if(rule) ⇒ Object
Sets a rule that skips this step entirely when true.
-
#step_size(value) ⇒ void
Declares the increment a numeric step's stepper arrows move by.
-
#text(content) ⇒ Object
Sets the display text for non-collecting steps (say/header/btw/warning).
-
#transition(to:, if_rule: nil, requires_server: false) ⇒ Object
Adds a conditional transition.
-
#type(value) ⇒ Object
Sets the input data type for :ask steps.
-
#widget(type:, target: :desktop, **opts) ⇒ Object
Sets a rendering hint for the given target context.
Methods included from RuleHelpers
#all, #any, #contains, #equals, #greater_than, #less_than, #not_empty
Constructor Details
#initialize(verb) ⇒ StepBuilder
Returns a new instance of StepBuilder.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/inquirex/dsl/step_builder.rb', line 11 def initialize(verb) @verb = verb @type = nil @question = nil @text = nil @options = nil @transitions = [] @skip_if = nil @default = nil @required = true @requiredness = nil @compute = nil @widget_hints = {} @accumulations = [] end |
Instance Method Details
#accumulate(target, lookup: nil, per_selection: nil, per_unit: nil, flat: nil) ⇒ Object
Declares how this step's answer contributes to a named accumulator. Exactly one shape key should be provided:
lookup: Hash of answer_value => amount (for :enum)
per_selection: Hash of option_value => amount (for :multi_enum)
per_unit: Numeric rate (multiplied by the numeric answer)
flat: Numeric (added when the step has any answer)
39 40 41 42 |
# File 'lib/inquirex/dsl/step_builder.rb', line 39 def accumulate(target, lookup: nil, per_selection: nil, per_unit: nil, flat: nil) shape, payload = pick_accumulator_shape(lookup:, per_selection:, per_unit:, flat:) @accumulations << Accumulation.new(target:, shape:, payload:) end |
#build(id) ⇒ Node
Builds the Node for the given step id.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/inquirex/dsl/step_builder.rb', line 229 def build(id) Node.new( id:, verb: @verb, type: resolve_type, question: @question, text: @text, options: @options, transitions: @transitions, skip_if: @skip_if, default: @default, required: @required, min: @min, max: @max, step_size: @step_size, widget_hints: , accumulations: @accumulations ) end |
#compute {|Answers| ... } ⇒ Object
Registers a compute block: auto-calculates a value from answers, not shown to user. The computed value is stored server-side only and stripped from JSON serialization.
176 177 178 |
# File 'lib/inquirex/dsl/step_builder.rb', line 176 def compute(&block) @compute = block end |
#default(value = nil, &block) ⇒ Object
Sets a default value for this step (shown pre-filled; user can change it).
Can be a static value or a proc receiving collected answers so far.
On a required false step the default is also what Engine#skip records
into the answers when the user skips the question.
123 124 125 |
# File 'lib/inquirex/dsl/step_builder.rb', line 123 def default(value = nil, &block) @default = block || value end |
#max(value) ⇒ void
This method returns an undefined value.
Declares the inclusive upper bound of a numeric step.
205 206 207 |
# File 'lib/inquirex/dsl/step_builder.rb', line 205 def max(value) @max = value end |
#min(value) ⇒ void
This method returns an undefined value.
Declares the inclusive lower bound of a numeric step.
Only meaningful for :integer, :decimal and :currency; declaring it
on any other type raises at build time rather than being ignored.
196 197 198 |
# File 'lib/inquirex/dsl/step_builder.rb', line 196 def min(value) @min = value end |
#optional(value = true) ⇒ void
This method returns an undefined value.
Declares this step skippable — the inverse of #required, and the form
most flows want. Since steps are required by default, required true is
a no-op and the keyword only ever appears as required false; optional
says the same thing without the double negative.
Sugar only: both spellings serialize to the single wire field
"required": false, so a definition round-trips identically however it
was authored and no consumer has to learn a second key.
168 169 170 |
# File 'lib/inquirex/dsl/step_builder.rb', line 168 def optional(value = true) assign_requiredness(:optional, value ? false : true) end |
#options(list) ⇒ Object
Sets the list of options for :enum or :multi_enum steps. Accepts an Array (option keys) or a Hash (key => label).
81 82 83 |
# File 'lib/inquirex/dsl/step_builder.rb', line 81 def (list) @options = list end |
#price(**kwargs) ⇒ Object
Sugar for the common :price accumulator. Accepts either a shape keyword
(lookup:, per_selection:, per_unit:, flat:) or — when given plain
option=>amount keys — treats it as a lookup. So both work:
price single: 200, mfj: 400 # => lookup
price per_unit: 25 # => per_unit
price lookup: { single: 200, ... } # => lookup (explicit)
51 52 53 54 55 56 57 58 |
# File 'lib/inquirex/dsl/step_builder.rb', line 51 def price(**kwargs) shape_keys = %i[lookup per_selection per_unit flat] if kwargs.keys.intersect?(shape_keys) accumulate(:price, **kwargs.slice(*shape_keys)) else accumulate(:price, lookup: kwargs) end end |
#question(text) ⇒ Object
Sets the prompt/question text for collecting steps.
68 69 70 |
# File 'lib/inquirex/dsl/step_builder.rb', line 68 def question(text) @question = text end |
#required(value = true) ⇒ Object
Declares whether the user must answer this step (true by default).
required false marks the question as optional: renderers show a small
Skip control, and Engine#skip records the step's default (when one is
declared) into the answers while marking the step as skipped.
143 144 145 |
# File 'lib/inquirex/dsl/step_builder.rb', line 143 def required(value = true) assign_requiredness(:required, value ? true : false) end |
#skip_if(rule) ⇒ Object
Sets a rule that skips this step entirely when true. The step is omitted from the user's path and no answer is recorded.
113 114 115 |
# File 'lib/inquirex/dsl/step_builder.rb', line 113 def skip_if(rule) @skip_if = rule end |
#step_size(value) ⇒ void
This method returns an undefined value.
Declares the increment a numeric step's stepper arrows move by.
Defaults, when unset, to 1 for :integer and 0.01 for :decimal and
:currency — the renderer applies that, not this builder, so an unset
value stays absent from the wire format.
Spelled step_size rather than step because a step is the unit of
a flow; steps.employees.step would read as a nested flow step.
221 222 223 |
# File 'lib/inquirex/dsl/step_builder.rb', line 221 def step_size(value) @step_size = value end |
#text(content) ⇒ Object
Sets the display text for non-collecting steps (say/header/btw/warning).
74 75 76 |
# File 'lib/inquirex/dsl/step_builder.rb', line 74 def text(content) @text = content end |
#transition(to:, if_rule: nil, requires_server: false) ⇒ Object
Adds a conditional transition. First matching transition wins.
105 106 107 |
# File 'lib/inquirex/dsl/step_builder.rb', line 105 def transition(to:, if_rule: nil, requires_server: false) @transitions << Transition.new(target: to, rule: if_rule, requires_server:) end |
#type(value) ⇒ Object
Sets the input data type for :ask steps.
62 63 64 |
# File 'lib/inquirex/dsl/step_builder.rb', line 62 def type(value) @type = value end |
#widget(type:, target: :desktop, **opts) ⇒ Object
Sets a rendering hint for the given target context. Recognized targets: :desktop, :mobile, :tty (and any future targets).
96 97 98 |
# File 'lib/inquirex/dsl/step_builder.rb', line 96 def (type:, target: :desktop, **opts) @widget_hints[target.to_sym] = WidgetHint.new(type:, options: opts) end |