Skip to content

feat:Expand and collaps button added#460

Open
hussainjamal760 wants to merge 7 commits into
open-telemetry:mainfrom
hussainjamal760:expand/collapse-functionality
Open

feat:Expand and collaps button added#460
hussainjamal760 wants to merge 7 commits into
open-telemetry:mainfrom
hussainjamal760:expand/collapse-functionality

Conversation

@hussainjamal760
Copy link
Copy Markdown
Contributor

issue #394

Description: Added Expand All/Collapse All functionality to Telemetry Section

This PR introduces "Expand All" and "Collapse All" controls for the Metrics and Spans sections in the Java Agent instrumentation details page. The goal is to improve information hierarchy and reduce cognitive load by allowing users to toggle the visibility of technical details globally.

Key Changes

Features

  • Global Expansion Controls: Added segmented pill-shaped buttons to expand or collapse all Metrics and Spans simultaneously.
  • Improved Information Hierarchy: Details are now collapsible, keeping the initial view clean while allowing deep-dives on demand.

UI/UX Enhancements

  • Consistent Styling: Matched the new controls with the application's design system (using SegmentedTabList aesthetic: bg-muted container and secondary active states).
  • Refined Layout:
    • Repositioned global buttons below section headers for better flow.
    • Simplified card headers by removing redundant individual chevrons.
    • Restored badge alignment (e.g., histogram, CLIENT Span) to the right side for better readability.
  • Responsive Spacing: Adjusted margins and padding for a balanced look on both mobile and desktop.

Technical Improvements

  • Performance Optimization: Replaced useEffect state synchronization with inline state adjustment during render to prevent cascading renders.
  • Component Flexibility: Updated SectionDivider to support custom className props.
  • Clean Code: Removed unused functions and applied consistent formatting via Prettier.

Verification Results

  • Automated Tests: All 18 unit tests in telemetry-section.test.tsx passed successfully.
  • Manual Check: Verified that the "Expand/Collapse All" interaction is fluid and visual states are consistent with the main navigation tabs.
image

@hussainjamal760 hussainjamal760 requested review from a team as code owners May 13, 2026 01:02
@netlify
Copy link
Copy Markdown

netlify Bot commented May 13, 2026

Deploy Preview for otel-ecosystem-explorer ready!

Name Link
🔨 Latest commit e24cff1
🔍 Latest deploy log https://app.netlify.com/projects/otel-ecosystem-explorer/deploys/6a0bbdb9f9cef50008219059
😎 Deploy Preview https://deploy-preview-460--otel-ecosystem-explorer.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Member

@vitorvasc vitorvasc left a comment

Choose a reason for hiding this comment

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

Thank you @hussainjamal760!

We could also consider adding controls to collapse or expand a single element when clicking on this section, as well as the visual indicators for that:

Image

What do you think?

@vitorvasc vitorvasc self-assigned this May 13, 2026
@hussainjamal760
Copy link
Copy Markdown
Contributor Author

Thank you @hussainjamal760!

We could also consider adding controls to collapse or expand a single element when clicking on this section, as well as the visual indicators for that:

Image What do you think?

Yeah, I understand your point. But I think having http.client.request.duration, the badge, and the expand/collapse button all in the same line might make the UI feel a bit messy and crowded. Maybe we could keep the interaction simpler or separate the controls slightly to maintain readability.

what do you think?

@hussainjamal760 hussainjamal760 requested a review from vitorvasc May 13, 2026 19:20
@vitorvasc
Copy link
Copy Markdown
Member

Yeah, I understand your point. But I think having http.client.request.duration, the badge, and the expand/collapse button all in the same line might make the UI feel a bit messy and crowded. Maybe we could keep the interaction simpler or separate the controls slightly to maintain readability.

what do you think?

That makes sense. If the visual indicator feels like too much information, we can skip it and use cursor: pointer when hovering that section instead. I believe this still indicates to users that they can interact with it.

My rationale for allowing elements to be collapsed independently is that some libraries have a lot of metrics, for example: https://deploy-preview-460--otel-ecosystem-explorer.netlify.app/java-agent/instrumentation/2.27.0/grpc-1.6.

While collapsing all elements indeed reduces the cognitive load while navigating the page, the usability still isn't quite there yet, since the user currently has to either collapse everything or expand everything. If they want to see the details for a single metric at the bottom of the page, for example, they still have to expand everything and scroll through a bunch of information they don't actually need.

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

Yeah, I understand your point. But I think having http.client.request.duration, the badge, and the expand/collapse button all in the same line might make the UI feel a bit messy and crowded. Maybe we could keep the interaction simpler or separate the controls slightly to maintain readability.
what do you think?

That makes sense. If the visual indicator feels like too much information, we can skip it and use cursor: pointer when hovering that section instead. I believe this still indicates to users that they can interact with it.

My rationale for allowing elements to be collapsed independently is that some libraries have a lot of metrics, for example: https://deploy-preview-460--otel-ecosystem-explorer.netlify.app/java-agent/instrumentation/2.27.0/grpc-1.6.

While collapsing all elements indeed reduces the cognitive load while navigating the page, the usability still isn't quite there yet, since the user currently has to either collapse everything or expand everything. If they want to see the details for a single metric at the bottom of the page, for example, they still have to expand everything and scroll through a bunch of information they don't actually need.

That’s a fair point, especially for instrumentations with a large number of metrics. I agree that allowing individual sections to be expanded/collapsed would improve navigation and make it easier for users to focus only on the information they need.

I still think we should be careful with the visual density of the header row, but using cursor: pointer instead of adding another explicit indicator sounds like a clean compromise. That could keep the UI lightweight while still making the interaction discoverable.

I’ll explore an approach where individual items can be toggled independently without overcrowding the layout.

Copy link
Copy Markdown
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

Adds per-card and "Expand All / Collapse All" controls to the Metrics and Spans lists inside the Java-agent telemetry section. Card bodies are collapsed/expanded individually via a clickable header (chevron + badge), and a pill-shaped segmented control below each section heading toggles every card at once. SectionDivider is extended with an optional className so the new controls can sit flush under it, and three new Vitest cases cover the toggle behavior.

Changes:

  • Add expandedMetrics / expandedSpans state plus toggle/expand-all/collapse-all handlers in TelemetrySection, including a render-time sync block that resets expansion when currentTelemetry changes.
  • Restructure metric and span cards into a clickable role="button" header (with chevron) and a conditionally-rendered detail panel; add duplicated pill-style "Expand All / Collapse All" controls per section.
  • Allow callers to pass a custom className to SectionDivider, and add tests for click and keyboard toggling.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
ecosystem-explorer/src/features/java-agent/components/telemetry-section.tsx New expand/collapse state, clickable card headers, and per-section Expand/Collapse All pill controls.
ecosystem-explorer/src/features/java-agent/components/telemetry-section.test.tsx Adds three tests covering click toggle on metric/span headers and Enter/Space keyboard activation.
ecosystem-explorer/src/components/ui/section-divider.tsx Threads an optional className prop through to the wrapper div.
Comments suppressed due to low confidence (1)

ecosystem-explorer/src/features/java-agent/components/telemetry-section.tsx:269

  • Same accessibility issue as the metrics header: role="button" div with no aria-expanded, no aria-controls, and re-implementing Enter/Space handling that a native <button> would provide. Prefer a real <button type="button"> element here.
                      <div
                        role="button"
                        tabIndex={0}
                        onClick={() => toggleSpan(index.toString())}
                        onKeyDown={(e) => {
                          if (e.key === "Enter" || e.key === " ") {
                            e.preventDefault();
                            toggleSpan(index.toString());
                          }
                        }}
                        className="flex cursor-pointer items-center justify-between gap-4 p-4 transition-colors hover:bg-white/[0.02] sm:px-6 sm:py-5"
                      >

Comment on lines +152 to +163
<div
role="button"
tabIndex={0}
onClick={() => toggleMetric(metric.name)}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
toggleMetric(metric.name);
}
}}
className="flex cursor-pointer items-center justify-between gap-4 p-4 transition-colors hover:bg-white/[0.02] sm:px-6 sm:py-5"
>
Comment on lines +114 to +141
<div className="mt-4 flex justify-center">
<div className="border-border/50 bg-muted/80 inline-flex items-center rounded-xl border p-1 shadow-sm backdrop-blur-sm">
<button
type="button"
onClick={expandAllMetrics}
className={`flex items-center gap-1.5 rounded-lg px-4 py-2 text-[10px] font-bold tracking-widest uppercase transition-all duration-200 ${
expandedMetrics.size === (currentTelemetry.metrics?.length || 0)
? "border-secondary/40 bg-secondary/12 text-secondary border shadow-sm"
: "text-muted-foreground hover:text-foreground border border-transparent"
}`}
>
<Maximize2 className="h-3 w-3" />
Expand All
</button>
<button
type="button"
onClick={collapseAllMetrics}
className={`flex items-center gap-1.5 rounded-lg px-4 py-2 text-[10px] font-bold tracking-widest uppercase transition-all duration-200 ${
expandedMetrics.size === 0
? "border-secondary/40 bg-secondary/12 text-secondary border shadow-sm"
: "text-muted-foreground hover:text-foreground border border-transparent"
}`}
>
<Minimize2 className="h-3 w-3" />
Collapse All
</button>
</div>
</div>
Comment on lines +42 to +43
const [expandedSpans, setExpandedSpans] = useState<Set<string>>(
new Set(currentTelemetry?.spans?.map((_, i) => i.toString()) || [])
Comment on lines +39 to +55
const [expandedMetrics, setExpandedMetrics] = useState<Set<string>>(
new Set(currentTelemetry?.metrics?.map((m) => m.name) || [])
);
const [expandedSpans, setExpandedSpans] = useState<Set<string>>(
new Set(currentTelemetry?.spans?.map((_, i) => i.toString()) || [])
);

// Synchronize expanded state when telemetry changes without using useEffect
const [prevTelemetry, setPrevTelemetry] = useState(currentTelemetry);
if (currentTelemetry !== prevTelemetry) {
setPrevTelemetry(currentTelemetry);
setExpandedMetrics(new Set(currentTelemetry?.metrics?.map((m) => m.name) || []));
setExpandedSpans(new Set(currentTelemetry?.spans?.map((_, i) => i.toString()) || []));
}

const expandAllMetrics = () => {
setExpandedMetrics(new Set(currentTelemetry?.metrics?.map((m) => m.name) || []));
Comment on lines +439 to +440
const metricHeader = screen.getByText("http.server.duration").parentElement!;
await user.click(metricHeader);
Copy link
Copy Markdown
Member

@jaydeluca jaydeluca left a comment

Choose a reason for hiding this comment

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

the feature itself looks good, can you address the copilot comments that I gave a " 👍 " to? then this should be good to go

@hussainjamal760
Copy link
Copy Markdown
Contributor Author

the feature itself looks good, can you address the copilot comments that I gave a " 👍 " to? then this should be good to go

Sure ,

@hussainjamal760 hussainjamal760 requested a review from jaydeluca May 19, 2026 01:35
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.

4 participants