Skip to content

fix(explorer): stop rendering search-highlight markup as tree labels#955

Merged
JoaoGSP merged 4 commits into
Autonomy-Logic:developmentfrom
emerson-d-lopes:bugfix/gh-640-explorer-search-highlight
Jul 24, 2026
Merged

fix(explorer): stop rendering search-highlight markup as tree labels#955
JoaoGSP merged 4 commits into
Autonomy-Logic:developmentfrom
emerson-d-lopes:bugfix/gh-640-explorer-search-highlight

Conversation

@emerson-d-lopes

@emerson-d-lopes emerson-d-lopes commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Pull request info

References

This PR resolves #640.

Link to Jira task

External contribution — no Jira access; branch follows the bugfix/gh-<n>-<slug> convention from CONTRIBUTING.md.

Description of the changes proposed

Root cause (explains why the issue was unreproducible in the original thread): the corruption is not caused by editing a function block — it is triggered by the project search. explorer/project.tsx passed extractSearchQuery(pou.name, searchQuery) — a sanitized HTML string with <span class='bg-brand-light...'> around matches — as the label prop of ProjectTreeLeaf, which renders its label as plain text. Since searchQuery persists in the store after a search completes (it is only cleared when the search modal reopens or the project closes), the explorer permanently displayed the matching element's name as literal markup until restart. The reporter had searched for his function block at some point before editing it; editing was coincidental.

Deterministic reproduction on current development (verified in the running app): create a function block named Taktgeber → Search → type Taktgeber → Find → the tree leaf displays <span class=\"bg-brand-light dark:bg-brand-medium-dark border-0 rounded-sm\">Taktgeber</span> — byte-identical to the issue's screenshot.

Secondary hazard fixed by the same change: the decorated string was also used as the element's identityProjectTreeLeaf seeds its rename input from label and passes label to rename/duplicate/delete/selection. While a highlight matched, those actions targeted a POU name that does not exist.

Fix: label now always carries the plain element name (identity), and a new optional highlightQuery prop on ProjectTreeLeaf/ProjectTreeExpandableLeaf renders the visual highlight safely through the existing HighlightedText atom — the same approach the search results panel already uses. All 10 explorer call sites updated; extractSearchQuery remains in use by the search results panel where it is rendered correctly.

After the fix (running app, same repro steps — name renders with a proper highlight, matching the search panel):

tree highlight after fix

DOD checklist

  • The code is complete and according to developers' standards.
  • I have performed a self-review of my code.
  • Meet the acceptance criteria.
  • Unit tests are written and green (4 new tests: safe highlight applied on both leaf variants, no literal markup, no-query and non-matching-query cases).
  • Test coverage: components are outside the enforced coverage directories; full suite passes (5323 tests; the 4 pre-existing board-info-resolver failures on Windows fail identically on a clean checkout).
  • Integration tests are written and green. (N/A — verified end-to-end in the running app: the reproduction that showed literal markup before the change now renders a highlighted name.)
  • Changes were communicated and updated in the ticket description. (External contribution — GitHub issue referenced instead.)
  • Reviewed and accepted by the Product Owner.
  • End-to-end test are successful. (Repo's Playwright setup currently contains only the example spec.)

🤖 Generated with Claude Code

https://claude.ai/code/session_01U5TQ1y3yBEDx73tYTHoUBj

Summary by CodeRabbit

  • New Features

    • The project explorer’s tree item labels now visually highlight matching search terms in-place.
    • Highlighting is consistent across expandable and non-expandable entries.
  • Bug Fixes

    • Matching text is highlighted safely, keeping label content plain (no literal markup is introduced).
    • Labels are no longer rewritten for search—selection and identity still use the original label value.
    • No highlighting is shown when there’s no search query or no match.
  • Tests

    • Added coverage for safe highlight rendering and correct selection behavior.

After any project search, the explorer tree displayed the matching
element name as literal markup ("<span class=...") because the
decorated HTML string from extractSearchQuery was passed as the leaf
label, which ProjectTreeLeaf renders as plain text. The decorated
string was also used as the element identity, so rename, duplicate,
and delete targeted a name that does not exist while highlighted.

Pass the plain name as the label everywhere and add a highlightQuery
prop to ProjectTreeLeaf/ProjectTreeExpandableLeaf, which render the
match safely through the existing HighlightedText atom - the same
approach the search results panel already uses.

Fixes Autonomy-Logic#640

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U5TQ1y3yBEDx73tYTHoUBj
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9813bafa-8f29-4072-97fd-afdafe50723b

📥 Commits

Reviewing files that changed from the base of the PR and between 33cc5ac and 66e8f18.

📒 Files selected for processing (2)
  • src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx
  • src/frontend/components/_organisms/explorer/project.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/frontend/components/_molecules/project-tree/tests/leaf-highlight.test.tsx
  • src/frontend/components/_organisms/explorer/project.tsx

Walkthrough

Project tree leaves now accept search queries and render labels through HighlightedText. The explorer passes raw names and search queries across POU, data type, server, and remote-device branches. Tests verify safe highlighting and preserved label identity.

Changes

Project tree highlighting

Layer / File(s) Summary
Leaf highlighting contract and rendering
src/frontend/components/_molecules/project-tree/index.tsx, src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx
Leaf components accept highlightQuery, render labels with HighlightedText, and test matching, missing, non-matching, interaction, and expandable-leaf behavior safely.
Explorer search-query wiring
src/frontend/components/_organisms/explorer/project.tsx
Explorer branches pass raw labels and searchQuery to project tree leaves and expandable leaves.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProjectExplorer
  participant ProjectTreeLeaf
  participant ProjectTreeExpandableLeaf
  participant HighlightedText
  ProjectExplorer->>ProjectTreeLeaf: pass raw label and searchQuery
  ProjectExplorer->>ProjectTreeExpandableLeaf: pass raw label and searchQuery
  ProjectTreeLeaf->>HighlightedText: render highlighted label
  ProjectTreeExpandableLeaf->>HighlightedText: render highlighted label
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: joaogsp

Poem

I’m a rabbit with labels bright,
Queries make the tree alight.
No markup sneaks into the view,
Safe little spans appear on cue.
Hop through leaves, both wide and small—
Search now sparkles through them all!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately describes the main explorer label highlighting fix.
Description check ✅ Passed The PR description covers the issue reference, root cause, fix, and checklist, with only minor template deviations.
Linked Issues check ✅ Passed The changes address #640 by keeping tree labels plain and moving highlight rendering to a separate prop.
Out of Scope Changes check ✅ Passed The tests and component changes stay focused on the search-highlight label bug and add no unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx (1)

11-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover identity callbacks with the plain label.

These tests verify safe rendering, but not selection/rename/delete behavior. Add a mocked-store regression test asserting those callbacks receive Taktgeber, not a decorated HTML string, when highlightQuery is set.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx`
around lines 11 - 50, Add a mocked-store regression test around ProjectTreeLeaf
that sets highlightQuery to a matching value and triggers the selection, rename,
or delete identity callbacks. Assert each callback receives the plain label
"Taktgeber", not highlighted HTML markup, using the existing store-mocking setup
and callback symbols exposed by ProjectTreeLeaf.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx`:
- Around line 11-50: Add a mocked-store regression test around ProjectTreeLeaf
that sets highlightQuery to a matching value and triggers the selection, rename,
or delete identity callbacks. Assert each callback receives the plain label
"Taktgeber", not highlighted HTML markup, using the existing store-mocking setup
and callback symbols exposed by ProjectTreeLeaf.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 28f8a9dd-4f4a-4a90-b334-9caf5c6c2f6a

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6e025 and 32f4324.

📒 Files selected for processing (3)
  • src/frontend/components/_molecules/project-tree/__tests__/leaf-highlight.test.tsx
  • src/frontend/components/_molecules/project-tree/index.tsx
  • src/frontend/components/_organisms/explorer/project.tsx

…ighted

Address review feedback: selection through a highlighted leaf must
record the real POU name, never the decorated display string.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U5TQ1y3yBEDx73tYTHoUBj
@emerson-d-lopes

Copy link
Copy Markdown
Contributor Author

Addressed the nitpick — added an identity regression test: clicking a highlighted leaf records the plain name (Taktgeber) in the store's selection, never the decorated string. 5/5 tests green.

@JoaoGSP JoaoGSP left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tested and it works, thank you

@JoaoGSP

JoaoGSP commented Jul 24, 2026

Copy link
Copy Markdown
Member

Mirror PR for the shared src/frontend/ code (repo policy — external forks can't open it): https://github.com/Autonomy-Logic/openplc-web/pull/622 — diff byte-identical, authorship preserved.

@JoaoGSP
JoaoGSP merged commit 246a90f into Autonomy-Logic:development Jul 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error in name after editing a function block

2 participants