(Feature) Add support of VotingToManageEmissionFunds.cancelNewBallot
This commit is contained in:
parent
b3f262674a
commit
d43f03036d
|
@ -19,6 +19,7 @@ const zeroTimeTo = '00:00'
|
|||
@inject('commonStore', 'contractsStore', 'routing', 'ballotsStore')
|
||||
@observer
|
||||
export class BallotCard extends React.Component {
|
||||
@observable cancelDeadline = 0
|
||||
@observable startTime
|
||||
@observable endTime
|
||||
@observable timeTo = {}
|
||||
|
@ -34,6 +35,11 @@ export class BallotCard extends React.Component {
|
|||
displayValue: zeroTimeTo,
|
||||
title: 'To close'
|
||||
}
|
||||
@observable
|
||||
timeToCancel = {
|
||||
val: 0,
|
||||
displayValue: zeroTimeTo
|
||||
}
|
||||
@observable creatorMiningKey
|
||||
@observable creator
|
||||
@observable progress
|
||||
|
@ -42,34 +48,50 @@ export class BallotCard extends React.Component {
|
|||
@observable freezeVotes
|
||||
@observable sendVotes
|
||||
@observable isFinalized
|
||||
@observable isCanceled = false
|
||||
@observable canBeFinalized
|
||||
@observable hasAlreadyVoted
|
||||
@observable memo
|
||||
|
||||
@computed
|
||||
get finalizeButtonDisplayName() {
|
||||
const displayName = this.isFinalized ? 'Finalized' : 'Finalize ballot'
|
||||
return displayName
|
||||
}
|
||||
|
||||
@computed
|
||||
get finalizeButtonClass() {
|
||||
const cls = this.isFinalized
|
||||
? 'btn btn-primary btn-finalize disabled text-capitalize'
|
||||
: 'btn btn-primary btn-finalize text-capitalize'
|
||||
return cls
|
||||
}
|
||||
|
||||
@computed
|
||||
get finalizeDescription() {
|
||||
get cancelOrFinalizeButtonDisplayName() {
|
||||
if (this.isFinalized) {
|
||||
return 'Finalized'
|
||||
} else if (this.isCanceled) {
|
||||
return 'Canceled'
|
||||
} else if (this.timeToCancel.val > 0) {
|
||||
return 'Cancel ballot'
|
||||
} else {
|
||||
return 'Finalize ballot'
|
||||
}
|
||||
}
|
||||
|
||||
@computed
|
||||
get cancelOrFinalizeButtonClass() {
|
||||
if (this.isFinalized) {
|
||||
return 'btn btn-primary btn-finalize disabled text-capitalize'
|
||||
} else if (this.isCanceled) {
|
||||
return 'btn btn-primary disabled text-capitalize'
|
||||
} else if (this.timeToCancel.val > 0) {
|
||||
return 'btn btn-danger text-capitalize'
|
||||
} else {
|
||||
return 'btn btn-primary btn-finalize text-capitalize'
|
||||
}
|
||||
}
|
||||
|
||||
@computed
|
||||
get cancelOrFinalizeDescription() {
|
||||
if (this.isFinalized || this.isCanceled) {
|
||||
return ''
|
||||
} else if (this.timeToCancel.val > 0) {
|
||||
return `You can cancel this ballot within ${this.timeToCancel.displayValue}`
|
||||
} else {
|
||||
let description = 'Finalization is available after ballot time is finished'
|
||||
if (this.canBeFinalized !== null) {
|
||||
description += ' or all validators are voted'
|
||||
}
|
||||
return description
|
||||
}
|
||||
let description = 'Finalization is available after ballot time is finished'
|
||||
if (this.canBeFinalized !== null) {
|
||||
description += ' or all validators are voted'
|
||||
}
|
||||
return description
|
||||
}
|
||||
|
||||
@computed
|
||||
|
@ -165,10 +187,20 @@ export class BallotCard extends React.Component {
|
|||
@action('Calculate time to start/finish')
|
||||
calcTimeTo = () => {
|
||||
const _now = moment()
|
||||
const cancel = moment.utc(this.cancelDeadline, USDateTimeFormat)
|
||||
const start = moment.utc(this.startTime, USDateTimeFormat)
|
||||
const finish = moment.utc(this.endTime, USDateTimeFormat)
|
||||
let msStart = start.diff(_now)
|
||||
let msFinish = finish.diff(_now)
|
||||
const msCancel = cancel.diff(_now)
|
||||
const msStart = start.diff(_now)
|
||||
const msFinish = finish.diff(_now)
|
||||
|
||||
if (msCancel > 0) {
|
||||
this.timeToCancel.val = msCancel
|
||||
this.timeToCancel.displayValue = this.formatMs(msCancel, ':mm:ss')
|
||||
} else {
|
||||
this.timeToCancel.val = 0
|
||||
this.timeToCancel.displayValue = zeroTimeTo
|
||||
}
|
||||
|
||||
if (msStart > 0) {
|
||||
this.timeToStart.val = msStart + 5000
|
||||
|
@ -275,6 +307,9 @@ export class BallotCard extends React.Component {
|
|||
this.progress = Number(ballotInfo.progress)
|
||||
}
|
||||
this.isFinalized = Boolean(ballotInfo.isFinalized)
|
||||
if (ballotInfo.hasOwnProperty('isCanceled')) {
|
||||
this.isCanceled = Boolean(ballotInfo.isCanceled)
|
||||
}
|
||||
if (ballotInfo.hasOwnProperty('canBeFinalizedNow')) {
|
||||
this.canBeFinalized = Boolean(ballotInfo.canBeFinalizedNow)
|
||||
} else {
|
||||
|
@ -293,6 +328,7 @@ export class BallotCard extends React.Component {
|
|||
ballotsStore.ballotCards[pos].props.votingState.progress = this.progress
|
||||
}
|
||||
ballotsStore.ballotCards[pos].props.votingState.isFinalized = this.isFinalized
|
||||
ballotsStore.ballotCards[pos].props.votingState.isCanceled = this.isCanceled
|
||||
ballotsStore.ballotCards[pos].props.votingState.canBeFinalized = this.canBeFinalized
|
||||
ballotsStore.ballotCards[pos].props.votingState.hasAlreadyVoted = this.hasAlreadyVoted
|
||||
|
||||
|
@ -304,11 +340,69 @@ export class BallotCard extends React.Component {
|
|||
)
|
||||
}
|
||||
|
||||
finalize = async e => {
|
||||
if (this.isFinalized) {
|
||||
cancelOrFinalize = e => {
|
||||
if (this.isFinalized || this.isCanceled) {
|
||||
return
|
||||
}
|
||||
if (this.timeToCancel.val > 0) {
|
||||
this.cancel(e)
|
||||
} else {
|
||||
this.finalize(e)
|
||||
}
|
||||
}
|
||||
|
||||
cancel = async e => {
|
||||
console.log('cancel function called')
|
||||
const { votingState, contractsStore, commonStore, ballotsStore, votingType, id, pos } = this.props
|
||||
const { push } = this.props.routing
|
||||
const contract = this.getContract(contractsStore, votingType)
|
||||
let canCancel = true
|
||||
|
||||
if (!this.timeToCancel.val) {
|
||||
canCancel = false
|
||||
}
|
||||
if (votingState.creator.toLowerCase() !== contractsStore.miningKey.toLowerCase()) {
|
||||
canCancel = false
|
||||
}
|
||||
commonStore.showLoading()
|
||||
if (!votingState.creationTime) {
|
||||
canCancel = false
|
||||
} else {
|
||||
const currentTime = Number(await contract.getTime())
|
||||
if (currentTime - votingState.creationTime > contractsStore.ballotCancelingThreshold) {
|
||||
canCancel = false
|
||||
}
|
||||
}
|
||||
|
||||
if (!canCancel) {
|
||||
commonStore.hideLoading()
|
||||
swal('Warning!', messages.INVALID_CANCEL_MSG, 'warning')
|
||||
return
|
||||
}
|
||||
|
||||
sendTransactionByVotingKey(
|
||||
this.props,
|
||||
contract.address,
|
||||
contract.cancelBallot(id),
|
||||
async tx => {
|
||||
this.isFinalized = false
|
||||
this.isCanceled = true
|
||||
ballotsStore.ballotCards[pos].props.votingState.isFinalized = this.isFinalized
|
||||
ballotsStore.ballotCards[pos].props.votingState.isCanceled = this.isCanceled
|
||||
if (this.canBeFinalized !== null) {
|
||||
this.canBeFinalized = false
|
||||
ballotsStore.ballotCards[pos].props.votingState.canBeFinalized = this.canBeFinalized
|
||||
}
|
||||
swal('Congratulations!', messages.CANCELED_SUCCESS_MSG, 'success').then(result => {
|
||||
push(`${commonStore.rootPath}`)
|
||||
})
|
||||
},
|
||||
messages.CANCEL_BALLOT_FAILED_TX
|
||||
)
|
||||
}
|
||||
|
||||
finalize = async e => {
|
||||
console.log('finalize function called')
|
||||
if (this.timeToStart.val > 0) {
|
||||
swal('Warning!', messages.ballotIsNotActiveMsg(this.timeTo.displayValue), 'warning')
|
||||
return
|
||||
|
@ -349,7 +443,9 @@ export class BallotCard extends React.Component {
|
|||
})
|
||||
if (events.length > 0) {
|
||||
this.isFinalized = true
|
||||
this.isCanceled = false
|
||||
ballotsStore.ballotCards[pos].props.votingState.isFinalized = this.isFinalized
|
||||
ballotsStore.ballotCards[pos].props.votingState.isCanceled = this.isCanceled
|
||||
if (this.canBeFinalized !== null) {
|
||||
this.canBeFinalized = false
|
||||
ballotsStore.ballotCards[pos].props.votingState.canBeFinalized = this.canBeFinalized
|
||||
|
@ -419,8 +515,17 @@ export class BallotCard extends React.Component {
|
|||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
const { votingState } = this.props
|
||||
const { votingState, contractsStore } = this.props
|
||||
// getTimes
|
||||
if (
|
||||
votingState.hasOwnProperty('creationTime') &&
|
||||
contractsStore.ballotCancelingThreshold > 0 &&
|
||||
votingState.creator === contractsStore.miningKey
|
||||
) {
|
||||
this.cancelDeadline = moment
|
||||
.utc((votingState.creationTime + contractsStore.ballotCancelingThreshold) * 1000)
|
||||
.format(USDateTimeFormat)
|
||||
}
|
||||
this.startTime = moment.utc(votingState.startTime * 1000).format(USDateTimeFormat)
|
||||
this.endTime = moment.utc(votingState.endTime * 1000).format(USDateTimeFormat)
|
||||
this.calcTimeTo()
|
||||
|
@ -442,6 +547,10 @@ export class BallotCard extends React.Component {
|
|||
}
|
||||
// getIsFinalized
|
||||
this.isFinalized = votingState.isFinalized
|
||||
// getIsCanceled
|
||||
if (votingState.hasOwnProperty('isCanceled')) {
|
||||
this.isCanceled = votingState.isCanceled
|
||||
}
|
||||
// canBeFinalizedNow
|
||||
if (votingState.hasOwnProperty('canBeFinalizedNow')) {
|
||||
this.canBeFinalized = votingState.canBeFinalizedNow
|
||||
|
@ -478,9 +587,12 @@ export class BallotCard extends React.Component {
|
|||
showCard = () => {
|
||||
let { commonStore } = this.props
|
||||
let checkToFinalizeFilter = commonStore.isToFinalizeFilter
|
||||
? !this.isFinalized && (this.timeToFinish.val === 0 || this.canBeFinalized) && this.timeToStart.val === 0
|
||||
? !this.isFinalized &&
|
||||
!this.isCanceled &&
|
||||
(this.timeToFinish.val === 0 || this.canBeFinalized) &&
|
||||
this.timeToStart.val === 0
|
||||
: true
|
||||
let show = commonStore.isActiveFilter ? !this.isFinalized : checkToFinalizeFilter
|
||||
let show = commonStore.isActiveFilter ? !this.isFinalized && !this.isCanceled : checkToFinalizeFilter
|
||||
return show
|
||||
}
|
||||
|
||||
|
@ -664,10 +776,10 @@ export class BallotCard extends React.Component {
|
|||
</div>
|
||||
<div className="ballots-footer">
|
||||
<div className="ballots-footer-left">
|
||||
<button type="button" onClick={e => this.finalize(e)} className={this.finalizeButtonClass}>
|
||||
{this.finalizeButtonDisplayName}
|
||||
<button type="button" onClick={e => this.cancelOrFinalize(e)} className={this.cancelOrFinalizeButtonClass}>
|
||||
{this.cancelOrFinalizeButtonDisplayName}
|
||||
</button>
|
||||
<p>{this.finalizeDescription}</p>
|
||||
<p>{this.cancelOrFinalizeDescription}</p>
|
||||
</div>
|
||||
{showHasAlreadyVotedLabel}
|
||||
<div className="ballots-i--vote-label">
|
||||
|
|
|
@ -35,16 +35,14 @@ export class BallotEmissionFundsMetadata extends React.Component {
|
|||
this.endDateTime = '...loading date...'
|
||||
|
||||
let emissionReleaseTime = Number(await votingToManageEmissionFunds.emissionReleaseTime())
|
||||
let emissionReleaseThreshold = 0
|
||||
const emissionReleaseThreshold = Number(await votingToManageEmissionFunds.emissionReleaseThreshold())
|
||||
const currentTime = Number(await votingToManageEmissionFunds.getTime())
|
||||
const distributionThreshold = Number(await votingToManageEmissionFunds.distributionThreshold())
|
||||
if (currentTime > emissionReleaseTime) {
|
||||
emissionReleaseThreshold = Number(await votingToManageEmissionFunds.emissionReleaseThreshold())
|
||||
const diff = Math.floor((currentTime - emissionReleaseTime) / emissionReleaseThreshold)
|
||||
if (diff > 0) {
|
||||
emissionReleaseTime += emissionReleaseThreshold * diff
|
||||
}
|
||||
}
|
||||
emissionReleaseTime = votingToManageEmissionFunds.refreshEmissionReleaseTime(
|
||||
emissionReleaseTime,
|
||||
emissionReleaseThreshold,
|
||||
currentTime
|
||||
)
|
||||
|
||||
const releasePlusDistribution = emissionReleaseTime + distributionThreshold
|
||||
|
||||
|
@ -52,9 +50,6 @@ export class BallotEmissionFundsMetadata extends React.Component {
|
|||
this.beginDateTime = moment.unix(emissionReleaseTime).format(dateTimeFormat)
|
||||
this.endDateTime = moment.unix(releasePlusDistribution).format(dateTimeFormat)
|
||||
} else {
|
||||
if (emissionReleaseThreshold === 0) {
|
||||
emissionReleaseThreshold = Number(await votingToManageEmissionFunds.emissionReleaseThreshold())
|
||||
}
|
||||
const futureEmissionReleaseTime = emissionReleaseTime + emissionReleaseThreshold
|
||||
this.beginDateTime = moment.unix(futureEmissionReleaseTime).format(dateTimeFormat)
|
||||
this.endDateTime = moment.unix(futureEmissionReleaseTime + distributionThreshold).format(dateTimeFormat)
|
||||
|
|
|
@ -280,15 +280,15 @@ export class NewBallot extends React.Component {
|
|||
|
||||
if (ballotStore.ballotType === ballotStore.BallotType.emissionFunds) {
|
||||
const votingContract = contractsStore.votingToManageEmissionFunds
|
||||
|
||||
let emissionReleaseTime = Number(await votingContract.emissionReleaseTime())
|
||||
const emissionReleaseThreshold = Number(await votingContract.emissionReleaseThreshold())
|
||||
const currentTime = Number(await votingContract.getTime())
|
||||
if (currentTime > emissionReleaseTime) {
|
||||
const emissionReleaseThreshold = Number(await votingContract.emissionReleaseThreshold())
|
||||
const diff = Math.floor((currentTime - emissionReleaseTime) / emissionReleaseThreshold)
|
||||
if (diff > 0) {
|
||||
emissionReleaseTime += emissionReleaseThreshold * diff
|
||||
}
|
||||
}
|
||||
emissionReleaseTime = votingContract.refreshEmissionReleaseTime(
|
||||
emissionReleaseTime,
|
||||
emissionReleaseThreshold,
|
||||
currentTime
|
||||
)
|
||||
|
||||
if (currentTime < emissionReleaseTime) {
|
||||
commonStore.hideLoading()
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class VotingToManageEmissionFunds {
|
|||
}
|
||||
|
||||
// setters
|
||||
cancelNewBallot() {
|
||||
cancelBallot(_id) {
|
||||
return this.instance.methods.cancelNewBallot().encodeABI()
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,17 @@ export default class VotingToManageEmissionFunds {
|
|||
return this.instance.methods.emissionReleaseTime().call()
|
||||
}
|
||||
|
||||
refreshEmissionReleaseTime(emissionReleaseTime, emissionReleaseThreshold, currentTime) {
|
||||
let emissionReleaseTimeRefreshed = emissionReleaseTime
|
||||
if (currentTime > emissionReleaseTime) {
|
||||
const diff = Math.floor((currentTime - emissionReleaseTime) / emissionReleaseThreshold)
|
||||
if (diff > 0) {
|
||||
emissionReleaseTimeRefreshed += emissionReleaseThreshold * diff
|
||||
}
|
||||
}
|
||||
return emissionReleaseTimeRefreshed
|
||||
}
|
||||
|
||||
getBallotInfo(_id, _votingKey) {
|
||||
return this.instance.methods.getBallotInfo(_id).call()
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ class AppMainRouter extends Component {
|
|||
|
||||
contractsStore.getKeysBallotThreshold()
|
||||
contractsStore.getProxyBallotThreshold()
|
||||
contractsStore.getBallotCancelingThreshold()
|
||||
contractsStore.getBallotsLimits()
|
||||
console.log('votingKey', contractsStore.votingKey)
|
||||
console.log('miningKey', contractsStore.miningKey)
|
||||
|
|
|
@ -5,9 +5,11 @@ messages.invalidVotingKeyMsg = key => {
|
|||
messages.VOTED_SUCCESS_MSG = 'You successfully voted'
|
||||
messages.BALLOT_CREATED_SUCCESS_MSG = 'You successfully created a new ballot'
|
||||
messages.FINALIZED_SUCCESS_MSG = 'You successfully finalized'
|
||||
messages.CANCELED_SUCCESS_MSG = 'You successfully canceled'
|
||||
messages.ALREADY_FINALIZED_MSG = 'This ballot is already finalized'
|
||||
messages.INVALID_VOTE_MSG = "You can't vote on this ballot"
|
||||
messages.INVALID_FINALIZE_MSG = "You can't finalize this ballot"
|
||||
messages.INVALID_CANCEL_MSG = "You can't cancel this ballot"
|
||||
messages.AFFECTED_KEY_IS_NOT_ADDRESS_MSG = "Ballot affectedKey isn't address"
|
||||
messages.MINING_KEY_IS_NOT_ADDRESS_MSG = "Ballot miningKey isn't address"
|
||||
messages.PROPOSED_ADDRESS_IS_NOT_ADDRESS_MSG = "Proposed address isn't address"
|
||||
|
@ -40,6 +42,8 @@ messages.VOTE_FAILED_TX = `Your transaction was failed. Please make sure you hav
|
|||
Make sure you don't have Transaction Error. Exception thrown in contract code message in Metamask before you sign it.`
|
||||
messages.FINALIZE_FAILED_TX = `Your transaction was failed. Make sure you don't have Transaction Error.
|
||||
Exception thrown in contract code message in Metamask before you sign it.`
|
||||
messages.CANCEL_BALLOT_FAILED_TX = `Your transaction was failed. Make sure you don't have Transaction Error.
|
||||
Exception thrown in contract code message in Metamask before you sign it.`
|
||||
messages.DESCRIPTION_IS_EMPTY = 'Description cannot be empty'
|
||||
messages.wrongRepo = repo => {
|
||||
return `There is no contracts.json in configured repo ${repo}`
|
||||
|
|
|
@ -40,6 +40,8 @@ class ContractsStore {
|
|||
@observable keysBallotThreshold
|
||||
@observable minThresholdBallotThreshold
|
||||
@observable proxyBallotThreshold
|
||||
@observable emissionFundsBallotThreshold
|
||||
@observable ballotCancelingThreshold
|
||||
@observable validatorLimits
|
||||
@observable validatorsMetadata
|
||||
@observable netId
|
||||
|
@ -69,6 +71,13 @@ class ContractsStore {
|
|||
this.emissionFundsBallotThreshold = this.proxyBallotThreshold
|
||||
}
|
||||
|
||||
@action('Get ballot canceling threshold')
|
||||
getBallotCancelingThreshold = async () => {
|
||||
this.ballotCancelingThreshold = this.votingToManageEmissionFunds
|
||||
? Number(await this.votingToManageEmissionFunds.ballotCancelingThreshold())
|
||||
: 0
|
||||
}
|
||||
|
||||
@action('Set web3Instance')
|
||||
setWeb3Instance = web3Config => {
|
||||
this.web3Instance = web3Config.web3Instance
|
||||
|
|
Loading…
Reference in New Issue