mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-23 15:19:38 +02:00
Multi-step account forms + clearer balance editing (#2427)
* Initial multi-step property form * Improve form structure, add optional tooltip help icons to form fields * Add basic inline alert component * Clean up and improve property form lifecycle * Implement Account status concept * Lint fixes * Remove whitespace * Balance editing, scope updates for account * Passing tests * Fix brakeman warning * Remove stale columns * data constraint tweaks * Redundant property
This commit is contained in:
parent
ba7e8d3893
commit
662f2c04ce
66 changed files with 1036 additions and 427 deletions
|
@ -1,42 +1,38 @@
|
|||
class StyledFormBuilder < ActionView::Helpers::FormBuilder
|
||||
# Fields that visually inherit from "text field"
|
||||
class_attribute :text_field_helpers, default: field_helpers - [ :label, :check_box, :radio_button, :fields_for, :fields, :hidden_field, :file_field ]
|
||||
|
||||
# Wraps "text" inputs with custom structure + base styles
|
||||
text_field_helpers.each do |selector|
|
||||
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
||||
def #{selector}(method, options = {})
|
||||
merged_options = { class: "form-field__input" }.merge(options)
|
||||
label = build_label(method, options)
|
||||
field = super(method, merged_options)
|
||||
form_options = options.slice(:label, :label_tooltip, :inline, :container_class, :required)
|
||||
html_options = options.except(:label, :label_tooltip, :inline, :container_class)
|
||||
|
||||
build_styled_field(label, field, merged_options)
|
||||
build_field(method, form_options, html_options) do |merged_options|
|
||||
super(method, merged_options)
|
||||
end
|
||||
end
|
||||
RUBY_EVAL
|
||||
end
|
||||
|
||||
def radio_button(method, tag_value, options = {})
|
||||
merged_options = { class: "form-field__radio" }.merge(options)
|
||||
|
||||
super(method, tag_value, merged_options)
|
||||
end
|
||||
|
||||
def select(method, choices, options = {}, html_options = {})
|
||||
merged_html_options = { class: "form-field__input" }.merge(html_options)
|
||||
field_options = normalize_options(options, html_options)
|
||||
|
||||
label = build_label(method, options.merge(required: merged_html_options[:required]))
|
||||
field = super(method, choices, options, merged_html_options)
|
||||
|
||||
build_styled_field(label, field, options, remove_padding_right: true)
|
||||
build_field(method, field_options, html_options) do |merged_html_options|
|
||||
super(method, choices, options, merged_html_options)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
|
||||
merged_html_options = { class: "form-field__input" }.merge(html_options)
|
||||
field_options = normalize_options(options, html_options)
|
||||
|
||||
label = build_label(method, options.merge(required: merged_html_options[:required]))
|
||||
field = super(method, collection, value_method, text_method, options, merged_html_options)
|
||||
|
||||
build_styled_field(label, field, options, remove_padding_right: true)
|
||||
build_field(method, field_options, html_options) do |merged_html_options|
|
||||
super(method, collection, value_method, text_method, options, merged_html_options)
|
||||
end
|
||||
end
|
||||
|
||||
def money_field(amount_method, options = {})
|
||||
|
@ -48,22 +44,15 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
|
|||
}
|
||||
end
|
||||
|
||||
# A custom styled "toggle" switch input. Underlying input is a `check_box` (uses same API)
|
||||
def toggle(method, options = {}, checked_value = "1", unchecked_value = "0")
|
||||
if object
|
||||
id = "#{object.id}_#{object_name}_#{method}"
|
||||
name = "#{object_name}[#{method}]"
|
||||
checked = object.send(method)
|
||||
else
|
||||
id = "#{method}_toggle_id"
|
||||
name = method
|
||||
checked = options[:checked]
|
||||
end
|
||||
field_id = field_id(method)
|
||||
field_name = field_name(method)
|
||||
checked = object ? object.send(method) : options[:checked]
|
||||
|
||||
@template.render(
|
||||
ToggleComponent.new(
|
||||
id: id,
|
||||
name: name,
|
||||
id: field_id,
|
||||
name: field_name,
|
||||
checked: checked,
|
||||
disabled: options[:disabled],
|
||||
checked_value: checked_value,
|
||||
|
@ -74,7 +63,6 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
|
|||
end
|
||||
|
||||
def submit(value = nil, options = {})
|
||||
# Rails superclass logic to extract the submit text
|
||||
value, options = nil, value if value.is_a?(Hash)
|
||||
value ||= submit_default_value
|
||||
|
||||
|
@ -88,16 +76,39 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
|
|||
end
|
||||
|
||||
private
|
||||
def build_styled_field(label, field, options, remove_padding_right: false)
|
||||
if options[:inline]
|
||||
label + field
|
||||
else
|
||||
@template.tag.div class: [ "form-field", options[:container_class], ("pr-0" if remove_padding_right) ] do
|
||||
label + field
|
||||
def build_field(method, options = {}, html_options = {}, &block)
|
||||
if options[:inline] || options[:label] == false
|
||||
return yield({ class: "form-field__input" }.merge(html_options))
|
||||
end
|
||||
|
||||
label_element = build_label(method, options)
|
||||
field_element = yield({ class: "form-field__input" }.merge(html_options))
|
||||
|
||||
container_classes = [ "form-field", options[:container_class] ].compact
|
||||
|
||||
@template.tag.div class: container_classes do
|
||||
if options[:label_tooltip]
|
||||
@template.tag.div(class: "form-field__header") do
|
||||
label_element +
|
||||
@template.tag.div(class: "form-field__actions") do
|
||||
build_tooltip(options[:label_tooltip])
|
||||
end
|
||||
end +
|
||||
@template.tag.div(class: "form-field__body") do
|
||||
field_element
|
||||
end
|
||||
else
|
||||
@template.tag.div(class: "form-field__body") do
|
||||
label_element + field_element
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_options(options, html_options)
|
||||
options.merge(required: options[:required] || html_options[:required])
|
||||
end
|
||||
|
||||
def build_label(method, options)
|
||||
return "".html_safe unless options[:label]
|
||||
|
||||
|
@ -113,4 +124,15 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
|
|||
return label(method, class: "form-field__label") if label_text == true
|
||||
label(method, label_text, class: "form-field__label")
|
||||
end
|
||||
|
||||
def build_tooltip(tooltip_text)
|
||||
return nil unless tooltip_text
|
||||
|
||||
@template.tag.div(data: { controller: "tooltip" }) do
|
||||
@template.safe_join([
|
||||
@template.icon("help-circle", size: "sm", color: "default", class: "cursor-help"),
|
||||
@template.tag.div(tooltip_text, role: "tooltip", data: { tooltip_target: "tooltip" }, class: "tooltip bg-gray-700 text-sm p-2 rounded w-64 text-white")
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue