diff --git a/app/controllers/filter_buttons_controller.rb b/app/controllers/filter_buttons_controller.rb new file mode 100644 index 000000000..20d316679 --- /dev/null +++ b/app/controllers/filter_buttons_controller.rb @@ -0,0 +1,4 @@ +class FilterButtonsController < ApplicationController + def create + end +end diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 05caac3d0..80621407e 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -1,27 +1,55 @@ module FiltersHelper - def buckets_filter_text(filter) - if filter.buckets.present? - filter.buckets.map(&:name).to_choice_sentence - else - "all projects" + def filter_button_id(value, name) + "#{name}_filter--#{value}" + end + + def filter_buttons(filter, **) + filter.to_h.map do |kind, object| + filter_button_from kind, object, ** + end.join.html_safe + end + + def filter_button_tag(display:, value:, name:, **options) + tag.button id: filter_button_id(value, name), class: [ "btn txt-small btn--remove", options.delete(:class) ], data: { action: "filter-form#removeFilter form#submit" } do + concat hidden_field_tag(name, value, id: nil) + concat tag.span(display) + concat image_tag("close.svg", aria: { hidden: true }, size: 24) end end - def assignments_filter_text(filter) - if filter.assignees.present? - "assigned to #{filter.assignees.map(&:name).to_choice_sentence}" - elsif filter.assignments.unassigned? - "assigned to no one" + def button_to_filter(text, kind:, object:, data: {}) + if object + button_to text, filter_buttons_path, method: :post, class: "btn btn--plain", params: filter_attrs(kind, object), data: data else - "assigned to anyone" + button_tag text, type: :button, class: "btn btn--plain", data: data end end - def tags_filter_text(filter) - if filter.tags.present? - filter.tags.map(&:hashtag).to_choice_sentence - else - "any tag" + private + def filter_button_from(kind, object, **) + if object.respond_to? :map + safe_join object.map { |o| filter_button_tag(**filter_attrs(kind, o), **) } + else + filter_button_tag(**filter_attrs(kind, object), **) + end + end + + def filter_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" ] + end.then do |display, value, name| + { display: display, value: value, name: name } + end end - end end diff --git a/app/javascript/controllers/filter_form_controller.js b/app/javascript/controllers/filter_form_controller.js new file mode 100644 index 000000000..b55cc6069 --- /dev/null +++ b/app/javascript/controllers/filter_form_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + removeFilter(event) { + event.preventDefault() + this.#removeButton(event.target.closest("button")) + } + + clearCategory({ params: { name } }) { + this.element.querySelectorAll(`input[name="${name}"]`).forEach(input => this.#removeButton(input.closest("button"))) + } + + #removeButton(button) { + button.querySelector("input").disabled = true + button.hidden = true + } +} diff --git a/app/models/filter/params.rb b/app/models/filter/params.rb index 1077203ab..ee63c983e 100644 --- a/app/models/filter/params.rb +++ b/app/models/filter/params.rb @@ -8,15 +8,23 @@ module Filter::Params end def as_params - params = {}.tap do |h| - h["tag_ids"] = tags.ids - h["bucket_ids"] = buckets.ids - h["assignee_ids"] = assignees.ids - h["indexed_by"] = indexed_by - h["assignments"] = assignments - end + @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 + end - params.compact_blank.reject { |k, v| default_fields[k] == v } + def to_h + @to_h ||= {}.tap do |h| + h["indexed_by"] = indexed_by + h["assignments"] = assignments + h["assignees"] = assignees + h["tags"] = tags + h["buckets"] = buckets + end.reject do |k, v| + default_fields[k] == v + end.compact_blank end def to_params diff --git a/app/views/bubbles/_filters.html.erb b/app/views/bubbles/_filters.html.erb index c8a511ac5..ebe553043 100644 --- a/app/views/bubbles/_filters.html.erb +++ b/app/views/bubbles/_filters.html.erb @@ -1,6 +1,6 @@ -