UNPKG

@hypernetlabs/web-ui

Version:
208 lines 13.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const objects_1 = require("@hypernetlabs/objects"); const core_1 = require("@material-ui/core"); const contexts_1 = require("../../contexts"); const react_1 = __importStar(require("react")); const components_1 = require("../../components"); const ProposalsWidget_1 = require("../../widgets/ProposalsWidget/ProposalsWidget"); const ProposalDetailWidget_style_1 = require("../../widgets/ProposalDetailWidget/ProposalDetailWidget.style"); const ProposalDetailWidget = ({ onProposalListNavigate, proposalId, }) => { const classes = (0, ProposalDetailWidget_style_1.useStyles)(); const { coreProxy, viewUtils } = (0, contexts_1.useStoreContext)(); const { setLoading, handleCoreError } = (0, contexts_1.useLayoutContext)(); const [proposal, setProposal] = (0, react_1.useState)(); const [blockNumber, setBlockNumber] = (0, react_1.useState)(); const [accountAddress, setAccountAddress] = (0, react_1.useState)(); const [supportStatus, setSupportStatus] = (0, react_1.useState)(); const [proposalDescriptionFromIPFS, setProposalDescriptionFromIPFS] = (0, react_1.useState)(); // This is set to true for some existing proposals in rinkeby. const [showRawDescription, setShowRawDescription] = (0, react_1.useState)(); (0, react_1.useEffect)(() => { getProposalDetail(); getBlockNumber(); }, []); const getProposalDetail = () => { setLoading(true); coreProxy.getEthereumAccounts().map((accounts) => { setAccountAddress(accounts[0]); // delegate votes, createProposal and then list all proposals coreProxy.governance .getProposalDetails(proposalId) .map((proposal) => { setProposal(proposal); if (!(0, ProposalsWidget_1.hasProposalDescriptionHash)(proposal.description)) { setShowRawDescription(true); return; } const descriptionHash = viewUtils.getProposalDescriptionHash(proposal.description); coreProxy.governance .getProposalDescription((0, objects_1.IpfsCID)(descriptionHash)) .map((description) => { setProposalDescriptionFromIPFS(description); }) .mapErr(handleCoreError); }) .mapErr(handleCoreError); getProposalVotesReceipt(accounts[0]); }); }; const getBlockNumber = () => { setLoading(true); coreProxy .getBlockNumber() .map((blockNumber) => { setBlockNumber(blockNumber); }) .mapErr(handleCoreError); }; const getProposalVotesReceipt = (account) => { setLoading(true); coreProxy.governance .getProposalVotesReceipt(proposalId, account) .map((proposalVoteReceipt) => { if (proposalVoteReceipt.hasVoted) { setSupportStatus(Number(proposalVoteReceipt.support)); } setLoading(false); }) .mapErr(handleCoreError); }; const proposalVotesFor = proposal ? proposal.votesFor : 0; const proposalVotesAgainst = proposal ? proposal.votesAgainst : 0; const proposalVotesAbstain = proposal ? proposal.votesAbstain : 0; const totalVotes = proposalVotesFor + proposalVotesAgainst + proposalVotesAbstain; const forPercentage = ((proposalVotesFor * 100) / totalVotes).toFixed(0) || "0"; const againstPercentage = ((proposalVotesAgainst * 100) / totalVotes).toFixed(0) || "0"; const abstainPercentage = ((proposalVotesAbstain * 100) / totalVotes).toFixed(0) || "0"; const showVotingButtons = Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) === objects_1.EProposalState.ACTIVE; const queueProposal = () => { setLoading(true); coreProxy.governance .queueProposal(proposalId) .map((proposal) => { setProposal(proposal); setLoading(false); }) .mapErr(handleCoreError); }; const cancelProposal = () => { setLoading(true); coreProxy.governance .cancelProposal(proposalId) .map((proposal) => { setProposal(proposal); setLoading(false); }) .mapErr(handleCoreError); }; const executeProposal = () => { setLoading(true); coreProxy.governance .executeProposal(proposalId) .map((proposal) => { setProposal(proposal); setLoading(false); }) .mapErr(handleCoreError); }; const castVote = (voteSupport) => { setLoading(true); coreProxy.governance .castVote(proposalId, voteSupport) .map((proposal) => { setProposal(proposal); if (accountAddress) { getProposalVotesReceipt(accountAddress); } }) .mapErr(handleCoreError); }; const isUserProposalOwner = (0, react_1.useMemo)(() => proposal && accountAddress && (0, objects_1.EthereumAccountAddress)(proposal.originator) === accountAddress, [JSON.stringify(proposal), accountAddress]); const canQueueProposal = (0, react_1.useMemo)(() => { return Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) === objects_1.EProposalState.SUCCEEDED; }, [JSON.stringify(proposal)]); const canExecuteProposal = (0, react_1.useMemo)(() => { return Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) === objects_1.EProposalState.QUEUED; }, [JSON.stringify(proposal)]); const canCancelProposal = (0, react_1.useMemo)(() => { return (isUserProposalOwner && [ objects_1.EProposalState.PENDING, objects_1.EProposalState.QUEUED, objects_1.EProposalState.ACTIVE, objects_1.EProposalState.SUCCEEDED, objects_1.EProposalState.DEFEATED, objects_1.EProposalState.EXPIRED, ].includes(Number(proposal === null || proposal === void 0 ? void 0 : proposal.state))); }, [JSON.stringify(proposal), isUserProposalOwner]); return (react_1.default.createElement(core_1.Box, null, react_1.default.createElement(components_1.GovernanceWidgetHeader, { label: "Proposal Detail", navigationLink: { label: "Proposal List", onClick: () => { onProposalListNavigate === null || onProposalListNavigate === void 0 ? void 0 : onProposalListNavigate(); }, }, rightContent: react_1.default.createElement(core_1.Box, { display: "flex", flexDirection: "row" }, canCancelProposal && (react_1.default.createElement(core_1.Box, { marginLeft: "10px" }, react_1.default.createElement(components_1.GovernanceButton, { onClick: () => { cancelProposal(); }, variant: "outlined" }, "Cancel Proposal"))), canQueueProposal && (react_1.default.createElement(core_1.Box, { marginLeft: "10px" }, react_1.default.createElement(components_1.GovernanceButton, { color: "primary", size: "medium", onClick: () => { queueProposal(); }, variant: "outlined" }, "Queue Proposal"))), canExecuteProposal && (react_1.default.createElement(core_1.Box, { marginLeft: "10px" }, react_1.default.createElement(components_1.GovernanceButton, { onClick: () => { executeProposal(); }, variant: "outlined" }, "Execute Proposal")))) }), (proposal === null || proposal === void 0 ? void 0 : proposal.state) != null && (react_1.default.createElement(core_1.Box, { className: classes.proposalStatus }, react_1.default.createElement(components_1.GovernanceStatusTag, { status: proposal === null || proposal === void 0 ? void 0 : proposal.state }))), react_1.default.createElement(core_1.Box, { display: "flex" }, react_1.default.createElement(core_1.Grid, { container: true, spacing: 3 }, react_1.default.createElement(core_1.Grid, { item: true, xs: 4 }, react_1.default.createElement(components_1.GovernanceVotingCard, { type: "for", value: proposalVotesFor, progressValue: parseFloat(forPercentage), onVoteClick: () => castVote(objects_1.EProposalVoteSupport.FOR), isVoted: supportStatus === objects_1.EProposalVoteSupport.FOR, showVoteButton: showVotingButtons, disableVoteButton: Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) !== objects_1.EProposalState.ACTIVE })), react_1.default.createElement(core_1.Grid, { item: true, xs: 4 }, react_1.default.createElement(components_1.GovernanceVotingCard, { type: "against", value: proposalVotesAgainst, progressValue: parseFloat(againstPercentage), onVoteClick: () => castVote(objects_1.EProposalVoteSupport.AGAINST), isVoted: supportStatus === objects_1.EProposalVoteSupport.AGAINST, showVoteButton: showVotingButtons, disableVoteButton: Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) !== objects_1.EProposalState.ACTIVE })), react_1.default.createElement(core_1.Grid, { item: true, xs: 4 }, react_1.default.createElement(components_1.GovernanceVotingCard, { type: "abstain", value: proposalVotesAbstain, progressValue: parseFloat(abstainPercentage), onVoteClick: () => castVote(objects_1.EProposalVoteSupport.ABSTAIN), isVoted: supportStatus === objects_1.EProposalVoteSupport.ABSTAIN, showVoteButton: showVotingButtons, disableVoteButton: Number(proposal === null || proposal === void 0 ? void 0 : proposal.state) !== objects_1.EProposalState.ACTIVE })))), react_1.default.createElement(core_1.Box, { className: classes.proposalDetails }, react_1.default.createElement(core_1.Typography, { variant: "h6", className: classes.proposalDetailsLabel }, "Details:"), react_1.default.createElement(core_1.Box, { className: classes.sectionWrapper }, react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionLabel }, "Proposer"), react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionValue }, proposal === null || proposal === void 0 ? void 0 : proposal.originator)), react_1.default.createElement(core_1.Box, { className: classes.sectionWrapper }, react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionLabel }, "Current Block"), react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionValue }, blockNumber)), react_1.default.createElement(core_1.Box, { className: classes.sectionWrapper }, react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionLabel }, "Start Block"), react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionValue }, proposal === null || proposal === void 0 ? void 0 : proposal.startBlock)), react_1.default.createElement(core_1.Box, { className: classes.sectionWrapper }, react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionLabel }, "End Block"), react_1.default.createElement(core_1.Typography, { variant: "body1", className: classes.sectionValue }, proposal === null || proposal === void 0 ? void 0 : proposal.endBlock)), react_1.default.createElement(components_1.GovernanceMarkdown, { source: showRawDescription ? proposal === null || proposal === void 0 ? void 0 : proposal.description : proposalDescriptionFromIPFS })))); }; exports.default = ProposalDetailWidget; //# sourceMappingURL=ProposalDetailWidget.js.map