Spell out button_to params

This commit is contained in:
Jose Farias
2024-11-13 13:23:12 -06:00
parent 768b48ea03
commit 72ddd18bcc
8 changed files with 136 additions and 110 deletions
+7 -74
View File
@@ -1,89 +1,22 @@
module FiltersHelper
def filter_chip_id(value, name)
"#{name}_filter--#{value}"
"#{name}__filter--#{value}"
end
def filter_chip_frame_id(kind)
"#{kind}_chips"
end
def filter_chips(filter, **)
safe_join [
chips_for_filter_kind(filter, :indexed_by, **),
chips_for_filter_kind(filter, :tags, **),
chips_for_filter_kind(filter, :assignees, **),
chips_for_filter_kind(filter, :assigners, **),
chips_for_filter_kind(filter, :buckets, **),
chips_for_filter_kind(filter, :terms, **)
]
end
def filter_chips_for_editing(filter, **)
safe_join [
frame_for_filter_kind(filter, :indexed_by, **),
frame_for_filter_kind(filter, :tags, **),
frame_for_filter_kind(filter, :assignees, **),
frame_for_filter_kind(filter, :assigners, **),
frame_for_filter_kind(filter, :buckets, **),
frame_for_filter_kind(filter, :terms, **)
]
end
def filter_chip_tag(display:, value:, name:, **options)
tag.button id: filter_chip_id(value, name),
class: [ "btn txt-small btn--remove", options.delete(:class) ],
def filter_chip_tag(text, name:, value:, **options)
tag.button id: filter_chip_id(value, name), class: [ "btn txt-small btn--remove", options.delete(:class) ],
data: { action: "filter-form#removeFilter form#submit", filter_form_target: "button" } do
concat hidden_field_tag(name, value, id: nil)
concat tag.span(display)
concat tag.span(text)
concat image_tag("close.svg", aria: { hidden: true }, size: 24)
end
end
def button_to_chip(text, kind:, object:, data: {})
if object
button_to text, filter_chips_path, method: :post, class: "btn btn--plain filter__button", params: chip_attrs(kind, object), data: data
def button_to_chip(text, params: {}, data: {})
if params.present?
button_to text, filter_chips_path, method: :post, class: "btn btn--plain filter__button", params: params, data: data
else
button_tag text, type: :button, class: "btn btn--plain filter__button", data: data
end
end
private
def chips_for_filter_kind(filter, kind, **)
Array(filter.to_h[kind]).map do |value|
if value.respond_to? :map
safe_join value.map { |v| filter_chip_tag(**chip_attrs(kind, v), **) }
else
filter_chip_tag(**chip_attrs(kind, value), **)
end
end
end
def chip_attrs(kind, object)
case kind&.to_sym
when :tags
[ object.hashtag, object.id, "tag_ids[]" ]
when :buckets
[ "in #{object.name}", object.id, "bucket_ids[]" ]
when :assignees
[ "for #{object.name}", object.id, "assignee_ids[]" ]
when :assigners
[ "by #{object.name}", object.id, "assigner_ids[]" ]
when :indexed_by
[ object.humanize, object, "indexed_by" ]
when :assignments
[ object.humanize, object, "assignments" ]
when :terms
[ %Q("#{object}"), object, "terms[]" ]
end.then do |display, value, name|
{ display: display, value: value, name: name, frame: filter_chip_frame_id(kind) }
end
end
def frame_for_filter_kind(filter, kind, **)
chips_for_filter_kind(filter, kind, **).then do |chips|
turbo_frame_tag filter_chip_frame_id(kind) do
safe_join chips
end
end
end
end
+2 -2
View File
@@ -5,7 +5,7 @@ module Filter::Fields
class_methods do
def default_fields
{ "indexed_by" => "most_active" }
{ indexed_by: "most_active" }
end
end
@@ -13,7 +13,7 @@ module Filter::Fields
store_accessor :fields, :indexed_by, :assignments, :terms
def indexed_by
(super || default_fields["indexed_by"]).inquiry
(super || default_fields[:indexed_by]).inquiry
end
def assignments
+10 -18
View File
@@ -8,24 +8,16 @@ module Filter::Params
end
def as_params
@as_params ||= to_h.dup.tap do |h|
h["tag_ids"] = h.delete("tags")&.ids
h["bucket_ids"] = h.delete("buckets")&.ids
h["assignee_ids"] = h.delete("assignees")&.ids
end.compact_blank.with_indifferent_access
end
def to_h
@to_h ||= {}.tap do |h|
h["tags"] = tags
h["terms"] = terms
h["buckets"] = buckets
h["assignees"] = assignees
h["indexed_by"] = indexed_by
h["assignments"] = assignments
end.reject do |k, v|
default_fields[k] == v
end.compact_blank.with_indifferent_access
@as_params ||= {
terms: terms,
tag_ids: tags.ids,
assignees: assignees,
indexed_by: indexed_by,
bucket_ids: buckets.ids,
assignments: assignments,
assignee_ids: assignees.ids,
assigner_ids: assigners.ids
}.reject { |k, v| default_fields[k] == v }.compact_blank
end
def to_params
+1
View File
@@ -5,6 +5,7 @@ module Filter::Resources
has_and_belongs_to_many :tags
has_and_belongs_to_many :buckets
has_and_belongs_to_many :assignees, class_name: "User", join_table: "assignees_filters", association_foreign_key: "assignee_id"
has_and_belongs_to_many :assigners, class_name: "User", join_table: "assigners_filters", association_foreign_key: "assigner_id"
end
def resource_removed(resource)
+97 -12
View File
@@ -10,7 +10,31 @@
</button>
<%= form_with url: bubbles_path, method: :get, class: "flex-inline center align-center gap-half", data: { controller: "form" } do %>
<%= filter_chips filter %>
<%= filter_chip_tag filter.indexed_by.humanize, name: "indexed_by", value: filter.indexed_by %>
<% filter.tags.each do |tag| %>
<%= filter_chip_tag tag.hashtag, name: "tag_ids[]", value: tag.id %>
<% end %>
<% filter.assignees.each do |assignee| %>
<%= filter_chip_tag "for #{assignee.name}", name: "assignee_ids[]", value: assignee.id %>
<% end %>
<% if filter.assignments.present? %>
<%= filter_chip_tag filter.assignments.humanize, name: "assignments", value: filter.assignments %>
<% end %>
<% filter.assigners.each do |assigner| %>
<%= filter_chip_tag "by #{assigner.name}", name: "assigner_ids[]", value: assigner.id %>
<% end %>
<% filter.buckets.each do |bucket| %>
<%= filter_chip_tag "in #{bucket.name}", name: "bucket_ids[]", value: bucket.id %>
<% end %>
<% filter.terms.each do |term| %>
<%= filter_chip_tag %Q("#{term}"), name: "terms[]", value: term %>
<% end %>
<% end %>
</div>
@@ -38,13 +62,50 @@
</button>
<%= form_with url: bubbles_path, id: :filter_form, method: :get, class: "flex-inline center align-center gap-half" do %>
<%= filter_chips_for_editing filter, class: "fill-selected" %>
<%= turbo_frame_tag :indexed_by_chips do %>
<%= filter_chip_tag filter.indexed_by.humanize, name: "indexed_by", value: filter.indexed_by, class: "fill-selected" %>
<% end %>
<%= turbo_frame_tag :tag_chips do %>
<% filter.tags.each do |tag| %>
<%= filter_chip_tag tag.hashtag, name: "tag_ids[]", value: tag.id, class: "fill-selected" %>
<% end %>
<% end %>
<%= turbo_frame_tag :assignee_chips do %>
<% filter.assignees.each do |assignee| %>
<%= filter_chip_tag "for #{assignee.name}", name: "assignee_ids[]", value: assignee.id, class: "fill-selected" %>
<% end %>
<% if filter.assignments.present? %>
<%= filter_chip_tag filter.assignments.humanize, name: "assignments", value: filter.assignments, class: "fill-selected" %>
<% end %>
<% end %>
<%= turbo_frame_tag :assigner_chips do %>
<% filter.assigners.each do |assigner| %>
<%= filter_chip_tag "by #{assigner.name}", name: "assigner_ids[]", value: assigner.id, class: "fill-selected" %>
<% end %>
<% end %>
<%= turbo_frame_tag :bucket_chips do %>
<% filter.buckets.each do |bucket| %>
<%= filter_chip_tag "in #{bucket.name}", name: "bucket_ids[]", value: bucket.id, class: "fill-selected" %>
<% end %>
<% end %>
<%= turbo_frame_tag :terms_chips do %>
<% filter.terms.each do |term| %>
<%= filter_chip_tag %Q("#{term}"), name: "terms[]", value: term, class: "fill-selected" %>
<% end %>
<% end %>
<% end %>
</div>
<%= form_with url: filter_chips_path, method: :post, class: "flex gap flex-item-grow align-center justify-center full-width center margin-block" do %>
<%= hidden_field_tag :name, "terms[]" %>
<%= hidden_field_tag :frame, filter_chip_frame_id(:terms) %>
<%= hidden_field_tag :frame, :terms_chips %>
<input name="value" type="text" class="input full-width" placeholder="Type to match words…" autocomplete="off" />
<button class="btn txt-small" type="submit">
@@ -58,8 +119,11 @@
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Sort by</strong></li>
<% Filter::INDEXES.each do |index| %>
<li><%= button_to_chip index.humanize, kind: :indexed_by, object: index, data: { action: "filter-form#clearCategory", filter_form_name_param: "indexed_by" } %></li>
<li>
<%= button_to_chip index.humanize, params: { text: index.humanize, name: "indexed_by", value: index, frame: :indexed_by_chips }, data: { action: "filter-form#clearCategory", filter_form_name_param: "indexed_by" } %>
</li>
<% end %>
</menu>
</div>
@@ -68,9 +132,15 @@
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">In Project</strong></li>
<li><%= button_to_chip "All projects", kind: :buckets, object: nil, data: { action: "filter-form#clearCategory", filter_form_name_param: "bucket_ids[]" } %></li>
<li>
<%= button_to_chip "All projects", data: { action: "filter-form#clearCategory", filter_form_name_param: "bucket_ids[]" } %>
</li>
<% Current.user.buckets.order(:name).each do |bucket| %>
<li><%= button_to_chip bucket.name, kind: :buckets, object: bucket %></li>
<li>
<%= button_to_chip bucket.name, params: { text: "in #{bucket.name}", name: "bucket_ids[]", value: bucket.id, frame: :bucket_chips } %>
</li>
<% end %>
</menu>
</div>
@@ -79,8 +149,11 @@
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Tagged</strong></li>
<% Current.account.tags.order(:title).each do |tag| %>
<li><%= button_to_chip tag.title, kind: :tags, object: tag %></li>
<li>
<%= button_to_chip tag.title, params: { text: tag.hashtag, name: "tag_ids[]", value: tag.id, frame: :tag_chips } %>
</li>
<% end %>
</menu>
</div>
@@ -89,10 +162,17 @@
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Assigned to…</strong></li>
<li><%= button_to_chip "No one", kind: :assignments, object: "unassigned", data: { action: "filter-form#clearCategory", filter_form_name_param: "assignee_ids[]" } %></li>
<li><%= button_to_chip "Me", kind: :assignees, object: Current.user, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %></li>
<li>
<%= button_to_chip "No one", params: { text: "Unassigned", name: "assignments", value: "unassigned", frame: :assignee_chips }, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignee_ids[]" } %>
</li>
<li>
<%= button_to_chip "Me", params: { text: "for Me", name: "assignee_ids[]", value: Current.user.id, frame: :assignee_chips }, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li><%= button_to_chip user.name, kind: :assignees, object: user, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %></li>
<li>
<%= button_to_chip user.name, params: { text: "for #{user.name}", name: "assignee_ids[]", value: user.id, frame: :assignee_chips }, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
</li>
<% end %>
</menu>
</div>
@@ -101,9 +181,14 @@
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Assigned by…</strong></li>
<li><%= button_to_chip "Me", kind: :assigners, object: Current.user %></li>
<li>
<%= button_to_chip "Me", params: { text: "by Me", name: "assigner_ids[]", value: Current.user.id, frame: :assigner_chips } %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li><%= button_to_chip user.name, kind: :assigners, object: user %></li>
<li>
<%= button_to_chip user.name, params: { text: "by #{user.name}", name: "assigner_ids[]", value: user.id, frame: :assigner_chips } %>
</li>
<% end %>
</menu>
</div>
@@ -1,7 +1,7 @@
<% display = params[:display] || %Q("#{params[:value]}") %>
<% text = params[:text] || %Q("#{params[:value]}") %>
<%= turbo_stream.remove filter_chip_id(params[:value], params[:name]) %>
<%= turbo_stream.remove filter_chip_id(params[:name], params[:value]) %>
<%= turbo_stream.append params[:frame] do %>
<%= filter_chip_tag display: display, value: params[:value], name: params[:name], class: "fill-selected" %>
<%= filter_chip_tag text, name: params[:name], value: params[:value], class: "fill-selected" %>
<% end %>
@@ -0,0 +1,8 @@
class CreateFilterAssignerJoinTable < ActiveRecord::Migration[8.0]
def change
create_join_table :filters, :assigners do |t|
t.index :filter_id
t.index :assigner_id
end
end
end
Generated
+8 -1
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2024_11_08_205445) do
ActiveRecord::Schema[8.0].define(version: 2024_11_13_185136) do
create_table "accesses", force: :cascade do |t|
t.integer "bucket_id", null: false
t.integer "user_id", null: false
@@ -65,6 +65,13 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_08_205445) do
t.index ["filter_id"], name: "index_assignees_filters_on_filter_id"
end
create_table "assigners_filters", id: false, force: :cascade do |t|
t.integer "filter_id", null: false
t.integer "assigner_id", null: false
t.index ["assigner_id"], name: "index_assigners_filters_on_assigner_id"
t.index ["filter_id"], name: "index_assigners_filters_on_filter_id"
end
create_table "assignments", force: :cascade do |t|
t.integer "assignee_id", null: false
t.integer "bubble_id", null: false