diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx deleted file mode 100644 index 95852e0e13c..00000000000 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/DetailView.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import { css } from '@emotion/css'; -import { memo, useCallback, useRef } from 'react'; - -import { DataFrame, GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { Trans } from '@grafana/i18n'; -import { SceneDataQuery, VizPanel } from '@grafana/scenes'; -import { Container, ScrollContainer, useStyles2 } from '@grafana/ui'; -import { isExpressionQuery } from 'app/features/expressions/guards'; - -import { DetailViewHeader } from './DetailViewHeader'; -import { ExpressionDetailView } from './ExpressionDetailView'; -import { PanelDataTransformationsTab, PanelDataTransformationsTabRendered } from './PanelDataTransformationsTab'; -import { QueryDetailView } from './QueryDetailView'; -import { QueryLibraryView, QueryLibraryViewRef } from './QueryLibraryView'; -import { TransformationPickerView } from './TransformationPickerView'; -import { TabId, QueryTransformItem } from './types'; - -export interface QueryLibraryMode { - active: boolean; - mode: 'browse' | 'save'; - currentQuery?: SceneDataQuery; -} - -interface DetailViewProps { - selectedItem: QueryTransformItem | undefined; - panel: VizPanel; - tabs: Array<{ tabId: TabId }>; - onRemoveTransform?: (index: number) => void; - onToggleTransformVisibility?: (index: number) => void; - isAddingTransform?: boolean; - onAddTransformation?: (selectedItem: SelectableValue, customOptions?: Record) => void; - onCancelAddTransform?: () => void; - transformationData?: DataFrame[]; - onGoToQueries?: () => void; - queryLibraryMode?: QueryLibraryMode; - onQueryLibrarySelect?: (query: SceneDataQuery) => void; - onQueryLibrarySave?: (name: string, description: string) => void; - onQueryLibraryClose?: () => void; - onOpenQueryLibrary?: (mode: 'browse' | 'save', index?: number) => void; - onOpenQueryInspector?: () => void; - isDebugMode?: boolean; - debugPosition?: number; -} - -export const DetailView = memo( - ({ - selectedItem, - panel, - tabs, - onRemoveTransform, - onToggleTransformVisibility, - isAddingTransform, - onAddTransformation, - onCancelAddTransform, - transformationData, - onGoToQueries, - queryLibraryMode, - onQueryLibrarySelect, - onQueryLibrarySave, - onQueryLibraryClose, - onOpenQueryLibrary, - onOpenQueryInspector, - isDebugMode, - debugPosition, - }: DetailViewProps) => { - const styles = useStyles2(getStyles); - const queryLibraryRef = useRef(null); - - const handleSelectQueryFromHeader = useCallback(() => { - queryLibraryRef.current?.selectCurrentQuery(); - }, []); - - const handleSaveQueryFromHeader = useCallback(() => { - queryLibraryRef.current?.saveQuery(); - }, []); - - const renderContent = useCallback(() => { - // Show transformation picker when in add mode - if (isAddingTransform && onAddTransformation && onCancelAddTransform) { - return ( - - ); - } - - // Show QueryLibraryView when in query library mode - if (queryLibraryMode?.active && onQueryLibraryClose) { - return ( - <> - - - - ); - } - - if (!selectedItem) { - return ( -
-

- - Select a query or transformation to edit - -

-
- ); - } - - if (selectedItem.type === 'query') { - const query = selectedItem.data; - return ( - <> - - - - - - ); - } else if (selectedItem.type === 'expression') { - const data = selectedItem.data; - if (isExpressionQuery(data)) { - return ( - <> - - - - - - ); - } - } else { - const transformsTab = tabs.find((t): t is PanelDataTransformationsTab => t.tabId === TabId.Transformations); - if (transformsTab) { - return ( - <> - - - - - - - - ); - } - } - - return null; - }, [ - isAddingTransform, - onAddTransformation, - onCancelAddTransform, - queryLibraryMode?.active, - queryLibraryMode?.mode, - queryLibraryMode?.currentQuery, - onQueryLibraryClose, - selectedItem, - transformationData, - onGoToQueries, - handleSelectQueryFromHeader, - handleSaveQueryFromHeader, - onQueryLibrarySelect, - onQueryLibrarySave, - styles.emptyState, - panel, - onOpenQueryLibrary, - onOpenQueryInspector, - tabs, - onRemoveTransform, - onToggleTransformVisibility, - isDebugMode, - debugPosition, - ]); - - return
{renderContent()}
; - } -); - -DetailView.displayName = 'DetailView'; - -const getStyles = (theme: GrafanaTheme2) => { - return { - container: css({ - display: 'flex', - flexDirection: 'column', - height: '100%', - width: '100%', - background: theme.colors.background.primary, - border: `1px solid ${theme.colors.border.weak}`, - borderTopLeftRadius: theme.shape.radius.md, - borderTopRightRadius: theme.shape.radius.md, - overflow: 'hidden', - }), - emptyState: css({ - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - height: '100%', - color: theme.colors.text.secondary, - fontSize: theme.typography.h5.fontSize, - }), - }; -}; diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx index 8fc158a684b..5cb9cd29713 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx @@ -1,8 +1,6 @@ -import { css, cx } from '@emotion/css'; import { useCallback, useMemo } from 'react'; -import { DataTransformerConfig, GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; +import { DataTransformerConfig, SelectableValue } from '@grafana/data'; import { SceneComponentProps, SceneDataQuery, @@ -13,7 +11,6 @@ import { SceneObjectUrlValues, VizPanel, } from '@grafana/scenes'; -import { useStyles2 } from '@grafana/ui'; import { getConfig } from 'app/core/config'; import { contextSrv } from 'app/core/services/context_srv'; import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control'; @@ -22,11 +19,10 @@ import { ExpressionQueryType } from 'app/features/expressions/types'; import { getQueryRunnerFor } from '../../utils/utils'; -import { DetailView, QueryLibraryMode } from './DetailView'; import { PanelDataAlertingTab } from './PanelDataAlertingTab'; import { PanelDataQueriesTab } from './PanelDataQueriesTab'; -import { PanelDataSidebarRendered } from './PanelDataSidebar'; import { PanelDataTransformationsTab } from './PanelDataTransformationsTab'; +import { QueryTransformDetailView, QueryLibraryMode } from './QueryTransformDetailView'; import { useQueryTransformItems } from './hooks'; import { PanelDataPaneTab, TabId } from './types'; import { isDataTransformerConfig, queryItemId, transformItemId } from './utils'; @@ -34,7 +30,6 @@ import { isDataTransformerConfig, queryItemId, transformItemId } from './utils'; export interface PanelDataPaneState extends SceneObjectState { tabs: PanelDataPaneTab[]; tab: TabId; - sidebarCollapsed: boolean; selectedQueryTransform: string | null; panelRef: SceneObjectRef; transformPickerIndex?: number | null; @@ -45,7 +40,6 @@ export interface PanelDataPaneState extends SceneObjectState { export class PanelDataPane extends SceneObjectBase { static Component = PanelDataPaneRendered; - static FooterComponent = PanelDataSidebarRendered; protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['tab', 'selectedQueryTransform'] }); @@ -67,7 +61,6 @@ export class PanelDataPane extends SceneObjectBase { panelRef, tabs, tab, - sidebarCollapsed: false, queryLibraryMode: { active: false, mode: 'browse', @@ -86,10 +79,6 @@ export class PanelDataPane extends SceneObjectBase { this.setState({ selectedQueryTransform: selectedId }); }; - public onCollapseSidebar = (newState: boolean) => { - this.setState({ sidebarCollapsed: newState }); - }; - public onTransformPicker = (index?: number | null) => { this.setState({ transformPickerIndex: index }); }; @@ -130,7 +119,6 @@ function PanelDataPaneRendered({ model }: SceneComponentProps) { isDebugMode = false, debugPosition = 0, } = model.useState(); - const styles = useStyles2(getStyles); // Subscribe to query runner and tab state changes const panel = panelRef.resolve(); @@ -325,30 +313,26 @@ function PanelDataPaneRendered({ model }: SceneComponentProps) { const series = sourceData?.data?.series || []; return ( -
-
- model.onTransformPicker(null)} - transformationData={series} - onGoToQueries={handleGoToQueries} - queryLibraryMode={queryLibraryMode} - onQueryLibrarySelect={handleQueryLibrarySelect} - onQueryLibrarySave={handleQueryLibrarySave} - onQueryLibraryClose={handleQueryLibraryClose} - onOpenQueryLibrary={handleOpenQueryLibrary} - onOpenQueryInspector={handleOpenQueryInspector} - isDebugMode={isDebugMode} - debugPosition={debugPosition} - /> -
-
+ model.onTransformPicker(null)} + transformationData={series} + onGoToQueries={handleGoToQueries} + queryLibraryMode={queryLibraryMode} + onQueryLibrarySelect={handleQueryLibrarySelect} + onQueryLibrarySave={handleQueryLibrarySave} + onQueryLibraryClose={handleQueryLibraryClose} + onOpenQueryLibrary={handleOpenQueryLibrary} + onOpenQueryInspector={handleOpenQueryInspector} + isDebugMode={isDebugMode} + debugPosition={debugPosition} + /> ); } @@ -365,23 +349,3 @@ export function shouldShowAlertingTab(pluginId: string) { return isGraph || isTimeseries; } - -function getStyles(theme: GrafanaTheme2) { - return { - dataPane: css({ - display: 'flex', - flexDirection: 'column', - flexGrow: 1, - minHeight: 0, - height: '100%', - width: '100%', - paddingLeft: theme.spacing(2), - }), - unifiedLayout: css({ - flex: 1, - minHeight: 0, - background: theme.colors.background.primary, - overflow: 'hidden', - }), - }; -} diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataSidebar.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataSidebar.tsx index d5db8402c49..872f8091266 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataSidebar.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataSidebar.tsx @@ -1,5 +1,5 @@ import { css } from '@emotion/css'; -import { useCallback, useEffect, useMemo } from 'react'; +import { Dispatch, SetStateAction, useCallback, useEffect, useMemo } from 'react'; import { DataTransformerConfig, GrafanaTheme2, SelectableValue } from '@grafana/data'; import { t } from '@grafana/i18n'; @@ -13,18 +13,35 @@ import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/d import { ExpressionQueryType } from '../../../expressions/types'; import { getQueryRunnerFor } from '../../utils/utils'; -import { QueryLibraryMode } from './DetailView'; import { PanelDataPane } from './PanelDataPane'; import { PanelDataQueriesTab } from './PanelDataQueriesTab'; import { PanelDataTransformationsTab } from './PanelDataTransformationsTab'; +import { QueryLibraryMode } from './QueryTransformDetailView'; import { QueryTransformList } from './QueryTransformList'; import { useQueryTransformItems } from './hooks'; import { TabId } from './types'; import { isDataTransformerConfig, queryItemId, transformItemId } from './utils'; -export function PanelDataSidebarRendered({ model }: SceneComponentProps) { - const { panelRef, tabs, selectedQueryTransform, sidebarCollapsed, transformPickerIndex } = model.useState(); - const styles = useStyles2(getStyles, sidebarCollapsed); +export enum SidebarSize { + Mini = 'mini', + Full = 'full', +} + +export interface SidebarState { + size: SidebarSize; + collapsed: boolean; +} + +export function PanelDataSidebar({ + model, + sidebarState, + setSidebarState, +}: SceneComponentProps & { + sidebarState: SidebarState; + setSidebarState: Dispatch>; +}) { + const { panelRef, tabs, selectedQueryTransform, transformPickerIndex } = model.useState(); + const styles = useStyles2(getStyles, sidebarState); const panel = panelRef.resolve(); @@ -291,13 +308,13 @@ export function PanelDataSidebarRendered({ model }: SceneComponentProps