Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions engine/app/assets/stylesheets/coplan/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,7 @@ img.avatar {
background: var(--color-highlight-open-bg);
border-bottom: 2px solid var(--color-highlight-open-border);
cursor: pointer;
pointer-events: auto;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do?

}

.anchor-highlight--open:hover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ export default class extends Controller {
}

openThreadPopover(event) {
event.stopPropagation()
this._showThreadPopoverFor(event.currentTarget, "pinned")
}

Expand Down Expand Up @@ -834,14 +835,6 @@ export default class extends Controller {
// Skip zero-length ranges (e.g. from text node splits by prior highlights)
if (localEnd <= localStart) continue

// If the text is already inside a highlight mark (from another thread
// anchored to the same text), reuse that mark instead of nesting.
const existingMark = tn.node.parentElement?.closest("mark.anchor-highlight")
if (existingMark) {
if (!marks.includes(existingMark)) marks.push(existingMark)
continue
}

const range = document.createRange()
range.setStart(tn.node, localStart)
range.setEnd(tn.node, localEnd)
Expand Down
60 changes: 60 additions & 0 deletions spec/system/comment_ux_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,66 @@ def create_anchored_thread(plan:, anchor_text:, body:, user:)
describe "creating a new comment" do
before { sign_in(author) }

it "keeps an overlapping heading comment visible and clickable after reload" do
plan.current_plan_version.update!(content_markdown: <<~MARKDOWN)
# Performance

## 1.3 Hard carts — and why native degrades fast

Cart shapes come from what actually co-occurs in fleet traffic.
MARKDOWN
resolved = create_anchored_thread(
plan: plan,
anchor_text: "1.3 Hard carts — and why native degrades fast",
body: "Previously addressed feedback.",
user: author
)
resolved.update!(status: "resolved", resolved_by_user: author)
visit plan_path(plan)

page.execute_script <<~JS
const content = document.querySelector('[data-coplan--text-selection-target="content"]');
const heading = content.querySelector('h2');
const walker = document.createTreeWalker(heading, NodeFilter.SHOW_TEXT);
let node;
while ((node = walker.nextNode()) && !node.textContent.includes('Hard')) {}
if (!node) throw new Error('Hard text node not found');
const start = node.textContent.indexOf('Hard');
const range = document.createRange();
range.setStart(node, start);
range.setEnd(node, start + 'Hard'.length);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
heading.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
JS

expect(page).to have_css(".comment-popover", visible: true, wait: 3)
find(".comment-popover button").click

within("#new-comment-form") do
textarea = find("textarea")
textarea.fill_in with: "This case needs more detail."
textarea.send_keys(:enter)
end

expect(page).not_to have_css("#new-comment-form", visible: true, wait: 5)
thread = plan.comment_threads.reload.last
expect(thread.anchor_text).to eq("Hard")
expect(page).to have_css("mark.anchor-highlight", text: "Hard", wait: 5)
expect(page).to have_css("##{ActionView::RecordIdentifier.dom_id(thread)}")
expect(page).to have_css("mark[data-thread-id='#{ActionView::RecordIdentifier.dom_id(thread)}']")

refresh

expect(page).to have_css("mark.anchor-highlight", text: "Hard", wait: 5)
mark = find("mark[data-thread-id='#{ActionView::RecordIdentifier.dom_id(thread)}']")
expect(mark[:class]).to include("anchor-highlight--todo")
mark.click
expect(page).to have_css("##{ActionView::RecordIdentifier.dom_id(thread)}_popover", visible: true)
expect(page).to have_content("This case needs more detail.")
end

it "creates a thread via the text selection form" do
visit plan_path(plan)

Expand Down
Loading