Skip to content

Commit 17eb79b

Browse files
committed
[AGILE-176] Give backlog filter panels stable ids
Pass an explicit, field-scoped `id:` to the filter `SelectPanel` so the panel element and its trigger button keep deterministic ids across Turbo frame replacements, instead of Primer's per-render random id. https://community.openproject.org/wp/AGILE-176
1 parent 4cfa55e commit 17eb79b

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

modules/backlogs/app/components/backlogs/backlog_filter_select_panel_component.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
panelClosed->backlogs--backlog-filter-select-panel#revertOnClose">
66
<%= render(
77
Primer::Alpha::SelectPanel.new(
8+
id: panel_id,
89
select_variant: :multiple,
910
fetch_strategy: :local,
1011
title: t(".select_panel_title")
@@ -18,6 +19,7 @@
1819

1920
<% items.each do |item| %>
2021
<% panel.with_item(
22+
id: item_id(item),
2123
label: item.name,
2224
active: selected_ids&.include?(item.id) || false,
2325
content_arguments: { data: { value: item.id } }

modules/backlogs/app/components/backlogs/backlog_filter_select_panel_component.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ def initialize(project:, field_name:)
4444

4545
private
4646

47+
def panel_id
48+
dom_target(filter_field_name, :filter_select_panel)
49+
end
50+
51+
def item_id(item)
52+
dom_target(panel_id, :item, item.id.to_s)
53+
end
54+
4755
def items
4856
if filter_field == :sprint_ids
4957
all_sprints_for(project)

modules/backlogs/spec/components/backlogs/backlog_filter_select_panel_component_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ def render_component(field_name:, **params)
6161
expect(page).to have_css("[aria-selected='true']", text: "Alpha Sprint")
6262
expect(page).to have_css("[aria-selected='false']", text: "Beta Sprint")
6363
end
64+
65+
it "scopes each item id under the panel id" do
66+
render_component(field_name: :sprint_ids)
67+
expect(page).to have_css("#sprint_filter_select_panel_item_#{sprint1.id}", visible: :all, text: "Alpha Sprint")
68+
expect(page).to have_css("#sprint_filter_select_panel_item_#{sprint2.id}", visible: :all, text: "Beta Sprint")
69+
end
6470
end
6571

6672
describe "bucket panel" do
@@ -83,6 +89,29 @@ def render_component(field_name:, **params)
8389
expect(page).to have_element(aria: { selected: false }, text: "Ideas")
8490
expect(page).to have_element(aria: { selected: true }, text: "Backlog")
8591
end
92+
93+
it "scopes each item id under the panel id, including the inbox sentinel" do
94+
render_component(field_name: :bucket_ids)
95+
expect(page).to have_css("#backlog_bucket_filter_select_panel_item_#{bucket1.id}", visible: :all, text: "Ideas")
96+
expect(page).to have_css("#backlog_bucket_filter_select_panel_item_#{bucket2.id}", visible: :all, text: "Backlog")
97+
expect(page).to have_css("#backlog_bucket_filter_select_panel_item_inbox", visible: :all, text: I18n.t(:label_inbox))
98+
end
99+
end
100+
101+
describe "stable DOM ids" do
102+
it "derives the sprint panel and its trigger button ids from the field name" do
103+
render_component(field_name: :sprint_ids)
104+
105+
expect(page).to have_css("#sprint_filter_select_panel", visible: :all)
106+
expect(page).to have_css("#sprint_filter_select_panel-button", visible: :all)
107+
end
108+
109+
it "derives the bucket panel and its trigger button ids from the field name" do
110+
render_component(field_name: :bucket_ids)
111+
112+
expect(page).to have_css("#backlog_bucket_filter_select_panel", visible: :all)
113+
expect(page).to have_css("#backlog_bucket_filter_select_panel-button", visible: :all)
114+
end
86115
end
87116

88117
describe "submission wiring" do

0 commit comments

Comments
 (0)