From 69dc2ffc505dc01ec684653dea3d49b08836b6e7 Mon Sep 17 00:00:00 2001 From: mkbeefcake Date: Mon, 13 Nov 2023 21:50:25 -0500 Subject: [PATCH] moved the idle period to the first --- .../app/pages/Election/Election.stories.tsx | 13 +- .../components/ElectionProgressBar.tsx | 247 ++++++++++-------- 2 files changed, 147 insertions(+), 113 deletions(-) diff --git a/packages/ui/src/app/pages/Election/Election.stories.tsx b/packages/ui/src/app/pages/Election/Election.stories.tsx index ec08ba07b8..f02a8138b5 100644 --- a/packages/ui/src/app/pages/Election/Election.stories.tsx +++ b/packages/ui/src/app/pages/Election/Election.stories.tsx @@ -8,7 +8,7 @@ import { MocksParameters } from '@/mocks/providers' import { Election } from './Election' type Args = { - electionStage: 'announcing' | 'revealing' | 'voting' | 'idle' + electionStage: 'announcing' | 'revealing' | 'voting' | 'inactive' remainingPeriod?: number | BN currentBlock?: number | BN } @@ -20,7 +20,7 @@ export default { component: Election, args: { electionStage: 'announcing', - remainingPeriod: 40000, + remainingPeriod: 10000, currentBlock: 4802561, }, parameters: { @@ -31,7 +31,7 @@ export default { consts: { council: { councilSize: new BN(3), - idlePeriodDuration: new BN(1), + idlePeriodDuration: new BN(14400), announcingPeriodDuration: new BN(129600), budgetRefillPeriod: new BN(14400), minCandidateStake: new BN(1666666666660000), @@ -53,10 +53,13 @@ export default { council: { stage: { stage: { - isIdle: args.electionStage === 'idle' ? true : false, + isIdle: args.electionStage === 'inactive' ? true : false, isAnnouncing: args.electionStage === 'announcing' ? true : false, }, - changedAt: Number(args.currentBlock) - Number(new BN(129600)) + Number(args.remainingPeriod), + changedAt: + args.electionStage === 'inactive' + ? Number(args.currentBlock) - Number(new BN(14400)) + Number(args.remainingPeriod) + : Number(args.currentBlock) - Number(new BN(129600)) + Number(args.remainingPeriod), }, }, referendum: { diff --git a/packages/ui/src/app/pages/Election/components/ElectionProgressBar.tsx b/packages/ui/src/app/pages/Election/components/ElectionProgressBar.tsx index 561d6c20bd..2825a1265e 100644 --- a/packages/ui/src/app/pages/Election/components/ElectionProgressBar.tsx +++ b/packages/ui/src/app/pages/Election/components/ElectionProgressBar.tsx @@ -66,32 +66,32 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { let announcingProgress = 0 let votingProgress = 0 let revealingProgress = 0 - const nextRoundProgress = 0 + let inactiveProgress = 0 let announcingColor = Colors.Blue[500] let votingColor = Colors.Blue[500] - let revealingColor = Colors.Blue[500] - const nextRoundColor = Colors.Blue[500] + const revealingColor = Colors.Blue[500] + let inactiveColor = Colors.Blue[500] let remainDays = 0 let announcingDays = 0 let votingDays = 0 let revealingDays = 0 - let nextRoundDays = 0 + let inactiveDays = 0 let announcingEndDay = '' let votingEndDay = '' let revealingEndDay = '' - let nextRoundEndDay = '' + let inactiveEndDay = '' let announcingEndBlock = 0 let votingEndBlock = 0 let revealingEndBlock = 0 - let nextRoundEndBlock = 0 + let inactiveEndBlock = 0 - const constants = useCouncilConstants() + let progressBarAttr = '1fr 14fr 3fr 3fr' - // console.log(`duration: ${duration}, constants: ${JSON.stringify(constants)}, currentBlock = ${currentBlock}`) + const constants = useCouncilConstants() if ( !isNaN(duration) && @@ -104,15 +104,23 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { announcingDays = Math.floor(constants?.announcingPeriod / constants?.budgetRefillPeriod) votingDays = Math.floor(constants?.election.votingPeriod / constants?.budgetRefillPeriod) revealingDays = Math.floor(constants?.election.revealingPeriod / constants?.budgetRefillPeriod) - nextRoundDays = Math.floor(constants?.idlePeriod / constants?.budgetRefillPeriod) + inactiveDays = Math.floor(constants?.idlePeriod / constants?.budgetRefillPeriod) - if (props.electionStage === 'announcing') { - announcingProgress = Math.floor(100 - (100 * duration) / constants?.announcingPeriod) + progressBarAttr = `${inactiveDays > 0 ? inactiveDays : 1}fr ${announcingDays > 0 ? announcingDays : 1}fr ${ + votingDays > 0 ? votingDays : 1 + }fr ${revealingDays > 0 ? revealingDays : 1}fr` + + if (props.electionStage === 'inactive') { + announcingProgress = 0 + votingProgress = 0 + revealingProgress = 0 + + inactiveProgress = Math.floor(100 - (100 * duration) / constants?.idlePeriod) remainDays = Math.floor( (duration + + constants?.announcingPeriod + constants?.election.votingPeriod + constants?.election.revealingPeriod + - constants?.idlePeriod + constants?.budgetRefillPeriod - 1) / constants?.budgetRefillPeriod @@ -122,6 +130,9 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { const date = new Date() date.setSeconds(date.getSeconds() + totalSeconds) + inactiveEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + + date.setSeconds(date.getSeconds() + Math.floor(constants?.announcingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK))) announcingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) date.setSeconds( @@ -134,21 +145,22 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { ) revealingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - date.setSeconds(date.getSeconds() + Math.floor(constants?.idlePeriod / (A_SECOND / MILLISECONDS_PER_BLOCK))) - nextRoundEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - // calculate the end of blocks of each stage - announcingEndBlock = currentBlock + duration + inactiveEndBlock = currentBlock + duration + announcingEndBlock = inactiveEndBlock + constants?.announcingPeriod votingEndBlock = announcingEndBlock + constants?.election.votingPeriod revealingEndBlock = votingEndBlock + constants?.election.revealingPeriod - nextRoundEndBlock = revealingEndBlock + constants?.idlePeriod - } else if (props.electionStage === 'voting') { - announcingProgress = 100 - announcingColor = Colors.Blue[200] + } else if (props.electionStage === 'announcing') { + inactiveProgress = 100 + inactiveColor = Colors.Blue[200] - votingProgress = Math.floor(100 - (100 * duration) / constants?.election.votingPeriod) + announcingProgress = Math.floor(100 - (100 * duration) / constants?.announcingPeriod) remainDays = Math.floor( - (duration + constants?.election.revealingPeriod + constants?.idlePeriod + constants?.budgetRefillPeriod - 1) / + (duration + + constants?.election.votingPeriod + + constants?.election.revealingPeriod + + constants?.budgetRefillPeriod - + 1) / constants?.budgetRefillPeriod ) @@ -156,155 +168,176 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { const date = new Date() date.setSeconds(date.getSeconds() + totalSeconds) - votingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + announcingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - const previousDate = date + const previousDate = new Date(date) previousDate.setSeconds( - previousDate.getSeconds() - Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + previousDate.getSeconds() - Math.floor(constants?.announcingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) - announcingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + inactiveEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + + date.setSeconds( + date.getSeconds() + Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + ) + votingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) date.setSeconds( date.getSeconds() + Math.floor(constants?.election.revealingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) revealingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - date.setSeconds(date.getSeconds() + Math.floor(constants?.idlePeriod / (A_SECOND / MILLISECONDS_PER_BLOCK))) - nextRoundEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - // calculate the end of blocks of each stage - votingEndBlock = currentBlock + duration - announcingEndBlock = votingEndBlock - constants?.election.votingPeriod + announcingEndBlock = currentBlock + duration + inactiveEndBlock = announcingEndBlock - constants?.announcingPeriod + votingEndBlock = announcingEndBlock + constants?.election.votingPeriod revealingEndBlock = votingEndBlock + constants?.election.revealingPeriod - nextRoundEndBlock = revealingEndBlock + constants?.idlePeriod - } else if (props.electionStage === 'revealing') { + } else if (props.electionStage === 'voting') { + inactiveProgress = 100 announcingProgress = 100 - votingProgress = 100 - + inactiveColor = Colors.Blue[200] announcingColor = Colors.Blue[200] - votingColor = Colors.Blue[200] - revealingProgress = Math.floor(100 - (100 * duration) / constants?.election.revealingPeriod) + votingProgress = Math.floor(100 - (100 * duration) / constants?.election.votingPeriod) remainDays = Math.floor( - (duration + constants?.idlePeriod + constants?.budgetRefillPeriod - 1) / constants?.budgetRefillPeriod + (duration + constants?.election.revealingPeriod + constants?.budgetRefillPeriod - 1) / + constants?.budgetRefillPeriod ) // calculate the end of day of each stage const date = new Date() date.setSeconds(date.getSeconds() + totalSeconds) - revealingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + votingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - const previousDate = date + const previousDate = new Date(date) previousDate.setSeconds( - previousDate.getSeconds() - - Math.floor(constants?.election.revealingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + previousDate.getSeconds() - Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) - votingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + announcingEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) previousDate.setSeconds( - previousDate.getSeconds() - Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + previousDate.getSeconds() - Math.floor(constants?.announcingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) - announcingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + inactiveEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - date.setSeconds(date.getSeconds() + Math.floor(constants?.idlePeriod / (A_SECOND / MILLISECONDS_PER_BLOCK))) - nextRoundEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + date.setSeconds( + date.getSeconds() + Math.floor(constants?.election.revealingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + ) + revealingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) // calculate the end of blocks of each stage - revealingEndBlock = currentBlock + duration - votingEndBlock = revealingEndBlock - constants?.election.revealingPeriod + votingEndBlock = currentBlock + duration announcingEndBlock = votingEndBlock - constants?.election.votingPeriod - nextRoundEndBlock = revealingEndBlock + constants?.idlePeriod - } else { + inactiveEndBlock = announcingEndBlock - constants?.announcingPeriod + revealingEndBlock = votingEndBlock + constants?.election.revealingPeriod + } else if (props.electionStage === 'revealing') { + inactiveProgress = 100 announcingProgress = 100 votingProgress = 100 - revealingProgress = 100 + inactiveColor = Colors.Blue[200] announcingColor = Colors.Blue[200] votingColor = Colors.Blue[200] - revealingColor = Colors.Blue[200] - revealingProgress = Math.floor(100 - (100 * duration) / constants?.idlePeriod) + revealingProgress = Math.floor(100 - (100 * duration) / constants?.election.revealingPeriod) + remainDays = Math.floor((duration + constants?.budgetRefillPeriod - 1) / constants?.budgetRefillPeriod) // calculate the end of day of each stage const date = new Date() date.setSeconds(date.getSeconds() + totalSeconds) - nextRoundEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - - date.setSeconds(date.getSeconds() - Math.floor(constants?.idlePeriod / (A_SECOND / MILLISECONDS_PER_BLOCK))) revealingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - date.setSeconds( - date.getSeconds() - Math.floor(constants?.election.revealingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + const previousDate = new Date(date) + previousDate.setSeconds( + previousDate.getSeconds() - + Math.floor(constants?.election.revealingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) - votingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + votingEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) - date.setSeconds( - date.getSeconds() - Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + previousDate.setSeconds( + previousDate.getSeconds() - Math.floor(constants?.election.votingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) ) - announcingEndDay = date.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + announcingEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) + + previousDate.setSeconds( + previousDate.getSeconds() - Math.floor(constants?.announcingPeriod / (A_SECOND / MILLISECONDS_PER_BLOCK)) + ) + inactiveEndDay = previousDate.toLocaleString('en-US', { timeZone: 'Europe/Paris' }) // calculate the end of blocks of each stage - nextRoundEndBlock = currentBlock + duration - revealingEndBlock = nextRoundEndBlock - constants?.idlePeriod + revealingEndBlock = currentBlock + duration votingEndBlock = revealingEndBlock - constants?.election.revealingPeriod announcingEndBlock = votingEndBlock - constants?.election.votingPeriod + inactiveEndBlock = announcingEndBlock - constants?.announcingPeriod } } const updateDescription = (selectedStage: string, choose: boolean) => { if (choose === false || props.electionStage === selectedStage) { - setStageDescription(defaultStaging) - setVerbIndicator(defaultVerbIndicator) - setDaysIndicator(defaultDaysIndicator) + if (props.electionStage === 'inactive') { + setStageDescription('The Round') + setVerbIndicator('begins in') + setDaysIndicator(defaultDaysIndicator) + } else { + setStageDescription(defaultStaging) + setVerbIndicator(defaultVerbIndicator) + setDaysIndicator(defaultDaysIndicator) + } setSelectedToolbarStage('') return } - if (props.electionStage === 'announcing') { + + if (props.electionStage === 'inactive') { setStageDescription(selectedStage) setVerbIndicator('begins in') - if (selectedStage === 'voting') { + if (selectedStage === 'announcing') { setDaysIndicator(defaultDaysIndicator) + } else if (selectedStage === 'voting') { + setDaysIndicator(convertDurationToTimeString(announcingEndBlock - currentBlock)) } else if (selectedStage === 'revealing') { setDaysIndicator(convertDurationToTimeString(votingEndBlock - currentBlock)) - } else if (selectedStage === 'nextround') { - setDaysIndicator(convertDurationToTimeString(revealingEndBlock - currentBlock)) } - } else if (props.electionStage === 'voting') { - if (selectedStage === 'announcing') { + } else if (props.electionStage === 'announcing') { + if (selectedStage === 'inactive') { setStageDescription(selectedStage) setVerbIndicator('ended on') - setDaysIndicator(announcingEndDay) + setDaysIndicator(inactiveEndDay) } else { setStageDescription(selectedStage) setVerbIndicator('begins in') - if (selectedStage === 'revealing') { + if (selectedStage === 'voting') { setDaysIndicator(defaultDaysIndicator) - } else if (selectedStage === 'nextround') { - setDaysIndicator(convertDurationToTimeString(revealingEndBlock - currentBlock)) + } else if (selectedStage === 'revealing') { + setDaysIndicator(convertDurationToTimeString(votingEndBlock - currentBlock)) } } - } else if (props.electionStage === 'revealing') { - if (selectedStage === 'announcing') { + } else if (props.electionStage === 'voting') { + if (selectedStage === 'inactive') { setStageDescription(selectedStage) setVerbIndicator('ended on') - setDaysIndicator(announcingEndDay) - } else if (selectedStage === 'voting') { + setDaysIndicator(inactiveEndDay) + } else if (selectedStage === 'announcing') { setStageDescription(selectedStage) setVerbIndicator('ended on') - setDaysIndicator(votingEndDay) - } else if (selectedStage === 'nextround') { - setStageDescription('Next Round') - setVerbIndicator('starts in') + setDaysIndicator(announcingEndDay) + } else if (selectedStage === 'revealing') { + setStageDescription(selectedStage) + setVerbIndicator('begins in') setDaysIndicator(defaultDaysIndicator) } - } else { - setStageDescription(defaultStaging) - setVerbIndicator(defaultVerbIndicator) - setDaysIndicator(defaultDaysIndicator) + } else if (props.electionStage === 'revealing') { + setStageDescription(selectedStage) + setVerbIndicator('ended on') + if (selectedStage === 'announcing') { + setDaysIndicator(announcingEndDay) + } else if (selectedStage === 'voting') { + setDaysIndicator(votingEndDay) + } else if (selectedStage === 'inactive') { + setDaysIndicator(inactiveEndDay) + } } setSelectedToolbarStage(selectedStage) } @@ -322,7 +355,18 @@ export const ElectionProgressBar = (props: ElectionProgressBarProps) => { {remainDays} days until next round - 1}> + + { updateDesc={updateDescription} tooltipText={`Revealing stage lasts ${revealingDays} days and ends on ${revealingEndDay} CET (block #${revealingEndBlock.toLocaleString( 'en-US' - )} block). During this time, voters can reveal their sealed votes. Any valid vote which is unsealed is counter, and in the end a winning set of candidates is selected`} + )} block). During this time, voters can reveal their sealed votes. Any valid vote which is unsealed is counted, and in the end a winning set of candidates is selected`} placement="bottom-end" /> - {constants?.idlePeriod != undefined && constants?.idlePeriod > 1 && ( - - )} ) @@ -428,7 +459,7 @@ const TooltipProgressBar = (props: TooltipProgressBarProps) => { const tooltipHandlers = { onClick: (event: React.MouseEvent) => { event.stopPropagation() - setTooltipActive(false) + setTooltipActive(true) }, onFocus: mouseIsOver, onBlur: mouseLeft, @@ -547,9 +578,9 @@ const StatisticBigLabel = styled.div<{ strong?: boolean }>` display: inline-block; color: ${({ strong }) => (strong ? `${Colors.Black[900]}` : `${Colors.Black[400]}`)}; ` -const ProgressBarLayout = styled.div<{ hasIdle?: boolean }>` +const ProgressBarLayout = styled.div<{ layout?: string }>` display: grid; - grid-template-columns: ${({ hasIdle }) => (hasIdle ? '14fr 3fr 3fr 1fr' : '15fr 3fr 3fr')}; + grid-template-columns: ${({ layout }) => (layout ? layout : '1fr 14fr 3fr 3fr')}; gap: 4px; width: 100%; max-width: 100%;