[Discover][Metrics] Persist flyout state across navigation#251637
[Discover][Metrics] Persist flyout state across navigation#251637lucaslopezf wants to merge 21 commits intoelastic:mainfrom
Conversation
|
/oblt-deploy |
1 similar comment
|
/oblt-deploy |
| const chartRefs = useRef<Map<string, HTMLDivElement>>(new Map()); | ||
| const { euiTheme } = useEuiTheme(); | ||
| const { flyoutState, onFlyoutStateChange } = useMetricsExperienceState(); | ||
| const fieldsMap = useMemo(() => createMetricFieldsMap(fields), [fields]); |
There was a problem hiding this comment.
Note for reviewer:
Since we now save the flyout state in Redux and need to retrieve it, we store a unique key (creating a Map for performance with O(1) lookup) to later retrieve the correct data whenever we want to render the flyout.
Key format: {dataViewIndex}::{metricName}
We use this structure because metricName alone is not unique (the same metric can exist in multiple data views).
| actionCreator: discardFlyoutsOnTabChange, | ||
| effect: () => { | ||
| dismissFlyouts([DiscoverFlyouts.lensEdit, DiscoverFlyouts.metricInsights]); | ||
| dismissFlyouts([DiscoverFlyouts.lensEdit]); |
There was a problem hiding this comment.
Note for reviewer:
The dismissFlyouts function programmatically clicks the close button of flyouts. When switching between Discover tabs, this was causing the metrics flyout to close and clear its state. Since now the flyout state is now managed per-tab in Redux (tab.uiState.metricsGrid.flyoutState) and each tab has its own independent flyout state we are fine
| }); | ||
|
|
||
| const metricsGridState = useCurrentTabSelector((state) => state.uiState.metricsGrid); | ||
| const isTabSelected = useInternalStateSelector( |
There was a problem hiding this comment.
Note for reviewer:
This solves a rendering conflict when multiple Discover tabs have flyouts open.
The problem: (using Metrics as example but is generic)
- Each Discover tab renders its own
MetricsGridcomponent - When a flyout is open, it uses
EuiPortalto render todocument.body - If Tab 1 and Tab 2 both have flyout state, both would render flyouts to
document.body - This causes visual overlap and event capture issues (clicking in Tab 2's flyout could affect Tab 1's state)
The solution:
- Compare the current tab's ID (
currentTabIdfromCurrentTabContext) with the active tab ID (state.tabs.unsafeCurrentId) - Pass
isTabSelectedto child components - Only render the flyout when
isTabSelected === true
This ensures only the active tab renders its flyout, while inactive tabs preserve their flyout state in Redux for when they become active again.
There was a problem hiding this comment.
Yeah kinda an unfortunate consequence of not unmounting the chart section when switching tabs (to preserve Lens state) that the flyout isn't unmounted. But I think what you've got here is probably the best we can do atm.
| </EuiFlexGrid> | ||
| </A11yGridWrapper> | ||
| {expandedMetric && ( | ||
| {flyoutData && isTabSelected && ( |
There was a problem hiding this comment.
We only render the flyout when isTabSelected is true to prevent multiple flyouts from overlapping.
More details here
|
/ci |
|
/oblt-deploy |
|
Pinging @elastic/obs-exploration-team (Team:obs-exploration) |
davismcphee
left a comment
There was a problem hiding this comment.
Data Discover changes LGTM 👍 Gave it a quick test locally, works well!
| }); | ||
|
|
||
| const metricsGridState = useCurrentTabSelector((state) => state.uiState.metricsGrid); | ||
| const isTabSelected = useInternalStateSelector( |
There was a problem hiding this comment.
Yeah kinda an unfortunate consequence of not unmounting the chart section when switching tabs (to preserve Lens state) that the flyout isn't unmounted. But I think what you've got here is probably the best we can do atm.
.../plugins/shared/discover/public/application/main/components/chart/chart_portals_renderer.tsx
Show resolved
Hide resolved
kpatticha
left a comment
There was a problem hiding this comment.
Regarding:
Pagination reset:
https://github.com/user-attachments/assets/576f4797-bc51-4baf-814f-61d64658eb16
can we know in advance if the pagination is different so we won't open the flyout and close it immediately? How could we solve it in the future?
I created issue 1- go to page 4, This should be automatically fixed once we have consistent query results.
I didn't notice this before your comment! It doesn't seem to happen consistently (at least in my case) but I'll take a look and see if we can fix in this PR! Thanks for catching this!! |
...ckages/shared/kbn-unified-chart-section-viewer/src/common/utils/metric_key/get_metric_key.ts
Outdated
Show resolved
Hide resolved
...hared/kbn-unified-chart-section-viewer/src/components/observability/metrics/metrics_grid.tsx
Outdated
Show resolved
Hide resolved
|
/oblt-deploy |
e4996ee to
a8d2a33
Compare
|
/oblt-deploy |
1 similar comment
|
/oblt-deploy |
a5baff4 to
e2c01fb
Compare
b43c150 to
0cbea55
Compare
|
/oblt-deploy |
|
/oblt-deploy |
|
/oblt-deploy |
1 similar comment
|
/oblt-deploy |
|
/oblt-deploy |
|
/ci |
|
/flaky scoutConfig:src/platform/plugins/shared/discover/test/scout/ui/parallel.playwright.config.ts:50 |
Flaky Test Runner✅ Build triggered - kibana-flaky-test-suite-runner#11039
|
|
/oblt-deploy |
|
@kpatticha I’m testing this PR before merging it, but I’m wondering if merging it could interfere with your metrics_info work. |
Flaky Test Runner Stats🎉 All tests passed! - kibana-flaky-test-suite-runner#11039[✅] src/platform/plugins/shared/discover/test/scout/ui/parallel.playwright.config.ts: 50/50 tests passed. |
|
Everything working as expected after EUI fix, but since this PR touches a lot of files, I’d prefer to wait for metrics_info PR to be to avoid creating extra rebase work on the work in progress. After that, I'll rebase and move forward. I've already mark the task as blocked by |
…255036) ## Summary Related to elastic/observability-dev#5219. Implements Tier 2 E2E coverage for Discover Metrics journeys, aligned with the existing metrics_experience test architecture and config pattern. Adds two new parallel Scout specs in metrics_experience: - `query_kickstart.spec.ts`: validates recommended-query kickstart behavior from the ES|QL help flow, with environment-aware handling when Search all metrics is unavailable and Search all fields is shown. - `breakdown_by_dimension.spec.ts`: validates that selecting “Breakdown by dimension” from the field list is reflected in the metrics toolbar and preserves metrics grid rendering. This patch introduces coverage for the two unblocked journeys, but does not yet implement the "switch between tabs" third journey, which is blocked by #251637. ## Test Plan Validated via Scout metrics parallel config: ``` node scripts/scout.js run-tests --arch stateful --domain classic --config src/platform/plugins/shared/discover/test/scout/ui/metrics_experience_parallel.playwright.config.ts ``` Result on latest run: ``` All tests pass: 36 passed, 8 skipped, 0 failed. Exit code 0. ``` --------- Co-authored-by: Lucas Francisco López <lucaslopezf@gmail.com>
…lastic#255036) ## Summary Related to elastic/observability-dev#5219. Implements Tier 2 E2E coverage for Discover Metrics journeys, aligned with the existing metrics_experience test architecture and config pattern. Adds two new parallel Scout specs in metrics_experience: - `query_kickstart.spec.ts`: validates recommended-query kickstart behavior from the ES|QL help flow, with environment-aware handling when Search all metrics is unavailable and Search all fields is shown. - `breakdown_by_dimension.spec.ts`: validates that selecting “Breakdown by dimension” from the field list is reflected in the metrics toolbar and preserves metrics grid rendering. This patch introduces coverage for the two unblocked journeys, but does not yet implement the "switch between tabs" third journey, which is blocked by elastic#251637. ## Test Plan Validated via Scout metrics parallel config: ``` node scripts/scout.js run-tests --arch stateful --domain classic --config src/platform/plugins/shared/discover/test/scout/ui/metrics_experience_parallel.playwright.config.ts ``` Result on latest run: ``` All tests pass: 36 passed, 8 skipped, 0 failed. Exit code 0. ``` --------- Co-authored-by: Lucas Francisco López <lucaslopezf@gmail.com>
…lastic#255036) ## Summary Related to elastic/observability-dev#5219. Implements Tier 2 E2E coverage for Discover Metrics journeys, aligned with the existing metrics_experience test architecture and config pattern. Adds two new parallel Scout specs in metrics_experience: - `query_kickstart.spec.ts`: validates recommended-query kickstart behavior from the ES|QL help flow, with environment-aware handling when Search all metrics is unavailable and Search all fields is shown. - `breakdown_by_dimension.spec.ts`: validates that selecting “Breakdown by dimension” from the field list is reflected in the metrics toolbar and preserves metrics grid rendering. This patch introduces coverage for the two unblocked journeys, but does not yet implement the "switch between tabs" third journey, which is blocked by elastic#251637. ## Test Plan Validated via Scout metrics parallel config: ``` node scripts/scout.js run-tests --arch stateful --domain classic --config src/platform/plugins/shared/discover/test/scout/ui/metrics_experience_parallel.playwright.config.ts ``` Result on latest run: ``` All tests pass: 36 passed, 8 skipped, 0 failed. Exit code 0. ``` --------- Co-authored-by: Lucas Francisco López <lucaslopezf@gmail.com>
Closes #235834
Summary
This PR implements persistence of the metrics flyout state when duplicating Discover tabs. Previously, when a user duplicated a Discover tab with an open "View details" flyout, the flyout would close in the new tab, forcing the user to find the metric and reopen it.
Demo
Screen.Recording.2026-02-04.at.18.35.26.mov
Manual Testing
Known Limitations (Out of Scope)
There are edge cases where the flyout may not restore after duplicating a tab. These will be addressed in a follow-up issue after discussing with Miguel:
Metric not available in new tab: Each tab executes its own query. If the metric that was open in the flyout doesn't exist in the new tab's query results (e.g., due to real-time data changes, sampling differences, or timing), the flyout won't render since there's no data to display.
Pagination reset: When the number of metrics differs between tabs, pagination resets to page 1. If the flyout was open for a metric on a different page, it won't render because the lookup only searches within the current page.
Checklist
Check the PR satisfies following conditions.
Reviewers should verify this PR satisfies this list as well.
release_note:breakinglabel should be applied in these situations.release_note:*label is applied per the guidelinesbackport:*labels.Identify risks
Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss.
Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging.