Skip to content

Conversation

@iOvergaard
Copy link
Contributor

@iOvergaard iOvergaard commented Nov 21, 2025

Summary

Enhances the donut chart on the Log Viewer. Chart slices are clickable and navigate to filtered search results. The router now supports SVGAElements as well.

Changes

Enhanced Components

  • Donut Chart Component (umb-donut-chart):

    • Added support for clickable slices via href property
    • Added show-inline-numbers attribute to display counts inside slices
    • Slices now wrap in SVG <a> tags when href is provided
    • Fixed tooltip positioning to appear near the cursor
    • Made container responsive with percentage-based width
  • Donut Slice Component (umb-donut-slice):

    • Added href property to make slices clickable
  • Log Viewer Overview (log-viewer-log-types-chart.element.ts):

    • Added clickable slices that navigate to the search view with appropriate filters
    • Implemented responsive layout using CSS Grid with container queries
    • Legend displays on the right on desktop (≥312px), centered below the chart on mobile
    • Added date range observer to pass current dates to search URLs

Core Router Enhancement

  • SVG Anchor Support (anchor.ts):
    • Router now intercepts clicks on SVG <a> elements (previously only HTML anchors)
    • Handles SVGAnimatedString type for SVG href and target properties
    • Resolves relative URLs correctly using document.location.origin as base
    • Validates origin to distinguish internal vs external links
    • Enables SPA navigation for SVG-based interactive charts throughout the application

Visual Changes

Desktop Layout (container ≥ 312px):

Before:
image

After:
image

Mobile Layout (container < 312px):

Before:
image

After:
image

Technical Details

URL Structure

Clicking a slice navigates to:
section/settings/workspace/logviewer/view/search/?loglevels=Information&startDate=2025-11-19&endDate=2025-11-21

Router Changes

The router's ensureAnchorHistory() function now handles both HTMLAnchorElement and SVGAElement:

  • Extracts href using .baseVal for SVG (handles SVGAnimatedString)
  • Uses URL constructor with document.location.origin for consistent URL resolution
  • Compares fullUrl.origin !== location.origin to distinguish internal/external links

Responsive Breakpoint

  • Container query at 312px switches between mobile/desktop layouts
  • Chart maintains square aspect ratio with aspect-ratio: 1
  • Max width of 200px prevents oversized charts

Test Steps

1. Basic Functionality

  • Navigate to Settings → Log Viewer → Overview
  • Verify donut chart displays with colored slices for each log level
  • Verify numbers appear inside each slice
  • Verify description text appears above the chart
  • Hover over slices and verify the tooltip appears near the cursor, showing the level name and count

2. Chart Interactions

  • Click on a donut slice (e.g., "Information")
  • Verify navigation to Search view without page reload (SPA navigation)
  • Verify URL contains correct log level filter: ?loglevels=Information
  • Verify URL contains current date range: &startDate=...&endDate=...
  • Verify search results show only logs matching the clicked level

3. Responsive Layout

Desktop (≥312px width):

  • Resize browser to > 312px width
  • Verify chart appears on the left, legend on the right
  • Verify legend items are left-aligned

Mobile (<312px width):

  • Resize browser to < 312px width
  • Verify chart appears above legend
  • Verify both chart and legend are centered
  • Verify layout remains readable and functional

4. Date Range Changes

  • Change the date range picker on overview page
  • Verify donut chart updates to reflect new log counts
  • Click a slice and verify the new date range is included in the URL

5. External Link Test (Router regression)

  • Open browser dev tools → Console
  • Add a test external link: Create a simple HTML anchor to https://google.com
  • Click the external link
  • Verify it opens in same/new tab (based on target attribute) without SPA router interception
  • Verify no JavaScript errors in console

Notes

  • The donut chart component is generic and can be reused elsewhere in the backoffice
  • SVG anchor support in the router is a general improvement that benefits the entire application
  • URL resolution uses document.location.origin to match existing Umbraco root-relative URL patterns

iOvergaard and others added 9 commits November 21, 2025 12:17
- Import and use repeat directive for better performance
- Add _logLevelKeys state property to track log level keys
- Update setLogLevelCount() to populate _logLevelKeys
- Replace .map() with repeat() in render method for legend and donut slices
- Update willUpdate to observe both filter and response changes
- Resolves TODO comment about using repeat directive

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add showInlineNumbers property to optionally display numbers inside slices
- Implement #getTextPosition() method to calculate text position at slice center
- Render SVG text elements when showInlineNumbers is enabled
- Fix tooltip positioning to appear near cursor (changed from x-10, y-70 to x+10, y+10)
- Recalculate container bounds on each mouse move to handle window resize
- Add pointer-events: none to tooltip to prevent mouse interference
- Add CSS styling for slice numbers (user-select: none)
- Enable inline numbers by default in log viewer log types chart

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add href property to donut-slice element for clickable slices
- Wrap SVG paths in <a> tags when href is provided
- Update Circle interface to include href property
- Add showDescription property to optionally display description text
- Render description as visible text below the chart
- Add CSS styling for description text
- Update log-types-chart to build search URLs with log level and date range
- Observe dateRange from context to build accurate search URLs
- Enable clickable slices and visible description in log-types-chart

Now clicking on a donut slice navigates to the search view filtered by that log level and the current date range.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add media query to switch from column to row layout on screens wider than 768px. This ensures the legend and donut chart are displayed side by side on desktop resolutions instead of stacked vertically.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copilot AI review requested due to automatic review settings November 21, 2025 17:40
@iOvergaard iOvergaard added the preview/backoffice Pull requests that can be previewed in a static version of the Backoffice label Nov 21, 2025
@github-actions
Copy link

Azure Static Web Apps: Your stage site is ready! Visit it here: https://victorious-ground-017b08103-20928.westeurope.6.azurestaticapps.net

Copilot finished reviewing on behalf of iOvergaard November 21, 2025 17:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the Log Viewer's donut chart component to be more interactive and responsive. It adds clickable slices that navigate to filtered search results, displays counts inline within slices, and implements responsive layouts for different screen sizes. The router was also enhanced to support SVG anchor elements for SPA navigation.

Key Changes:

  • Added clickable slices to the donut chart that link to filtered log search views with appropriate date ranges
  • Implemented responsive layout using CSS Grid with container queries (312px breakpoint)
  • Extended the core router to handle SVG <a> elements for SPA navigation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot/util/anchor.ts Added support for SVG anchor elements in the router's click handler, extracting href from SVGAnimatedString and handling URL resolution
src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/donut-chart/donut-chart.element.ts Added showInlineNumbers and showDescription properties, implemented text positioning for inline numbers, wrapped slices in SVG anchors when href is provided, made container responsive
src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/donut-chart/donut-slice.element.ts Added href property to enable clickable slices
src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-log-types-chart.element.ts Added date range observer, implemented #buildSearchUrl() method, refactored template to use Lit's repeat directive, implemented responsive CSS Grid layout
src/Umbraco.Web.UI.Client/src/mocks/data/log-viewer.data.ts Refactored getLevelCount() to use cleaner reduce pattern with proper TypeScript typing

override render() {
return html`
<uui-box id="types" headline="Log types">
<p id="description">In the chosen date range you have this number of log message of type:</p>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

The description text has a grammatical error. It should say "this number of log messages" (plural) since it refers to multiple messages.

Change to: "In the chosen date range you have this number of log messages of type:"

Suggested change
<p id="description">In the chosen date range you have this number of log message of type:</p>
<p id="description">In the chosen date range you have this number of log messages of type:</p>

Copilot uses AI. Check for mistakes.
Comment on lines 214 to 221
#calculateDetailsBoxPosition = (event: MouseEvent) => {
// Recalculate bounds on each mouse move to handle window resize
this.#containerBounds = this._container.getBoundingClientRect();
const x = this.#containerBounds ? event.clientX - this.#containerBounds?.left : 0;
const y = this.#containerBounds ? event.clientY - this.#containerBounds?.top : 0;
this._posX = x - 10;
this._posY = y - 70;
this._posX = x + 10;
this._posY = y + 10;
};
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

[nitpick] The #calculateDetailsBoxPosition method is called on every mousemove event and recalculates getBoundingClientRect() each time. This could impact performance, especially with many rapid mouse movements.

Consider throttling or debouncing the position calculation, or only recalculating the bounds when the window resizes rather than on every mouse move. The bounds don't change during mouse movement unless the window is resized.

Copilot uses AI. Check for mistakes.

// Change the history!
history.pushState(null, '', path);
history.pushState(null, '', fullUrl);
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

The history.pushState API expects a string for the URL parameter, not a URL object. While the URL object will be coerced to a string, it will include the full absolute URL (e.g., https://example.com/path) rather than just the path portion.

This differs from the previous implementation which passed pathname + search + hash, and may cause issues with the history state.

Recommend changing to:

history.pushState(null, '', fullUrl.pathname + fullUrl.search + fullUrl.hash);
Suggested change
history.pushState(null, '', fullUrl);
history.pushState(null, '', fullUrl.pathname + fullUrl.search + fullUrl.hash);

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/frontend preview/backoffice Pull requests that can be previewed in a static version of the Backoffice release/17.1.0 type/feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants