From 39306b71f4a465919ae9327f13cfe88b59647ca8 Mon Sep 17 00:00:00 2001 From: Michal Zielenkiewicz Date: Thu, 10 Oct 2024 10:23:01 +0200 Subject: [PATCH 1/4] Prepare components to render validator uptime --- .changelog/1569.trivial.md | 1 + src/app/components/UptimeStatus/index.tsx | 68 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 .changelog/1569.trivial.md create mode 100644 src/app/components/UptimeStatus/index.tsx diff --git a/.changelog/1569.trivial.md b/.changelog/1569.trivial.md new file mode 100644 index 000000000..1c65449e8 --- /dev/null +++ b/.changelog/1569.trivial.md @@ -0,0 +1 @@ +Prepare components to render validator uptime diff --git a/src/app/components/UptimeStatus/index.tsx b/src/app/components/UptimeStatus/index.tsx new file mode 100644 index 000000000..f45425d68 --- /dev/null +++ b/src/app/components/UptimeStatus/index.tsx @@ -0,0 +1,68 @@ +import { FC } from 'react' +import Box from '@mui/material/Box' +import { styled } from '@mui/material/styles' +import { COLORS } from '../../../styles/theme/colors' +import { PercentageValue } from '../PercentageValue' + +const getUptimeItemColor = (value: number | undefined) => { + if (!value) { + return COLORS.grayMediumLight + } + + if (value > 90) { + return COLORS.eucalyptus + } + + return COLORS.errorIndicatorBackground +} + +type UptimeItem = { + small?: boolean + value?: number +} + +const StyledBox = styled(Box)(({ small, value }) => ({ + background: getUptimeItemColor(value), + width: small ? '3px' : '7px', + minWidth: small ? '3px' : '7px', + height: small ? '15px' : '45px', + borderRadius: small ? '2px' : '4px', + color: COLORS.white, + marginRight: small ? 1 : 2, +})) + +const ensureTwelveElements = (inputArray: number[] = []) => { + const truncatedArray = inputArray.slice(0, 12) + const undefinedCount = 12 - truncatedArray.length + + if (undefinedCount > 0) { + const undefinedArray = new Array(undefinedCount).fill(undefined) + return truncatedArray.concat(undefinedArray) + } + return truncatedArray +} + +type UptimeStatusProps = { + percentage?: number + small?: boolean + status?: number[] +} + +export const UptimeStatus: FC = ({ percentage, status, small }) => { + const adjustedStatus = ensureTwelveElements(status) + + return ( + + + {adjustedStatus?.map((value, index) => ( + + ))} + + {percentage && ( + + + + )} + + ) +} From cbae0f4d53b18e67838c2bf03add57cebf3b51e5 Mon Sep 17 00:00:00 2001 From: Michal Zielenkiewicz Date: Thu, 10 Oct 2024 10:18:16 +0200 Subject: [PATCH 2/4] Render UptimeStatus with fake data --- src/app/components/PercentageValue/index.tsx | 8 ++++++-- src/app/components/Validators/index.tsx | 3 ++- src/app/pages/ValidatorDetailsPage/UptimeCard.tsx | 15 +++++++++++++-- src/locales/en/translation.json | 1 + 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/app/components/PercentageValue/index.tsx b/src/app/components/PercentageValue/index.tsx index a4bce6022..919905730 100644 --- a/src/app/components/PercentageValue/index.tsx +++ b/src/app/components/PercentageValue/index.tsx @@ -3,11 +3,15 @@ import { useTranslation } from 'react-i18next' type PercentageValueProps = { adaptMaximumFractionDigits?: boolean - total: number | undefined + total?: number value: number | undefined } -export const PercentageValue: FC = ({ adaptMaximumFractionDigits, value, total }) => { +export const PercentageValue: FC = ({ + adaptMaximumFractionDigits, + value, + total = 100, +}) => { const { t } = useTranslation() if (typeof value !== 'number' || typeof total !== 'number' || total <= 0) { diff --git a/src/app/components/Validators/index.tsx b/src/app/components/Validators/index.tsx index 8f2b66755..1de9a7e86 100644 --- a/src/app/components/Validators/index.tsx +++ b/src/app/components/Validators/index.tsx @@ -13,6 +13,7 @@ import { ValidatorLink } from './ValidatorLink' import { useRequiredScopeParam } from '../../hooks/useScopeParam' import { BalancesDiff } from '../BalancesDiff' import { PercentageValue } from '../PercentageValue' +import { UptimeStatus } from '../UptimeStatus' type ValidatorsProps = { validators?: Validator[] @@ -129,7 +130,7 @@ export const Validators: FC = ({ isLoading, limit, pagination, { // TODO: provide uptime when it is implemented in the API align: TableCellAlign.Right, - content: <>-, + content: , key: 'uptime', }, ], diff --git a/src/app/pages/ValidatorDetailsPage/UptimeCard.tsx b/src/app/pages/ValidatorDetailsPage/UptimeCard.tsx index 6a913770f..1094fa4d9 100644 --- a/src/app/pages/ValidatorDetailsPage/UptimeCard.tsx +++ b/src/app/pages/ValidatorDetailsPage/UptimeCard.tsx @@ -1,13 +1,24 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' +import Typography from '@mui/material/Typography' +import { COLORS } from '../../../styles/theme/colors' import { SnapshotTextCard } from '../../components/Snapshots/SnapshotCard' +import { UptimeStatus } from '../../components/UptimeStatus' export const UptimeCard: FC = () => { const { t } = useTranslation() return ( - - {/* TODO: provide uptime stats when API is ready */}- + + {t('validator.signedBlocksPercentage')} + + } + > + {/* TODO: provide data when API is ready */} + ) } diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 17b6616a4..d5d1bada1 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -671,6 +671,7 @@ "signed": "Signed", "signedBlocks": "Signed Blocks", "signedBlocksDescription": "Last 100 blocks", + "signedBlocksPercentage": "Percentage of blocks signed in the past 24h", "proposedBlocks": "Proposed Blocks", "snapshot": "Validator Snapshot", "self": "Self", From e07e543c812bf498537c4e84d9c0b724932bf592 Mon Sep 17 00:00:00 2001 From: Michal Zielenkiewicz Date: Tue, 22 Oct 2024 09:16:29 +0200 Subject: [PATCH 3/4] Add tests to helper function --- .../UptimeStatus/__tests__/index.test.tsx | 49 +++++++++++++++++++ src/app/components/UptimeStatus/index.tsx | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/app/components/UptimeStatus/__tests__/index.test.tsx diff --git a/src/app/components/UptimeStatus/__tests__/index.test.tsx b/src/app/components/UptimeStatus/__tests__/index.test.tsx new file mode 100644 index 000000000..549143e61 --- /dev/null +++ b/src/app/components/UptimeStatus/__tests__/index.test.tsx @@ -0,0 +1,49 @@ +import { ensureTwelveElements } from '..' + +describe('ensureTwelveElements', () => { + test('fills an array with undefined values when arary has less than 12 elements', () => { + const input = [1, 2, 3] + const result = ensureTwelveElements(input) + expect(result.length).toBe(12) + expect(result).toStrictEqual([ + 1, + 2, + 3, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ]) + }) + + test('returns an array with the same 12 elements', () => { + const input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + const result = ensureTwelveElements(input) + expect(result.length).toBe(12) + expect(result).toStrictEqual(input) + }) + + test('truncates the array if it has more than 12 elements', () => { + const input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + const result = ensureTwelveElements(input) + expect(result.length).toBe(12) + expect(result).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + }) + + test('returns an array with 12 undefined values when array is empty', () => { + const result = ensureTwelveElements([]) + expect(result.length).toBe(12) + expect(result).toStrictEqual(new Array(12).fill(undefined)) + }) + + test('returns an array with 12 undefined values when array is not provided', () => { + const result = ensureTwelveElements() + expect(result.length).toBe(12) + expect(result).toStrictEqual(new Array(12).fill(undefined)) + }) +}) diff --git a/src/app/components/UptimeStatus/index.tsx b/src/app/components/UptimeStatus/index.tsx index f45425d68..70d9420d0 100644 --- a/src/app/components/UptimeStatus/index.tsx +++ b/src/app/components/UptimeStatus/index.tsx @@ -31,7 +31,7 @@ const StyledBox = styled(Box)(({ small, value }) => ({ marginRight: small ? 1 : 2, })) -const ensureTwelveElements = (inputArray: number[] = []) => { +export const ensureTwelveElements = (inputArray: number[] = []) => { const truncatedArray = inputArray.slice(0, 12) const undefinedCount = 12 - truncatedArray.length From 23e4be8e0b85174fbdba720c5082353b775d4946 Mon Sep 17 00:00:00 2001 From: Michal Zielenkiewicz Date: Tue, 22 Oct 2024 09:18:47 +0200 Subject: [PATCH 4/4] Refactor helper function --- src/app/components/UptimeStatus/index.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/app/components/UptimeStatus/index.tsx b/src/app/components/UptimeStatus/index.tsx index 70d9420d0..a95602eb4 100644 --- a/src/app/components/UptimeStatus/index.tsx +++ b/src/app/components/UptimeStatus/index.tsx @@ -32,14 +32,7 @@ const StyledBox = styled(Box)(({ small, value }) => ({ })) export const ensureTwelveElements = (inputArray: number[] = []) => { - const truncatedArray = inputArray.slice(0, 12) - const undefinedCount = 12 - truncatedArray.length - - if (undefinedCount > 0) { - const undefinedArray = new Array(undefinedCount).fill(undefined) - return truncatedArray.concat(undefinedArray) - } - return truncatedArray + return [...inputArray, ...new Array(12).fill(undefined)].slice(0, 12) } type UptimeStatusProps = {