From 3b5dbc3a40f04621eb03b67b25f67e1dfc4bf200 Mon Sep 17 00:00:00 2001 From: Jorge Padilla Date: Wed, 28 Feb 2024 14:59:15 -0500 Subject: [PATCH] fix(frontend): ui cleanup and improvements --- web/src/components/ResourceCard/Box.tsx | 31 +++++++++++++ web/src/components/ResourceCard/TestCard.tsx | 7 +-- .../components/ResourceCard/TestSuiteCard.tsx | 7 +-- .../Resources/Content/Content.styled.ts | 2 +- .../components/Resources/Content/Content.tsx | 46 +++++++++++-------- .../RunDetailAutomate/RunDetailAutomate.tsx | 2 +- .../RunStatusIcon/RunStatusIcon.styled.ts | 12 ++++- .../RunStatusIcon/RunStatusIcon.tsx | 22 +++++---- .../RunStatusIcon/RunTooltipTitle.tsx | 23 ++++++++-- web/src/utils/Common.ts | 22 +++++++++ 10 files changed, 131 insertions(+), 43 deletions(-) create mode 100644 web/src/components/ResourceCard/Box.tsx diff --git a/web/src/components/ResourceCard/Box.tsx b/web/src/components/ResourceCard/Box.tsx new file mode 100644 index 0000000000..f0544c7213 --- /dev/null +++ b/web/src/components/ResourceCard/Box.tsx @@ -0,0 +1,31 @@ +import {Tooltip} from 'antd'; +import {ResourceType} from 'types/Resource.type'; +import {abbreviateNumber} from 'utils/Common'; +import * as S from './ResourceCard.styled'; + +const INITIAL_TIER = 1000; + +interface IProps { + num: number; + type: ResourceType; +} + +const Box = ({num, type}: IProps) => { + if (num < INITIAL_TIER) { + return ( + + {num} + + ); + } + + return ( + + + {abbreviateNumber(num)} + + + ); +}; + +export default Box; diff --git a/web/src/components/ResourceCard/TestCard.tsx b/web/src/components/ResourceCard/TestCard.tsx index 2a49f01ad5..b765d7b58f 100644 --- a/web/src/components/ResourceCard/TestCard.tsx +++ b/web/src/components/ResourceCard/TestCard.tsx @@ -6,6 +6,7 @@ import TracetestAPI from 'redux/apis/Tracetest'; import {ResourceType} from 'types/Resource.type'; import Test from 'models/Test.model'; import TestRun from 'models/TestRun.model'; +import Box from './Box'; import * as S from './ResourceCard.styled'; import ResourceCardActions from './ResourceCardActions'; import ResourceCardRuns from './ResourceCardRuns'; @@ -37,9 +38,9 @@ const TestCard = ({onEdit, onDelete, onDuplicate, onRun, onViewAll, test}: IProp {isCollapsed ? : } - - {test.summary.runs} - + + + {test.name} diff --git a/web/src/components/ResourceCard/TestSuiteCard.tsx b/web/src/components/ResourceCard/TestSuiteCard.tsx index a2d59c5ef5..a57bc54f01 100644 --- a/web/src/components/ResourceCard/TestSuiteCard.tsx +++ b/web/src/components/ResourceCard/TestSuiteCard.tsx @@ -7,6 +7,7 @@ import TracetestAPI from 'redux/apis/Tracetest'; import {ResourceType} from 'types/Resource.type'; import TestSuite from 'models/TestSuite.model'; import TestSuiteRun from 'models/TestSuiteRun.model'; +import Box from './Box'; import * as S from './ResourceCard.styled'; import ResourceCardActions from './ResourceCardActions'; import ResourceCardRuns from './ResourceCardRuns'; @@ -46,9 +47,9 @@ const TestSuiteCard = ({ {isCollapsed ? : } - - {summary.runs} - + + + {name} {description} diff --git a/web/src/components/Resources/Content/Content.styled.ts b/web/src/components/Resources/Content/Content.styled.ts index 16a94e810a..435454fd64 100644 --- a/web/src/components/Resources/Content/Content.styled.ts +++ b/web/src/components/Resources/Content/Content.styled.ts @@ -3,7 +3,7 @@ import styled from 'styled-components'; export const Body = styled.div` display: flex; - gap: 24px; + gap: 12px; width: 100%; `; diff --git a/web/src/components/Resources/Content/Content.tsx b/web/src/components/Resources/Content/Content.tsx index d600537d16..7fba2da2a7 100644 --- a/web/src/components/Resources/Content/Content.tsx +++ b/web/src/components/Resources/Content/Content.tsx @@ -15,43 +15,49 @@ const Content = () => {
- Tests + Tests Haven't created a test yet? Go to the 'Tests' page to kickstart your testing adventure. - { - e.preventDefault(); - navigate(`/tests`); - }} - > - {' '} - Go to tests - +
+ { + e.preventDefault(); + navigate(`/tests`); + }} + > + {' '} + Go to tests + +
- Documentation + Documentation The ultimate technical resources and step-by-step guides that allows you to quickly start. - - {' '} - View documentation - +
+ + {' '} + View documentation + +
- Community + Community Check the latest updates and support from the community. - - {' '} - Join our community - +
+ + {' '} + Join our community + +
diff --git a/web/src/components/RunDetailAutomate/RunDetailAutomate.tsx b/web/src/components/RunDetailAutomate/RunDetailAutomate.tsx index 28f827c2ec..fe5a378ce3 100644 --- a/web/src/components/RunDetailAutomate/RunDetailAutomate.tsx +++ b/web/src/components/RunDetailAutomate/RunDetailAutomate.tsx @@ -54,7 +54,7 @@ function getMethods(triggerType: TriggerTypes) { }, { id: 'typescript', - label: 'Typescript', + label: 'TypeScript', component: Typescript, }, ]; diff --git a/web/src/components/RunStatusIcon/RunStatusIcon.styled.ts b/web/src/components/RunStatusIcon/RunStatusIcon.styled.ts index 3aac020fac..f7c8dc400f 100644 --- a/web/src/components/RunStatusIcon/RunStatusIcon.styled.ts +++ b/web/src/components/RunStatusIcon/RunStatusIcon.styled.ts @@ -1,4 +1,10 @@ -import {CheckCircleFilled, InfoCircleFilled, LoadingOutlined, MinusCircleFilled} from '@ant-design/icons'; +import { + CheckCircleFilled, + ExclamationCircleFilled, + InfoCircleFilled, + LoadingOutlined, + MinusCircleFilled, +} from '@ant-design/icons'; import {Typography} from 'antd'; import styled from 'styled-components'; @@ -14,6 +20,10 @@ export const IconInfo = styled(InfoCircleFilled)` color: ${({theme}) => theme.color.textLight}; `; +export const IconWarning = styled(ExclamationCircleFilled)` + color: ${({theme}) => theme.color.warningYellow}; +`; + export const SequenceText = styled.div` color: ${({theme}) => theme.color.textLight}; font-weight: 600; diff --git a/web/src/components/RunStatusIcon/RunStatusIcon.tsx b/web/src/components/RunStatusIcon/RunStatusIcon.tsx index 922206cd27..0185cd4b45 100644 --- a/web/src/components/RunStatusIcon/RunStatusIcon.tsx +++ b/web/src/components/RunStatusIcon/RunStatusIcon.tsx @@ -18,21 +18,23 @@ const Icon = ({state, requiredGatesResult: {passed}}: IProps) => { return ; } - if (isRunStateFailed(state) || !passed) { + if (isRunStateFailed(state)) { + return ; + } + + if (!passed) { return ; } return ; }; -const RunStatusIcon = (props: IProps) => { - return ( - }> - - - - - ); -}; +const RunStatusIcon = (props: IProps) => ( + }> + + + + +); export default RunStatusIcon; diff --git a/web/src/components/RunStatusIcon/RunTooltipTitle.tsx b/web/src/components/RunStatusIcon/RunTooltipTitle.tsx index f901d4524c..6261d07157 100644 --- a/web/src/components/RunStatusIcon/RunTooltipTitle.tsx +++ b/web/src/components/RunStatusIcon/RunTooltipTitle.tsx @@ -1,9 +1,24 @@ -import {useTheme} from 'styled-components'; +import {TestState} from 'constants/TestRun.constants'; import TestRun, {isRunStateFailed, isRunStateFinished, isRunStateStopped} from 'models/TestRun.model'; import RequiredGatesResult from 'models/RequiredGatesResult.model'; +import {useTheme} from 'styled-components'; +import {TTestRunState} from 'types/TestRun.types'; import {ToTitle} from 'utils/Common'; import * as S from './RunStatusIcon.styled'; +function getRunStateFailedMessage(state: TTestRunState) { + switch (state) { + case TestState.TRIGGER_FAILED: + return 'The run failed in the trigger stage'; + case TestState.TRACE_FAILED: + return 'The run failed in fetching the trace'; + case TestState.ASSERTION_FAILED: + return 'The run failed to execute the assertions'; + default: + return 'The run execution failed'; + } +} + interface IProps { state: TestRun['state']; requiredGatesResult: RequiredGatesResult; @@ -17,6 +32,9 @@ const RunTooltipTitle = ({requiredGatesResult: {required, requiredFailedGates, p const isStopped = isRunStateStopped(state); if (isStopped) return <>The run has been manually stopped; + const isFailed = isRunStateFailed(state); + if (isFailed) return <>{getRunStateFailedMessage(state)}; + const isFinished = isRunStateFinished(state); const isSuccessful = isFinished && passed; if (isSuccessful) { @@ -34,9 +52,6 @@ const RunTooltipTitle = ({requiredGatesResult: {required, requiredFailedGates, p ); } - const isRunnerFailed = isRunStateFailed(state); - if (isRunnerFailed) return <>The run execution failed; - const isGatesFailed = isFinished && !passed; if (isGatesFailed) return ( diff --git a/web/src/utils/Common.ts b/web/src/utils/Common.ts index dac17555fd..cc4db6f1ad 100644 --- a/web/src/utils/Common.ts +++ b/web/src/utils/Common.ts @@ -100,3 +100,25 @@ export const withLowPriority = export const toPercent = (value: number) => { return `${value * 100}%`; }; + +export const abbreviateNumber = (num: number): string => { + const symbols = ['', 'k', 'M', 'G', 'T', 'P', 'E']; + + // tier to determine suffix + // eslint-disable-next-line no-bitwise + const tier = (Math.log10(num) / 3) | 0; + + // if zero not need a suffix + if (tier === 0) return num.toString(); + + // get suffix + const suffix = symbols[tier]; + if (!suffix) return num.toString(); + + // get scale + const scale = 10 ** (tier * 3); + const scaled = num / scale; + const rounded = scaled.toFixed(1); + + return rounded + suffix; +};