Skip to content

Commit

Permalink
Merge pull request #219 from makerdao/feature/sc-661/add-visual-for-h…
Browse files Browse the repository at this point in the history
…ow-many-mkr-needed-to-pass

Feature/sc 661/add visual for how many mkr needed to pass
  • Loading branch information
adamgoth authored Nov 2, 2021
2 parents a6a605d + 471d0c2 commit 888f008
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
9 changes: 5 additions & 4 deletions modules/executive/components/ExecutiveOverviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ import Stack from 'modules/app/components/layout/layouts/Stack';
import VoteModal from './VoteModal';
import { useAnalytics } from 'modules/app/client/analytics/useAnalytics';
import { ANALYTICS_PAGES } from 'modules/app/client/analytics/analytics.constants';
import { useMkrOnHat } from 'modules/executive/hooks/useMkrOnHat';

type Props = {
proposal: Proposal;
spellData?: SpellData;
isHat: boolean;
spellData?: SpellData;
};

export default function ExecutiveOverviewCard({ proposal, spellData, isHat, ...props }: Props): JSX.Element {
export default function ExecutiveOverviewCard({ proposal, isHat, spellData, ...props }: Props): JSX.Element {
const { trackButtonClick } = useAnalytics(ANALYTICS_PAGES.EXECUTIVE);

const account = useAccountsStore(state => state.currentAccount);
const { data: mkrOnHat } = useMkrOnHat();
const [voting, setVoting] = useState(false);
const { data: votedProposals } = useVotedProposals();
const network = getNetwork();
Expand Down Expand Up @@ -178,7 +179,7 @@ export default function ExecutiveOverviewCard({ proposal, spellData, isHat, ...p
<Divider my={0} />
<Flex sx={{ py: 2, justifyContent: 'center', fontSize: [1, 2], color: 'onSecondary' }}>
<Text as="p" sx={{ textAlign: 'center', px: [3, 4], mb: 1, wordBreak: 'break-word' }}>
{getStatusText(proposal.address, spellData)}
{getStatusText({ proposalAddress: proposal.address, spellData, mkrOnHat })}
</Text>
</Flex>
</Card>
Expand Down
34 changes: 33 additions & 1 deletion modules/executive/helpers/getStatusText.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import BigNumber from 'bignumber.js';
import { formatDateWithTime } from 'lib/datetime';
import { isBefore } from 'date-fns';
import { SPELL_SCHEDULED_DATE_OVERRIDES } from 'lib/constants';
import { SpellData } from '../types/spellData';
import { ZERO_ADDRESS } from 'stores/accounts';
import { CurrencyObject } from 'types/currency';

export const getStatusText = (proposalAddress: string, spellData?: SpellData): string => {
export const getStatusText = ({
proposalAddress,
spellData,
mkrOnHat
}: {
proposalAddress: string;
spellData?: SpellData;
mkrOnHat?: CurrencyObject;
}): string => {
if (!spellData) return 'Fetching status...';

if (proposalAddress === ZERO_ADDRESS) {
return `This proposal surpased the 80,000 MKR threshold on ${formatDateWithTime(1607704862000)} – the new
chief has been activated!`;
}

// check if scheduled or has been executed
if (spellData.hasBeenScheduled || spellData.dateExecuted) {
if (typeof spellData.dateExecuted === 'string') {
return `Passed on ${formatDateWithTime(spellData.datePassed)}. Executed on ${formatDateWithTime(
Expand All @@ -24,5 +36,25 @@ export const getStatusText = (proposalAddress: string, spellData?: SpellData): s
}.`;
}
}

// hasn't been passed or executed, check if expired
const isExpired = spellData.expiration ? isBefore(new Date(spellData.expiration), new Date()) : false;
if (isExpired) {
return `This proposal expired at ${formatDateWithTime(
spellData.expiration
)} and can no longer be executed.`;
}

// not expired, passed, or executed, check support level
if (!!spellData.mkrSupport && !!mkrOnHat) {
return `${mkrOnHat
.toBigNumber()
.minus(new BigNumber(spellData.mkrSupport))
.toFormat(2)} additional MKR support needed to pass. Expires at ${formatDateWithTime(
spellData.expiration
)}.`;
}

// hasn't been scheduled, executed, hasn't expired, must be active and not passed yet
return 'This proposal has not yet passed and is not available for execution.';
};
28 changes: 28 additions & 0 deletions modules/executive/hooks/useMkrOnHat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import getMaker from 'lib/maker';
import useSWR from 'swr';
import { CurrencyObject } from 'types/currency';

type MkrOnHatResponse = {
data?: CurrencyObject;
loading: boolean;
error: Error;
};

export const useMkrOnHat = (): MkrOnHatResponse => {
const { data, error } = useSWR<CurrencyObject>(
'/executive/mkr-on-hat',
async () => {
const maker = await getMaker();
const hat = await maker.service('chief').getHat();
return maker.service('chief').getApprovalCount(hat);
},
// refresh every 5 mins
{ refreshInterval: 300000 }
);

return {
data,
loading: !error && !data,
error
};
};
15 changes: 12 additions & 3 deletions pages/executive/[proposal-id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import invariant from 'tiny-invariant';
import { getExecutiveProposal, getExecutiveProposals } from 'modules/executive/api/fetchExecutives';
import { useSpellData } from 'modules/executive/hooks/useSpellData';
import { useVotedProposals } from 'modules/executive/hooks/useVotedProposals';
import { useMkrOnHat } from 'modules/executive/hooks/useMkrOnHat';
import { getNetwork, isDefaultNetwork } from 'lib/maker';
import { cutMiddle, limitString } from 'lib/string';
import { getStatusText } from 'modules/executive/helpers/getStatusText';
Expand All @@ -38,6 +39,7 @@ import { SpellEffectsTab } from 'modules/executive/components/SpellEffectsTab';

//types
import { CMSProposal, Proposal, SpellData } from 'modules/executive/types';
import { CurrencyObject } from 'types/currency';

type Props = {
proposal: Proposal;
Expand All @@ -50,17 +52,21 @@ const editMarkdown = content => {

const ProposalTimingBanner = ({
proposal,
spellData
spellData,
mkrOnHat
}: {
proposal: CMSProposal;
spellData?: SpellData;
mkrOnHat?: CurrencyObject;
}): JSX.Element => {
if (spellData || proposal.address === ZERO_ADDRESS)
return (
<>
<Divider my={1} />
<Flex sx={{ py: 2, justifyContent: 'center', fontSize: [1, 2], color: 'onSecondary' }}>
<Text sx={{ textAlign: 'center', px: [3, 4] }}>{getStatusText(proposal.address, spellData)}</Text>
<Text sx={{ textAlign: 'center', px: [3, 4] }}>
{getStatusText({ proposalAddress: proposal.address, spellData, mkrOnHat })}
</Text>
</Flex>
<Divider sx={{ mt: 1 }} />
</>
Expand All @@ -81,6 +87,7 @@ const ProposalView = ({ proposal }: Props): JSX.Element => {
);

const { data: votedProposals } = useVotedProposals();
const { data: mkrOnHat } = useMkrOnHat();

const { data: comments, error: commentsError } = useSWR(
`/api/executive/comments/list/${proposal.address}`,
Expand Down Expand Up @@ -202,7 +209,9 @@ const ProposalView = ({ proposal }: Props): JSX.Element => {
</div>,
commentsTab
]}
banner={<ProposalTimingBanner proposal={proposal} spellData={spellData} />}
banner={
<ProposalTimingBanner proposal={proposal} spellData={spellData} mkrOnHat={mkrOnHat} />
}
></Tabs>
) : (
<Tabs
Expand Down

0 comments on commit 888f008

Please sign in to comment.