Try this
This commit is contained in:
+9
-16
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
import { DragDropContext, DropResult, Droppable } from '@hello-pangea/dnd';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { DataTransformerConfig, GrafanaTheme2, PanelData } from '@grafana/data';
|
||||
import { DataTransformerConfig, getNextRefId, GrafanaTheme2, PanelData } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import {
|
||||
@@ -25,9 +25,7 @@ import { PanelDataPane } from './PanelDataPane';
|
||||
import { PanelDataQueriesTab } from './PanelDataQueriesTab';
|
||||
import { TransformationsDrawer } from './TransformationsDrawer';
|
||||
import { PanelDataPaneTab, TabId, PanelDataTabHeaderProps } from './types';
|
||||
import { scrollToQueryRow } from './utils';
|
||||
|
||||
const SET_TIMEOUT = 750;
|
||||
import { scrollToQueryRowWhenReady } from './utils';
|
||||
|
||||
interface PanelDataTransformationsTabState extends SceneObjectState {
|
||||
panelRef: SceneObjectRef<VizPanel>;
|
||||
@@ -100,23 +98,18 @@ export function PanelDataTransformationsTabRendered({ model }: SceneComponentPro
|
||||
return;
|
||||
}
|
||||
|
||||
// Always create a new SQL expression (it will be added to the end of the queries array)
|
||||
// Calculate the refId that will be assigned to the new query before adding it
|
||||
const currentQueries = queriesTab.getQueries();
|
||||
const newRefId = getNextRefId(currentQueries);
|
||||
|
||||
// Create a new SQL expression (it will be added to the end of the queries array)
|
||||
queriesTab.onAddExpressionOfType(ExpressionQueryType.sql);
|
||||
|
||||
// Navigate to the Queries tab
|
||||
parent.onChangeTab(queriesTab);
|
||||
|
||||
// Scroll to the newly created SQL query after tab renders
|
||||
setTimeout(() => {
|
||||
const queries = queriesTab.getQueries();
|
||||
// The newly added query is the last one in the array
|
||||
if (queries.length > 0) {
|
||||
const newQuery = queries[queries.length - 1];
|
||||
if (newQuery?.refId) {
|
||||
scrollToQueryRow(newQuery.refId);
|
||||
}
|
||||
}
|
||||
}, SET_TIMEOUT);
|
||||
// Scroll to the newly created SQL query when it appears in the DOM
|
||||
scrollToQueryRowWhenReady(newRefId);
|
||||
}, [model]);
|
||||
|
||||
const onAddTransformation = useCallback(
|
||||
|
||||
@@ -13,3 +13,33 @@ export function scrollToQueryRow(refId: string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a query row element to appear in the DOM, then scrolls to it.
|
||||
* Uses MutationObserver for reliable detection instead of setTimeout.
|
||||
*
|
||||
* @param refId - The refId of the query row to scroll to
|
||||
* @param timeoutMs - Maximum time to wait before giving up (default: 5000ms)
|
||||
*/
|
||||
export function scrollToQueryRowWhenReady(refId: string, timeoutMs = 5000): void {
|
||||
// First check if the element already exists
|
||||
const existingElement = document.querySelector(`[aria-controls^="${refId}_"]`);
|
||||
if (existingElement) {
|
||||
scrollToQueryRow(refId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use MutationObserver to watch for the element to appear
|
||||
const observer = new MutationObserver((_mutations, obs) => {
|
||||
const queryRowHeader = document.querySelector(`[aria-controls^="${refId}_"]`);
|
||||
if (queryRowHeader) {
|
||||
obs.disconnect();
|
||||
scrollToQueryRow(refId);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
// Safety timeout to prevent indefinite observation
|
||||
setTimeout(() => observer.disconnect(), timeoutMs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user