From 314f95a9149047f5f50bb8df163166c78ec58a25 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Mon, 7 Mar 2022 14:32:17 +0530 Subject: [PATCH 1/7] feat(FE): shared styled for custom styled components --- frontend/package.json | 4 +- frontend/src/components/Styled/index.ts | 32 ++++++++ frontend/src/components/Styled/styles.ts | 41 ++++++++++ frontend/src/components/Styled/types.ts | 5 ++ .../TraceDetail/TraceGraph.module.css | 3 - frontend/src/container/TraceDetail/index.tsx | 82 +++++++++++++------ frontend/src/container/TraceDetail/styles.ts | 5 ++ 7 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 frontend/src/components/Styled/index.ts create mode 100644 frontend/src/components/Styled/styles.ts create mode 100644 frontend/src/components/Styled/types.ts delete mode 100644 frontend/src/container/TraceDetail/TraceGraph.module.css create mode 100644 frontend/src/container/TraceDetail/styles.ts diff --git a/frontend/package.json b/frontend/package.json index 48c33a04fc..458341f1cb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,8 +7,8 @@ "dev": "cross-env NODE_ENV=development webpack serve --progress", "build": "webpack --config=webpack.config.prod.js --progress", "prettify": "prettier --write .", - "lint": "eslint . --debug", - "lint:fix": "eslint . --fix --debug", + "lint": "eslint .", + "lint:fix": "eslint . --fix", "cypress:open": "cypress open", "cypress:run": "cypress run", "jest": "jest", diff --git a/frontend/src/components/Styled/index.ts b/frontend/src/components/Styled/index.ts new file mode 100644 index 0000000000..f740b81bb9 --- /dev/null +++ b/frontend/src/components/Styled/index.ts @@ -0,0 +1,32 @@ +import { Col, ColProps, Row, RowProps } from 'antd'; +import React from 'react'; +import styled, { + css, + DefaultTheme, + FlattenSimpleInterpolation, + ThemedCssFunction, +} from 'styled-components'; + +import { IStyledClass } from './types'; + +const styledClass = (props: IStyledClass): FlattenSimpleInterpolation => + props.styledClass; + +interface IStyledCol extends ColProps, IStyledClass {} +const StyledCol = styled(Col)` + ${styledClass} +`; + +interface IStyledRow extends RowProps, IStyledClass {} +const StyledRow = styled(Row)` + ${styledClass} +`; + +interface IStyledDiv + extends React.HTMLAttributes, + IStyledClass {} +const StyledDiv = styled.div` + ${styledClass} +`; + +export { StyledCol, StyledDiv, StyledRow }; diff --git a/frontend/src/components/Styled/styles.ts b/frontend/src/components/Styled/styles.ts new file mode 100644 index 0000000000..153ef27a94 --- /dev/null +++ b/frontend/src/components/Styled/styles.ts @@ -0,0 +1,41 @@ +import { css, FlattenSimpleInterpolation } from 'styled-components'; + +const cssProprty = (key: string, value: any): FlattenSimpleInterpolation => + key && + value && + css` + ${key}: ${value}; + `; + +interface IFlexProps { + flexDirection?: string; // Need to replace this with exact css props. Not able to find any :( + flex?: number | string; +} +export const Flex = ({ + flexDirection, + flex, +}: IFlexProps): FlattenSimpleInterpolation => css` + ${cssProprty('flex-direction', flexDirection)} + ${cssProprty('flex', flex)} +`; + +interface IDisplayProps { + display?: string; +} +export const Display = ({ + display, +}: IDisplayProps): FlattenSimpleInterpolation => css` + ${cssProprty('display', display)} +`; + +interface ISpacingProps { + margin?: string; + padding?: string; +} +export const Spacing = ({ + margin, + padding, +}: ISpacingProps): FlattenSimpleInterpolation => css` + ${cssProprty('margin', margin)} + ${cssProprty('padding', padding)} +`; diff --git a/frontend/src/components/Styled/types.ts b/frontend/src/components/Styled/types.ts new file mode 100644 index 0000000000..5d9dbb9054 --- /dev/null +++ b/frontend/src/components/Styled/types.ts @@ -0,0 +1,5 @@ +import { FlattenSimpleInterpolation } from 'styled-components'; + +export interface IStyledClass { + styledClass: FlattenSimpleInterpolation[]; +} diff --git a/frontend/src/container/TraceDetail/TraceGraph.module.css b/frontend/src/container/TraceDetail/TraceGraph.module.css deleted file mode 100644 index 9127050c97..0000000000 --- a/frontend/src/container/TraceDetail/TraceGraph.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.trace-detail-content-spacing { - margin-right: 1rem; -} diff --git a/frontend/src/container/TraceDetail/index.tsx b/frontend/src/container/TraceDetail/index.tsx index 99d693fc85..57b602003b 100644 --- a/frontend/src/container/TraceDetail/index.tsx +++ b/frontend/src/container/TraceDetail/index.tsx @@ -1,21 +1,24 @@ -import React, { useEffect, useMemo, useState } from 'react'; -import { Col, Divider, Row, Typography, Space, Button } from 'antd'; import { FilterOutlined } from '@ant-design/icons'; +import { Button, Col, Divider, Row, Space, Typography } from 'antd'; +import { StyledCol, StyledDiv, StyledRow } from 'components/Styled'; +import * as StyledStyles from 'components/Styled/styles'; import GanttChart from 'container/GantChart'; import { getNodeById } from 'container/GantChart/utils'; import Timeline from 'container/Timeline'; import TraceFlameGraph from 'container/TraceFlameGraph'; import dayjs from 'dayjs'; +import useUrlQuery from 'hooks/useUrlQuery'; import { spanServiceNameToColorMapping } from 'lib/getRandomColor'; -import { getSortedData } from './utils'; +import history from 'lib/history'; +import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants'; +import React, { useEffect, useMemo, useState } from 'react'; import { ITraceTree, PayloadProps } from 'types/api/trace/getTraceItem'; import { getSpanTreeMetadata } from 'utils/getSpanTreeMetadata'; import { spanToTreeUtil } from 'utils/spanToTree'; + import SelectedSpanDetails from './SelectedSpanDetails'; -import useUrlQuery from 'hooks/useUrlQuery'; -import styles from './TraceGraph.module.css'; -import history from 'lib/history'; -import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants'; +import * as styles from './styles'; +import { getSortedData } from './utils'; import { INTERVAL_UNITS } from './utils'; const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { @@ -73,9 +76,21 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { }; return ( - - - + + + { intervalUnit={intervalUnit} /> - + { > {dayjs(traceMetaData.globalStart / 1e6).format('hh:mm:ssa MM/DD')} - { intervalUnit={intervalUnit} setIntervalUnit={setIntervalUnit} /> - + - {/* { - -
+ { spanId={spanId || ''} intervalUnit={intervalUnit} /> -
- + + @@ -189,7 +221,7 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { > -
+ ); }; diff --git a/frontend/src/container/TraceDetail/styles.ts b/frontend/src/container/TraceDetail/styles.ts new file mode 100644 index 0000000000..f4e99ed33d --- /dev/null +++ b/frontend/src/container/TraceDetail/styles.ts @@ -0,0 +1,5 @@ +import * as StyledStyles from 'components/Styled/styles'; + +export const traceDetailContentSpacing = StyledStyles.Spacing({ + margin: '0 1rem 0 0', +}); From c3ebbfa8ca9aadcaebb25d0e92c8d3b5d1de0287 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 9 Mar 2022 10:43:02 +0530 Subject: [PATCH 2/7] feat: new trace detail page code enhancemenets and cleanup --- frontend/src/components/Styled/index.ts | 61 ++++++++-- frontend/src/components/Styled/types.ts | 2 +- .../src/container/GantChart/Trace/index.tsx | 86 ++++++------- .../src/container/GantChart/Trace/styles.ts | 13 ++ frontend/src/container/GantChart/index.tsx | 24 ++-- frontend/src/container/GantChart/styles.ts | 1 + frontend/src/container/Timeline/index.tsx | 36 +++--- .../src/container/Timeline/style.module.css | 8 -- frontend/src/container/Timeline/styles.ts | 19 +++ .../SelectedSpanDetails/ErrorTag.tsx | 27 ++-- .../TraceDetail/SelectedSpanDetails/index.tsx | 24 ++-- .../TraceDetail/SelectedSpanDetails/styles.ts | 23 +++- frontend/src/container/TraceDetail/index.tsx | 115 ++++++------------ frontend/src/container/TraceDetail/styles.ts | 82 ++++++++++++- .../src/container/TraceFlameGraph/index.tsx | 27 ++-- frontend/src/store/actions/index.ts | 1 + 16 files changed, 341 insertions(+), 208 deletions(-) delete mode 100644 frontend/src/container/Timeline/style.module.css create mode 100644 frontend/src/container/Timeline/styles.ts diff --git a/frontend/src/components/Styled/index.ts b/frontend/src/components/Styled/index.ts index f740b81bb9..45b53896d1 100644 --- a/frontend/src/components/Styled/index.ts +++ b/frontend/src/components/Styled/index.ts @@ -1,4 +1,6 @@ -import { Col, ColProps, Row, RowProps } from 'antd'; +import * as AntD from 'antd'; +import { TextProps } from 'antd/lib/typography/Text'; +import { TitleProps } from 'antd/lib/typography/Title'; import React from 'react'; import styled, { css, @@ -10,15 +12,47 @@ import styled, { import { IStyledClass } from './types'; const styledClass = (props: IStyledClass): FlattenSimpleInterpolation => - props.styledClass; + props.styledclass; -interface IStyledCol extends ColProps, IStyledClass {} -const StyledCol = styled(Col)` +interface IStyledCol extends AntD.ColProps, IStyledClass {} +const StyledCol = styled(AntD.Col)` ${styledClass} `; -interface IStyledRow extends RowProps, IStyledClass {} -const StyledRow = styled(Row)` +interface IStyledRow extends AntD.RowProps, IStyledClass {} +const StyledRow = styled(AntD.Row)` + ${styledClass} +`; + +interface IStyledDivider extends AntD.DividerProps, IStyledClass {} +const StyledDivider = styled(AntD.Divider)` + ${styledClass} +`; + +interface IStyledSpace extends AntD.SpaceProps, IStyledClass {} +const StyledSpace = styled(AntD.Space)` + ${styledClass} +`; + +interface IStyledTabs extends AntD.TabsProps, IStyledClass {} +const StyledTabs = styled(AntD.Divider)` + ${styledClass} +`; + +interface IStyledButton extends AntD.ButtonProps, IStyledClass {} +const StyledButton = styled(AntD.Button)` + ${styledClass} +`; + +const { Text } = AntD.Typography; +interface IStyledTypographyText extends TextProps, IStyledClass {} +const StyledTypographyText = styled(Text)` + ${styledClass} +`; + +const { Title } = AntD.Typography; +interface IStyledTypographyTitle extends TitleProps, IStyledClass {} +const StyledTypographyTitle = styled(Title)` ${styledClass} `; @@ -29,4 +63,17 @@ const StyledDiv = styled.div` ${styledClass} `; -export { StyledCol, StyledDiv, StyledRow }; +const StyledTypography = { + Text: StyledTypographyText, + Title: StyledTypographyTitle, +}; +export { + StyledButton, + StyledCol, + StyledDiv, + StyledDivider, + StyledRow, + StyledSpace, + StyledTabs, + StyledTypography, +}; diff --git a/frontend/src/components/Styled/types.ts b/frontend/src/components/Styled/types.ts index 5d9dbb9054..fb829fb394 100644 --- a/frontend/src/components/Styled/types.ts +++ b/frontend/src/components/Styled/types.ts @@ -1,5 +1,5 @@ import { FlattenSimpleInterpolation } from 'styled-components'; export interface IStyledClass { - styledClass: FlattenSimpleInterpolation[]; + styledclass?: FlattenSimpleInterpolation[]; } diff --git a/frontend/src/container/GantChart/Trace/index.tsx b/frontend/src/container/GantChart/Trace/index.tsx index a4d10052b8..1feecac85b 100644 --- a/frontend/src/container/GantChart/Trace/index.tsx +++ b/frontend/src/container/GantChart/Trace/index.tsx @@ -1,22 +1,24 @@ -import React, { useRef, useState, useEffect } from 'react'; +import { CaretDownFilled, CaretRightFilled } from '@ant-design/icons'; +import { Col } from 'antd'; +import { StyledCol, StyledRow } from 'components/Styled'; +import { IIntervalUnit } from 'container/TraceDetail/utils'; +import useThemeMode from 'hooks/useThemeMode'; +import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants'; +import React, { useEffect, useRef, useState } from 'react'; +import { pushDStree } from 'store/actions'; +import { ITraceMetaData } from '..'; +import SpanLength from '../SpanLength'; +import SpanName from '../SpanName'; +import { getMetaDataFromSpanTree, getTopLeftFromBody } from '../utils'; import { CardComponent, CardContainer, CaretContainer, - Wrapper, HoverCard, + styles, + Wrapper, } from './styles'; -import { CaretDownFilled, CaretRightFilled } from '@ant-design/icons'; -import SpanLength from '../SpanLength'; -import SpanName from '../SpanName'; -import { pushDStree } from 'store/actions'; -import { getMetaDataFromSpanTree, getTopLeftFromBody } from '../utils'; -import { ITraceMetaData } from '..'; -import { Col, Row } from 'antd'; -import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants' -import { IIntervalUnit, resolveTimeFromInterval } from 'container/TraceDetail/utils'; -import useThemeMode from 'hooks/useThemeMode'; const Trace = (props: TraceProps): JSX.Element => { const { @@ -38,7 +40,7 @@ const Trace = (props: TraceProps): JSX.Element => { intervalUnit, } = props; - const { isDarkMode } = useThemeMode() + const { isDarkMode } = useThemeMode(); const [isOpen, setOpen] = useState(activeSpanPath[level] === id); const localTreeExpandInteraction = useRef(0); // Boolean is for the state of the expansion whereas the number i.e. 0 is for skipping the user interaction. @@ -47,20 +49,18 @@ const Trace = (props: TraceProps): JSX.Element => { if (localTreeExpandInteraction.current !== 0) { setOpen(localTreeExpandInteraction.current); localTreeExpandInteraction.current = 0; + } else if (!isOpen) { + setOpen(activeSpanPath[level] === id); } - else if (!isOpen) { - setOpen(activeSpanPath[level] === id) - } - }, [activeSpanPath, isOpen]) + }, [activeSpanPath, isOpen]); useEffect(() => { if (isExpandAll) { - setOpen(isExpandAll) + setOpen(isExpandAll); + } else { + setOpen(activeSpanPath[level] === id); } - else { - setOpen(activeSpanPath[level] === id) - } - }, [isExpandAll]) + }, [isExpandAll]); const isOnlyChild = props.children.length === 1; const [top, setTop] = useState(0); @@ -69,9 +69,13 @@ const Trace = (props: TraceProps): JSX.Element => { React.useEffect(() => { if (activeSelectedId === id) { - ref.current?.scrollIntoView({ block: 'nearest', behavior: 'auto', inline: 'nearest' }); + ref.current?.scrollIntoView({ + block: 'nearest', + behavior: 'auto', + inline: 'nearest', + }); } - }, [activeSelectedId]) + }, [activeSelectedId]); const onMouseEnterHandler = () => { setActiveHoverId(props.id); @@ -87,18 +91,21 @@ const Trace = (props: TraceProps): JSX.Element => { const onClick = () => { setActiveSelectedId(id); - } + }; const onClickTreeExpansion = (event) => { - event.stopPropagation() - setOpen((state) => { localTreeExpandInteraction.current = !isOpen; return !state }); - } + event.stopPropagation(); + setOpen((state) => { + localTreeExpandInteraction.current = !isOpen; + return !state; + }); + }; const { totalSpans } = getMetaDataFromSpanTree(props); const inMsCount = value; const nodeLeftOffset = ((startTime - globalStart) * 1e2) / globalSpread; const width = (value * 1e2) / (globalSpread * 1e6); - const panelWidth = SPAN_DETAILS_LEFT_COL_WIDTH - (level * (16 + 1)) - 16; + const panelWidth = SPAN_DETAILS_LEFT_COL_WIDTH - level * (16 + 1) - 48; return ( <> @@ -115,17 +122,12 @@ const Trace = (props: TraceProps): JSX.Element => { isDarkMode={isDarkMode} /> - - - + + + {totalSpans !== 1 && ( - + {totalSpans} {isOpen ? : } @@ -136,15 +138,15 @@ const Trace = (props: TraceProps): JSX.Element => { - - - + + + diff --git a/frontend/src/container/GantChart/Trace/styles.ts b/frontend/src/container/GantChart/Trace/styles.ts index b500db6120..16eb99305d 100644 --- a/frontend/src/container/GantChart/Trace/styles.ts +++ b/frontend/src/container/GantChart/Trace/styles.ts @@ -75,3 +75,16 @@ export const HoverCard = styled.div` height: 3rem; opacity: 0.5; `; + +const flexNoWrap = css` + flex-wrap: nowrap; +`; + +const overFlowHidden = css` + overflow: hidden; +`; + +export const styles = { + flexNoWrap, + overFlowHidden, +}; diff --git a/frontend/src/container/GantChart/index.tsx b/frontend/src/container/GantChart/index.tsx index fa8b37d15a..575f22d7a5 100644 --- a/frontend/src/container/GantChart/index.tsx +++ b/frontend/src/container/GantChart/index.tsx @@ -1,11 +1,12 @@ +import { MinusSquareOutlined, PlusSquareOutlined } from '@ant-design/icons'; +import { IIntervalUnit } from 'container/TraceDetail/utils'; import React, { useEffect, useState } from 'react'; -import Trace from './Trace'; -import { MinusSquareOutlined, PlusSquareOutlined } from '@ant-design/icons' -import { Wrapper, CardWrapper, CardContainer, CollapseButton } from './styles'; -import { getSpanPath } from './utils'; -import { IIntervalUnit } from 'container/TraceDetail/utils' import { ITraceTree } from 'types/api/trace/getTraceItem'; +import { CardContainer, CardWrapper, CollapseButton, Wrapper } from './styles'; +import Trace from './Trace'; +import { getSpanPath } from './utils'; + const GanttChart = (props: GanttChartProps): JSX.Element => { const { data, @@ -15,7 +16,7 @@ const GanttChart = (props: GanttChartProps): JSX.Element => { activeSelectedId, setActiveSelectedId, spanId, - intervalUnit + intervalUnit, } = props; const { globalStart, spread: globalSpread } = traceMetaData; @@ -24,11 +25,11 @@ const GanttChart = (props: GanttChartProps): JSX.Element => { const [activeSpanPath, setActiveSpanPath] = useState([]); useEffect(() => { - setActiveSpanPath(getSpanPath(data, spanId)) + setActiveSpanPath(getSpanPath(data, spanId)); }, [spanId]); useEffect(() => { - setActiveSpanPath(getSpanPath(data, activeSelectedId)) + setActiveSpanPath(getSpanPath(data, activeSelectedId)); }, [activeSelectedId]); const handleCollapse = () => { @@ -38,7 +39,10 @@ const GanttChart = (props: GanttChartProps): JSX.Element => { <> - + {isExpandAll ? : } @@ -81,7 +85,7 @@ export interface GanttChartProps { setActiveHoverId: React.Dispatch>; setActiveSelectedId: React.Dispatch>; spanId: string; - intervalUnit: IIntervalUnit + intervalUnit: IIntervalUnit; } export default GanttChart; diff --git a/frontend/src/container/GantChart/styles.ts b/frontend/src/container/GantChart/styles.ts index cefa618526..4d523c4998 100644 --- a/frontend/src/container/GantChart/styles.ts +++ b/frontend/src/container/GantChart/styles.ts @@ -44,4 +44,5 @@ export const CollapseButton = styled.div` position: absolute; top: 0; left: 0; + font-size: 1.2rem; `; diff --git a/frontend/src/container/Timeline/index.tsx b/frontend/src/container/Timeline/index.tsx index c729ac15f0..155d11de66 100644 --- a/frontend/src/container/Timeline/index.tsx +++ b/frontend/src/container/Timeline/index.tsx @@ -1,15 +1,12 @@ -import React, { useState, useMemo } from 'react'; -import { isEqual } from 'lodash-es'; -import styles from './style.module.css'; -import { useMeasure } from 'react-use'; -import { toFixed } from 'utils/toFixed'; -import { - INTERVAL_UNITS, - resolveTimeFromInterval, -} from 'container/TraceDetail/utils'; +import { StyledDiv } from 'components/Styled'; +import { INTERVAL_UNITS } from 'container/TraceDetail/utils'; import useThemeMode from 'hooks/useThemeMode'; +import React, { useMemo, useState } from 'react'; +import { useMeasure } from 'react-use'; + +import { styles, Svg, TimelineInterval } from './styles'; import { Interval } from './types'; -import { getIntervalSpread, getIntervals } from './utils'; +import { getIntervals, getIntervalSpread } from './utils'; interface TimelineProps { traceMetaData: object; globalTraceMetadata: object; @@ -21,7 +18,7 @@ const Timeline = ({ globalTraceMetadata, intervalUnit, setIntervalUnit, -}: TimelineProps) => { +}: TimelineProps): JSX.Element => { const [ref, { width }] = useMeasure(); const { isDarkMode } = useThemeMode(); @@ -61,12 +58,10 @@ const Timeline = ({ }, [traceMetaData, globalTraceMetadata]); return ( -
- + {intervals && intervals.map((interval, index) => ( - {interval.label} @@ -95,10 +89,10 @@ const Timeline = ({ stroke={isDarkMode ? 'white' : 'black'} strokeWidth="1" /> - + ))} - -
+ + ); }; diff --git a/frontend/src/container/Timeline/style.module.css b/frontend/src/container/Timeline/style.module.css deleted file mode 100644 index 2ddc6e497f..0000000000 --- a/frontend/src/container/Timeline/style.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.svg-container { - overflow: visible; - position: absolute; -} -.timeline-tick { - text-anchor: middle; - font-size: 0.6rem; -} diff --git a/frontend/src/container/Timeline/styles.ts b/frontend/src/container/Timeline/styles.ts new file mode 100644 index 0000000000..f3f1345014 --- /dev/null +++ b/frontend/src/container/Timeline/styles.ts @@ -0,0 +1,19 @@ +import styled, { css } from 'styled-components'; + +const timelineContainer = css` + flex: 1; + overflow: visible; +`; + +export const styles = { + timelineContainer, +}; +export const Svg = styled.svg` + overflow: visible !important; + position: absolute; +`; + +export const TimelineInterval = styled.g` + text-anchor: middle; + font-size: 0.6rem; +`; diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx b/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx index ebe2ea2559..5f11be4b3d 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx @@ -1,23 +1,24 @@ -import { Button, Modal, Collapse } from 'antd'; +import { Collapse, Modal } from 'antd'; +import { StyledButton } from 'components/Styled'; import useThemeMode from 'hooks/useThemeMode'; -import React, { useRef, useState } from 'react'; +import React, { useState } from 'react'; import { ITraceTree } from 'types/api/trace/getTraceItem'; -import { CustomSubText, CustomSubTitle } from './styles'; + +import { CustomSubText, CustomSubTitle, styles } from './styles'; // import Editor from 'components/Editor'; const { Panel } = Collapse; -const ErrorTag = ({ event }: ErrorTagProps) => { +const ErrorTag = ({ event }: ErrorTagProps): JSX.Element => { const [isOpen, setIsOpen] = useState(false); const { isDarkMode } = useThemeMode(); - // const useTextRef = useRef(''); const [text, setText] = useState({ text: '', subText: '', }); - const onToggleHandler = (state: boolean) => { + const onToggleHandler = (state: boolean): void => { setIsOpen(state); }; @@ -28,6 +29,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => { return ( @@ -46,24 +48,21 @@ const ErrorTag = ({ event }: ErrorTagProps) => { {value}
{isEllipsed && ( - + )} - - ); })} @@ -72,7 +71,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => { ); })} onToggleHandler(false)} + onCancel={(): void => onToggleHandler(false)} title="Log Message" visible={isOpen} destroyOnClose diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx b/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx index 35ed013d9c..13df0efef8 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx @@ -1,15 +1,18 @@ import { Space, Tabs, Typography } from 'antd'; +import { StyledSpace, StyledTabs } from 'components/Styled'; +import useThemeMode from 'hooks/useThemeMode'; import React from 'react'; import { ITraceTree } from 'types/api/trace/getTraceItem'; + +import ErrorTag from './ErrorTag'; import { CardContainer, CustomSubText, CustomSubTitle, CustomText, CustomTitle, + styles, } from './styles'; -import ErrorTag from './ErrorTag'; -import useThemeMode from 'hooks/useThemeMode'; const { TabPane } = Tabs; @@ -24,7 +27,11 @@ const SelectedSpanDetails = (props: SelectedSpanDetailsProps): JSX.Element => { return ( - + Details for selected Span Service @@ -34,13 +41,16 @@ const SelectedSpanDetails = (props: SelectedSpanDetailsProps): JSX.Element => { Operation {name} - - + + {tags.length !== 0 ? ( tags.map((tags) => { return ( - + {tags.value && ( <> {tags.key} @@ -63,7 +73,7 @@ const SelectedSpanDetails = (props: SelectedSpanDetailsProps): JSX.Element => { No events data in selected span )} - + ); }; diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts b/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts index f467a87b35..b93e1f5647 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts @@ -1,5 +1,5 @@ import { Typography } from 'antd'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; const { Text, Title, Paragraph } = Typography; export const CustomTitle = styled(Title)` @@ -44,3 +44,24 @@ export const CardContainer = styled.div` flex: 1; overflow-y: auto; `; + +const removeMargin = css` + margin: 0; +`; +const removePadding = css` + padding: 0; +`; + +const selectedSpanDetailsContainer = css` + margin-left: 0.5rem; +`; + +const spanEventsTabsContainer = css` + margin-top: 1rem; +`; +export const styles = { + removeMargin, + removePadding, + selectedSpanDetailsContainer, + spanEventsTabsContainer, +}; diff --git a/frontend/src/container/TraceDetail/index.tsx b/frontend/src/container/TraceDetail/index.tsx index 57b602003b..de3b45e222 100644 --- a/frontend/src/container/TraceDetail/index.tsx +++ b/frontend/src/container/TraceDetail/index.tsx @@ -1,6 +1,13 @@ import { FilterOutlined } from '@ant-design/icons'; -import { Button, Col, Divider, Row, Space, Typography } from 'antd'; -import { StyledCol, StyledDiv, StyledRow } from 'components/Styled'; +import { Button, Col } from 'antd'; +import { + StyledCol, + StyledDiv, + StyledDivider, + StyledRow, + StyledSpace, + StyledTypography, +} from 'components/Styled'; import * as StyledStyles from 'components/Styled/styles'; import GanttChart from 'container/GantChart'; import { getNodeById } from 'container/GantChart/utils'; @@ -43,7 +50,7 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { return getSpanTreeMetadata(getSortedData(treeData), spanServiceColors); }, [treeData]); - const [globalTraceMetadata, _setGlobalTraceMetadata] = useState({ + const [globalTraceMetadata, _setGlobalTraceMetadata] = useState({ ...traceMetaData, }); @@ -60,7 +67,7 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { return getNodeById(activeSelectedId, treeData); }, [activeSelectedId, treeData]); - const onSearchHandler = (value: string) => { + const onSearchHandler = (value: string): void => { setSearchSpanString(value); setTreeData(spanToTreeUtil(response[0].events)); }; @@ -71,37 +78,25 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { } }; - const onResetHandler = () => { + const onResetHandler = (): void => { setTreeData(spanToTreeUtil(response[0].events)); }; return ( - - - - + + + - + Trace Details - - + + {traceMetaData.totalSpans} Span - - + + { /> - - + { }} > {dayjs(traceMetaData.globalStart / 1e6).format('hh:mm:ssa MM/DD')} - - + + { setIntervalUnit={setIntervalUnit} /> - - + + { /> */} - + - + - + { - + - + - + ); }; diff --git a/frontend/src/container/TraceDetail/styles.ts b/frontend/src/container/TraceDetail/styles.ts index f4e99ed33d..38c420042c 100644 --- a/frontend/src/container/TraceDetail/styles.ts +++ b/frontend/src/container/TraceDetail/styles.ts @@ -1,5 +1,79 @@ -import * as StyledStyles from 'components/Styled/styles'; +import { css } from 'styled-components'; -export const traceDetailContentSpacing = StyledStyles.Spacing({ - margin: '0 1rem 0 0', -}); +/** + * Styles for the left container. Containers flamegraph, timeline and gantt chart + */ +export const leftContainer = [ + css` + display: flex; + flex-direction: column; + `, +]; + +/** + * Styles for the top container. Contains TotalSpans, FlameGraph and Timeline. + */ +export const flameAndTimelineContainer = [ + css` + margin: 0 1rem 0 0; + `, +]; + +export const traceMetaDataContainer = [ + css` + display: flex; + flex-direction: column; + align-items: center; + `, +]; + +export const traceDateAndTimelineContainer = css` + margin-top: 2rem; +`; + +export const traceDateTimeContainer = css` + display: flex; + aligh-items: center; + justify-content: center; +`; +export const timelineContainer = css` + overflow: visible; + margin: 0 1rem 0 0; +`; +export const ganttChartContainer = css` + margin: 1.5rem 1rem 0.5rem; + display: flex; + flex-direction: column; + position: relative; + flex: 1; + overflow-y: auto; + overflow-x: hidden; +`; + +export const selectedSpanDetailContainer = css` + height: 100%; + position: relative; + display: flex; + flex-direction: column; +`; + + +/** + * Generic / Common styles + */ + +export const verticalSeparator = css` + height: 100%; + margin: 0; +`; + +export const traceDetailContentSpacing = css` + margin: 0 1rem 0 0; +`; + +export const floatRight = css` + float: right; +`; +export const removeMargin = css` + margin: 0; +`; diff --git a/frontend/src/container/TraceFlameGraph/index.tsx b/frontend/src/container/TraceFlameGraph/index.tsx index 511becaf39..7e1d2f0d6b 100644 --- a/frontend/src/container/TraceFlameGraph/index.tsx +++ b/frontend/src/container/TraceFlameGraph/index.tsx @@ -1,17 +1,18 @@ -import React, { useState, useLayoutEffect, useMemo } from 'react'; import Color from 'color'; -import { pushDStree } from 'store/actions'; -import { - SpanItemContainer, - TraceFlameGraphContainer, - TOTAL_SPAN_HEIGHT, -} from './styles'; import { IIntervalUnit, resolveTimeFromInterval, } from 'container/TraceDetail/utils'; -import { toFixed } from 'utils/toFixed'; import useThemeMode from 'hooks/useThemeMode'; +import React, { useLayoutEffect, useMemo, useState } from 'react'; +import { pushDStree } from 'store/actions'; +import { toFixed } from 'utils/toFixed'; + +import { + SpanItemContainer, + TOTAL_SPAN_HEIGHT, + TraceFlameGraphContainer, +} from './styles'; const SpanItem = ({ topOffset = 0, // top offset in px @@ -33,7 +34,7 @@ const SpanItem = ({ onSpanHover: Function; hoveredSpanId: string; selectedSpanId: string; -}) => { +}): JSX.Element => { const { serviceColour } = spanData; const [isSelected, setIsSelected] = useState(false); const [isLocalHover, setIsLocalHover] = useState(false); @@ -48,14 +49,14 @@ const SpanItem = ({ } }, [hoveredSpanId, selectedSpanId]); - const handleHover = (hoverState: boolean) => { + const handleHover = (hoverState: boolean): void => { setIsLocalHover(hoverState); if (hoverState) onSpanHover(spanData.id); else onSpanHover(null); }; - const handleClick = () => { + const handleClick = (): void => { onSpanSelect(spanData.id); }; @@ -96,7 +97,7 @@ const TraceFlameGraph = (props: { hoveredSpanId: string; selectedSpanId: string; intervalUnit: IIntervalUnit; -}) => { +}): null | JSX.Element => { if (!props.treeData || props.treeData.id === 'empty' || !props.traceMetaData) { return null; } @@ -125,7 +126,7 @@ const TraceFlameGraph = (props: { onSpanSelect: Function; hoveredSpanId: string; selectedSpanId: string; - }) => { + }): null | JSX.Element => { if (!spanData) { return null; } diff --git a/frontend/src/store/actions/index.ts b/frontend/src/store/actions/index.ts index 6ee8a31184..403f685057 100644 --- a/frontend/src/store/actions/index.ts +++ b/frontend/src/store/actions/index.ts @@ -4,5 +4,6 @@ export * from './global'; export * from './metrics'; export * from './MetricsActions'; export * from './serviceMap'; +export * from './traces'; export * from './types'; export * from './usage'; From 7f3d9e2e35b58784c839702d235340664129df26 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 16 Mar 2022 16:05:21 +0530 Subject: [PATCH 3/7] feat: PR review changes --- frontend/src/components/Styled/index.ts | 41 ++++++++----------- frontend/src/components/Styled/styles.ts | 2 +- frontend/src/container/Timeline/index.tsx | 9 ++-- frontend/src/container/TraceDetail/index.tsx | 7 ++-- .../src/container/TraceFlameGraph/index.tsx | 1 - 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/frontend/src/components/Styled/index.ts b/frontend/src/components/Styled/index.ts index 45b53896d1..bff30f653e 100644 --- a/frontend/src/components/Styled/index.ts +++ b/frontend/src/components/Styled/index.ts @@ -3,10 +3,7 @@ import { TextProps } from 'antd/lib/typography/Text'; import { TitleProps } from 'antd/lib/typography/Title'; import React from 'react'; import styled, { - css, - DefaultTheme, FlattenSimpleInterpolation, - ThemedCssFunction, } from 'styled-components'; import { IStyledClass } from './types'; @@ -14,52 +11,50 @@ import { IStyledClass } from './types'; const styledClass = (props: IStyledClass): FlattenSimpleInterpolation => props.styledclass; -interface IStyledCol extends AntD.ColProps, IStyledClass {} -const StyledCol = styled(AntD.Col)` +type TStyledCol = AntD.ColProps & IStyledClass; +const StyledCol = styled(AntD.Col)` ${styledClass} `; -interface IStyledRow extends AntD.RowProps, IStyledClass {} -const StyledRow = styled(AntD.Row)` +type TStyledRow = AntD.RowProps & IStyledClass; +const StyledRow = styled(AntD.Row)` ${styledClass} `; -interface IStyledDivider extends AntD.DividerProps, IStyledClass {} -const StyledDivider = styled(AntD.Divider)` +type TStyledDivider = AntD.DividerProps & IStyledClass; +const StyledDivider = styled(AntD.Divider)` ${styledClass} `; -interface IStyledSpace extends AntD.SpaceProps, IStyledClass {} -const StyledSpace = styled(AntD.Space)` +type TStyledSpace = AntD.SpaceProps & IStyledClass; +const StyledSpace = styled(AntD.Space)` ${styledClass} `; -interface IStyledTabs extends AntD.TabsProps, IStyledClass {} -const StyledTabs = styled(AntD.Divider)` +type TStyledTabs = AntD.TabsProps & IStyledClass; +const StyledTabs = styled(AntD.Divider)` ${styledClass} `; -interface IStyledButton extends AntD.ButtonProps, IStyledClass {} -const StyledButton = styled(AntD.Button)` +type TStyledButton = AntD.ButtonProps & IStyledClass; +const StyledButton = styled(AntD.Button)` ${styledClass} `; const { Text } = AntD.Typography; -interface IStyledTypographyText extends TextProps, IStyledClass {} -const StyledTypographyText = styled(Text)` +type TStyledTypographyText = TextProps & IStyledClass; +const StyledTypographyText = styled(Text)` ${styledClass} `; const { Title } = AntD.Typography; -interface IStyledTypographyTitle extends TitleProps, IStyledClass {} -const StyledTypographyTitle = styled(Title)` +type TStyledTypographyTitle = TitleProps & IStyledClass; +const StyledTypographyTitle = styled(Title)` ${styledClass} `; -interface IStyledDiv - extends React.HTMLAttributes, - IStyledClass {} -const StyledDiv = styled.div` +type TStyledDiv = React.HTMLAttributes & IStyledClass; +const StyledDiv = styled.div` ${styledClass} `; diff --git a/frontend/src/components/Styled/styles.ts b/frontend/src/components/Styled/styles.ts index 153ef27a94..8425beae07 100644 --- a/frontend/src/components/Styled/styles.ts +++ b/frontend/src/components/Styled/styles.ts @@ -1,6 +1,6 @@ import { css, FlattenSimpleInterpolation } from 'styled-components'; -const cssProprty = (key: string, value: any): FlattenSimpleInterpolation => +const cssProprty = (key: string, value): FlattenSimpleInterpolation => key && value && css` diff --git a/frontend/src/container/Timeline/index.tsx b/frontend/src/container/Timeline/index.tsx index 2e3fbd2053..6458b8a5a3 100644 --- a/frontend/src/container/Timeline/index.tsx +++ b/frontend/src/container/Timeline/index.tsx @@ -1,5 +1,5 @@ import { StyledDiv } from 'components/Styled'; -import { INTERVAL_UNITS } from 'container/TraceDetail/utils'; +import { IIntervalUnit, INTERVAL_UNITS } from 'container/TraceDetail/utils'; import useThemeMode from 'hooks/useThemeMode'; import React, { useEffect, useState } from 'react'; import { useMeasure } from 'react-use'; @@ -68,10 +68,9 @@ const Timeline = ({ {intervals && intervals.map((interval, index) => ( @@ -93,7 +92,7 @@ const Timeline = ({ interface TimelineProps { traceMetaData: object; globalTraceMetadata: object; - intervalUnit: object; + intervalUnit: IIntervalUnit; setIntervalUnit: any; } diff --git a/frontend/src/container/TraceDetail/index.tsx b/frontend/src/container/TraceDetail/index.tsx index 553f4f292b..e89d78530a 100644 --- a/frontend/src/container/TraceDetail/index.tsx +++ b/frontend/src/container/TraceDetail/index.tsx @@ -25,8 +25,7 @@ import { spanToTreeUtil } from 'utils/spanToTree'; import SelectedSpanDetails from './SelectedSpanDetails'; import * as styles from './styles'; -import { getSortedData } from './utils'; -import { INTERVAL_UNITS } from './utils'; +import { getSortedData, IIntervalUnit, INTERVAL_UNITS } from './utils'; const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { const spanServiceColors = useMemo( @@ -37,7 +36,9 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { const urlQuery = useUrlQuery(); const [spanId] = useState(urlQuery.get('spanId')); - const [intervalUnit, setIntervalUnit] = useState(INTERVAL_UNITS[0]); + const [intervalUnit, setIntervalUnit] = useState( + INTERVAL_UNITS[0], + ); // const [searchSpanString, setSearchSpanString] = useState(''); const [activeHoverId, setActiveHoverId] = useState(''); const [activeSelectedId, setActiveSelectedId] = useState(spanId || ''); diff --git a/frontend/src/container/TraceFlameGraph/index.tsx b/frontend/src/container/TraceFlameGraph/index.tsx index bbf35b9fce..344098624f 100644 --- a/frontend/src/container/TraceFlameGraph/index.tsx +++ b/frontend/src/container/TraceFlameGraph/index.tsx @@ -5,7 +5,6 @@ import { } from 'container/TraceDetail/utils'; import useThemeMode from 'hooks/useThemeMode'; import React, { useLayoutEffect, useMemo, useState } from 'react'; -import { pushDStree } from 'store/actions'; import { ITraceTree } from 'types/api/trace/getTraceItem'; import { toFixed } from 'utils/toFixed'; From 00c7eccb0c1287297caa08b02c9c822d4cb57141 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 16 Mar 2022 16:14:27 +0530 Subject: [PATCH 4/7] fix: remove any type --- frontend/src/container/Timeline/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/Timeline/index.tsx b/frontend/src/container/Timeline/index.tsx index 6458b8a5a3..86030630e3 100644 --- a/frontend/src/container/Timeline/index.tsx +++ b/frontend/src/container/Timeline/index.tsx @@ -93,7 +93,7 @@ interface TimelineProps { traceMetaData: object; globalTraceMetadata: object; intervalUnit: IIntervalUnit; - setIntervalUnit: any; + setIntervalUnit: () => void; } export default Timeline; From 3ebffae1c6027e15ead591d3ec8238fdeba39eb0 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 16 Mar 2022 16:16:20 +0530 Subject: [PATCH 5/7] chore: revert eslint --debug flag --- frontend/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 458341f1cb..48c33a04fc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,8 +7,8 @@ "dev": "cross-env NODE_ENV=development webpack serve --progress", "build": "webpack --config=webpack.config.prod.js --progress", "prettify": "prettier --write .", - "lint": "eslint .", - "lint:fix": "eslint . --fix", + "lint": "eslint . --debug", + "lint:fix": "eslint . --fix --debug", "cypress:open": "cypress open", "cypress:run": "cypress run", "jest": "jest", From da8b16f5887e52de2df64f775cfbcdd7ef53cd35 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 16 Mar 2022 16:27:06 +0530 Subject: [PATCH 6/7] feat: Updates TS type --- frontend/src/container/Timeline/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/Timeline/index.tsx b/frontend/src/container/Timeline/index.tsx index 86030630e3..127c7c1b97 100644 --- a/frontend/src/container/Timeline/index.tsx +++ b/frontend/src/container/Timeline/index.tsx @@ -91,7 +91,7 @@ const Timeline = ({ interface TimelineProps { traceMetaData: object; - globalTraceMetadata: object; + globalTraceMetadata: Record; intervalUnit: IIntervalUnit; setIntervalUnit: () => void; } From daadc584ea8829033aa3c5650a922328a382cfd0 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Wed, 16 Mar 2022 16:28:11 +0530 Subject: [PATCH 7/7] feat: update ts type --- frontend/src/container/Timeline/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/Timeline/index.tsx b/frontend/src/container/Timeline/index.tsx index 127c7c1b97..deed52a9cf 100644 --- a/frontend/src/container/Timeline/index.tsx +++ b/frontend/src/container/Timeline/index.tsx @@ -93,7 +93,7 @@ interface TimelineProps { traceMetaData: object; globalTraceMetadata: Record; intervalUnit: IIntervalUnit; - setIntervalUnit: () => void; + setIntervalUnit: VoidFunction; } export default Timeline;