From 24d538e317828a68e99b7562fde962b9930b1b1a Mon Sep 17 00:00:00 2001 From: Oscar Reyes Date: Fri, 23 Feb 2024 15:50:57 -0600 Subject: [PATCH] feat(frontend): Adding Span Result Detail Drawer (#3680) * feat(frontend): * feat(frontend): Adding Span Result Detail Drawer --- .../components/RunDetailTest/TestPanel.tsx | 20 ++- .../Assertion.tsx | 8 +- .../components/SpanResultDetail/Content.tsx | 52 ++++++++ .../components/SpanResultDetail/Detail.tsx | 66 ++++++++++ .../components/SpanResultDetail/Header.tsx | 28 ++++ .../SpanResultDetail.styled.ts | 121 ++++++++++++++++++ .../SpanResultDetail/SpanResultDetail.tsx | 38 ++++++ web/src/components/SpanResultDetail/index.ts | 2 + web/src/components/TestSpecDetail/Content.tsx | 19 +-- .../components/TestSpecDetail/ResultCard.tsx | 65 ---------- .../components/TestSpecDetail/SpanHeader.tsx | 41 ------ .../components/TestSpecDetail/SpanResult.tsx | 52 ++++++++ .../TestSpecDetail/TestSpecDetail.styled.ts | 10 +- .../TestSpecs/TestSpecs.provider.tsx | 11 +- .../TestSpecs/hooks/useTestSpecsCrud.ts | 11 +- web/src/redux/slices/TestSpecs.slice.ts | 6 + web/src/selectors/TestSpecs.selectors.ts | 1 + web/src/services/Assertion.service.ts | 4 + web/src/types/TestSpecs.types.ts | 8 ++ 19 files changed, 431 insertions(+), 132 deletions(-) rename web/src/components/{TestSpecDetail => SpanResultDetail}/Assertion.tsx (88%) create mode 100644 web/src/components/SpanResultDetail/Content.tsx create mode 100644 web/src/components/SpanResultDetail/Detail.tsx create mode 100644 web/src/components/SpanResultDetail/Header.tsx create mode 100644 web/src/components/SpanResultDetail/SpanResultDetail.styled.ts create mode 100644 web/src/components/SpanResultDetail/SpanResultDetail.tsx create mode 100644 web/src/components/SpanResultDetail/index.ts delete mode 100644 web/src/components/TestSpecDetail/ResultCard.tsx delete mode 100644 web/src/components/TestSpecDetail/SpanHeader.tsx create mode 100644 web/src/components/TestSpecDetail/SpanResult.tsx diff --git a/web/src/components/RunDetailTest/TestPanel.tsx b/web/src/components/RunDetailTest/TestPanel.tsx index ed5633a040..56cd2a5078 100644 --- a/web/src/components/RunDetailTest/TestPanel.tsx +++ b/web/src/components/RunDetailTest/TestPanel.tsx @@ -24,6 +24,7 @@ import * as S from './RunDetailTest.styled'; import Visualization from './Visualization'; import {FillPanel} from '../ResizablePanels'; import SkipTraceCollectionInfo from '../SkipTraceCollectionInfo'; +import SpanResultDetail from '../SpanResultDetail'; const TABS = { SPECS: 'specs', @@ -39,8 +40,17 @@ interface IProps { const TestPanel = ({run, testId, runEvents}: IProps) => { const [query, updateQuery] = useSearchParams(); const {selectedSpan, onSetFocusedSpan} = useSpan(); - const {remove, revert, selectedTestSpec, setSelectedSpec, setSelectorSuggestions, setPrevSelector, specs} = - useTestSpecs(); + const { + remove, + revert, + selectedTestSpec, + selectedSpanResult, + setSelectedSpanResult, + setSelectedSpec, + setSelectorSuggestions, + setPrevSelector, + specs, + } = useTestSpecs(); const {isOpen: isTestSpecFormOpen, formProps, onSubmit, open, close, isValid, onIsValid} = useTestSpecForm(); const { isEditing, @@ -219,6 +229,12 @@ const TestPanel = ({run, testId, runEvents}: IProps) => { selectedSpan={selectedSpan?.id} testSpec={selectedTestSpec} /> + + setSelectedSpanResult()} + /> diff --git a/web/src/components/TestSpecDetail/Assertion.tsx b/web/src/components/SpanResultDetail/Assertion.tsx similarity index 88% rename from web/src/components/TestSpecDetail/Assertion.tsx rename to web/src/components/SpanResultDetail/Assertion.tsx index 23fc50533c..bdcd0baebf 100644 --- a/web/src/components/TestSpecDetail/Assertion.tsx +++ b/web/src/components/SpanResultDetail/Assertion.tsx @@ -5,7 +5,7 @@ import {ICheckResult} from 'types/Assertion.types'; import {TCompareOperatorSymbol} from 'types/Operator.types'; import {SupportedEditors} from 'constants/Editor.constants'; import {Editor} from 'components/Inputs'; -import * as S from './TestSpecDetail.styled'; +import * as S from './SpanResultDetail.styled'; interface IProps { check: ICheckResult; @@ -15,14 +15,14 @@ interface IProps { } const Assertion = ({check, testId, runId, selector}: IProps) => ( - + {check.result.error && AssertionService.isValidError(check.result.error) ? ( <> - + - + ) : ( <> diff --git a/web/src/components/SpanResultDetail/Content.tsx b/web/src/components/SpanResultDetail/Content.tsx new file mode 100644 index 0000000000..f357c821ef --- /dev/null +++ b/web/src/components/SpanResultDetail/Content.tsx @@ -0,0 +1,52 @@ +import {useMemo} from 'react'; +import {useTest} from 'providers/Test/Test.provider'; +import {ICheckResult} from 'types/Assertion.types'; +import AssertionService from 'services/Assertion.service'; +import Span from 'models/Span.model'; +import {useTestRun} from 'providers/TestRun/TestRun.provider'; +import * as S from './SpanResultDetail.styled'; +import Assertion from './Assertion'; +import Header from './Header'; +import {useTestSpecs} from '../../providers/TestSpecs/TestSpecs.provider'; + +interface IProps { + span: Span; + checkResults: ICheckResult[]; + onClose(): void; +} + +const Content = ({checkResults, span, onClose}: IProps) => { + const { + run: {id: runId}, + } = useTestRun(); + const { + test: {id: testId}, + } = useTest(); + + const totalPassedChecks = useMemo(() => AssertionService.getTotalPassedSpanChecks(checkResults), [checkResults]); + const {selectedTestSpec} = useTestSpecs(); + + return ( + <> +
+ + {checkResults.map(checkResult => ( + + ))} + + + ); +}; + +export default Content; diff --git a/web/src/components/SpanResultDetail/Detail.tsx b/web/src/components/SpanResultDetail/Detail.tsx new file mode 100644 index 0000000000..11d756b307 --- /dev/null +++ b/web/src/components/SpanResultDetail/Detail.tsx @@ -0,0 +1,66 @@ +import Span from 'models/Span.model'; +import {ClockCircleOutlined, SettingOutlined, ToolOutlined} from '@ant-design/icons'; +import {Tooltip} from 'antd'; +import * as STestSpec from 'components/TestSpec/TestSpec.styled'; +import {SemanticGroupNamesToText} from 'constants/SemanticGroupNames.constants'; +import * as SSpanNode from 'components/Visualization/components/DAG/BaseSpanNode/BaseSpanNode.styled'; +import * as S from './SpanResultDetail.styled'; + +interface IProps { + assertionsFailed: number; + assertionsPassed: number; + span: Span; +} + +const Detail = ({ + assertionsFailed, + assertionsPassed, + span: {duration, name, id, service, kind, system, type}, +}: IProps) => { + return ( + <> + + + + + {name} + + +
+ {Boolean(assertionsPassed) && ( + + + {assertionsPassed} + + )} + {Boolean(assertionsFailed) && ( + + + {assertionsFailed} + + )} +
+
+ + + + + {`${service} ${kind}`} + + {Boolean(system) && ( + + + {system} + + )} + + + + {duration} + + + + ); +}; + +export default Detail; diff --git a/web/src/components/SpanResultDetail/Header.tsx b/web/src/components/SpanResultDetail/Header.tsx new file mode 100644 index 0000000000..87275c8397 --- /dev/null +++ b/web/src/components/SpanResultDetail/Header.tsx @@ -0,0 +1,28 @@ +import Span from 'models/Span.model'; +import {ArrowLeftOutlined} from '@ant-design/icons'; +import {Button, Divider} from 'antd'; +import * as S from './SpanResultDetail.styled'; +import Detail from './Detail'; + +interface IProps { + assertionsFailed: number; + assertionsPassed: number; + onClose(): void; + span: Span; +} + +const Header = ({span, assertionsFailed, assertionsPassed, onClose}: IProps) => ( + <> + + +