Skip to content

Commit 0474b85

Browse files
committed
Add stable DOM ids to sprint backlog menus
Assign deterministic ids to sprint headers and sprint menu elements so Turbo morphing can reconcile the old and new DOM reliably.
1 parent 5d42fa4 commit 0474b85

File tree

6 files changed

+34
-3
lines changed

6 files changed

+34
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ See COPYRIGHT and LICENSE files for more details.
2929

3030
<%= component_wrapper(tag: :section) do %>
3131
<%= render(Primer::Beta::BorderBox.new(**@system_arguments)) do |border_box| %>
32-
<% border_box.with_header do %>
32+
<% border_box.with_header(id: dom_target(sprint, :header)) do %>
3333
<%= render(Backlogs::SprintHeaderComponent.new(sprint:, folded: folded?)) %>
3434
<% end %>
3535
<% if stories.empty? %>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ See COPYRIGHT and LICENSE files for more details.
2828
++# %>
2929

3030
<%=
31-
render(Primer::Alpha::ActionMenu.new(anchor_align: :end, classes: "hide-when-print")) do |menu|
31+
render(Primer::Alpha::ActionMenu.new(**@system_arguments)) do |menu|
3232
menu.with_show_button(
3333
scheme: :invisible,
3434
icon: :"kebab-horizontal",
@@ -38,6 +38,7 @@ See COPYRIGHT and LICENSE files for more details.
3838

3939
if user_allowed?(:create_sprints)
4040
menu.with_item(
41+
id: dom_target(sprint, :menu, :edit_sprint),
4142
label: t(".action_menu.edit_sprint"),
4243
href: edit_dialog_project_sprint_path(project, sprint),
4344
content_arguments: { data: { controller: "async-dialog" } }
@@ -48,6 +49,7 @@ See COPYRIGHT and LICENSE files for more details.
4849

4950
if user_allowed?(:manage_sprint_items)
5051
menu.with_item(
52+
id: dom_target(sprint, :menu, :new_story),
5153
label: t(".action_menu.new_story"),
5254
href: new_project_work_packages_dialog_path(
5355
project,
@@ -66,6 +68,7 @@ See COPYRIGHT and LICENSE files for more details.
6668

6769
menu.with_item(
6870
# TODO: sprint_id filter does not exist for work packages. Add?
71+
id: dom_target(sprint, :menu, :stories_tasks),
6972
scheme: :danger,
7073
label: t(".action_menu.stories_tasks"),
7174
tag: :a,

modules/backlogs/app/components/backlogs/sprint_menu_component.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,20 @@ class SprintMenuComponent < ApplicationComponent
3434

3535
attr_reader :sprint, :project, :current_user
3636

37-
def initialize(sprint:, project:, current_user: User.current)
37+
def initialize(sprint:, project:, current_user: User.current, **system_arguments)
3838
super()
3939

4040
@sprint = sprint
4141
@project = project
4242
@current_user = current_user
43+
44+
@system_arguments = system_arguments
45+
@system_arguments[:menu_id] = dom_target(sprint, :menu)
46+
@system_arguments[:anchor_align] = :end
47+
@system_arguments[:classes] = class_names(
48+
@system_arguments[:classes],
49+
"hide-when-print"
50+
)
4351
end
4452

4553
def stories

modules/backlogs/spec/components/backlogs/sprint_component_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ def render_component
9494
expect(page).to have_css(".Box-header h3", text: "Sprint 1")
9595
end
9696

97+
it "renders a stable id on the sprint header" do
98+
render_component
99+
100+
expect(page).to have_element(:div, class: "Box-header", id: /\Aagile_sprint_#{sprint.id}_header\z/)
101+
end
102+
97103
it "renders StoryComponent for each story" do
98104
render_component
99105

modules/backlogs/spec/components/backlogs/sprint_header_component_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ def render_component(folded: false)
123123

124124
expect(page).to have_css("action-menu")
125125
end
126+
127+
it "renders a stable id on the sprint menu trigger" do
128+
render_component
129+
130+
expect(page).to have_element(:button, id: /\Aagile_sprint_#{sprint.id}_menu-button\z/)
131+
end
126132
end
127133

128134
context "with no stories" do

modules/backlogs/spec/components/backlogs/sprint_menu_component_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ def render_component
105105
describe "always-visible items" do
106106
let(:permissions) { [:view_sprints] }
107107

108+
it "renders stable ids on the action menu and stories/tasks item" do
109+
render_component
110+
111+
expect(page).to have_element(:button, id: /\Aagile_sprint_#{sprint.id}_menu-button\z/)
112+
expect(page).to have_element(:ul, id: /\Aagile_sprint_#{sprint.id}_menu-list\z/)
113+
expect(page).to have_element(:a, id: /\Aagile_sprint_#{sprint.id}_menu_stories_tasks\z/)
114+
end
115+
108116
it "shows Stories/Tasks link" do
109117
render_component
110118

0 commit comments

Comments
 (0)