diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx index fe149b59c33..d327a4b5aeb 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx @@ -300,7 +300,18 @@ export const ExamplesHoverHeader = () => { ); }; -export const Basic: StoryFn = (args: PanelChromeProps) => { +export const Basic: StoryFn = (overrides?: Partial) => { + const args = { + width: 400, + height: 200, + title: 'Very long title that should get ellipsis when there is no more space', + description, + menu, + children: () => undefined, + }; + + merge(args, overrides); + const contentStyle = getContentStyle(); return ( @@ -345,12 +356,4 @@ Basic.argTypes = { }, }; -Basic.args = { - width: 400, - height: 200, - title: 'Very long title that should get ellipsis when there is no more space', - description, - menu, -}; - export default meta; diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index 152cf4946d3..8e566b13f90 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -1,5 +1,6 @@ import { css, cx } from '@emotion/css'; import React, { CSSProperties, ReactElement, ReactNode } from 'react'; +import { useMeasure } from 'react-use'; import { GrafanaTheme2, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; @@ -20,10 +21,8 @@ import { TitleItem } from './TitleItem'; /** * @internal */ -export interface PanelChromeProps { - width: number; - height: number; - children: (innerWidth: number, innerHeight: number) => ReactNode; +export type PanelChromeProps = FixedDimensions | AutoSize; +interface BaseProps { padding?: PanelPadding; hoverHeaderOffset?: number; title?: string; @@ -59,6 +58,18 @@ export interface PanelChromeProps { onOpenMenu?: () => void; } +interface FixedDimensions extends BaseProps { + width: number; + height: number; + children: (innerWidth: number, innerHeight: number) => ReactNode; +} + +interface AutoSize extends BaseProps { + width?: never; + height?: never; + children: ReactNode; +} + /** * @internal */ @@ -98,7 +109,7 @@ export function PanelChrome({ const showOnHoverClass = 'show-on-hover'; const headerHeight = getHeaderHeight(theme, hasHeader); - const { contentStyle, innerWidth, innerHeight } = getContentStyle(padding, theme, width, headerHeight, height); + const { contentStyle, innerWidth, innerHeight } = getContentStyle(padding, theme, headerHeight, height, width); const headerStyles: CSSProperties = { height: headerHeight, @@ -111,6 +122,8 @@ export function PanelChrome({ containerStyles.border = 'none'; } + const [ref, { width: loadingBarWidth }] = useMeasure(); + /** Old property name now maps to actions */ if (leftItems) { actions = leftItems; @@ -130,7 +143,6 @@ export function PanelChrome({ {titleItems} - {loadingState === LoadingState.Streaming && ( @@ -160,9 +172,11 @@ export function PanelChrome({ return ( // tabIndex={0} is needed for keyboard accessibility in the plot area // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -
+
- {loadingState === LoadingState.Loading ? : null} + {loadingState === LoadingState.Loading ? ( + + ) : null}
{hoverHeader && ( @@ -207,8 +221,8 @@ export function PanelChrome({
)} -
- {children(innerWidth, innerHeight)} +
+ {typeof children === 'function' ? children(innerWidth, innerHeight) : children}
); @@ -230,22 +244,29 @@ const getHeaderHeight = (theme: GrafanaTheme2, hasHeader: boolean) => { const getContentStyle = ( padding: string, theme: GrafanaTheme2, - width: number, headerHeight: number, - height: number + height?: number, + width?: number ) => { const chromePadding = (padding === 'md' ? theme.components.panel.padding : 0) * theme.spacing.gridSize; const panelPadding = chromePadding * 2; const panelBorder = 1 * 2; - const innerWidth = width - panelPadding - panelBorder; - const innerHeight = height - headerHeight - panelPadding - panelBorder; + let innerWidth = 0; + if (width) { + innerWidth = width - panelPadding - panelBorder; + } const contentStyle: CSSProperties = { padding: chromePadding, }; + let innerHeight = 0; + if (height) { + innerHeight = height - headerHeight - panelPadding - panelBorder; + } + return { contentStyle, innerWidth, innerHeight }; }; @@ -293,6 +314,9 @@ const getStyles = (theme: GrafanaTheme2) => { width: '100%', overflow: 'hidden', }), + containNone: css({ + contain: 'none', + }), content: css({ label: 'panel-content', flexGrow: 1, diff --git a/public/app/features/explore/Graph/GraphContainer.tsx b/public/app/features/explore/Graph/GraphContainer.tsx index 56f0fd17b08..70dbd601f92 100644 --- a/public/app/features/explore/Graph/GraphContainer.tsx +++ b/public/app/features/explore/Graph/GraphContainer.tsx @@ -18,7 +18,9 @@ import { ExploreGraph } from './ExploreGraph'; import { ExploreGraphLabel } from './ExploreGraphLabel'; import { loadGraphStyle } from './utils'; -interface Props extends Pick { +interface Props extends Pick { + width: number; + height: number; data: DataFrame[]; annotations?: DataFrame[]; eventBus: EventBus; diff --git a/public/app/features/explore/TraceView/TraceViewContainer.tsx b/public/app/features/explore/TraceView/TraceViewContainer.tsx index 789440cc7ce..b7b17f9d550 100644 --- a/public/app/features/explore/TraceView/TraceViewContainer.tsx +++ b/public/app/features/explore/TraceView/TraceViewContainer.tsx @@ -1,9 +1,8 @@ -import { css } from '@emotion/css'; import React, { RefObject, useMemo, useState } from 'react'; -import { DataFrame, SplitOpen, PanelData, GrafanaTheme2 } from '@grafana/data'; +import { DataFrame, PanelData, SplitOpen } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { useStyles2 } from '@grafana/ui'; +import { PanelChrome } from '@grafana/ui/src/components/PanelChrome/PanelChrome'; import { StoreState, useSelector } from 'app/types'; import { TraceView } from './TraceView'; @@ -11,6 +10,7 @@ import TracePageSearchBar from './components/TracePageHeader/SearchBar/TracePage import { TopOfViewRefType } from './components/TraceTimelineViewer/VirtualizedTraceView'; import { useSearch } from './useSearch'; import { transformDataFrames } from './utils/transform'; + interface Props { dataFrames: DataFrame[]; splitOpenFn: SplitOpen; @@ -20,26 +20,9 @@ interface Props { topOfViewRef: RefObject; } -const getStyles = (theme: GrafanaTheme2) => ({ - container: css` - label: container; - margin-bottom: ${theme.spacing(1)}; - background-color: ${theme.colors.background.primary}; - border: 1px solid ${theme.colors.border.medium}; - position: relative; - border-radius: ${theme.shape.radius.default}; - width: 100%; - display: flex; - flex-direction: column; - flex: 1 1 0; - padding: ${config.featureToggles.newTraceViewHeader ? 0 : theme.spacing(theme.components.panel.padding)}; - `, -}); - export function TraceViewContainer(props: Props) { // At this point we only show single trace const frame = props.dataFrames[0]; - const style = useStyles2(getStyles); const { dataFrames, splitOpenFn, exploreId, scrollElement, topOfViewRef, queryResponse } = props; const traceProp = useMemo(() => transformDataFrames(frame), [frame]); const { search, setSearch, spanFindMatches } = useSearch(traceProp?.spans); @@ -55,20 +38,25 @@ export function TraceViewContainer(props: Props) { } return ( -
- {!config.featureToggles.newTraceViewHeader && ( - - )} + + ) + } + > -
+ ); } diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/Actions/ActionButton.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/Actions/ActionButton.tsx index 8be7be68cd4..9149c81c07c 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/Actions/ActionButton.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/Actions/ActionButton.tsx @@ -10,8 +10,6 @@ export const getStyles = (theme: GrafanaTheme2) => { label: ActionButton; overflow: hidden; position: relative; - width: 110px; - justify-content: center; &:after { content: ''; background: ${theme.colors.primary.main}; @@ -46,6 +44,7 @@ export default function ActionButton(props: ActionButtonProps) { return (