Compare commits

...

1 Commits

Author SHA1 Message Date
Sean Griffin 4ec220dc47 Try this 2025-12-19 16:04:53 -05:00
2 changed files with 39 additions and 16 deletions
@@ -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);
}