Skip to content

[Lens] [ES|QL] Refresh ES|QL results grid on data load#264017

Merged
mariairiartef merged 19 commits into
elastic:mainfrom
mariairiartef:lens-esql/259082
May 6, 2026
Merged

[Lens] [ES|QL] Refresh ES|QL results grid on data load#264017
mariairiartef merged 19 commits into
elastic:mainfrom
mariairiartef:lens-esql/259082

Conversation

@mariairiartef
Copy link
Copy Markdown
Contributor

@mariairiartef mariairiartef commented Apr 17, 2026

Summary

Fix #259082

How it was fixed

When the visualization finishes reloading (signaled by dataLoading$false), the editor re-runs getSuggestions for the last submitted ES|QL query with current time/filters so dataGridAttrs (the results section) stays in sync with what the chart just used. Additionally, suppressNextChartLoadGridRefreshRef avoids a duplicate grid fetch right after submit.

Before
Screen.Recording.2026-04-17.at.12.35.26.mov

Changing the time range or applying filters updated the visualization but did not refresh the “ES|QL query results” section.

After
Screen.Recording.2026-04-17.at.12.57.34.mov

Changing the time range or applying filters updates the visualization and refreshes the “ES|QL query results” section.

Checklist

@mariairiartef mariairiartef self-assigned this Apr 17, 2026
@mariairiartef mariairiartef added Team:Visualizations Team label for Lens, elastic-charts, Graph, legacy editors (TSVB, Visualize, Timelion) t// Feature:Lens backport:version Backport to applied version labels v9.4.0 v9.5.0 labels Apr 17, 2026
@mariairiartef
Copy link
Copy Markdown
Contributor Author

/ci

@mariairiartef
Copy link
Copy Markdown
Contributor Author

/ci

@mariairiartef mariairiartef marked this pull request as ready for review April 20, 2026 15:27
@mariairiartef mariairiartef requested a review from a team as a code owner April 20, 2026 15:27
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-visualizations (Team:Visualizations)

@mariairiartef mariairiartef added the release_note:skip Skip the PR/issue when compiling release notes label Apr 21, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] affected Scout: [ observability / synthetics ] plugin / local-stateful-classic - FilterMonitors - filters monitors by tags with AND/OR logic

Metrics [docs]

Async chunks

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

id before after diff
lens 2.0MB 2.0MB +339.0B

History

cc @mariairiartef

Comment on lines +128 to +131
const lensAdaptersRef = useRef(lensAdapters);
useEffect(() => {
lensAdaptersRef.current = lensAdapters;
}, [lensAdapters]);
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.

Do we need the useEffect here? Maybe we can do the same like with the refs further up like:

const lensAdaptersRef = useRef(lensAdapters);
lensAdaptersRef.current = lensAdapters;

lensAdaptersRef.current = lensAdapters;
}, [lensAdapters]);

/** Skips duplicate `getSuggestions` when chart reload follows a query submit (see `runQuery`) */
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.

Maybe we can be more specific with that triggers an update? Then we don't have to track duplicates but can separate what's triggering an update. As far as I could see searchSessionId is in redux what tracks external context change (time range, filters, auto-refresh, manual refresh), so it would cover triggers besides the editor submit. So we could do something like the following:

const searchSessionId = useLensSelector(selectSearchSessionId);
  const isInitialRenderRef = useRef(true);

  useEffect(() => {
    // Skip the initial render — the grid is populated by useInitializeChart → runQuery
    if (isInitialRenderRef.current) {
      isInitialRenderRef.current = false;
      return;
    }
    const lastSubmittedQuery = submittedQueryRef.current;
    if (isOfAggregateQueryType(lastSubmittedQuery)) {
      getSuggestions(
        lastSubmittedQuery,
        data,
        http,
        uiSettings,
        datasourceMap,
        visualizationMap,
        adHocDataViews,
        undefined,
        undefined,
        setDataGridAttrs,
        esqlVariables,
        false,
        currentAttributesRef.current
      ).catch(() => {
        // Grid refresh is best-effort; errors here (e.g. expired time range) are non-fatal.
        // The chart itself will surface query errors via its own error handling path.
      });
    }
  }, [
    searchSessionId,
    esqlVariables,
    data,
    http,
    uiSettings,
    datasourceMap,
    visualizationMap,
    adHocDataViews,
  ]);

We could then use useObservable() instead of managing the subscription ourselves. Like:

// Update activeData and column limit indicator when chart data finishes loading
  const isDataLoading = useObservable(dataLoading$ ?? EMPTY);

  useEffect(() => {
    if (isDataLoading !== false) {
      return;
    }

    const activeData = getActiveDataFromDatatable(layerId, lensAdaptersRef.current?.tables?.tables);

    const table = activeData?.[layerId];

    if (table) {
      // there are cases where a query can return a big amount of columns
      // at this case we don't suggest all columns in a table but the first `MAX_NUM_OF_COLUMNS`
      setSuggestsLimitedColumns(table.columns.length >= MAX_NUM_OF_COLUMNS);
    }

    if (Object.keys(activeData).length > 0) {
      dispatch(onActiveDataChange({ activeData }));
    }
  }, [isDataLoading, dispatch, layerId]);

We won't get rid of refs completely but it's less nested/complex than what suppressNextChartLoadGridRefreshRef tries to do maybe. What do you think?

Copy link
Copy Markdown
Contributor Author

@mariairiartef mariairiartef May 5, 2026

Choose a reason for hiding this comment

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

I like you idea! It makes sense to make it less complicated. Applied your suggestion here

Copy link
Copy Markdown
Contributor Author

@mariairiartef mariairiartef May 5, 2026

Choose a reason for hiding this comment

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

Nit

I've noticed that when you run the query, the "ES|QL Query Results" section is collapsed:

Screen.Recording.2026-05-05.at.16.39.23.mov

@teresaalvarezsoler, do you think we should do the same when the ES|QL query results section updates on date / filters change?

Copy link
Copy Markdown
Contributor

@walterra walterra left a comment

Choose a reason for hiding this comment

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

Latest changes LTGM!

@mariairiartef mariairiartef enabled auto-merge (squash) May 6, 2026 08:00
@kibanamachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
lens 1749 1751 +2

Async chunks

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

id before after diff
lens 2.0MB 2.0MB +758.0B

History

cc @mariairiartef

@mariairiartef mariairiartef merged commit 979c1ae into elastic:main May 6, 2026
31 checks passed
@kibanamachine kibanamachine added backport:skip This PR does not require backporting and removed backport:version Backport to applied version labels labels May 6, 2026
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 Feature:Lens release_note:skip Skip the PR/issue when compiling release notes Team:Visualizations Team label for Lens, elastic-charts, Graph, legacy editors (TSVB, Visualize, Timelion) t// v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Lens] [ES|QL] Query results do not update on changing time picker

4 participants