Skip to content

Commit

Permalink
Merge pull request #17355 from opf/59769-when-adding-new-relations-au…
Browse files Browse the repository at this point in the history
…to-scroll-to-show-the-newly-added-relation

[59769] When adding new relations, auto-scroll to show the newly added relation
  • Loading branch information
HDinger authored Dec 18, 2024
2 parents f194423 + d878858 commit a4b7f24
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 23 deletions.
66 changes: 46 additions & 20 deletions app/components/work_package_relations_tab/index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ class WorkPackageRelationsTab::IndexComponent < ApplicationComponent
include Turbo::FramesHelper
include OpTurbo::Streamable

attr_reader :work_package, :relations, :children, :directionally_aware_grouped_relations
attr_reader :work_package, :relations, :children, :directionally_aware_grouped_relations, :scroll_to_id

def initialize(work_package:, relations:, children:)
def initialize(work_package:, relations:, children:, scroll_to_id: nil)
super()

@work_package = work_package
@relations = relations
@children = children
@directionally_aware_grouped_relations = group_relations_by_directional_context
@scroll_to_id = scroll_to_id
end

def self.wrapper_key
Expand Down Expand Up @@ -47,23 +48,44 @@ def group_relations_by_directional_context
def any_relations? = relations.any? || children.any?

def render_relation_group(title:, relation_type:, items:, &_block)
render(border_box_container(padding: :condensed,
data: { test_selector: "op-relation-group-#{relation_type}" })) do |border_box|
border_box.with_header(py: 3) do
flex_layout(align_items: :center) do |flex|
flex.with_column(mr: 2) do
render(Primer::Beta::Text.new(font_size: :normal, font_weight: :bold)) { title }
end
flex.with_column do
render(Primer::Beta::Counter.new(count: items.size, round: true, scheme: :primary))
end
render(border_box_container(
padding: :condensed,
data: { test_selector: "op-relation-group-#{relation_type}" }
)) do |border_box|
render_header(border_box, title, items)
render_items(border_box, items, &_block)
end
end

def render_header(border_box, title, items)
border_box.with_header(py: 3) do
flex_layout(align_items: :center) do |flex|
flex.with_column(mr: 2) do
render(Primer::Beta::Text.new(font_size: :normal, font_weight: :bold)) { title }
end
flex.with_column do
render(Primer::Beta::Counter.new(count: items.size, round: true, scheme: :primary))
end
end
end
end

items.each do |item|
border_box.with_row(test_selector: row_test_selector(item)) do
yield(item)
end
def render_items(border_box, items)
items.each do |item|
related_work_package_id = find_related_work_package_id(item)
data_attribute = nil
if related_work_package_id.to_s == @scroll_to_id
data_attribute = {
controller: "work-packages--relations-tab--scroll",
application_target: "dynamic",
"work-packages--relations-tab--scroll-target": "scrollToRow"
}
end
border_box.with_row(
test_selector: row_test_selector(item),
data: data_attribute
) do
yield(item)
end
end
end
Expand All @@ -83,11 +105,15 @@ def new_button_test_selector(relation_type:)
end

def row_test_selector(item)
related_work_package_id = find_related_work_package_id(item)
"op-relation-row-#{related_work_package_id}"
end

def find_related_work_package_id(item)
if item.is_a?(Relation)
target = item.to == work_package ? item.from : item.to
"op-relation-row-#{target.id}"
else # Work Package object
"op-relation-row-#{item.id}"
item.from_id == work_package.id ? item.to_id : item.from_id
else
item.id
end
end
end
3 changes: 2 additions & 1 deletion app/controllers/work_package_children_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def create
component = WorkPackageRelationsTab::IndexComponent.new(
work_package: @work_package,
relations: @relations,
children: @children
children: @children,
scroll_to_id: target_work_package_id
)
replace_via_turbo_stream(component:)
update_flash_message_via_turbo_stream(
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/work_package_relations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ def create
.call(create_relation_params)

if service_result.success?
target_work_package_id = params[:relation][:to_id]
@work_package.reload
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package,
relations: @work_package.relations,
children: @work_package.children)
children: @work_package.children,
scroll_to_id: target_work_package_id)
replace_via_turbo_stream(component:)
respond_with_turbo_streams
else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';

export default class ScrollController extends Controller {
static targets = ['scrollToRow'];

declare readonly scrollToRowTarget:HTMLElement;
declare readonly hasScrollToRowTarget:boolean;

scrollToRowTargetConnected() {
if (this.hasScrollToRowTarget) {
setTimeout(() => {
this.scrollToRowTarget.scrollIntoView({ behavior: 'smooth', block: 'center' });
});
}
}
}
2 changes: 1 addition & 1 deletion spec/controllers/work_package_relations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
new_relation = Relation.last

expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new)
.with(work_package:, relations: [relation, new_relation], children:)
.with(work_package:, relations: [relation, new_relation], children:, scroll_to_id: unrelated_work_package.id)
expect(controller).to have_received(:replace_via_turbo_stream)
.with(component: an_instance_of(WorkPackageRelationsTab::IndexComponent))
end
Expand Down

0 comments on commit a4b7f24

Please sign in to comment.