Skip to content

[APM] Fix metrics tab crash: migrate from controlGroupState to pinned_panels#254999

Merged
smith merged 14 commits intoelastic:mainfrom
smith:fix/apm-metrics-dashboard-controls
Mar 4, 2026
Merged

[APM] Fix metrics tab crash: migrate from controlGroupState to pinned_panels#254999
smith merged 14 commits intoelastic:mainfrom
smith:fix/apm-metrics-dashboard-controls

Conversation

@smith
Copy link
Copy Markdown
Contributor

@smith smith commented Feb 25, 2026

Summary

The APM service metrics tab crashes when loading the static JSON dashboard because the dashboard plugin's DashboardState no longer has a controlGroupState property — controls are now represented as pinned_panels.

Caused by: [Controls Anywhere] Feature Branch — #245588

That PR refactored the entire controls system, removing the controlGroup embeddable and replacing controlGroupState with pinned_panels in DashboardState. The APM static_dashboard/index.tsx was updated to use the new controlGroupStateBuilder API signature (adding the uiActions param), but the fundamental issue was missed: the controlGroupState object built by the builder is no longer consumed by the dashboard. The getInitialInput() return value spreads into DashboardState, which silently ignores the controlGroupState property — or worse, the controlGroupStateBuilder.addDataControlFromField() call throws during control type detection via uiActions, causing getCreationOptions to fall into the catch block and return empty options (no panels rendered at all).

A follow-up PR ([Dashboards as Code] snake_case controls schemas — #249300) snake_cased the field names in the builder call but didn't address the underlying issue.

Fix:

  • Replace the controlGroupStateBuilder + controlGroupState pattern with a direct pinned_panels array in the new format
  • Add useControlsIntegration: true to DashboardCreationOptions so the controls render
  • Remove the now-unused @kbn/control-group-renderer dependency and UiActionsStart parameter

Changes

  • x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx — migrated controls from controlGroupState to pinned_panels
  • x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.test.tsx — added Jest tests for getCreationOptions contract
  • x-pack/solutions/observability/plugins/apm/tsconfig.json — replaced @kbn/control-group-renderer reference with @kbn/controls-constants

Test plan

  • Navigate to an APM service with a known runtime dashboard (e.g. Java, Node.js) → Metrics tab
  • Verify the "Node name" options list control renders above the dashboard
  • Verify dashboard panels load without errors
  • Verify filtering by node name works correctly
  • Jest tests pass

@smith smith requested review from Heenawter and Copilot February 25, 2026 20:01
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

This PR fixes a crash in the APM service metrics tab by migrating the dashboard controls system from the deprecated controlGroupState API to the new pinned_panels format introduced in the "Controls Anywhere" feature.

Changes:

  • Replaced controlGroupStateBuilder with direct pinned_panels array configuration
  • Added useControlsIntegration: true flag to enable controls rendering
  • Removed unused @kbn/control-group-renderer dependency and UiActionsStart parameter

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx Migrated controls from deprecated controlGroupState to new pinned_panels format and removed unused imports
x-pack/solutions/observability/plugins/apm/tsconfig.json Updated dependency from @kbn/control-group-renderer to @kbn/controls-constants

@smith
Copy link
Copy Markdown
Contributor Author

smith commented Feb 25, 2026

/oblt-deploy

@smith smith added release_note:fix backport:skip This PR does not require backporting labels Feb 26, 2026
smith and others added 2 commits February 25, 2026 21:45
…nned_panels

The dashboard plugin removed `controlGroupState` from `DashboardState`,
replacing it with `pinned_panels`. The APM static dashboard component
was still using `controlGroupStateBuilder.addDataControlFromField()`
to build a `controlGroupState` object passed via `getInitialInput()`.
This caused the "Node name" options list control to either fail to
initialize or be silently dropped.

Replace the deprecated pattern with direct `pinned_panels` array
construction and enable `useControlsIntegration` in creation options.

Co-authored-by: Cursor <cursoragent@cursor.com>
Verify the pinned_panels contract: useControlsIntegration flag,
options list control shape, data view ID pass-through, panel
forwarding, and error toast on failure.

Made-with: Cursor
@smith smith force-pushed the fix/apm-metrics-dashboard-controls branch from 1b29825 to b6600a9 Compare February 26, 2026 03:47
@smith smith marked this pull request as ready for review February 26, 2026 03:48
@smith smith requested a review from a team as a code owner February 26, 2026 03:48
@smith smith requested a review from Copilot February 26, 2026 03:48
@smith smith enabled auto-merge (squash) February 26, 2026 03:48
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

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

@botelastic botelastic bot added the Team:obs-presentation Focus: APM UI, Infra UI, Hosts UI, Universal Profiling, Obs Overview and left Navigation label Feb 26, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/obs-presentation-team (Team:obs-presentation)

smith and others added 6 commits February 26, 2026 08:07
…pp/metrics/static_dashboard/index.test.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…pp/metrics/static_dashboard/index.test.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The pinned_panels array element is a discriminated union of control types.
Accessing config.data_view_id without narrowing fails type checking because
not all control variants (e.g. timeSlider, esqlControl) have that property.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@Heenawter Heenawter left a comment

Choose a reason for hiding this comment

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

Solution makes sense to me 🙇 Thanks for tackling this - code review LGTM

Comment on lines +85 to +86
jest.restoreAllMocks();
jest.clearAllMocks();
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.

It seems to be redundant to call clearAllMocks(). Are they not overlapping?

@rmyz
Copy link
Copy Markdown
Contributor

rmyz commented Mar 4, 2026

/ci

@smith smith merged commit d5727c9 into elastic:main Mar 4, 2026
13 checks passed
@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Jest Tests #9 / discover responsive sidebar search bar customization should allow to toggle sidebar

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
apm 2229 2207 -22

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
apm 2.7MB 2.7MB -71.7KB
Unknown metric groups

async chunk count

id before after diff
apm 86 85 -1

History

SoniaSanzV pushed a commit to SoniaSanzV/kibana that referenced this pull request Mar 5, 2026
…_panels (elastic#254999)

## Summary

The APM service metrics tab crashes when loading the static JSON
dashboard because the dashboard plugin's `DashboardState` no longer has
a `controlGroupState` property — controls are now represented as
`pinned_panels`.

**Caused by:** [Controls Anywhere] Feature Branch —
elastic#245588

That PR refactored the entire controls system, removing the
`controlGroup` embeddable and replacing `controlGroupState` with
`pinned_panels` in `DashboardState`. The APM
`static_dashboard/index.tsx` was updated to use the new
`controlGroupStateBuilder` API signature (adding the `uiActions` param),
but the fundamental issue was missed: the `controlGroupState` object
built by the builder is no longer consumed by the dashboard. The
`getInitialInput()` return value spreads into `DashboardState`, which
silently ignores the `controlGroupState` property — or worse, the
`controlGroupStateBuilder.addDataControlFromField()` call throws during
control type detection via `uiActions`, causing `getCreationOptions` to
fall into the catch block and return empty options (no panels rendered
at all).

A follow-up PR ([Dashboards as Code] `snake_case` controls schemas —
elastic#249300) snake_cased the field
names in the builder call but didn't address the underlying issue.

**Fix:**
- Replace the `controlGroupStateBuilder` + `controlGroupState` pattern
with a direct `pinned_panels` array in the new format
- Add `useControlsIntegration: true` to `DashboardCreationOptions` so
the controls render
- Remove the now-unused `@kbn/control-group-renderer` dependency and
`UiActionsStart` parameter

### Changes
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx`
— migrated controls from `controlGroupState` to `pinned_panels`
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.test.tsx`
— added Jest tests for `getCreationOptions` contract
- `x-pack/solutions/observability/plugins/apm/tsconfig.json` — replaced
`@kbn/control-group-renderer` reference with `@kbn/controls-constants`

## Test plan
- [x] Navigate to an APM service with a known runtime dashboard (e.g.
Java, Node.js) → Metrics tab
- [x] Verify the "Node name" options list control renders above the
dashboard
- [x] Verify dashboard panels load without errors
- [x] Verify filtering by node name works correctly
- [x] Jest tests pass

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
rbrtj pushed a commit to rbrtj/kibana that referenced this pull request Mar 5, 2026
…_panels (elastic#254999)

## Summary

The APM service metrics tab crashes when loading the static JSON
dashboard because the dashboard plugin's `DashboardState` no longer has
a `controlGroupState` property — controls are now represented as
`pinned_panels`.

**Caused by:** [Controls Anywhere] Feature Branch —
elastic#245588

That PR refactored the entire controls system, removing the
`controlGroup` embeddable and replacing `controlGroupState` with
`pinned_panels` in `DashboardState`. The APM
`static_dashboard/index.tsx` was updated to use the new
`controlGroupStateBuilder` API signature (adding the `uiActions` param),
but the fundamental issue was missed: the `controlGroupState` object
built by the builder is no longer consumed by the dashboard. The
`getInitialInput()` return value spreads into `DashboardState`, which
silently ignores the `controlGroupState` property — or worse, the
`controlGroupStateBuilder.addDataControlFromField()` call throws during
control type detection via `uiActions`, causing `getCreationOptions` to
fall into the catch block and return empty options (no panels rendered
at all).

A follow-up PR ([Dashboards as Code] `snake_case` controls schemas —
elastic#249300) snake_cased the field
names in the builder call but didn't address the underlying issue.

**Fix:**
- Replace the `controlGroupStateBuilder` + `controlGroupState` pattern
with a direct `pinned_panels` array in the new format
- Add `useControlsIntegration: true` to `DashboardCreationOptions` so
the controls render
- Remove the now-unused `@kbn/control-group-renderer` dependency and
`UiActionsStart` parameter

### Changes
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx`
— migrated controls from `controlGroupState` to `pinned_panels`
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.test.tsx`
— added Jest tests for `getCreationOptions` contract
- `x-pack/solutions/observability/plugins/apm/tsconfig.json` — replaced
`@kbn/control-group-renderer` reference with `@kbn/controls-constants`

## Test plan
- [x] Navigate to an APM service with a known runtime dashboard (e.g.
Java, Node.js) → Metrics tab
- [x] Verify the "Node name" options list control renders above the
dashboard
- [x] Verify dashboard panels load without errors
- [x] Verify filtering by node name works correctly
- [x] Jest tests pass

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
DennisKo pushed a commit to DennisKo/kibana that referenced this pull request Mar 6, 2026
…_panels (elastic#254999)

## Summary

The APM service metrics tab crashes when loading the static JSON
dashboard because the dashboard plugin's `DashboardState` no longer has
a `controlGroupState` property — controls are now represented as
`pinned_panels`.

**Caused by:** [Controls Anywhere] Feature Branch —
elastic#245588

That PR refactored the entire controls system, removing the
`controlGroup` embeddable and replacing `controlGroupState` with
`pinned_panels` in `DashboardState`. The APM
`static_dashboard/index.tsx` was updated to use the new
`controlGroupStateBuilder` API signature (adding the `uiActions` param),
but the fundamental issue was missed: the `controlGroupState` object
built by the builder is no longer consumed by the dashboard. The
`getInitialInput()` return value spreads into `DashboardState`, which
silently ignores the `controlGroupState` property — or worse, the
`controlGroupStateBuilder.addDataControlFromField()` call throws during
control type detection via `uiActions`, causing `getCreationOptions` to
fall into the catch block and return empty options (no panels rendered
at all).

A follow-up PR ([Dashboards as Code] `snake_case` controls schemas —
elastic#249300) snake_cased the field
names in the builder call but didn't address the underlying issue.

**Fix:**
- Replace the `controlGroupStateBuilder` + `controlGroupState` pattern
with a direct `pinned_panels` array in the new format
- Add `useControlsIntegration: true` to `DashboardCreationOptions` so
the controls render
- Remove the now-unused `@kbn/control-group-renderer` dependency and
`UiActionsStart` parameter

### Changes
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx`
— migrated controls from `controlGroupState` to `pinned_panels`
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.test.tsx`
— added Jest tests for `getCreationOptions` contract
- `x-pack/solutions/observability/plugins/apm/tsconfig.json` — replaced
`@kbn/control-group-renderer` reference with `@kbn/controls-constants`

## Test plan
- [x] Navigate to an APM service with a known runtime dashboard (e.g.
Java, Node.js) → Metrics tab
- [x] Verify the "Node name" options list control renders above the
dashboard
- [x] Verify dashboard panels load without errors
- [x] Verify filtering by node name works correctly
- [x] Jest tests pass

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
qn895 pushed a commit to qn895/kibana that referenced this pull request Mar 11, 2026
…_panels (elastic#254999)

## Summary

The APM service metrics tab crashes when loading the static JSON
dashboard because the dashboard plugin's `DashboardState` no longer has
a `controlGroupState` property — controls are now represented as
`pinned_panels`.

**Caused by:** [Controls Anywhere] Feature Branch —
elastic#245588

That PR refactored the entire controls system, removing the
`controlGroup` embeddable and replacing `controlGroupState` with
`pinned_panels` in `DashboardState`. The APM
`static_dashboard/index.tsx` was updated to use the new
`controlGroupStateBuilder` API signature (adding the `uiActions` param),
but the fundamental issue was missed: the `controlGroupState` object
built by the builder is no longer consumed by the dashboard. The
`getInitialInput()` return value spreads into `DashboardState`, which
silently ignores the `controlGroupState` property — or worse, the
`controlGroupStateBuilder.addDataControlFromField()` call throws during
control type detection via `uiActions`, causing `getCreationOptions` to
fall into the catch block and return empty options (no panels rendered
at all).

A follow-up PR ([Dashboards as Code] `snake_case` controls schemas —
elastic#249300) snake_cased the field
names in the builder call but didn't address the underlying issue.

**Fix:**
- Replace the `controlGroupStateBuilder` + `controlGroupState` pattern
with a direct `pinned_panels` array in the new format
- Add `useControlsIntegration: true` to `DashboardCreationOptions` so
the controls render
- Remove the now-unused `@kbn/control-group-renderer` dependency and
`UiActionsStart` parameter

### Changes
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.tsx`
— migrated controls from `controlGroupState` to `pinned_panels`
-
`x-pack/solutions/observability/plugins/apm/public/components/app/metrics/static_dashboard/index.test.tsx`
— added Jest tests for `getCreationOptions` contract
- `x-pack/solutions/observability/plugins/apm/tsconfig.json` — replaced
`@kbn/control-group-renderer` reference with `@kbn/controls-constants`

## Test plan
- [x] Navigate to an APM service with a known runtime dashboard (e.g.
Java, Node.js) → Metrics tab
- [x] Verify the "Node name" options list control renders above the
dashboard
- [x] Verify dashboard panels load without errors
- [x] Verify filtering by node name works correctly
- [x] Jest tests pass

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:fix Team:obs-presentation Focus: APM UI, Infra UI, Hosts UI, Universal Profiling, Obs Overview and left Navigation v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants