From 8b45eb1161d8fb6e3393a2fe1b5d673bcc862792 Mon Sep 17 00:00:00 2001 From: Andrej Ocenas Date: Tue, 11 Jan 2022 13:34:39 +0100 Subject: [PATCH] TraceView: Refactor theming to use Grafana theme directly (#43856) * Use grafana theme and utils * Use grafana colors * Fix tests * Use useStyles2 --- packages/jaeger-ui-components/src/Theme.tsx | 175 +----------------- .../SpanGraph/CanvasSpanGraph.test.js | 4 +- .../SpanGraph/CanvasSpanGraph.tsx | 10 +- .../TracePageHeader/SpanGraph/GraphTicks.tsx | 9 +- .../TracePageHeader/SpanGraph/Scrubber.tsx | 9 +- .../TracePageHeader/SpanGraph/TickLabels.tsx | 11 +- .../SpanGraph/ViewingLayer.test.js | 27 +-- .../SpanGraph/ViewingLayer.tsx | 10 +- .../src/TracePageHeader/TracePageHeader.tsx | 12 +- .../TracePageHeader/TracePageSearchBar.tsx | 8 +- .../TraceTimelineViewer/ReferencesButton.tsx | 6 +- .../src/TraceTimelineViewer/SpanBar.tsx | 12 +- .../src/TraceTimelineViewer/SpanBarRow.tsx | 11 +- .../SpanDetail/AccordianKeyValues.tsx | 12 +- .../SpanDetail/AccordianLogs.tsx | 10 +- .../SpanDetail/AccordianReferences.tsx | 9 +- .../SpanDetail/AccordianText.tsx | 13 +- .../SpanDetail/KeyValuesTable.test.js | 4 +- .../SpanDetail/KeyValuesTable.tsx | 13 +- .../SpanDetail/TextList.tsx | 9 +- .../TraceTimelineViewer/SpanDetail/index.tsx | 12 +- .../TraceTimelineViewer/SpanDetailRow.test.js | 9 +- .../src/TraceTimelineViewer/SpanDetailRow.tsx | 10 +- .../SpanTreeOffset.test.js | 7 +- .../TraceTimelineViewer/SpanTreeOffset.tsx | 11 +- .../src/TraceTimelineViewer/Ticks.tsx | 10 +- .../TimelineHeaderRow/TimelineCollapser.tsx | 9 +- .../TimelineColumnResizer.tsx | 4 +- .../TimelineHeaderRow/TimelineHeaderRow.tsx | 10 +- .../TimelineViewingLayer.tsx | 5 +- .../src/TraceTimelineViewer/TimelineRow.tsx | 8 +- .../VirtualizedTraceView.test.js | 1 - .../VirtualizedTraceView.tsx | 11 +- .../src/TraceTimelineViewer/index.test.js | 4 +- .../src/TraceTimelineViewer/index.tsx | 10 +- .../src/common/BreakableText.tsx | 10 +- .../src/common/CopyIcon.tsx | 4 +- .../src/common/LabeledList.tsx | 11 +- .../src/common/LoadingIndicator.tsx | 8 +- .../src/common/NewWindowIcon.tsx | 9 +- .../src/common/TraceName.tsx | 12 +- .../src/utils/color-generator.test.js | 14 +- .../src/utils/color-generator.tsx | 11 +- .../features/explore/TraceView/TraceView.tsx | 139 ++++++-------- 44 files changed, 265 insertions(+), 448 deletions(-) diff --git a/packages/jaeger-ui-components/src/Theme.tsx b/packages/jaeger-ui-components/src/Theme.tsx index d647301cfa4..45cc4847a63 100644 --- a/packages/jaeger-ui-components/src/Theme.tsx +++ b/packages/jaeger-ui-components/src/Theme.tsx @@ -12,161 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React, { useContext } from 'react'; -import hoistNonReactStatics from 'hoist-non-react-statics'; -import memoizeOne from 'memoize-one'; import tinycolor from 'tinycolor2'; - -const COLORS_HEX = [ - '#17B8BE', - '#F8DCA1', - '#B7885E', - '#FFCB99', - '#F89570', - '#829AE3', - '#E79FD5', - '#1E96BE', - '#89DAC1', - '#B3AD9E', - '#12939A', - '#DDB27C', - '#88572C', - '#FF9833', - '#EF5D28', - '#162A65', - '#DA70BF', - '#125C77', - '#4DC19C', - '#776E57', -]; - -const COLORS_HEX_DARK = [ - '#17B8BE', - '#F8DCA1', - '#B7885E', - '#FFCB99', - '#F89570', - '#829AE3', - '#E79FD5', - '#1E96BE', - '#89DAC1', - '#B3AD9E', - '#12939A', - '#DDB27C', - '#88572C', - '#FF9833', - '#EF5D28', - '#DA70BF', - '#4DC19C', - '#776E57', -]; - -export type ThemeOptions = Partial; - -export enum ThemeType { - Dark, - Light, -} - -export type Theme = { - type: ThemeType; - servicesColorPalette: string[]; - borderStyle: string; - components?: { - TraceName?: { - fontSize?: number | string; - }; - }; -}; - -export const defaultTheme: Theme = { - type: ThemeType.Light, - borderStyle: '1px solid #bbb', - servicesColorPalette: COLORS_HEX, -}; - -export function isLight(theme?: Theme | ThemeOptions) { - // Light theme is default type not set which only happens if called for ThemeOptions. - return theme && theme.type ? theme.type === ThemeType.Light : false; -} - -const ThemeContext = React.createContext(undefined); -ThemeContext.displayName = 'ThemeContext'; - -export const ThemeProvider = ThemeContext.Provider; - -type ThemeConsumerProps = { - children: (theme: Theme) => React.ReactNode; -}; -export function ThemeConsumer(props: ThemeConsumerProps) { - return ( - - {(value: ThemeOptions | undefined) => { - const theme = memoizedThemeMerge(value); - return props.children(theme); - }} - - ); -} - -const memoizedThemeMerge = memoizeOne((value?: ThemeOptions) => { - const darkOverrides: Partial = {}; - if (!isLight(value)) { - darkOverrides.servicesColorPalette = COLORS_HEX_DARK; - } - return value - ? { - ...defaultTheme, - ...darkOverrides, - ...value, - } - : defaultTheme; -}); - -type WrappedWithThemeComponent = React.ComponentType> & { - wrapped: React.ComponentType; -}; - -export const withTheme = ( - Component: React.ComponentType -): WrappedWithThemeComponent => { - let WithTheme: React.ComponentType> = (props) => { - return ( - - {(theme: Theme) => { - return ( - - ); - }} - - ); - }; - - WithTheme.displayName = `WithTheme(${Component.displayName})`; - WithTheme = hoistNonReactStatics>, React.ComponentType>( - WithTheme, - Component - ); - (WithTheme as WrappedWithThemeComponent).wrapped = Component; - return WithTheme as WrappedWithThemeComponent; -}; - -export function useTheme(): Theme { - const theme = useContext(ThemeContext); - return { - ...defaultTheme, - ...theme, - }; -} - -export const createStyle = ReturnType>(fn: Fn) => { - return memoizeOne(fn); -}; +import { GrafanaTheme2 } from '@grafana/data'; /** * Tries to get a dark variant color. Either by simply inverting the luminosity and darkening or lightening the color @@ -176,8 +23,8 @@ export const createStyle = ReturnT * @param hex * @param base */ -export function autoColor(theme: Theme, hex: string, base?: string) { - if (isLight(theme)) { +export function autoColor(theme: GrafanaTheme2, hex: string, base?: string) { + if (theme.isLight) { return hex; } else { if (base) { @@ -204,19 +51,3 @@ export function autoColor(theme: Theme, hex: string, base?: string) { return newColor.isLight() ? newColor.darken(5).toHex8String() : newColor.lighten(5).toHex8String(); } } - -/** - * With theme overrides you can use both number or string (for things like rem units) so this makes sure we convert - * the value accordingly or use fallback if not set - */ -export function safeSize(size: number | string | undefined, fallback: string): string { - if (!size) { - return fallback; - } - - if (typeof size === 'string') { - return size; - } else { - return `${size}px`; - } -} diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js index 9dafc7bc955..6799d5290e6 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js @@ -14,14 +14,14 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { createTheme } from '@grafana/data'; import { UnthemedCanvasSpanGraph } from './CanvasSpanGraph'; -import { defaultTheme } from '../../Theme'; describe('', () => { it('renders without exploding', () => { const items = [{ valueWidth: 1, valueOffset: 1, serviceName: 'service-name-0' }]; - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper).toBeDefined(); wrapper.instance()._setCanvasRef({ getContext: () => ({ diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx index 68541efc35f..2e62d4ad3b8 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx @@ -19,9 +19,11 @@ import renderIntoCanvas from './render-into-canvas'; import { getRgbColorByKey } from '../../utils/color-generator'; import { TNil } from '../../types'; -import { autoColor, createStyle, Theme, withTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; +import { withTheme2, stylesFactory } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { CanvasSpanGraph: css` label: CanvasSpanGraph; @@ -36,7 +38,7 @@ const getStyles = createStyle((theme: Theme) => { type CanvasSpanGraphProps = { items: Array<{ valueWidth: number; valueOffset: number; serviceName: string }>; valueWidth: number; - theme: Theme; + theme: GrafanaTheme2; }; export class UnthemedCanvasSpanGraph extends React.PureComponent { @@ -73,4 +75,4 @@ export class UnthemedCanvasSpanGraph extends React.PureComponent { +const getStyles = () => { return { GraphTick: css` label: GraphTick; @@ -24,7 +24,7 @@ const getStyles = createStyle(() => { stroke-width: 1px; `, }; -}); +}; type GraphTicksProps = { numTicks: number; @@ -32,11 +32,12 @@ type GraphTicksProps = { export default function GraphTicks(props: GraphTicksProps) { const { numTicks } = props; + const styles = useStyles2(getStyles); const ticks = []; // i starts at 1, limit is `i < numTicks` so the first and last ticks aren't drawn for (let i = 1; i < numTicks; i++) { const x = `${(i / numTicks) * 100}%`; - ticks.push(); + ticks.push(); } return ( diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx index e8609567a95..9242819e1fa 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx @@ -14,11 +14,10 @@ import React from 'react'; import cx from 'classnames'; - -import { createStyle } from '../../Theme'; import { css } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; -export const getStyles = createStyle(() => { +export const getStyles = () => { return { ScrubberHandleExpansion: cx( css` @@ -70,7 +69,7 @@ export const getStyles = createStyle(() => { } `, }; -}); +}; type ScrubberProps = { isDragging: boolean; @@ -82,7 +81,7 @@ type ScrubberProps = { export default function Scrubber({ isDragging, onMouseDown, onMouseEnter, onMouseLeave, position }: ScrubberProps) { const xPercent = `${position * 100}%`; - const styles = getStyles(); + const styles = useStyles2(getStyles); const className = cx({ [styles.ScrubberDragging]: isDragging }); return ( diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx index 862e393638e..188b36cc900 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx @@ -13,13 +13,12 @@ // limitations under the License. import React from 'react'; +import { css } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; import { formatDuration } from '../../utils/date'; -import { createStyle } from '../../Theme'; -import { css } from '@emotion/css'; - -const getStyles = createStyle(() => { +const getStyles = () => { return { TickLabels: css` label: TickLabels; @@ -34,7 +33,7 @@ const getStyles = createStyle(() => { user-select: none; `, }; -}); +}; type TickLabelsProps = { numTicks: number; @@ -43,7 +42,7 @@ type TickLabelsProps = { export default function TickLabels(props: TickLabelsProps) { const { numTicks, duration } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); const ticks = []; for (let i = 0; i < numTicks + 1; i++) { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js index 68199d422a6..3530d9602a3 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js @@ -14,13 +14,13 @@ import { shallow } from 'enzyme'; import React from 'react'; +import { createTheme } from '@grafana/data'; import GraphTicks from './GraphTicks'; import Scrubber from './Scrubber'; import ViewingLayer, { dragTypes, getStyles } from './ViewingLayer'; import { EUpdateTypes } from '../../utils/DraggableManager'; import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; -import { defaultTheme } from '../../Theme'; function getViewRange(viewStart, viewEnd) { return { @@ -45,7 +45,6 @@ describe('', () => { viewRange: getViewRange(0, 1), }; wrapper = shallow() - .dive() .dive() .dive(); }); @@ -54,7 +53,6 @@ describe('', () => { beforeEach(() => { props = { ...props, viewRange: getViewRange(0.1, 0.9) }; wrapper = shallow() - .dive() .dive() .dive(); wrapper.instance()._setRoot({ @@ -130,7 +128,6 @@ describe('', () => { const time = { ...props.viewRange.time, reframe: { anchor } }; props = { ...props, viewRange: { time } }; wrapper = shallow() - .dive() .dive() .dive(); wrapper.instance()._handleReframeDragUpdate({ value }); @@ -160,7 +157,6 @@ describe('', () => { const time = { ...props.viewRange.time, reframe: { anchor } }; props = { ...props, viewRange: { time } }; wrapper = shallow() - .dive() .dive() .dive(); wrapper.instance()._handleReframeDragEnd({ manager, value }); @@ -176,7 +172,6 @@ describe('', () => { const time = { ...props.viewRange.time, reframe: { anchor } }; props = { ...props, viewRange: { time } }; wrapper = shallow() - .dive() .dive() .dive(); wrapper.instance()._handleReframeDragEnd({ manager, value }); @@ -274,28 +269,28 @@ describe('', () => { describe('.ViewingLayer--resetZoom', () => { it('should not render .ViewingLayer--resetZoom if props.viewRange.time.current = [0,1]', () => { - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(0); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(0); wrapper.setProps({ viewRange: { time: { current: [0, 1] } } }); - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(0); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(0); }); it('should render ViewingLayer--resetZoom if props.viewRange.time.current[0] !== 0', () => { // If the test fails on the following expect statement, this may be a false negative - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(0); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(0); wrapper.setProps({ viewRange: { time: { current: [0.1, 1] } } }); - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(1); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(1); }); it('should render ViewingLayer--resetZoom if props.viewRange.time.current[1] !== 1', () => { // If the test fails on the following expect statement, this may be a false negative - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(0); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(0); wrapper.setProps({ viewRange: { time: { current: [0, 0.9] } } }); - expect(wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`).length).toBe(1); + expect(wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`).length).toBe(1); }); it('should call props.updateViewRangeTime when clicked', () => { wrapper.setProps({ viewRange: { time: { current: [0.1, 0.9] } } }); - const resetZoomButton = wrapper.find(`.${getStyles(defaultTheme).ViewingLayerResetZoom}`); + const resetZoomButton = wrapper.find(`.${getStyles(createTheme()).ViewingLayerResetZoom}`); // If the test fails on the following expect statement, this may be a false negative caused // by a regression to rendering. expect(resetZoomButton.length).toBe(1); @@ -313,11 +308,10 @@ describe('', () => { it('renders a filtering box if leftBound exists', () => { const _props = { ...props, viewRange: getViewRange(0.2, 1) }; wrapper = shallow() - .dive() .dive() .dive(); - const leftBox = wrapper.find(`.${getStyles(defaultTheme).ViewingLayerInactive}`); + const leftBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`); expect(leftBox.length).toBe(1); const width = Number(leftBox.prop('width').slice(0, -1)); const x = leftBox.prop('x'); @@ -328,11 +322,10 @@ describe('', () => { it('renders a filtering box if rightBound exists', () => { const _props = { ...props, viewRange: getViewRange(0, 0.8) }; wrapper = shallow() - .dive() .dive() .dive(); - const rightBox = wrapper.find(`.${getStyles(defaultTheme).ViewingLayerInactive}`); + const rightBox = wrapper.find(`.${getStyles(createTheme()).ViewingLayerInactive}`); expect(rightBox.length).toBe(1); const width = Number(rightBox.prop('width').slice(0, -1)); const x = Number(rightBox.prop('x').slice(0, -1)); diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx index 384e0805c8c..1dd594fcff6 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx @@ -15,14 +15,16 @@ import cx from 'classnames'; import * as React from 'react'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { withTheme2, stylesFactory } from '@grafana/ui'; import GraphTicks from './GraphTicks'; import Scrubber from './Scrubber'; import { TUpdateViewRangeTimeFunction, UIButton, ViewRange, ViewRangeTimeUpdate, TNil } from '../..'; -import { withTheme, Theme, autoColor, createStyle } from '../../Theme'; +import { autoColor } from '../../Theme'; import DraggableManager, { DraggableBounds, DraggingUpdate, EUpdateTypes } from '../../utils/DraggableManager'; -export const getStyles = createStyle((theme: Theme) => { +export const getStyles = stylesFactory((theme: GrafanaTheme2) => { // Need this cause emotion will merge emotion generated classes into single className if used with cx from emotion // package and the selector won't work const ViewingLayerResetZoomHoverClassName = 'JaegerUiComponents__ViewingLayerResetZoomHoverClassName'; @@ -91,7 +93,7 @@ type ViewingLayerProps = { updateViewRangeTime: TUpdateViewRangeTimeFunction; updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void; viewRange: ViewRange; - theme: Theme; + theme: GrafanaTheme2; }; type ViewingLayerState = { @@ -406,4 +408,4 @@ export class UnthemedViewingLayer extends React.PureComponent { +const getStyles = (theme: GrafanaTheme2) => { return { TracePageHeader: css` label: TracePageHeader; @@ -135,7 +135,7 @@ const getStyles = createStyle((theme: Theme) => { white-space: nowrap; `, }; -}); +}; type TracePageHeaderEmbedProps = { canCollapse: boolean; @@ -225,7 +225,7 @@ export default function TracePageHeader(props: TracePageHeaderEmbedProps) { timeZone, } = props; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); const links = React.useMemo(() => { if (!trace) { return []; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx index 0ff39cb3da7..4569c8bc6e8 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx @@ -16,18 +16,18 @@ import * as React from 'react'; import cx from 'classnames'; import IoAndroidLocate from 'react-icons/lib/io/android-locate'; import { css } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; import * as markers from './TracePageSearchBar.markers'; import UiFindInput from '../common/UiFindInput'; import { TNil } from '../types'; import { UIButton, UIInputGroup } from '../uiElementsContext'; -import { createStyle } from '../Theme'; import { ubFlexAuto, ubJustifyEnd } from '../uberUtilityStyles'; // eslint-disable-next-line no-duplicate-imports import { memo } from 'react'; -export const getStyles = createStyle(() => { +export const getStyles = () => { return { TracePageSearchBar: css` label: TracePageSearchBar; @@ -58,7 +58,7 @@ export const getStyles = createStyle(() => { padding: 1px 8px 4px; `, }; -}); +}; type TracePageSearchBarProps = { textFilter: string | TNil; @@ -86,7 +86,7 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps) searchValue, hideSearchButtons, } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); const count = textFilter ? {resultCount} : null; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx index 6a5b4ec78bd..5ac6bd1c7cc 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx @@ -14,14 +14,14 @@ import React from 'react'; import { css } from '@emotion/css'; +import { stylesFactory } from '@grafana/ui'; + import NewWindowIcon from '../common/NewWindowIcon'; import { TraceSpanReference } from '../types/trace'; import { UITooltip, UIDropdown, UIMenuItem, UIMenu, TooltipPlacement } from '../uiElementsContext'; - import ReferenceLink from '../url/ReferenceLink'; -import { createStyle } from '../Theme'; -export const getStyles = createStyle(() => { +export const getStyles = stylesFactory(() => { return { MultiParent: css` padding: 0 5px; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx index 682e580c67b..13bea7c3db3 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx @@ -17,14 +17,16 @@ import { css } from '@emotion/css'; import { groupBy as _groupBy } from 'lodash'; import React from 'react'; import { compose, onlyUpdateForKeys, withProps, withState } from 'recompose'; -import { autoColor, createStyle, Theme } from '../Theme'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; +import { autoColor } from '../Theme'; import { TraceSpan } from '../types/trace'; import { TNil } from '../types'; import { UIPopover } from '../uiElementsContext'; import AccordianLogs from './SpanDetail/AccordianLogs'; import { ViewedBoundsFunctionType } from './utils'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { wrapper: css` label: wrapper; @@ -86,7 +88,7 @@ const getStyles = createStyle((theme: Theme) => { } `, }; -}); +}; type TCommonProps = { color: string; @@ -105,7 +107,6 @@ type TCommonProps = { span: TraceSpan; className?: string; labelClassName?: string; - theme: Theme; }; type TInnerProps = { @@ -136,7 +137,6 @@ function SpanBar(props: TInnerProps) { rpc, traceStartTime, span, - theme, className, labelClassName, } = props; @@ -146,7 +146,7 @@ function SpanBar(props: TInnerProps) { // round to the nearest 0.2% return toPercent(Math.round(posPercent * 500) / 500); }); - const styles = getStyles(theme); + const styles = useStyles2(getStyles); return (
{ +const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { nameWrapper: css` label: nameWrapper; @@ -260,7 +262,7 @@ const getStyles = createStyle((theme: Theme) => { type SpanBarRowProps = { className?: string; - theme: Theme; + theme: GrafanaTheme2; color: string; columnDivision: number; isChildrenExpanded: boolean; @@ -505,7 +507,6 @@ export class UnthemedSpanBarRow extends React.PureComponent { rpc={rpc} viewStart={viewStart} viewEnd={viewEnd} - theme={theme} getViewedBounds={getViewedBounds} color={color} shortLabel={label} @@ -521,4 +522,4 @@ export class UnthemedSpanBarRow extends React.PureComponent { } } -export default withTheme(UnthemedSpanBarRow); +export default withTheme2(UnthemedSpanBarRow); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx index c44c552c446..909b5c3f366 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx @@ -22,10 +22,12 @@ import * as markers from './AccordianKeyValues.markers'; import KeyValuesTable from './KeyValuesTable'; import { TNil } from '../../types'; import { TraceKeyValuePair, TraceLink } from '../../types/trace'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { uAlignIcon, uTxEllipsis } from '../../uberUtilityStyles'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; -export const getStyles = createStyle((theme: Theme) => { +export const getStyles = (theme: GrafanaTheme2) => { return { header: css` label: header; @@ -80,7 +82,7 @@ export const getStyles = createStyle((theme: Theme) => { padding: 0 0.2em; `, }; -}); +}; type AccordianKeyValuesProps = { className?: string | TNil; @@ -96,7 +98,7 @@ type AccordianKeyValuesProps = { // export for tests export function KeyValuesSummary(props: { data?: TraceKeyValuePair[] }) { const { data } = props; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); if (!Array.isArray(data) || !data.length) { return null; @@ -123,7 +125,7 @@ KeyValuesSummary.defaultProps = { export default function AccordianKeyValues(props: AccordianKeyValuesProps) { const { className, data, highContrast, interactive, isOpen, label, linksGetter, onToggle } = props; const isEmpty = !Array.isArray(data) || !data.length; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); const iconCls = cx(uAlignIcon, { [styles.emptyIcon]: isEmpty }); let arrow: React.ReactNode | null = null; let headerProps: {} | null = null; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx index d507586b7f5..1a0c812dd7f 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx @@ -17,15 +17,17 @@ import { sortBy as _sortBy } from 'lodash'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; import AccordianKeyValues from './AccordianKeyValues'; import { formatDuration } from '../utils'; import { TNil } from '../../types'; import { TraceLog, TraceKeyValuePair, TraceLink } from '../../types/trace'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { AccordianLogs: css` label: AccordianLogs; @@ -54,7 +56,7 @@ const getStyles = createStyle((theme: Theme) => { color: ${autoColor(theme, '#999')}; `, }; -}); +}; type AccordianLogsProps = { interactive?: boolean; @@ -82,7 +84,7 @@ export default function AccordianLogs(props: AccordianLogsProps) { }; } - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return (
diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx index 28398b20651..5adf26e802e 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx @@ -15,16 +15,15 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; import { TraceSpanReference } from '../../types/trace'; import ReferenceLink from '../../url/ReferenceLink'; - -import { createStyle } from '../../Theme'; import { uAlignIcon } from '../../uberUtilityStyles'; -const getStyles = createStyle(() => { +const getStyles = () => { return { ReferencesList: css` background: #fff; @@ -63,7 +62,7 @@ const getStyles = createStyle(() => { } `, }; -}); +}; type AccordianReferencesProps = { data: TraceSpanReference[]; @@ -82,7 +81,7 @@ type ReferenceItemProps = { // export for test export function References(props: ReferenceItemProps) { const { data, focusSpan } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); return (
diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx index 8943e41ccd2..f2bc2b74620 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx @@ -17,13 +17,16 @@ import { css } from '@emotion/css'; import cx from 'classnames'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; + import TextList from './TextList'; import { TNil } from '../../types'; import { getStyles as getAccordianKeyValuesStyles } from './AccordianKeyValues'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { uAlignIcon } from '../../uberUtilityStyles'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { header: css` cursor: pointer; @@ -36,7 +39,7 @@ const getStyles = createStyle((theme: Theme) => { } `, }; -}); +}; type AccordianTextProps = { className?: string | TNil; @@ -66,7 +69,7 @@ export default function AccordianText(props: AccordianTextProps) { TextComponent = DefaultTextComponent, } = props; const isEmpty = !Array.isArray(data) || !data.length; - const accordianKeyValuesStyles = getAccordianKeyValuesStyles(useTheme()); + const accordianKeyValuesStyles = useStyles2(getAccordianKeyValuesStyles); const iconCls = cx(uAlignIcon, { [accordianKeyValuesStyles.emptyIcon]: isEmpty }); let arrow: React.ReactNode | null = null; let headerProps: {} | null = null; @@ -78,7 +81,7 @@ export default function AccordianText(props: AccordianTextProps) { role: 'switch', }; } - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return (
diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js index 4a26b725193..bdbfac59793 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js @@ -14,13 +14,13 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { createTheme } from '@grafana/data'; import CopyIcon from '../../common/CopyIcon'; import KeyValuesTable, { LinkValue, getStyles } from './KeyValuesTable'; import { UIDropdown, UIIcon } from '../../uiElementsContext'; import { ubInlineBlock } from '../../uberUtilityStyles'; -import { defaultTheme } from '../../Theme'; describe('LinkValue', () => { const title = 'titleValue'; @@ -39,7 +39,7 @@ describe('LinkValue', () => { }); it('renders correct Icon', () => { - const styles = getStyles(defaultTheme); + const styles = getStyles(createTheme()); expect(wrapper.find(UIIcon).hasClass(styles.linkIcon)).toBe(true); expect(wrapper.find(UIIcon).prop('type')).toBe('export'); }); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx index e9b4058d633..2fb4191dc5b 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx @@ -16,18 +16,19 @@ import * as React from 'react'; import jsonMarkup from 'json-markup'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import CopyIcon from '../../common/CopyIcon'; - import { TNil } from '../../types'; import { TraceKeyValuePair, TraceLink } from '../../types/trace'; import { UIDropdown, UIIcon, UIMenu, UIMenuItem } from '../../uiElementsContext'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { ubInlineBlock, uWidth100 } from '../../uberUtilityStyles'; const copyIconClassName = 'copyIcon'; -export const getStyles = createStyle((theme: Theme) => { +export const getStyles = (theme: GrafanaTheme2) => { return { KeyValueTable: css` label: KeyValueTable; @@ -71,7 +72,7 @@ export const getStyles = createStyle((theme: Theme) => { font-weight: bold; `, }; -}); +}; const jsonObjectOrArrayStartRegex = /^(\[|\{)/; @@ -88,7 +89,7 @@ function parseIfComplexJson(value: any) { } export const LinkValue = (props: { href: string; title?: string; children: React.ReactNode }) => { - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return ( {props.children} @@ -118,7 +119,7 @@ type KeyValuesTableProps = { export default function KeyValuesTable(props: KeyValuesTableProps) { const { data, linksGetter } = props; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return (
diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx index ef4119e594b..6a79a69ca67 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx @@ -15,10 +15,9 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; -import { createStyle } from '../../Theme'; - -const getStyles = createStyle(() => { +const getStyles = () => { return { TextList: css` max-height: 450px; @@ -38,7 +37,7 @@ const getStyles = createStyle(() => { } `, }; -}); +}; type TextListProps = { data: string[]; @@ -46,7 +45,7 @@ type TextListProps = { export default function TextList(props: TextListProps) { const { data } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); return (
    diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx index 5fd019ab0e2..a1ea131a29d 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx @@ -15,6 +15,8 @@ import React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { DataLinkButton, TextArea, useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import AccordianKeyValues from './AccordianKeyValues'; import AccordianLogs from './AccordianLogs'; @@ -23,16 +25,14 @@ import DetailState from './DetailState'; import { formatDuration } from '../utils'; import CopyIcon from '../../common/CopyIcon'; import LabeledList from '../../common/LabeledList'; - import { SpanLinkFunc, TNil } from '../../types'; import { TraceKeyValuePair, TraceLink, TraceLog, TraceSpan } from '../../types/trace'; import AccordianReferences from './AccordianReferences'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { UIDivider } from '../../uiElementsContext'; import { ubFlex, ubFlexAuto, ubItemsCenter, ubM0, ubMb1, ubMy1, ubTxRightAlign } from '../../uberUtilityStyles'; -import { DataLinkButton, TextArea } from '@grafana/ui'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { divider: css` label: divider; @@ -100,7 +100,7 @@ const getStyles = createStyle((theme: Theme) => { white-space: pre; `, }; -}); +}; type SpanDetailProps = { detailState: DetailState; @@ -172,7 +172,7 @@ export default function SpanDetail(props: SpanDetailProps) { }, ]; const deepLinkCopyText = `${window.location.origin}${window.location.pathname}?uiFind=${spanID}`; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); const link = createSpanLink?.(span); return ( diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js index e142ecf67b0..cdfe935b52d 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js @@ -14,8 +14,9 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { createTheme } from '@grafana/data'; -import SpanDetailRow from './SpanDetailRow'; +import { UnthemedSpanDetailRow } from './SpanDetailRow'; import SpanDetail from './SpanDetail'; import DetailState from './SpanDetail/DetailState'; import SpanTreeOffset from './SpanTreeOffset'; @@ -37,6 +38,7 @@ describe('', () => { span: { spanID, depth: 3 }, tagsToggle: jest.fn(), traceStartTime: 1000, + theme: createTheme(), }; let wrapper; @@ -48,10 +50,7 @@ describe('', () => { props.logsToggle.mockReset(); props.processToggle.mockReset(); props.tagsToggle.mockReset(); - wrapper = shallow() - .dive() - .dive() - .dive(); + wrapper = shallow(); }); it('renders without exploding', () => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx index 827292384b9..d6cdadac5f7 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx @@ -19,12 +19,14 @@ import SpanDetail from './SpanDetail'; import DetailState from './SpanDetail/DetailState'; import SpanTreeOffset from './SpanTreeOffset'; import TimelineRow from './TimelineRow'; -import { autoColor, createStyle, Theme, withTheme } from '../Theme'; +import { autoColor } from '../Theme'; +import { stylesFactory, withTheme2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink } from '../types/trace'; import { SpanLinkFunc } from '../types'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { expandedAccent: css` cursor: pointer; @@ -85,7 +87,7 @@ type SpanDetailRowProps = { hoverIndentGuideIds: Set; addHoverIndentGuideId: (spanID: string) => void; removeHoverIndentGuideId: (spanID: string) => void; - theme: Theme; + theme: GrafanaTheme2; createSpanLink?: SpanLinkFunc; }; @@ -166,4 +168,4 @@ export class UnthemedSpanDetailRow extends React.PureComponent { }, }; wrapper = shallow() - .dive() .dive() .dive(); }); @@ -53,7 +52,6 @@ describe('SpanTreeOffset', () => { it('renders only one .SpanTreeOffset--indentGuide for entire trace if span has no ancestors', () => { spanAncestorIdsSpy.mockReturnValue([]); wrapper = shallow() - .dive() .dive() .dive(); const indentGuides = wrapper.find('[data-test-id="SpanTreeOffset--indentGuide"]'); @@ -72,10 +70,9 @@ describe('SpanTreeOffset', () => { it('adds .is-active to correct indentGuide', () => { props.hoverIndentGuideIds = new Set([parentSpanID]); wrapper = shallow() - .dive() .dive() .dive(); - const styles = getStyles(defaultTheme); + const styles = getStyles(createTheme()); const activeIndentGuide = wrapper.find(`.${styles.indentGuideActive}`); expect(activeIndentGuide.length).toBe(1); expect(activeIndentGuide.prop('data-ancestor-id')).toBe(parentSpanID); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx index 313a4640820..741dd06655f 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx @@ -18,13 +18,14 @@ import IoChevronRight from 'react-icons/lib/io/chevron-right'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory, withTheme2 } from '@grafana/ui'; import { TraceSpan } from '../types/trace'; import spanAncestorIds from '../utils/span-ancestor-ids'; +import { autoColor } from '../Theme'; -import { autoColor, createStyle, Theme, withTheme } from '../Theme'; - -export const getStyles = createStyle((theme: Theme) => { +export const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { SpanTreeOffset: css` label: SpanTreeOffset; @@ -74,7 +75,7 @@ type TProps = { hoverIndentGuideIds: Set; addHoverIndentGuideId: (spanID: string) => void; removeHoverIndentGuideId: (spanID: string) => void; - theme: Theme; + theme: GrafanaTheme2; }; export class UnthemedSpanTreeOffset extends React.PureComponent { @@ -167,4 +168,4 @@ export class UnthemedSpanTreeOffset extends React.PureComponent { } } -export default withTheme(UnthemedSpanTreeOffset); +export default withTheme2(UnthemedSpanTreeOffset); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx index c660a9aa440..952b8d2b1e9 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx @@ -15,12 +15,14 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import { formatDuration } from './utils'; import { TNil } from '../types'; -import { autoColor, createStyle, Theme, useTheme } from '../Theme'; +import { autoColor } from '../Theme'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { Ticks: css` label: Ticks; @@ -47,7 +49,7 @@ const getStyles = createStyle((theme: Theme) => { right: 0.25rem; `, }; -}); +}; type TicksProps = { endTime?: number | TNil; @@ -68,7 +70,7 @@ export default function Ticks(props: TicksProps) { labels.push(formatDuration(durationAtTick)); } } - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); const ticks: React.ReactNode[] = []; for (let i = 0; i < numTicks; i++) { const portion = i / (numTicks - 1); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx index 0ac5100432a..5a4e407fef8 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx @@ -12,12 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { IconButton } from '@grafana/ui'; +import { IconButton, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; import React from 'react'; -import { createStyle } from '../../Theme'; -const getStyles = createStyle(() => { +const getStyles = () => { return { TimelineCollapser: css` align-items: center; @@ -27,7 +26,7 @@ const getStyles = createStyle(() => { margin-right: 0.5rem; `, }; -}); +}; type CollapserProps = { onCollapseAll: () => void; @@ -38,7 +37,7 @@ type CollapserProps = { export function TimelineCollapser(props: CollapserProps) { const { onExpandAll, onExpandOne, onCollapseAll, onCollapseOne } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); return (
    diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx index a3f4f971d20..72f41ea852a 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx @@ -15,12 +15,12 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { stylesFactory } from '@grafana/ui'; import { TNil } from '../../types'; import DraggableManager, { DraggableBounds, DraggingUpdate } from '../../utils/DraggableManager'; -import { createStyle } from '../../Theme'; -export const getStyles = createStyle(() => { +export const getStyles = stylesFactory(() => { return { TimelineColumnResizer: css` left: 0; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx index b98bef3a18e..b973ec1fbd5 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx @@ -15,6 +15,8 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import { TimelineCollapser } from './TimelineCollapser'; import TimelineColumnResizer from './TimelineColumnResizer'; @@ -22,10 +24,10 @@ import TimelineViewingLayer from './TimelineViewingLayer'; import Ticks from '../Ticks'; import TimelineRow from '../TimelineRow'; import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; -import { autoColor, createStyle, Theme, useTheme } from '../../Theme'; +import { autoColor } from '../../Theme'; import { ubFlex, ubPx2 } from '../../uberUtilityStyles'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { TimelineHeaderRow: css` label: TimelineHeaderRow; @@ -50,7 +52,7 @@ const getStyles = createStyle((theme: Theme) => { align-items: center; `, }; -}); +}; type TimelineHeaderRowProps = { duration: number; @@ -83,7 +85,7 @@ export default function TimelineHeaderRow(props: TimelineHeaderRowProps) { columnResizeHandleHeight, } = props; const [viewStart, viewEnd] = viewRangeTime.current; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return ( diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx index e182aba22e8..7c066b8db42 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx @@ -14,14 +14,13 @@ import * as React from 'react'; import { css, cx } from '@emotion/css'; - +import { stylesFactory } from '@grafana/ui'; import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; import { TNil } from '../../types'; import DraggableManager, { DraggableBounds, DraggingUpdate } from '../../utils/DraggableManager'; -import { createStyle } from '../../Theme'; // exported for testing -export const getStyles = createStyle(() => { +export const getStyles = stylesFactory(() => { return { TimelineViewingLayer: css` label: TimelineViewingLayer; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx index f1ec8231e37..95bcd4deffe 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx @@ -15,10 +15,10 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { createStyle } from '../Theme'; +import { useStyles2 } from '@grafana/ui'; import { ubRelative } from '../uberUtilityStyles'; -const getStyles = createStyle(() => { +const getStyles = () => { return { flexRow: css` display: flex; @@ -26,7 +26,7 @@ const getStyles = createStyle(() => { flex-direction: row; `, }; -}); +}; type TTimelineRowProps = { children: React.ReactNode; @@ -42,7 +42,7 @@ interface TimelineRowCellProps extends React.HTMLAttributes { export default function TimelineRow(props: TTimelineRowProps) { const { children, className = '', ...rest } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); return (
    {children} diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js index 5c4c0e13f1c..c47bd1bfe92 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js @@ -90,7 +90,6 @@ describe('', () => { } }); wrapper = shallow() - .dive() .dive() .dive(); instance = wrapper.instance(); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx index a79cc4496a6..01eed9b8b6f 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx @@ -17,6 +17,9 @@ import { css } from '@emotion/css'; import { isEqual } from 'lodash'; import memoizeOne from 'memoize-one'; +import { stylesFactory, withTheme2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; + import ListView from './ListView'; import SpanBarRow from './SpanBarRow'; import DetailState from './SpanDetail/DetailState'; @@ -36,13 +39,11 @@ import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink } from '../typ import TTraceTimeline from '../types/TTraceTimeline'; import { PEER_SERVICE } from '../constants/tag-keys'; -import { createStyle, Theme, withTheme } from '../Theme'; - type TExtractUiFindFromStateReturn = { uiFind: string | undefined; }; -const getStyles = createStyle(() => { +const getStyles = stylesFactory(() => { return { rowsWrapper: css` width: 100%; @@ -82,7 +83,7 @@ type TVirtualizedTraceViewOwnProps = { hoverIndentGuideIds: Set; addHoverIndentGuideId: (spanID: string) => void; removeHoverIndentGuideId: (spanID: string) => void; - theme: Theme; + theme: GrafanaTheme2; createSpanLink?: SpanLinkFunc; scrollElement?: Element; }; @@ -486,4 +487,4 @@ export class UnthemedVirtualizedTraceView extends React.Component', () => { const trace = transformTraceData(traceGenerator.trace({})); @@ -38,7 +38,7 @@ describe('', () => { collapseAll: jest.fn(), expandOne: jest.fn(), collapseOne: jest.fn(), - theme: defaultTheme, + theme: createTheme(), history: { replace: () => {}, }, diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx index 5e4fd7518b7..b8e560a40d5 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx @@ -14,6 +14,8 @@ import React from 'react'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory, withTheme2 } from '@grafana/ui'; import TimelineHeaderRow from './TimelineHeaderRow'; import VirtualizedTraceView from './VirtualizedTraceView'; @@ -23,14 +25,14 @@ import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from './ import { SpanLinkFunc, TNil } from '../types'; import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink } from '../types/trace'; import TTraceTimeline from '../types/TTraceTimeline'; -import { autoColor, createStyle, Theme, withTheme } from '../Theme'; +import { autoColor } from '../Theme'; import ExternalLinkContext from '../url/externalLinkContext'; type TExtractUiFindFromStateReturn = { uiFind: string | undefined; }; -const getStyles = createStyle((theme: Theme) => { +const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { TraceTimelineViewer: css` label: TraceTimelineViewer; @@ -98,7 +100,7 @@ type TProps = TExtractUiFindFromStateReturn & { addHoverIndentGuideId: (spanID: string) => void; removeHoverIndentGuideId: (spanID: string) => void; linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[]; - theme: Theme; + theme: GrafanaTheme2; createSpanLink?: SpanLinkFunc; scrollElement?: Element; }; @@ -193,4 +195,4 @@ export class UnthemedTraceTimelineViewer extends React.PureComponent { +const getStyles = () => { return { BreakableText: css` label: BreakableText; @@ -25,7 +24,7 @@ const getStyles = createStyle(() => { white-space: pre; `, }; -}); +}; const WORD_RX = /\W*\w+\W*/g; @@ -41,6 +40,7 @@ export default function BreakableText( props: Props ): any /* React.ReactNode /* React.ReactElement | React.ReactElement[] \*\/ */ { const { className, text, wordRegexp = WORD_RX } = props; + const styles = useStyles2(getStyles); if (!text) { return typeof text === 'string' ? text : null; } @@ -50,7 +50,7 @@ export default function BreakableText( let match: RegExpExecArray | string[] | null = wordRegexp.exec(text) || [text]; while (match) { spans.push( - + {match[0]} ); diff --git a/packages/jaeger-ui-components/src/common/CopyIcon.tsx b/packages/jaeger-ui-components/src/common/CopyIcon.tsx index 74c086baca7..035fb1f6a67 100644 --- a/packages/jaeger-ui-components/src/common/CopyIcon.tsx +++ b/packages/jaeger-ui-components/src/common/CopyIcon.tsx @@ -16,11 +16,11 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; import copy from 'copy-to-clipboard'; +import { stylesFactory } from '@grafana/ui'; import { UITooltip, TooltipPlacement, UIButton } from '../uiElementsContext'; -import { createStyle } from '../Theme'; -const getStyles = createStyle(() => { +const getStyles = stylesFactory(() => { return { CopyIcon: css` background-color: transparent; diff --git a/packages/jaeger-ui-components/src/common/LabeledList.tsx b/packages/jaeger-ui-components/src/common/LabeledList.tsx index f19adf2d5bc..65735d2fb1b 100644 --- a/packages/jaeger-ui-components/src/common/LabeledList.tsx +++ b/packages/jaeger-ui-components/src/common/LabeledList.tsx @@ -15,11 +15,12 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; -import { createStyle, isLight, Theme, useTheme } from '../Theme'; import { UIDivider } from '../uiElementsContext'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { LabeledList: css` label: LabeledList; @@ -33,11 +34,11 @@ const getStyles = createStyle((theme: Theme) => { `, LabeledListLabel: css` label: LabeledListLabel; - color: ${isLight(theme) ? '#999' : '#666'}; + color: ${theme.isLight ? '#999' : '#666'}; margin-right: 0.25rem; `, }; -}); +}; type LabeledListProps = { className?: string; @@ -47,7 +48,7 @@ type LabeledListProps = { export default function LabeledList(props: LabeledListProps) { const { className, dividerClassName, items } = props; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); return (
      {items.map(({ key, label, value }, i) => { diff --git a/packages/jaeger-ui-components/src/common/LoadingIndicator.tsx b/packages/jaeger-ui-components/src/common/LoadingIndicator.tsx index 14a66681fd7..421dd8c9ea4 100644 --- a/packages/jaeger-ui-components/src/common/LoadingIndicator.tsx +++ b/packages/jaeger-ui-components/src/common/LoadingIndicator.tsx @@ -15,11 +15,11 @@ import React from 'react'; import cx from 'classnames'; import { css, keyframes } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; -import { createStyle } from '../Theme'; import { UIIcon } from '../uiElementsContext'; -const getStyles = createStyle(() => { +const getStyles = () => { const LoadingIndicatorColorAnim = keyframes` /* rgb(0, 128, 128) == teal @@ -52,7 +52,7 @@ const getStyles = createStyle(() => { font-size: 0.7em; `, }; -}); +}; type LoadingIndicatorProps = { centered?: boolean; @@ -62,7 +62,7 @@ type LoadingIndicatorProps = { export default function LoadingIndicator(props: LoadingIndicatorProps) { const { centered, className, small, ...rest } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); const cls = cx(styles.LoadingIndicator, { [styles.LoadingIndicatorCentered]: centered, [styles.LoadingIndicatorSmall]: small, diff --git a/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx b/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx index 7ebc6fd5c86..57256c75faf 100644 --- a/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx +++ b/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx @@ -16,17 +16,16 @@ import React from 'react'; import cx from 'classnames'; import IoAndroidOpen from 'react-icons/lib/io/android-open'; import { css } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; -import { createStyle } from '../Theme'; - -export const getStyles = createStyle(() => { +export const getStyles = () => { return { NewWindowIconLarge: css` label: NewWindowIconLarge; font-size: 1.5em; `, }; -}); +}; type Props = { isLarge?: boolean; @@ -35,7 +34,7 @@ type Props = { export default function NewWindowIcon(props: Props) { const { isLarge, className, ...rest } = props; - const styles = getStyles(); + const styles = useStyles2(getStyles); const cls = cx({ [styles.NewWindowIconLarge]: isLarge }, className); return ; } diff --git a/packages/jaeger-ui-components/src/common/TraceName.tsx b/packages/jaeger-ui-components/src/common/TraceName.tsx index bd14247d883..349e0951253 100644 --- a/packages/jaeger-ui-components/src/common/TraceName.tsx +++ b/packages/jaeger-ui-components/src/common/TraceName.tsx @@ -15,27 +15,27 @@ import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; import BreakableText from './BreakableText'; import LoadingIndicator from './LoadingIndicator'; import { fetchedState, FALLBACK_TRACE_NAME } from '../constants'; - import { FetchedState, TNil } from '../types'; import { ApiError } from '../types/api-error'; -import { createStyle, safeSize, Theme, useTheme } from '../Theme'; -const getStyles = createStyle((theme: Theme) => { +const getStyles = (theme: GrafanaTheme2) => { return { TraceName: css` label: TraceName; - font-size: ${safeSize(theme.components?.TraceName?.fontSize, 'unset')}; + font-size: ${theme.typography.size.lg}; `, TraceNameError: css` label: TraceNameError; color: #c00; `, }; -}); +}; type Props = { className?: string; @@ -48,7 +48,7 @@ export default function TraceName(props: Props) { const { className, error, state, traceName } = props; const isErred = state === fetchedState.ERROR; let title: string | React.ReactNode = traceName || FALLBACK_TRACE_NAME; - const styles = getStyles(useTheme()); + const styles = useStyles2(getStyles); let errorCssClass = ''; if (isErred) { errorCssClass = styles.TraceNameError; diff --git a/packages/jaeger-ui-components/src/utils/color-generator.test.js b/packages/jaeger-ui-components/src/utils/color-generator.test.js index 01f77471018..d211220bbb1 100644 --- a/packages/jaeger-ui-components/src/utils/color-generator.test.js +++ b/packages/jaeger-ui-components/src/utils/color-generator.test.js @@ -13,26 +13,26 @@ // limitations under the License. import { getColorByKey, clear } from './color-generator'; -import { defaultTheme } from '../Theme'; +import { createTheme } from '@grafana/data'; it('gives the same color for the same key', () => { clear(); - const colorOne = getColorByKey('serviceA', defaultTheme); - const colorTwo = getColorByKey('serviceA', defaultTheme); + const colorOne = getColorByKey('serviceA', createTheme()); + const colorTwo = getColorByKey('serviceA', createTheme()); expect(colorOne).toBe(colorTwo); }); it('gives different colors for each for each key', () => { clear(); - const colorOne = getColorByKey('serviceA', defaultTheme); - const colorTwo = getColorByKey('serviceB', defaultTheme); + const colorOne = getColorByKey('serviceA', createTheme()); + const colorTwo = getColorByKey('serviceB', createTheme()); expect(colorOne).not.toBe(colorTwo); }); it('should clear cache', () => { clear(); - const colorOne = getColorByKey('serviceA', defaultTheme); + const colorOne = getColorByKey('serviceA', createTheme()); clear(); - const colorTwo = getColorByKey('serviceB', defaultTheme); + const colorTwo = getColorByKey('serviceB', createTheme()); expect(colorOne).toBe(colorTwo); }); diff --git a/packages/jaeger-ui-components/src/utils/color-generator.tsx b/packages/jaeger-ui-components/src/utils/color-generator.tsx index 0229d578bba..c4d7ef614d9 100644 --- a/packages/jaeger-ui-components/src/utils/color-generator.tsx +++ b/packages/jaeger-ui-components/src/utils/color-generator.tsx @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Theme } from '../Theme'; import memoizeOne from 'memoize-one'; +import { GrafanaTheme2 } from '@grafana/data'; +import { colors } from '@grafana/ui'; // TS needs the precise return type function strToRgb(s: string): [number, number, number] { @@ -83,10 +84,10 @@ export function clear() { getGenerator([]); } -export function getColorByKey(key: string, theme: Theme) { - return getGenerator(theme.servicesColorPalette).getColorByKey(key); +export function getColorByKey(key: string, theme: GrafanaTheme2) { + return getGenerator(colors).getColorByKey(key); } -export function getRgbColorByKey(key: string, theme: Theme): [number, number, number] { - return getGenerator(theme.servicesColorPalette).getRgbColorByKey(key); +export function getRgbColorByKey(key: string, theme: GrafanaTheme2): [number, number, number] { + return getGenerator(colors).getRgbColorByKey(key); } diff --git a/public/app/features/explore/TraceView/TraceView.tsx b/public/app/features/explore/TraceView/TraceView.tsx index f4f105ed3de..4b5b1239304 100644 --- a/public/app/features/explore/TraceView/TraceView.tsx +++ b/public/app/features/explore/TraceView/TraceView.tsx @@ -1,9 +1,5 @@ import { DataFrame, DataFrameView, SplitOpen, TraceSpanRow } from '@grafana/data'; -import { colors, useTheme } from '@grafana/ui'; import { - ThemeOptions, - ThemeProvider, - ThemeType, Trace, TracePageHeader, TraceProcess, @@ -75,21 +71,6 @@ export function TraceView(props: Props) { ?.tracesToLogs; const timeZone = useSelector((state: StoreState) => getTimeZone(state.user)); - const theme = useTheme(); - const traceTheme = useMemo( - () => - ({ - type: theme.isDark ? ThemeType.Dark : ThemeType.Light, - servicesColorPalette: colors, - components: { - TraceName: { - fontSize: theme.typography.size.lg, - }, - }, - } as ThemeOptions), - [theme] - ); - const traceTimeline: TTraceTimeline = useMemo( () => ({ childrenHiddenIDs, @@ -113,67 +94,65 @@ export function TraceView(props: Props) { } return ( - - - - - - + + + + ); }