Skip to content

[chores:fix] Preserve indoor overlay URL fragment on popup close #547

Merged
nemesifier merged 3 commits into
masterfrom
fix/546-preserve-overlay-fragment
May 22, 2026
Merged

[chores:fix] Preserve indoor overlay URL fragment on popup close #547
nemesifier merged 3 commits into
masterfrom
fix/546-preserve-overlay-fragment

Conversation

@dee077
Copy link
Copy Markdown
Member

@dee077 dee077 commented May 21, 2026

Follow up of #542.

Added configurable fragment preservation support for bookmarkable actions so indoor map overlays retain their URL fragment when only the popup nodeId is removed.

Fixes #546

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #546.

Description of Changes

  • Added new config preserveFragment to support removing the nodeId param based on the config
  • Also fix leaving # on removing all the URL fragments
  • Fix tests

Added configurable fragment preservation support for bookmarkable actions so indoor map overlays retain their URL fragment when only the popup nodeId is removed.

Fixes #546
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Introduces a new bookmarkableActions.preserveFragment option (default false) and sets it true in the indoor map example. updateUrlFragments now removes the hash when empty. removeUrlFragment gains a preserveFragment parameter so removing nodeId can retain an id-only fragment when requested. NetJSONGraphGUI.loadNodePopup reads preserveFragment and passes it to removeUrlFragment in failure and popup-remove paths. Tests and README updated to reflect the new option and method signature.

Sequence Diagram(s)

sequenceDiagram
  participant Client as User / Browser
  participant GUI as NetJSONGraphGUI.loadNodePopup
  participant Config as config.bookmarkableActions
  participant Utils as utils.removeUrlFragment
  participant History as Browser History

  Client->>GUI: open node popup (may set fragment nodeId)
  GUI->>Config: read { id, preserveFragment }
  alt Content build fails
    GUI->>Utils: removeUrlFragment(id, "nodeId", preserveFragment)
    Utils->>History: updateUrlFragments / pushState
  end
  alt Popup removed and fragment nodeId matches popup
    GUI->>Utils: removeUrlFragment(id, "nodeId", preserveFragment)
    Utils->>History: updateUrlFragments / pushState
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • openwisp/netjsongraph.js#542: Both PRs modify NetJSONGraphGUI.loadNodePopup and URL-fragment cleanup by extending removeUrlFragment behavior for node-popup flows.
  • openwisp/netjsongraph.js#417: This PR's changes to URL fragment handling build on the bookmarkable-URL/history fragment system introduced in that PR.

Suggested reviewers

  • nemesifier
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title uses a non-standard type format '[chores:fix]' instead of the required single type format, and the title accurately describes the main change of preserving indoor overlay URL fragments on popup close. Update the title to use a single type from the allowed list (fix, change, feature, qa, ci, chores, docs). Suggested: '[fix] Preserve indoor overlay URL fragment on popup close' since the linked issue is a bug fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The pull request successfully implements all objectives from issue #546: adds configurable fragment preservation, removes nodeId parameter while preserving overlay fragment, and fixes the trailing '#' issue when all fragments are removed.
Out of Scope Changes check ✅ Passed All changes directly support the linked issue objectives: configuration additions, URL fragment handling, tests, and documentation updates are all scoped to the fragment preservation feature.
Bug Fixes ✅ Passed Adds preserveFragment parameter to removeUrlFragment() fixing root cause. Regression tests included and deterministic with mocks. Backward compatible with default false value resolves issue #546.
Description check ✅ Passed PR description follows template structure with all required sections completed: checklist items checked, issue reference provided, and clear description of changes included.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/546-preserve-overlay-fragment

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 and usage tips.

@coderabbitai coderabbitai Bot added bug javascript Pull requests that update Javascript code labels May 21, 2026
@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented May 21, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0

Incremental Review (fa3071b..HEAD)

The latest commit adds:

Documentation (src/js/netjsongraph.util.js lines 1348-1349):

  • Added JSDoc comment for the preserveFragment parameter in removeUrlFragment
  • Documents the behavior: "If true, keep a bare id-only fragment after removing paramName"

Test Coverage (test/netjsongraph.util.test.js lines 736-751):

  • New test case "removeUrlFragment keeps an id-only fragment when preserveFragment is true"
  • Tests the preserveFragment: true configuration path
  • Properly mocks dependencies and verifies the fragment is preserved
  • Complements existing test for default preserveFragment: false behavior

Previous Review Context

The PR implements a well-structured fix for issue #546 that allows indoor map overlays to preserve their URL fragment ID when popups close. The core implementation was reviewed in previous commits and found to be sound.


Files Reviewed (2 incremental + 6 previous)
  • src/js/netjsongraph.util.js (incremental - JSDoc)
  • test/netjsongraph.util.test.js (incremental - new test)
  • public/example_templates/netjsonmap-indoormap-overlay.html
  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.gui.js
  • test/netjsongraph.dom.test.js
  • README.md
Existing Inline Comments (3 active)
File Line Issue
test/netjsongraph.dom.test.js 744 Nitpick
test/netjsongraph.dom.test.js 744 Updated!
test/netjsongraph.dom.test.js 744 @dee077 Thanks for adding the "loadNodePopup forwards pre

Reviewed by kimi-k2.5 · 95,532 tokens

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@test/netjsongraph.dom.test.js`:
- Around line 740-744: Add a test that sets bookmarkableActions.preserveFragment
= true before triggering the popup cleanup and assert that
testGraph.utils.removeUrlFragment was called with the third argument true (i.e.
expect(testGraph.utils.removeUrlFragment).toHaveBeenCalledWith("id", "nodeId",
true)); locate the existing popup cleanup test that currently asserts the
false/default path and duplicate/extend it to set preserveFragment true, trigger
the same cleanup flow (the same setup that calls popup cleanup), and add the new
expectation referencing testGraph.utils.removeUrlFragment so the true-path is
covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f5041171-f887-41e7-9c45-04850a4bdbc5

📥 Commits

Reviewing files that changed from the base of the PR and between b2ea68a and ccc7c41.

📒 Files selected for processing (5)
  • public/example_templates/netjsonmap-indoormap-overlay.html
  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.gui.js
  • src/js/netjsongraph.util.js
  • test/netjsongraph.dom.test.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Tests and Coverage (echarts-only)
  • GitHub Check: Tests and Coverage (prod)
  • GitHub Check: Tests and Coverage (dev)
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,css,scss,json}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using openwisp-qa-format command with Python virtualenv enabled and yarn lint:fix (runs eslint --fix and prettier via lint-staged)

Files:

  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.util.js
  • src/js/netjsongraph.gui.js
  • test/netjsongraph.dom.test.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Husky pre-commit hooks automatically run lint-staged to format JavaScript files in src/**/*.js with prettier

Files:

  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.util.js
  • src/js/netjsongraph.gui.js
**/*.test.{js,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Write unit tests using Jest with jsdom and run with yarn test

Files:

  • test/netjsongraph.dom.test.js
🧠 Learnings (4)
📚 Learning: 2026-01-20T00:56:36.062Z
Learnt from: dee077
Repo: openwisp/netjsongraph.js PR: 417
File: src/js/netjsongraph.core.js:132-145
Timestamp: 2026-01-20T00:56:36.062Z
Learning: In the netjsongraph.js codebase, the data model does not support parallel links (multiple links between the same source and target). Ensure nodeLinkIndex is keyed by a single 'source~target' pair and that adding a link does not overwrite existing links for that pair. If parallel links are ever required, the data model must be changed (e.g., allow an array of links per 'source~target' key) rather than storing only one link.

Applied to files:

  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.util.js
  • src/js/netjsongraph.gui.js
  • test/netjsongraph.dom.test.js
📚 Learning: 2026-01-20T16:50:56.414Z
Learnt from: codesankalp
Repo: openwisp/netjsongraph.js PR: 425
File: src/js/netjsongraph.render.js:1-26
Timestamp: 2026-01-20T16:50:56.414Z
Learning: In netjsongraph.js, prefer importing from echarts/lib/chart/*/install, echarts/lib/component/*/install, and echarts/lib/renderer/install* rather than the public entry points (echarts/charts, echarts/components, echarts/renderers) to improve tree-shaking and reduce bundle size. Apply this pattern across JS files in src (update imports accordingly) and verify by comparing bundle sizes between the install-path imports and the public-entry imports.

Applied to files:

  • src/js/netjsongraph.config.js
  • src/js/netjsongraph.util.js
  • src/js/netjsongraph.gui.js
📚 Learning: 2026-01-04T08:00:36.595Z
Learnt from: dee077
Repo: openwisp/netjsongraph.js PR: 417
File: src/js/netjsongraph.util.js:1302-1341
Timestamp: 2026-01-04T08:00:36.595Z
Learning: In the netjsongraph.js codebase, specifically in src/js/netjsongraph.util.js, the pattern '== null' is intentionally used to detect both null and undefined in a single comparison. Do not flag or replace these checks with strict equality checks (=== null or === undefined) for this file; preserve the established idiom.

Applied to files:

  • src/js/netjsongraph.util.js
📚 Learning: 2026-05-19T23:25:39.778Z
Learnt from: nemesifier
Repo: openwisp/netjsongraph.js PR: 542
File: src/js/netjsongraph.util.js:1478-1481
Timestamp: 2026-05-19T23:25:39.778Z
Learning: When reviewing netjsongraph label rendering logic in src/js/netjsongraph.util.js and src/js/netjsongraph.render.js, follow the documented contract for showMapLabelsAtZoom: (1) if showMapLabelsAtZoom is false, map labels must be completely disabled; (2) if it is 0, labels must always be shown regardless of zoom (do not treat 0 as disabled); (3) if it is a positive number N, labels must be shown only when zoom >= N. Ensure comparisons implement the intended semantics (i.e., zoom >= 0 is intentionally always true when the setting is 0).

Applied to files:

  • src/js/netjsongraph.util.js
🔇 Additional comments (4)
src/js/netjsongraph.config.js (1)

304-304: LGTM!

public/example_templates/netjsonmap-indoormap-overlay.html (1)

317-317: LGTM!

src/js/netjsongraph.util.js (1)

1273-1281: LGTM!

Also applies to: 1349-1362

src/js/netjsongraph.gui.js (1)

328-329: LGTM!

Also applies to: 357-357, 400-404

Comment thread test/netjsongraph.dom.test.js
@nemesifier nemesifier changed the title [fix] Preserve indoor overlay URL fragment on popup close [chroes:fix] Preserve indoor overlay URL fragment on popup close May 22, 2026
@nemesifier nemesifier changed the title [chroes:fix] Preserve indoor overlay URL fragment on popup close [chores:fix] Preserve indoor overlay URL fragment on popup close May 22, 2026
@github-project-automation github-project-automation Bot moved this from In progress to Reviewer approved in OpenWISP Priorities for next releases May 22, 2026
@nemesifier nemesifier merged commit ced65ac into master May 22, 2026
13 checks passed
@nemesifier nemesifier deleted the fix/546-preserve-overlay-fragment branch May 22, 2026 20:08
@github-project-automation github-project-automation Bot moved this from Backlog to Done in 26.06 Release May 22, 2026
@github-project-automation github-project-automation Bot moved this from Reviewer approved to Done in OpenWISP Priorities for next releases May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug javascript Pull requests that update Javascript code

Development

Successfully merging this pull request may close these issues.

[bug] Indoor map popup close should preserve overlay fragment id

2 participants