diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx index 66cb7375489..d1b2778d987 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx @@ -18,67 +18,76 @@ interface DetailViewProps { selectedItem: QueryTransformItem | undefined; panel: VizPanel; tabs: Array<{ tabId: TabId }>; + onRemoveTransform?: (index: number) => void; + onToggleTransformVisibility?: (index: number) => void; } -export const DetailView = memo(({ selectedItem, panel, tabs }: DetailViewProps) => { - const styles = useStyles2(getStyles); +export const DetailView = memo( + ({ selectedItem, panel, tabs, onRemoveTransform, onToggleTransformVisibility }: DetailViewProps) => { + const styles = useStyles2(getStyles); - const renderContent = useCallback(() => { - if (!selectedItem) { - return ( -
-

- - Select a query or transformation to edit - -

-
- ); - } + const renderContent = useCallback(() => { + if (!selectedItem) { + return ( +
+

+ + Select a query or transformation to edit + +

+
+ ); + } - if (selectedItem.type === 'query' && 'refId' in selectedItem.data) { - const query = selectedItem.data; - return ( - <> - - - - - - ); - } else if (selectedItem.type === 'expression' && 'refId' in selectedItem.data) { - const data = selectedItem.data; - if (isExpressionQuery(data)) { + if (selectedItem.type === 'query' && 'refId' in selectedItem.data) { + const query = selectedItem.data; return ( <> - + ); + } else if (selectedItem.type === 'expression' && 'refId' in selectedItem.data) { + const data = selectedItem.data; + if (isExpressionQuery(data)) { + return ( + <> + + + + + + ); + } + } else { + const transformsTab = tabs.find((t): t is PanelDataTransformationsTab => t.tabId === TabId.Transformations); + if (transformsTab && 'id' in selectedItem.data) { + return ( + <> + + + + + + + + ); + } } - } else { - const transformsTab = tabs.find((t): t is PanelDataTransformationsTab => t.tabId === TabId.Transformations); - if (transformsTab && 'id' in selectedItem.data) { - return ( - <> - - - - - - - - ); - } - } - return null; - }, [selectedItem, panel, tabs, styles.emptyState]); + return null; + }, [selectedItem, panel, tabs, styles.emptyState, onRemoveTransform, onToggleTransformVisibility]); - return
{renderContent()}
; -}); + return
{renderContent()}
; + } +); DetailView.displayName = 'DetailView'; diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailViewHeader.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailViewHeader.tsx index 666851ab22e..58e09e1077c 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailViewHeader.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailViewHeader.tsx @@ -32,6 +32,8 @@ import { QueryTransformItem } from './QueryTransformList'; interface DetailViewHeaderProps { selectedItem: QueryTransformItem; panel: VizPanel; + onRemoveTransform?: (index: number) => void; + onToggleTransformVisibility?: (index: number) => void; } const ITEM_CONFIG = (theme: GrafanaTheme2) => ({ @@ -49,7 +51,12 @@ const ITEM_CONFIG = (theme: GrafanaTheme2) => ({ }, }); -export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps) => { +export const DetailViewHeader = ({ + selectedItem, + panel, + onRemoveTransform, + onToggleTransformVisibility, +}: DetailViewHeaderProps) => { const theme = useTheme2(); const config = useMemo(() => ITEM_CONFIG(theme)[selectedItem.type], [theme, selectedItem.type]); const styles = useStyles2(getStyles, config); @@ -243,12 +250,30 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps) queryRunner?.runQueries(); }, [panel]); + // Transformation action handlers + const onRemoveTransformation = useCallback(() => { + if (selectedItem.type !== 'transform' || selectedItem.index === undefined) { + return; + } + onRemoveTransform?.(selectedItem.index); + }, [selectedItem, onRemoveTransform]); + + const onToggleTransformationVisibility = useCallback(() => { + if (selectedItem.type !== 'transform' || selectedItem.index === undefined) { + return; + } + onToggleTransformVisibility?.(selectedItem.index); + }, [selectedItem, onToggleTransformVisibility]); + const refId = 'refId' in selectedItem.data ? selectedItem.data.refId : ''; const isHidden = (selectedItem.type === 'query' || selectedItem.type === 'expression') && 'hide' in selectedItem.data && selectedItem.data.hide; + const isTransformDisabled = + selectedItem.type === 'transform' && 'disabled' in selectedItem.data && selectedItem.data.disabled; + // Get transformation display name const transformationName = useMemo(() => { if (selectedItem.type === 'transform' && 'id' in selectedItem.data) { @@ -314,7 +339,7 @@ export const DetailViewHeader = ({ selectedItem, panel }: DetailViewHeaderProps) )} - {/* Right side: Run Query + Actions Menu */} + {/* Right side: Run Query + Actions Menu for queries/expressions */} {(selectedItem.type === 'query' || selectedItem.type === 'expression') && (