FIX: Loading more tags in edit nav menu tags modal not working (#22770)

Why this change?

When setting up the `IntersectionObserver`, we did not account for the
top margin and padding causing no intersection event to fire when the
last tag is load into view. This commits fixes the problem by setting a
bottom margin using the `rootMargin` option when setting up the
`IntersectionObserver`.

This commit also improves the test coverage surrounding the loading of
more tags.
This commit is contained in:
Alan Guo Xiang Tan 2023-07-25 13:44:25 +08:00 committed by GitHub
parent 25a948c892
commit fe1034e89c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 15 deletions

View File

@ -61,6 +61,11 @@ export default class extends Component {
if (this.observer) { if (this.observer) {
this.observer.disconnect(); this.observer.disconnect();
} else { } else {
const root = document.querySelector(".modal-body");
const style = window.getComputedStyle(root);
const marginTop = parseFloat(style.marginTop);
const paddingTop = parseFloat(style.paddingTop);
this.observer = new IntersectionObserver( this.observer = new IntersectionObserver(
(entries) => { (entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
@ -71,6 +76,7 @@ export default class extends Component {
}, },
{ {
root: document.querySelector(".modal-body"), root: document.querySelector(".modal-body"),
rootMargin: `0px 0px ${marginTop + paddingTop}px 0px`,
threshold: 1.0, threshold: 1.0,
} }
); );

View File

@ -1,4 +1,5 @@
.sidebar-tags-form { .sidebar-tags-form {
height: 100%;
display: grid; display: grid;
gap: 0 0.5em; gap: 0 0.5em;
margin: 0; margin: 0;

View File

@ -5,15 +5,15 @@ RSpec.describe "Editing sidebar tags navigation", type: :system do
fab!(:tag1) { Fabricate(:tag, name: "tag").tap { |tag| Fabricate.times(3, :topic, tags: [tag]) } } fab!(:tag1) { Fabricate(:tag, name: "tag").tap { |tag| Fabricate.times(3, :topic, tags: [tag]) } }
fab!(:tag2) do fab!(:tag2) do
Fabricate(:tag, name: "tag2").tap { |tag| Fabricate.times(2, :topic, tags: [tag]) } Fabricate(:tag, name: "tag 2").tap { |tag| Fabricate.times(2, :topic, tags: [tag]) }
end end
fab!(:tag3) do fab!(:tag3) do
Fabricate(:tag, name: "tag3").tap { |tag| Fabricate.times(1, :topic, tags: [tag]) } Fabricate(:tag, name: "tag 3").tap { |tag| Fabricate.times(1, :topic, tags: [tag]) }
end end
fab!(:tag4) do fab!(:tag4) do
Fabricate(:tag, name: "tag4").tap do |tag| Fabricate(:tag, name: "tag 4").tap do |tag|
Fabricate.times(1, :topic, tags: [tag]) Fabricate.times(1, :topic, tags: [tag])
# Ensures tags in tag groups are shown as well # Ensures tags in tag groups are shown as well
@ -21,9 +21,6 @@ RSpec.describe "Editing sidebar tags navigation", type: :system do
end end
end end
# This tag should not be displayed in the modal as it has not been used in a topic
fab!(:tag5) { Fabricate(:tag, name: "tag5") }
let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new } let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
before { sign_in(user) } before { sign_in(user) }
@ -99,7 +96,7 @@ RSpec.describe "Editing sidebar tags navigation", type: :system do
expect(modal).to have_tag_checkboxes([tag1, tag2, tag3, tag4]) expect(modal).to have_tag_checkboxes([tag1, tag2, tag3, tag4])
modal.filter("tag2") modal.filter("tag 2")
expect(modal).to have_tag_checkboxes([tag2]) expect(modal).to have_tag_checkboxes([tag2])
@ -164,7 +161,7 @@ RSpec.describe "Editing sidebar tags navigation", type: :system do
expect(modal).to have_tag_checkboxes([tag1, tag2]) expect(modal).to have_tag_checkboxes([tag1, tag2])
modal.filter("tag2") modal.filter("tag 2")
expect(modal).to have_tag_checkboxes([tag2]) expect(modal).to have_tag_checkboxes([tag2])
@ -178,14 +175,25 @@ RSpec.describe "Editing sidebar tags navigation", type: :system do
end end
it "loads more tags when the user scrolls views the last tag in the modal and there is more tags to load" do it "loads more tags when the user scrolls views the last tag in the modal and there is more tags to load" do
stub_const(TagsController, "LIST_LIMIT", 2) do Tag.delete_all
visit "/latest"
expect(sidebar).to have_tags_section tags =
(TagsController::LIST_LIMIT + 1).times.map.with_index do |index|
Fabricate(:tag, name: "Tag #{sprintf("%03d", index)}")
end
modal = sidebar.click_edit_tags_button visit "/latest"
expect(modal).to have_tag_checkboxes([tag1, tag2, tag3, tag4]) expect(sidebar).to have_tags_section
end
modal = sidebar.click_edit_tags_button
first_page_tags = tags.first(TagsController::LIST_LIMIT)
expect(modal).to have_tag_checkboxes(first_page_tags)
modal.scroll_to_tag(first_page_tags.last)
expect(modal).to have_tag_checkboxes(tags)
end end
end end

View File

@ -6,8 +6,9 @@ module PageObjects
module Modals module Modals
class SidebarEditTags < SidebarEditNavigationModal class SidebarEditTags < SidebarEditNavigationModal
def has_tag_checkboxes?(tags) def has_tag_checkboxes?(tags)
find(".sidebar-tags-form").has_content?( expect(form).to have_content(
tags.map { |tag| "#{tag.name} (#{tag.public_topic_count})" }.join("\n"), tags.map { |tag| "#{tag.name} (#{tag.public_topic_count})" }.join("\n"),
exact: true,
) )
end end
@ -26,6 +27,18 @@ module PageObjects
self self
end end
def scroll_to_tag(tag)
page.execute_script(
"document.querySelector('.sidebar-tags-form__tag[data-tag-name=\"#{tag.name}\"]').scrollIntoView()",
)
end
private
def form
find(".sidebar-tags-form")
end
end end
end end
end end