Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deploy: production #140

Merged
merged 24 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
acbdf30
fix: ignore .env.testnet
HashMapsData2Value Dec 6, 2023
b2dc55e
feat: ENG-63 Sorts passed proposals to the top
HashMapsData2Value Dec 7, 2023
d3e0143
fix: ignore .env.testnet specifically
HashMapsData2Value Dec 7, 2023
d534fbb
fix: includes only .env.*.template
HashMapsData2Value Dec 7, 2023
d368094
fix: add whitespace ending
HashMapsData2Value Dec 7, 2023
31c7d4c
feat: ensures forcePassed are sorted to top as well
HashMapsData2Value Dec 11, 2023
77220bb
chore: remove chips from results, remove home nav
PhearZero Dec 11, 2023
fa7b72e
chore: remove back buttons
PhearZero Dec 11, 2023
0c61c21
chore: redirect to live voting round
PhearZero Dec 11, 2023
fbb8a2b
chore: remove vote details and add total votes
PhearZero Dec 11, 2023
501bee6
chore: skip redirect on local only
PhearZero Dec 11, 2023
5d1bcd8
chore: fix lint errors
PhearZero Dec 11, 2023
ccea19e
Merge pull request #138 from algorandfoundation/chore/redirect-to-act…
PhearZero Dec 11, 2023
b4e35a9
fix: use type-guard for appId
PhearZero Dec 11, 2023
a9273e1
fix: remove effect from redirect
PhearZero Dec 11, 2023
63eacfe
chore: trigger fresh build after cleanup
PhearZero Dec 11, 2023
1d60a03
fix: use window.location in place of import.meta.env
PhearZero Dec 12, 2023
0db694c
Merge remote-tracking branch 'origin/develop' into feat-ENG-63-pin-ap…
HashMapsData2Value Dec 12, 2023
221e48c
feat: sort in VoteResults bab
HashMapsData2Value Dec 12, 2023
124b64b
fix: reinstate Question import
HashMapsData2Value Dec 12, 2023
51d4920
Merge pull request #136 from algorandfoundation/feat-ENG-63-pin-appro…
HashMapsData2Value Dec 12, 2023
6ca4abd
chore: add livestream url link, update hero, temporarily remove redirect
PhearZero Dec 12, 2023
2f8c2e2
chore: add disaster recovery documentation
PhearZero Dec 12, 2023
61d34b9
Merge pull request #139 from algorandfoundation/chore/bab-update-to-p…
PhearZero Dec 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,15 @@ We recommend using the following IAM policy, which gives the least access possib
]
}
```
# Disaster Recovery

During a deployment, there is a chance for a race condition between the CDK S3 deployer and CloudFront invalidation.
It is intermittent and is being tracked in [an issue in the cdk library](https://github.com/aws/aws-cdk/issues/15891).
If the deployment fails to update the Custom::CDKBucketDeployment, use the following process:

1. Log into the effected AWS account and navigate to CloudFormation
2. Select the failed deployment and use the `Stack options` drop down to select `Continue update rollback`
1. In the `Continue update rollback`, make sure to expand `Advanced` and select `skip` for the failing resource
2. Trigger the rollback
3. Re-run the failed deployment from the CI/CD platform (GithubActions). This may require a second deployment to ensure the cache is invalidated

3 changes: 2 additions & 1 deletion src/build-a-bull/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ dist-ssr
*.sln
*.sw?

.env
.env*
!.env*.template
Binary file modified src/build-a-bull/public/images/hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 1 addition & 5 deletions src/build-a-bull/src/components/siteHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ interface Link {
onClick?: () => void
}

const createNavigation = () =>
[
{ name: 'Home', href: '/', protect: false },
{ name: 'Create', href: '/create', protect: true },
] as Link[]
const createNavigation = () => [{ name: 'Create', href: '/create', protect: true }] as Link[]

function NavLink(props: { currentClasses: string; defaultClasses: string; link: Link; displayName?: string }) {
const classes = 'no-underline text-black'
Expand Down
10 changes: 9 additions & 1 deletion src/build-a-bull/src/features/rounds/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Alert, Button, Skeleton, Typography } from '@mui/material'
import sortBy from 'lodash.sortby'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Link, useNavigate } from 'react-router-dom'
import { VotingRoundGlobalState, fetchVotingRoundGlobalStatesByCreators } from '@/shared/VotingRoundContract'
import { VoteType } from '@/shared/types'
import { getHasVoteEnded, getHasVoteStarted } from '@/shared/vote'
Expand Down Expand Up @@ -36,6 +36,14 @@
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null)

// Redirect to live round
const navigate = useNavigate()

Check warning on line 40 in src/build-a-bull/src/features/rounds/index.tsx

View workflow job for this annotation

GitHub Actions / CI Events Dapp / node-ci

'navigate' is assigned a value but never used

Check warning on line 40 in src/build-a-bull/src/features/rounds/index.tsx

View workflow job for this annotation

GitHub Actions / Events Dapp / node-ci

'navigate' is assigned a value but never used
// TODO: add production voting round
const appId = window.location.hostname.includes('testnet') ? 499163907 : 1158913461

Check warning on line 42 in src/build-a-bull/src/features/rounds/index.tsx

View workflow job for this annotation

GitHub Actions / CI Events Dapp / node-ci

'appId' is assigned a value but never used

Check warning on line 42 in src/build-a-bull/src/features/rounds/index.tsx

View workflow job for this annotation

GitHub Actions / Events Dapp / node-ci

'appId' is assigned a value but never used
if (import.meta.env.VITE_ENVIRONMENT !== 'local') {
// navigate(`/vote/${appId}`)
}

useEffect(() => {
let addressesToFetch = [] as string[]
if (showMyRounds && activeAddress) {
Expand Down
78 changes: 42 additions & 36 deletions src/build-a-bull/src/features/vote/VoteResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import FileDownloadIcon from '@mui/icons-material/FileDownload'
import { Alert, Button, Skeleton, Typography } from '@mui/material'
import { saveAs } from 'file-saver'
import Papa from 'papaparse'
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { VotingRoundMetadata } from '@/shared/IPFSGateway'
import { useMemo, useState } from 'react'
import { Question, VotingRoundMetadata } from '@/shared/IPFSGateway'
import { VotingRoundGlobalState } from '@/shared/VotingRoundContract'
import { ProposalCard } from '@/shared/ProposalCard'
import { VotingRoundResult } from '@/shared/types'
import { generateOptionIDsToCountsMapping } from '@/utils/common'
import { VoteDetails } from './VoteDetails'
import VotingStats from './VotingStats'
import { VotingTime } from './VotingTime'

Expand All @@ -33,7 +31,25 @@ export const VoteResults = ({
const [error, setError] = useState<string | null>(null)

const optionIDsToCounts = votingRoundResults !== undefined ? generateOptionIDsToCountsMapping(votingRoundResults) : {}
function getTotalVotes() {
return votingRoundResults && votingRoundMetadata
? votingRoundResults.reduce((c, r) => {
const isYesOption = votingRoundMetadata.questions.map((q) => q.options[0]).some((el) => el.id === r.optionId)
return isYesOption ? c + r.count : c
}, 0)
: 0
}

const countVotesTally = (question: Question) => {
return question.options.length > 0 && optionIDsToCounts[question.options[0].id] ? optionIDsToCounts[question.options[0].id] : 0
}

const passedToTopSort = (q1: Question, q2: Question) => {
if (!q1.metadata?.threshold || !q2.metadata?.threshold) return 0
return countVotesTally(q2) / q2.metadata.threshold - countVotesTally(q1) / q1.metadata.threshold
}

const totalVotes = useMemo(() => getTotalVotes(), [votingRoundResults, votingRoundMetadata])
const generateProposalsResultsCsv = async () => {
if (votingRoundMetadata) {
setIsDownloadingProposalsCsv(true)
Expand Down Expand Up @@ -67,23 +83,11 @@ export const VoteResults = ({

return (
<div>
<div className="mb-4">
<Link to="/" className="no-underline text-gray-600 hover:underline">
<Typography>&#60; Back to Voting sessions</Typography>
</Link>
</div>
<div className="grid grid-cols-1 xl:grid-cols-3 gap-4">
<div className="col-span-1 xl:col-span-2">
<Typography variant="h3">{votingRoundMetadata?.title} - Results</Typography>
</div>
<div>
<VoteDetails
globalState={votingRoundGlobalState}
appId={votingRoundGlobalState.appId}
loading={isLoadingVotingRoundData}
roundMetadata={votingRoundMetadata}
/>
</div>
<div></div>
<div>
<VotingStats
isLoading={isLoadingVotingRoundData || isLoadingVotingRoundResults}
Expand Down Expand Up @@ -111,25 +115,27 @@ export const VoteResults = ({
</>
))}
{!isLoadingVotingRoundResults &&
votingRoundMetadata?.questions.map((question) => (
<div key={question.id}>
{question.metadata && (
<ProposalCard
title={question.prompt}
description={question.description}
category={question.metadata.category}
focus_area={question.metadata.focus_area}
link={question.metadata.link}
threshold={question.metadata.threshold}
ask={question.metadata.ask}
votesTally={
question.options.length > 0 && optionIDsToCounts[question.options[0].id] ? optionIDsToCounts[question.options[0].id] : 0
}
hasClosed={true}
/>
)}
</div>
))}
votingRoundMetadata?.questions
.sort((q1, q2) => passedToTopSort(q1, q2))
.map((question) => (
<div key={question.id}>
{question.metadata && (
<ProposalCard
title={question.prompt}
description={question.description}
category={question.metadata.category}
focus_area={question.metadata.focus_area}
link={question.metadata.link}
threshold={question.metadata.threshold}
ask={question.metadata.ask}
skipTags={true}
totalVotes={totalVotes}
votesTally={countVotesTally(question)}
hasClosed={true}
/>
)}
</div>
))}
</div>
<div className="w-full text-right mt-4">
<Button
Expand Down
15 changes: 8 additions & 7 deletions src/build-a-bull/src/features/vote/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { Alert, Box, Button, Checkbox, IconButton, Link, Skeleton, Typography } from '@mui/material'
import clsx from 'clsx'
import { useEffect, useMemo, useState } from 'react'
import { Link as RouterLink, useNavigate, useParams } from 'react-router-dom'
import { useNavigate, useParams } from 'react-router-dom'
import { Question, VotingRoundMetadata, fetchVotingRoundMetadata } from '@/shared/IPFSGateway'
import {
TallyCounts,
Expand All @@ -29,6 +29,7 @@
import VotingStats from './VotingStats'
import { VotingTime } from './VotingTime'
import { generateOptionIDsToCountsMapping } from '@/utils/common'
import YouTubeIcon from '@mui/icons-material/YouTube'

// Fisher-Yates shuffle
Array.prototype.shuffle = function () {
Expand Down Expand Up @@ -316,11 +317,6 @@

return (
<div>
<div className="mb-4">
<RouterLink to="/" className="no-underline text-gray-600 hover:underline">
<Typography>&#60; Back to events</Typography>
</RouterLink>
</div>
<div>
{error && (
<Alert className="max-w-xl mt-4 text-white bg-red font-semibold" icon={false}>
Expand All @@ -331,7 +327,12 @@
{isLoadingVotingRoundData ? (
<Skeleton className="h-12 w-1/2" variant="text" />
) : (
<Typography variant="h3">{votingRoundMetadata?.title}</Typography>
<div className="grid lg:grid-cols-4 grid-cols-3">
<Typography className="lg:col-span-3 col-span-2" variant="h3">{votingRoundMetadata?.title}</Typography>

Check warning on line 331 in src/build-a-bull/src/features/vote/index.tsx

View workflow job for this annotation

GitHub Actions / CI Events Dapp / node-ci

Replace `{votingRoundMetadata?.title}` with `⏎··············{votingRoundMetadata?.title}⏎············`

Check warning on line 331 in src/build-a-bull/src/features/vote/index.tsx

View workflow job for this annotation

GitHub Actions / Events Dapp / node-ci

Replace `{votingRoundMetadata?.title}` with `⏎··············{votingRoundMetadata?.title}⏎············`
<Button onClick={()=>window.open("https://www.youtube.com/live/HVpyIZVIV9s?feature=shared", '_blank', 'noopener, noreferrer')} className="col-span-1" startIcon={<YouTubeIcon />} variant="contained">

Check warning on line 332 in src/build-a-bull/src/features/vote/index.tsx

View workflow job for this annotation

GitHub Actions / CI Events Dapp / node-ci

Replace `·onClick={()=>window.open("https://www.youtube.com/live/HVpyIZVIV9s?feature=shared",·'_blank',·'noopener,·noreferrer')}·className="col-span-1"·startIcon={<YouTubeIcon·/>}·variant="contained"` with `⏎··············onClick={()·=>·window.open('https://www.youtube.com/live/HVpyIZVIV9s?feature=shared',·'_blank',·'noopener,·noreferrer')}⏎··············className="col-span-1"⏎··············startIcon={<YouTubeIcon·/>}⏎··············variant="contained"⏎············`

Check warning on line 332 in src/build-a-bull/src/features/vote/index.tsx

View workflow job for this annotation

GitHub Actions / Events Dapp / node-ci

Replace `·onClick={()=>window.open("https://www.youtube.com/live/HVpyIZVIV9s?feature=shared",·'_blank',·'noopener,·noreferrer')}·className="col-span-1"·startIcon={<YouTubeIcon·/>}·variant="contained"` with `⏎··············onClick={()·=>·window.open('https://www.youtube.com/live/HVpyIZVIV9s?feature=shared',·'_blank',·'noopener,·noreferrer')}⏎··············className="col-span-1"⏎··············startIcon={<YouTubeIcon·/>}⏎··············variant="contained"⏎············`
Watch Live
</Button>
</div>
)}
{votingRoundMetadata?.description && <Typography>{votingRoundMetadata.description}</Typography>}
{votingRoundMetadata?.informationUrl && (
Expand Down
6 changes: 4 additions & 2 deletions src/build-a-bull/src/shared/ProposalCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type ProposalCardProps = {
totalVotes?: number | undefined
hasClosed?: boolean
forcePass?: boolean
skipTags?: boolean
}

export const ProposalCard = ({
Expand All @@ -30,6 +31,7 @@ export const ProposalCard = ({
totalVotes = 0,
hasClosed = false,
forcePass = false,
skipTags = false,
}: ProposalCardProps) => {
// Handle collapse state
const [isOverflow, setIsOverflow] = useState(false)
Expand All @@ -51,8 +53,8 @@ export const ProposalCard = ({
<Paper elevation={0} className="p-5">
<div className="flex justify-between">
<div>
{hasPassed && <PassedChip />}
{hasClosed && !hasPassed && <DidNotPassChip />}
{hasPassed && !skipTags && <PassedChip />}
{hasClosed && !hasPassed && !skipTags && <DidNotPassChip />}
</div>
<div className="text-right">
<span className="hidden md:inline-block">
Expand Down
3 changes: 2 additions & 1 deletion src/xgov-dapp/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ dist-ssr
*.sln
*.sw?

.env
.env*
!.env*.template
62 changes: 35 additions & 27 deletions src/xgov-dapp/src/features/vote/VoteResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ export const VoteResults = ({

const optionIDsToCounts = votingRoundResults !== undefined ? generateOptionIDsToCountsMapping(votingRoundResults) : {}

const countVotesTally = (question: Question) => {
return question.options.length > 0 && optionIDsToCounts[question.options[0].id] ? optionIDsToCounts[question.options[0].id] : 0
}

const passedToTopSort = (q1: Question, q2: Question) => {
if (!q1.metadata?.threshold || !q2.metadata?.threshold) return 0
return countVotesTally(q2) / q2.metadata.threshold - countVotesTally(q1) / q1.metadata.threshold
}

const passedToTopSortReserve = (q1: Question, q2: Question, passedReserveList: Set<string>) => {
return passedReserveList.has(q2.id) ? 100 : passedReserveList.has(q1.id) ? -100 : passedToTopSort(q1, q2)
}

// clone the voting round metadata and adjust the threshold to be out of total votes instead of total voting power
// we clone the metadata so that we don't mutate the original metadata
const votingRoundMetadataClone = useMemo<VotingRoundMetadata | undefined>(() => {
Expand Down Expand Up @@ -224,6 +237,7 @@ export const VoteResults = ({
? !isReserveList(q, optionIDsToCounts[q.options[0].id])
: true,
)
.sort((q1, q2) => passedToTopSort(q1, q2))
.map((question) => (
<div key={question.id}>
{question.metadata && (
Expand All @@ -235,11 +249,7 @@ export const VoteResults = ({
link={question.metadata.link}
threshold={question.metadata.threshold}
ask={question.metadata.ask}
votesTally={
question.options.length > 0 && optionIDsToCounts[question.options[0].id]
? optionIDsToCounts[question.options[0].id]
: 0
}
votesTally={countVotesTally(question)}
hasClosed={true}
/>
)}
Expand All @@ -265,28 +275,26 @@ export const VoteResults = ({
</>
))}
{!isLoadingVotingRoundResults &&
reserveList.map((question) => (
<div key={question.id}>
{question.metadata && (
<ProposalCard
title={question.prompt}
description={question.description}
category={question.metadata.category}
focus_area={question.metadata.focus_area}
link={question.metadata.link}
threshold={question.metadata.threshold}
ask={question.metadata.ask}
votesTally={
question.options.length > 0 && optionIDsToCounts[question.options[0].id]
? optionIDsToCounts[question.options[0].id]
: 0
}
hasClosed={true}
forcePass={passedReserveList.has(question.id)}
/>
)}
</div>
))}
reserveList
.sort((q1, q2) => passedToTopSortReserve(q1, q2, passedReserveList))
.map((question) => (
<div key={question.id}>
{question.metadata && (
<ProposalCard
title={question.prompt}
description={question.description}
category={question.metadata.category}
focus_area={question.metadata.focus_area}
link={question.metadata.link}
threshold={question.metadata.threshold}
ask={question.metadata.ask}
votesTally={countVotesTally(question)}
hasClosed={true}
forcePass={passedReserveList.has(question.id)}
/>
)}
</div>
))}
</>
)}
</div>
Expand Down