Several fixes for saving filters

- Unify terms with the settings form so that terms are saved normally in the same form.
- Fix filter normalization since it was sometimes failing to match the saved filters due to using quotes around number strings.
This commit is contained in:
Jorge Manrubia
2025-09-22 12:55:19 +02:00
parent 717f921a73
commit ce80c843d0
14 changed files with 66 additions and 64 deletions
+5 -1
View File
@@ -17,10 +17,14 @@ module FilterScoped
if params[:filter_id].present?
@filter = Current.user.filters.find(params[:filter_id])
else
@filter = Current.user.filters.from_params params.reverse_merge(**Filter.default_values).permit(*Filter::PERMITTED_PARAMS)
@filter = Current.user.filters.from_params filter_params
end
end
def filter_params
params.reverse_merge(**Filter.default_values).permit(*Filter::PERMITTED_PARAMS)
end
def set_user_filtering
@user_filtering = User::Filtering.new(Current.user, @filter, expanded: expanded_param)
end
@@ -1,7 +0,0 @@
class Filters::SaveToggleRefreshesController < ApplicationController
include FilterScoped
def create
turbo_stream.replace("filter-toggle", partial: "filters/filter_toggle", locals: { filter: @filter })
end
end
@@ -0,0 +1,6 @@
class Filters::SettingsRefreshesController < ApplicationController
include FilterScoped
def create
end
end
+1 -1
View File
@@ -16,6 +16,6 @@ class FiltersController < ApplicationController
end
def filter_params
params.permit(*Filter::PERMITTED_PARAMS).compact_blank
Filter.normalize_params(params.permit(*Filter::PERMITTED_PARAMS))
end
end
@@ -5,26 +5,26 @@ import { post } from "@rails/request.js"
export default class extends Controller {
static classes = ["filtersSet"]
static targets = ["field", "form"]
static values = { refreshSaveToggleUrl: String }
static values = { refreshUrl: String }
initialize() {
this.debouncedChange = debounce(this.change.bind(this), 50)
this.debouncedToggle = debounce(this.#toggle.bind(this), 50)
}
connect() {
this.change()
this.#toggle()
}
change() {
this.#toggleFiltersSetClass()
this.#toggle()
this.#refreshSaveToggleButton()
}
async fieldTargetConnected(field) {
this.debouncedChange()
this.debouncedToggle()
}
#toggleFiltersSetClass(shouldAdd) {
#toggle() {
this.element.classList.toggle(this.filtersSetClass, this.#hasFiltersSet)
}
@@ -47,7 +47,7 @@ export default class extends Controller {
}
#refreshSaveToggleButton() {
post(this.refreshSaveToggleUrlValue, {
post(this.refreshUrlValue, {
body: this.#collectFilterFormData(),
responseKind: "turbo-stream"
})
+7 -1
View File
@@ -28,7 +28,13 @@ module Filter::Params
end
def normalize_params(params)
params.to_h.compact_blank.reject(&method(:default_value?)).sort_by { |name, _| name.to_s }
params
.to_h
.compact_blank
.reject(&method(:default_value?))
.collect { |name, value| [ name, value.is_a?(Array) ? value.collect(&:to_s) : value.to_s ] }
.sort_by { |name, _| name.to_s }
.to_h
end
end
+3 -4
View File
@@ -1,14 +1,13 @@
<div id="filter-toggle">
<div id="filter-settings-save-toggle">
<% if filter.persisted? %>
<%= button_to filter_path(filter), method: :delete, class: "btn txt-x-small btn--reversed", form_class: "inline" do %>
<%= icon_tag "bookmark-outline" %>
<span class="for-screen-reader">Remove saved filter</span>
<% end %>
<% else %>
<% filter_params = filter.as_params.transform_values { |v| v.respond_to?(:to_str) ? v.to_str : v } %>
<%= button_to filters_path, method: :post, params: filter_params, class: "btn txt-x-small", form_class: "inline" do %>
<%= button_to filters_path(filter.as_params), method: :post, class: "btn txt-x-small", form_class: "inline" do %>
<%= icon_tag "bookmark-outline" %>
<span class="for-screen-reader">Save filter</span>
<% end %>
<% end %>
</div>
</div>
+20 -7
View File
@@ -1,13 +1,26 @@
<% cache user_filtering do %>
<%= tag.aside id: "filter-settings",
class: class_names("filters flex align-center gap-half justify-center center margin-block-end", { "filters--expanded": user_filtering.expanded? }),
data: { controller: "toggle-class filter-settings", toggle_class_toggle_class: "filters--expanded", filter_settings_filters_set_class: "filters--has-filters-set", filter_settings_refresh_save_toggle_url_value: save_toggle_refresh_path } do %>
<div class="flex-inline center align-center gap-half" data-controller="toggle-enable">
<%= render "filters/settings/terms", user_filtering: user_filtering %>
<%= render "filters/settings/controls", user_filtering: user_filtering %>
data: {
controller: "toggle-class filter-settings",
toggle_class_toggle_class: "filters--expanded",
filter_settings_filters_set_class: "filters--has-filters-set",
filter_settings_refresh_url_value: settings_refresh_path } do %>
<%= form_with url: cards_path, method: :get, class: "", data: { controller: "form", turbo_frame: "card_columns", filter_settings_target: "form", turbo_action: "advance" } do |form| %>
<%= hidden_field_tag :expand_all, true, disabled: !user_filtering.expanded?, data: { toggle_enable_target: "element" } %>
<% user_filtering.filter.collections.each do |collection| %>
<%= filter_hidden_field_tag "collection_ids[]", collection.id %>
<% end %>
<%= render "filters/settings/toggle", user_filtering: user_filtering %>
<%= render "filters/settings/manage", user_filtering: user_filtering %>
</div>
<div class="flex-inline center align-center gap-half" data-controller="toggle-enable">
<%= render "filters/settings/terms", filter: user_filtering.filter, form: form %>
<%= render "filters/settings/controls", user_filtering: user_filtering, form: form %>
<%= render "filters/settings/toggle", user_filtering: user_filtering %>
</div>
<% end %>
<%= render "filters/settings/manage", user_filtering: user_filtering %>
<% end %>
<% end %>
+1 -1
View File
@@ -1,2 +1,2 @@
<%= turbo_stream.replace("filter-toggle", partial: "filters/filter_toggle", locals: { filter: @filter }) %>
<%= turbo_stream.replace("filter-settings-save-toggle", partial: "filters/filter_toggle", locals: { filter: @filter }) %>
<%= turbo_stream.replace("my-filters", partial: "filters/menu/custom", locals: { filters: @filters }) %>
+6 -14
View File
@@ -1,15 +1,7 @@
<%= form_with url: cards_path, method: :get, class: "flex-inline center align-center gap-half",
data: { controller: "form", turbo_frame: "card_columns", turbo_action: "advance", filter_settings_target: "form" } do |form| %>
<%= hidden_field_tag :expand_all, true, disabled: !user_filtering.expanded?, data: { toggle_enable_target: "element" } %>
<% user_filtering.filter.collections.each do |collection| %>
<%= filter_hidden_field_tag "collection_ids[]", collection.id %>
<% end %>
<%= render "filters/settings/sorted_by", user_filtering: user_filtering %>
<%= render "filters/settings/indexed_by", user_filtering: user_filtering %>
<%= render "filters/settings/tags", user_filtering: user_filtering %>
<%= render "filters/settings/assignees", user_filtering: user_filtering %>
<%= render "filters/settings/creators", user_filtering: user_filtering %>
<%= render "filters/settings/closers", user_filtering: user_filtering %>
<% end %>
<%= render "filters/settings/sorted_by", user_filtering: user_filtering %>
<%= render "filters/settings/indexed_by", user_filtering: user_filtering %>
<%= render "filters/settings/tags", user_filtering: user_filtering %>
<%= render "filters/settings/assignees", user_filtering: user_filtering %>
<%= render "filters/settings/creators", user_filtering: user_filtering %>
<%= render "filters/settings/closers", user_filtering: user_filtering %>
+1 -1
View File
@@ -1,6 +1,6 @@
<% filter = user_filtering.filter %>
<div class="filters__manage center align-center gap-half">
<div class="filters__manage flex">
<%= render "filters/filter_toggle", filter: filter %>
<%= link_to cards_path(filter.as_params.except(:assignee_ids, :assignment_status, :card_ids, :creator_ids, :closer_ids, :stage_ids, :tag_ids, :terms, :indexed_by, :sorted_by, :creation, :closure)), class: "btn btn--remove txt-x-small" do %>
+7 -19
View File
@@ -1,24 +1,12 @@
<% filter = user_filtering.filter %>
<%= form_with url: cards_path, method: :get, class: "", data: { controller: "form", turbo_frame: "card_columns", action: "input->form#debouncedSubmit", filter_settings_target: "form" } do |form| %>
<% filter.as_params.except(:terms).each do |key, value| %>
<%= filter_hidden_field_tag key, value %>
<% end %>
<% filter.terms.each do |existing_term| %>
<%= hidden_field_tag "terms[]", existing_term %>
<% end %>
<% if user_filtering.expanded? %>
<%= hidden_field_tag :expand_all, user_filtering.expanded? %>
<% end %>
<%= form.text_field "terms[]", placeholder: "Filter these cards…", class: "input txt-x-small filter__terms",
autofocus: false, autocomplete: :off, autocorrect: "off", data: {
"1p-ignore": "true",
action: "input->form#debouncedSubmit keydown.enter->form#submitToTopTarget" } %>
<% filter.terms.each do |existing_term| %>
<%= hidden_field_tag "terms[]", existing_term %>
<% end %>
<%= form.text_field "terms[]", placeholder: "Filter these cards…", class: "input txt-x-small filter__terms",
autofocus: false, autocomplete: :off, autocorrect: "off", data: {
"1p-ignore": "true",
action: "input->form#debouncedSubmit keydown.enter->form#submitToTopTarget" } %>
<% if filter.terms.present? %>
<% filter.terms.each do |term| %>
<%= filter_chip_tag %Q("#{term}"), filter.as_params_without(:terms, term) %>
@@ -0,0 +1 @@
<%= turbo_stream.replace("filter-settings-save-toggle", partial: "filters/filter_toggle", locals: { filter: @filter }) %>
+1 -1
View File
@@ -84,7 +84,7 @@ Rails.application.routes.draw do
resources :filters do
scope module: :filters do
collection do
resource :save_toggle_refresh, only: :create
resource :settings_refresh, only: :create
end
end
end