Skip to content

Feature/extension bar and explorer tooltip - #4489

Merged
ChristianHuehn merged 4 commits into
mainfrom
feature/extension-bar-and-explorer-tooltip
Jun 12, 2026
Merged

Feature/extension bar and explorer tooltip#4489
ChristianHuehn merged 4 commits into
mainfrom
feature/extension-bar-and-explorer-tooltip

Conversation

@ChristianHuehn

@ChristianHuehn ChristianHuehn commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

{Meaningful title}

Please read the CONTRIBUTING.md before opening a PR.

Closes: #

Description

Descriptive pull request text, answering:

  • What problem/issue are you fixing?
  • What does this PR implement and how?

Definition of Done

A PR is only ready for merge once all the following acceptance criteria are fulfilled:

  • Changes have been manually tested
  • All TODOs related to this PR have been closed
  • There are automated tests for newly written code and bug fixes
  • All bugs discovered while working on this PR have been submitted as issues (if not already an open issue)
  • Documentation (GH-pages, analysis/visualization READMEs, parser READMEs, --help, etc.) has been updated (almost always necessary except for bug fixes)
  • CHANGELOG.md has been updated

Screenshots or gifs

Summary by CodeRabbit

  • New Features

    • Added hover tooltips in the file explorer displaying node name and metric values
    • Added vertical dividers in the navbar between controls
  • Changed

    • Moved file extension bar to the bottom of the screen (above the bottom bar)
    • CodeCharta logo now links to codecharta.com instead of GitHub
    • Removed native browser tooltips from explorer tree items
  • Bug Fixes

    • Updated layout and screenshot handling to accommodate repositioned components

christian-huehn-mw and others added 4 commits June 12, 2026 11:05
The metric distribution strip is now fixed directly above the bottom
bar instead of sitting below the toolbar. It publishes its height as
--cc-file-extension-bar-height, which the floating metrics bar, the
legend, both sidebars, and the screenshot capture region account for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Separate Compare, 3D Print, and Settings with short vertical lines and
point the CodeCharta logo at https://codecharta.com/ instead of the
GitHub repository.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hovering a file or folder in the File Explorer shows the map's hover
tooltip (node name plus active area/height/color metric values),
anchored to the right edge of the hovered row. The tooltip service now
accepts a minimal TooltipNode so CodeMapNode works alongside the layout
Node. The native browser title tooltip on row names is removed as
redundant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements explorer row hover tooltips using a shared tooltip service, repositions the file extension bar to measure and publish its dynamic height via CSS variables, updates layout components to account for separated bar measurements, and adds navbar polish including dividers and a branding link update.

Changes

Explorer tooltip and file extension bar layout updates

Layer / File(s) Summary
Tooltip node contract and service updates
visualization/app/codeCharta/ui/codeMap/codeMap.tooltip.service.ts
The shared tooltip service now accepts a TooltipNode interface with required name, optional id, and optional attributes. Metric value lookup uses optional chaining to tolerate missing attributes.
Explorer tree hover tooltip wiring and tests
visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeLevel/explorerTreeLevel.component.ts, explorerTreeLevel.component.html, explorerTreeLevel.component.spec.ts, explorerTreeItemName/explorerTreeItemName.component.html, visualization/CHANGELOG.md, plans/2026-06-12-explorer-hover-tooltip.md
Explorer tree rows forward mouse events, compute row bounds, and trigger tooltip display/hide. Native title tooltips on row names are removed. Tests verify tooltip behavior with node data and coordinates.
File extension bar height publishing
visualization/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.ts, visualization/app/codeCharta/codeCharta.component.html
The file extension bar component gains lifecycle hooks to measure its rendered height, publish it via the --cc-file-extension-bar-height CSS variable using ResizeObserver, and maintain the property on destroy. The bar is reordered in the template to appear after metrics and legend panels.
Layout consumers: bars height and positioning
visualization/app/codeCharta/ui/codeMap/codeMap.component.ts, codeMap.component.scss, features/metricsBar/components/metricsBar/metricsBar.component.ts, features/sidebarExplorer/components/sidebarExplorer/sidebarExplorer.component.ts, features/sidebarInspector/components/sidebarInspector/sidebarInspector.component.ts, ui/legendPanel/legendPanel.component.scss
The nav bar observer is simplified to track only cc-nav-bar. Layout components update positioning and sizing to use the new --cc-file-extension-bar-height CSS variable with 49px fallbacks for navbar bar height.
Screenshot canvas sizing adjustments
visualization/app/codeCharta/features/viewCubeToolbox/services/screenshot.service.ts
The screenshot service computes bottomBarsHeight from file extension and bottom bar heights separately, adjusting the html2canvas capture region to exclude the repositioned bars.
Navbar dividers, logo link, and documentation
visualization/app/codeCharta/features/navBar/components/navBar/navBar.component.html, navBarLogo/navBarLogo.component.html, visualization/CHANGELOG.md, plans/2026-06-12-navbar-extension-bar-fixes.md
The navbar adds thin vertical dividers around the 3D Print button, updates the CC logo link and tooltip to the project website, and documents the layout and branding changes in the changelog and plan files.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • MaibornWolff/codecharta#4485: Both PRs modify ScreenshotService.buildScreenShotCanvas to adjust how the screenshot viewport region is calculated and cropped.

Suggested reviewers

  • christian-spahn-mw

Poem

🐰 A tooltip hops through explorer trees,
The bar below now dances free,
With CSS heights and navbar cheer,
Layout dance perfected here!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely unmodified from the template with placeholders not filled in: the meaningful title, problem/issue description, implementation details, and all Definition of Done checklist items remain blank or unchecked. Replace placeholder text with actual descriptions of what problem was fixed, how the features were implemented, verify all Definition of Done criteria, and include screenshots/gifs if applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feature/extension bar and explorer tooltip' clearly summarizes the two main features implemented: moving the extension bar and adding explorer hover tooltips.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/extension-bar-and-explorer-tooltip

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.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
visualization/app/codeCharta/features/viewCubeToolbox/services/screenshot.service.ts (1)

73-114: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Restore temporary label styles in a finally block.

If html2canvas() or getCroppedCanvas() throws, restoreLabelsAfterScreenshot() never runs and the map labels stay in their screenshot-only styling for the rest of the session.

Suggested fix
     private async buildScreenShotCanvas(renderer: WebGLRenderer): Promise<HTMLCanvasElement> {
         renderer.setPixelRatio(window.devicePixelRatio)
         renderer.setClearColor(new Color(0, 0, 0), 0)
         renderer.render(this.threeSceneService.scene, this.threeCameraService.camera)

         const savedLabelStyles = this.prepareLabelsForScreenshot()
@@
-        const canvas = await html2canvas(document.querySelector("body"), {
-            removeContainer: true,
-            backgroundColor: null,
-            scrollY: -navBarHeight,
-            height: Math.max(0, bodyHeight - navBarHeight - bottomBarsHeight),
-            ignoreElements(element) {
-                return (
-                    tagsNamesToIgnore.has(element.tagName.toLowerCase()) ||
-                    idsToIgnore.has(element.id) ||
-                    (element as HTMLElement).style.zIndex === "10000"
-                )
-            }
-        })
-
-        this.restoreLabelsAfterScreenshot(savedLabelStyles)
-
-        return this.getCroppedCanvas(canvas)
+        try {
+            const canvas = await html2canvas(document.querySelector("body"), {
+                removeContainer: true,
+                backgroundColor: null,
+                scrollY: -navBarHeight,
+                height: Math.max(0, bodyHeight - navBarHeight - bottomBarsHeight),
+                ignoreElements(element) {
+                    return (
+                        tagsNamesToIgnore.has(element.tagName.toLowerCase()) ||
+                        idsToIgnore.has(element.id) ||
+                        (element as HTMLElement).style.zIndex === "10000"
+                    )
+                }
+            })
+
+            return this.getCroppedCanvas(canvas)
+        } finally {
+            this.restoreLabelsAfterScreenshot(savedLabelStyles)
+        }
     }
🤖 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
`@visualization/app/codeCharta/features/viewCubeToolbox/services/screenshot.service.ts`
around lines 73 - 114, The temporary label styles set by
prepareLabelsForScreenshot() must always be restored; wrap the async screenshot
capture and cropping in a try/finally so
restoreLabelsAfterScreenshot(savedLabelStyles) runs regardless of errors: call
const savedLabelStyles = this.prepareLabelsForScreenshot() before the try, then
inside try await html2canvas(document.querySelector("body"), {...}) and return
this.getCroppedCanvas(canvas) (or store the result), and in finally call
this.restoreLabelsAfterScreenshot(savedLabelStyles); keep the ignoreElements
logic and options for html2canvas unchanged.
visualization/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.ts (1)

26-29: ⚠️ Potential issue | 🟠 Major

Unsubscribe from hoveredNodeMetricDistribution$ in ngOnDestroy()

FileExtensionBarComponent.ngOnInit() creates a raw subscribe() to metricDistributionService.hoveredNodeMetricDistribution$, but ngOnDestroy() only disconnects the ResizeObserver and removes --cc-file-extension-bar-height. Since <cc-file-extension-bar> is rendered inside @if (isInitialized()) in codeCharta.component.html, the component can be recreated and each old subscriber will remain active.

Suggested fix
 export class FileExtensionBarComponent implements OnInit, AfterViewInit, OnDestroy {
     showAbsoluteValues = false
     metricDistribution: CategorizedMetricDistribution

     private readonly elementReference = inject(ElementRef<HTMLElement>)
     private resizeObserver?: ResizeObserver
+    private metricDistributionSubscription?: { unsubscribe(): void }

     constructor(private readonly metricDistributionService: MetricDistributionService) {}

     ngOnInit(): void {
-        this.metricDistributionService.hoveredNodeMetricDistribution$.subscribe(metricDistribution => {
+        this.metricDistributionSubscription = this.metricDistributionService.hoveredNodeMetricDistribution$.subscribe(metricDistribution => {
             this.metricDistribution = metricDistribution
         })
     }
@@
     ngOnDestroy(): void {
+        this.metricDistributionSubscription?.unsubscribe()
         this.resizeObserver?.disconnect()
         document.documentElement.style.removeProperty("--cc-file-extension-bar-height")
     }
 }
🤖 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
`@visualization/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.ts`
around lines 26 - 29, The component creates a raw subscription to
metricDistributionService.hoveredNodeMetricDistribution$ in ngOnInit but never
tears it down; add a Subscription (e.g., hoveredMetricSubscription) or a
destroyed Subject and store the subscription returned from
metricDistributionService.hoveredNodeMetricDistribution$.subscribe(...) in that
field inside ngOnInit, then unsubscribe (or complete the Subject and use
takeUntil) in ngOnDestroy alongside the existing ResizeObserver cleanup and
removal of --cc-file-extension-bar-height to prevent leaked subscribers when
FileExtensionBarComponent is recreated.
🤖 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.

Outside diff comments:
In
`@visualization/app/codeCharta/features/viewCubeToolbox/services/screenshot.service.ts`:
- Around line 73-114: The temporary label styles set by
prepareLabelsForScreenshot() must always be restored; wrap the async screenshot
capture and cropping in a try/finally so
restoreLabelsAfterScreenshot(savedLabelStyles) runs regardless of errors: call
const savedLabelStyles = this.prepareLabelsForScreenshot() before the try, then
inside try await html2canvas(document.querySelector("body"), {...}) and return
this.getCroppedCanvas(canvas) (or store the result), and in finally call
this.restoreLabelsAfterScreenshot(savedLabelStyles); keep the ignoreElements
logic and options for html2canvas unchanged.

In
`@visualization/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.ts`:
- Around line 26-29: The component creates a raw subscription to
metricDistributionService.hoveredNodeMetricDistribution$ in ngOnInit but never
tears it down; add a Subscription (e.g., hoveredMetricSubscription) or a
destroyed Subject and store the subscription returned from
metricDistributionService.hoveredNodeMetricDistribution$.subscribe(...) in that
field inside ngOnInit, then unsubscribe (or complete the Subject and use
takeUntil) in ngOnDestroy alongside the existing ResizeObserver cleanup and
removal of --cc-file-extension-bar-height to prevent leaked subscribers when
FileExtensionBarComponent is recreated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 231a9679-d201-4b1f-9b6a-b64cec6244e3

📥 Commits

Reviewing files that changed from the base of the PR and between 9ce1131 and 6295a11.

📒 Files selected for processing (19)
  • plans/2026-06-12-explorer-hover-tooltip.md
  • plans/2026-06-12-navbar-extension-bar-fixes.md
  • visualization/CHANGELOG.md
  • visualization/app/codeCharta/codeCharta.component.html
  • visualization/app/codeCharta/features/metricsBar/components/metricsBar/metricsBar.component.ts
  • visualization/app/codeCharta/features/navBar/components/navBar/navBar.component.html
  • visualization/app/codeCharta/features/navBar/components/navBarLogo/navBarLogo.component.html
  • visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeItemName/explorerTreeItemName.component.html
  • visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeLevel/explorerTreeLevel.component.html
  • visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeLevel/explorerTreeLevel.component.spec.ts
  • visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeLevel/explorerTreeLevel.component.ts
  • visualization/app/codeCharta/features/sidebarExplorer/components/sidebarExplorer/sidebarExplorer.component.ts
  • visualization/app/codeCharta/features/sidebarInspector/components/sidebarInspector/sidebarInspector.component.ts
  • visualization/app/codeCharta/features/viewCubeToolbox/services/screenshot.service.ts
  • visualization/app/codeCharta/ui/codeMap/codeMap.component.scss
  • visualization/app/codeCharta/ui/codeMap/codeMap.component.ts
  • visualization/app/codeCharta/ui/codeMap/codeMap.tooltip.service.ts
  • visualization/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.ts
  • visualization/app/codeCharta/ui/legendPanel/legendPanel.component.scss
💤 Files with no reviewable changes (1)
  • visualization/app/codeCharta/features/sidebarExplorer/components/explorerTreeItemName/explorerTreeItemName.component.html

@ChristianHuehn
ChristianHuehn enabled auto-merge (squash) June 12, 2026 09:16
@ChristianHuehn
ChristianHuehn disabled auto-merge June 12, 2026 09:16
@ChristianHuehn
ChristianHuehn merged commit fd25fde into main Jun 12, 2026
8 checks passed
@ChristianHuehn
ChristianHuehn deleted the feature/extension-bar-and-explorer-tooltip branch June 12, 2026 09:17
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.

2 participants