2018-09-27 13:39:37 -07:00
|
|
|
import {
|
|
|
|
Contributor,
|
2019-02-11 14:51:31 -08:00
|
|
|
MILESTONE_STAGE,
|
2018-12-21 10:47:50 -08:00
|
|
|
Proposal,
|
2018-10-03 12:04:08 -07:00
|
|
|
ProposalMilestone,
|
2019-01-09 10:23:08 -08:00
|
|
|
STATUS,
|
2019-02-09 19:03:19 -08:00
|
|
|
PROPOSAL_ARBITER_STATUS,
|
2018-10-04 21:27:02 -07:00
|
|
|
} from 'types';
|
2019-11-13 15:23:36 -08:00
|
|
|
import { PROPOSAL_STAGE } from 'api/constants';
|
2018-09-25 12:02:29 -07:00
|
|
|
import BN from 'bn.js';
|
2019-02-05 13:25:58 -08:00
|
|
|
import moment from 'moment';
|
2018-09-25 12:02:29 -07:00
|
|
|
|
2018-12-27 11:08:14 -08:00
|
|
|
const oneZec = new BN('100000000');
|
2018-09-25 12:02:29 -07:00
|
|
|
|
|
|
|
export function getGovernanceMilestonesProps({
|
|
|
|
isContributor = true,
|
|
|
|
}: {
|
|
|
|
isContributor?: boolean;
|
|
|
|
}) {
|
|
|
|
return {
|
|
|
|
accounts: [
|
|
|
|
isContributor
|
|
|
|
? '0xAAA91bde2303f2f43325b2108d26f1eaba1e32b'
|
|
|
|
: '0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
|
|
|
|
],
|
|
|
|
isMilestoneActionPending: false,
|
|
|
|
milestoneActionError: '',
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-12-27 11:08:14 -08:00
|
|
|
export function generateProposal({
|
2018-09-25 12:02:29 -07:00
|
|
|
amount = 10,
|
|
|
|
funded = 5,
|
|
|
|
created = Date.now(),
|
|
|
|
milestoneOverrides = [],
|
|
|
|
contributorOverrides = [],
|
2018-10-03 12:04:08 -07:00
|
|
|
milestoneCount = 3,
|
2018-09-25 12:02:29 -07:00
|
|
|
}: {
|
|
|
|
amount?: number;
|
|
|
|
funded?: number;
|
|
|
|
created?: number;
|
|
|
|
deadline?: number;
|
2019-02-11 13:22:40 -08:00
|
|
|
milestoneOverrides?: Array<Partial<ProposalMilestone>>;
|
2018-09-25 12:02:29 -07:00
|
|
|
contributorOverrides?: Array<Partial<Contributor>>;
|
2018-10-03 12:04:08 -07:00
|
|
|
milestoneCount?: number;
|
2018-09-25 12:02:29 -07:00
|
|
|
}) {
|
2018-12-27 11:08:14 -08:00
|
|
|
const amountBn = oneZec.mul(new BN(amount));
|
|
|
|
const fundedBn = oneZec.mul(new BN(funded));
|
|
|
|
const percentFunded = amount / funded;
|
2018-09-25 12:02:29 -07:00
|
|
|
|
2018-10-03 12:04:08 -07:00
|
|
|
let contributors = [
|
2018-09-25 12:02:29 -07:00
|
|
|
{
|
|
|
|
address: '0xAAA91bde2303f2f43325b2108d26f1eaba1e32b',
|
|
|
|
contributionAmount: new BN(0),
|
|
|
|
refundVote: false,
|
|
|
|
refunded: false,
|
|
|
|
proportionalContribution: '',
|
|
|
|
milestoneNoVotes: [false],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
address: '0xBBB491bde2303f2f43325b2108d26f1eaba1e32b',
|
|
|
|
contributionAmount: new BN(0),
|
|
|
|
refundVote: false,
|
|
|
|
refunded: false,
|
|
|
|
proportionalContribution: '',
|
|
|
|
milestoneNoVotes: [false],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
address: '0xCCC491bde2303f2f43325b2108d26f1eaba1e32b',
|
|
|
|
contributionAmount: new BN(0),
|
|
|
|
refundVote: false,
|
|
|
|
refunded: false,
|
|
|
|
proportionalContribution: '',
|
|
|
|
milestoneNoVotes: [false],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
address: '0xDDD491bde2303f2f43325b2108d26f1eaba1e32b',
|
|
|
|
contributionAmount: new BN(0),
|
|
|
|
refundVote: false,
|
|
|
|
refunded: false,
|
|
|
|
proportionalContribution: '',
|
|
|
|
milestoneNoVotes: [false],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const eachContributorAmount = fundedBn.div(new BN(contributors.length));
|
|
|
|
contributors.forEach(c => (c.contributionAmount = eachContributorAmount));
|
|
|
|
contributorOverrides.forEach((co, idx) => {
|
|
|
|
Object.assign(contributors[idx], co);
|
|
|
|
});
|
|
|
|
|
2018-10-03 12:04:08 -07:00
|
|
|
if (funded === 0) {
|
|
|
|
contributors = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const genMilestoneTitle = () => {
|
|
|
|
const ts = ['40chr ', 'Really ', 'Really ', 'Long ', 'Milestone Title'];
|
|
|
|
const rand = Math.floor(Math.random() * Math.floor(ts.length));
|
|
|
|
return ts.slice(rand).join('');
|
|
|
|
};
|
|
|
|
|
2019-01-09 10:23:08 -08:00
|
|
|
const genMilestone = (
|
|
|
|
overrides: Partial<ProposalMilestone> = {},
|
|
|
|
): ProposalMilestone => {
|
2018-10-03 12:04:08 -07:00
|
|
|
if (overrides.index) {
|
2019-02-05 13:25:58 -08:00
|
|
|
overrides.dateEstimated = moment()
|
|
|
|
.add(overrides.index, 'month')
|
|
|
|
.unix();
|
2018-10-03 12:04:08 -07:00
|
|
|
}
|
|
|
|
|
2018-12-27 11:08:14 -08:00
|
|
|
const defaults: ProposalMilestone = {
|
2019-02-11 21:42:21 -08:00
|
|
|
id: 0,
|
2018-12-27 11:08:14 -08:00
|
|
|
title: 'Milestone A',
|
|
|
|
content: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
|
|
|
tempor incididunt ut labore et dolore magna aliqua.`,
|
2019-02-05 13:25:58 -08:00
|
|
|
dateEstimated: moment().unix(),
|
2018-12-27 11:08:14 -08:00
|
|
|
immediatePayout: true,
|
|
|
|
index: 0,
|
2019-02-11 13:22:40 -08:00
|
|
|
stage: MILESTONE_STAGE.IDLE,
|
2018-12-27 11:08:14 -08:00
|
|
|
amount: amountBn,
|
|
|
|
payoutPercent: '33',
|
|
|
|
};
|
|
|
|
return { ...defaults, ...overrides };
|
2018-10-03 12:04:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
const milestones = [...Array(milestoneCount).keys()].map(i => {
|
|
|
|
const overrides = {
|
2019-02-11 21:42:21 -08:00
|
|
|
id: i,
|
2018-10-03 12:04:08 -07:00
|
|
|
index: i,
|
|
|
|
title: genMilestoneTitle(),
|
|
|
|
immediatePayout: i === 0,
|
|
|
|
payoutRequestVoteDeadline: i !== 0 ? Date.now() + 3600000 : 0,
|
|
|
|
payoutPercent: '' + (1 / milestoneCount) * 100,
|
|
|
|
};
|
|
|
|
return genMilestone(overrides);
|
|
|
|
});
|
2018-09-25 12:02:29 -07:00
|
|
|
|
2018-10-03 12:04:08 -07:00
|
|
|
const eachMilestoneAmount = amountBn.div(new BN(milestones.length));
|
2018-09-25 12:02:29 -07:00
|
|
|
milestones.forEach(ms => (ms.amount = eachMilestoneAmount));
|
|
|
|
milestoneOverrides.forEach((mso, idx) => {
|
|
|
|
Object.assign(milestones[idx], mso);
|
|
|
|
});
|
|
|
|
|
2018-12-21 10:47:50 -08:00
|
|
|
const proposal: Proposal = {
|
2018-11-07 09:33:19 -08:00
|
|
|
proposalId: 12345,
|
2019-01-09 10:23:08 -08:00
|
|
|
status: STATUS.DRAFT,
|
2018-11-07 09:33:19 -08:00
|
|
|
proposalUrlId: '12345-crowdfund-title',
|
|
|
|
proposalAddress: '0x033fDc6C01DC2385118C7bAAB88093e22B8F0710',
|
2018-12-27 11:08:14 -08:00
|
|
|
payoutAddress: 'z123',
|
2018-09-25 12:02:29 -07:00
|
|
|
dateCreated: created / 1000,
|
2019-01-09 10:23:08 -08:00
|
|
|
datePublished: created / 1000,
|
2019-02-05 13:06:45 -08:00
|
|
|
dateApproved: created / 1000,
|
2018-12-27 11:08:14 -08:00
|
|
|
deadlineDuration: 86400 * 60,
|
|
|
|
target: amountBn,
|
|
|
|
funded: fundedBn,
|
|
|
|
percentFunded,
|
2019-01-29 15:50:27 -08:00
|
|
|
contributionMatching: 0,
|
2019-03-06 12:25:58 -08:00
|
|
|
contributionBounty: new BN(0),
|
2018-09-25 12:02:29 -07:00
|
|
|
title: 'Crowdfund Title',
|
2018-11-16 15:05:17 -08:00
|
|
|
brief: 'A cool test crowdfund',
|
2018-11-14 09:59:48 -08:00
|
|
|
content: 'body',
|
2019-02-13 08:54:46 -08:00
|
|
|
stage: PROPOSAL_STAGE.WIP,
|
2019-01-31 14:56:16 -08:00
|
|
|
isStaked: true,
|
2019-10-23 14:34:10 -07:00
|
|
|
authedFollows: false,
|
|
|
|
followersCount: 0,
|
2019-10-24 10:32:00 -07:00
|
|
|
authedLiked: false,
|
|
|
|
likesCount: 0,
|
ZF Grants 2.1 (#496)
* fix ccr pagination defaults
* add ccr admin tests
* add ccr user tests
* checkpoint
* fix tslint
* request changes discussion flow mvp
* admin - add discussion status
* backend - add live drafts
* admin - add live drafts
* frontend - add live drafts
* frontend - add edit discussion proposal
* fix tsc
* include DISCUSSION status in propsal listview
* do not make live draft on admin request changes
* hide live drafts from user proposal draft list
* fix backend tests
* add admin tests
* add user tests
* fix: liking, viewing discussion proposals, admin menu
* admin - update hints for live drafts
* fe - add better messaging when updating a proposal
* be - fix like test
* remove TODO comments
* add new email types
* fix storybook
* add revision tab story
* backend - implement proposal revisions
* frontend - implement proposal revisions
* update revision tab story
* fix lint
* remove set detection
* email proposal followers on revision
* restrict banner to team members only
* misc bug fixes
* update, add backend tests
* add milestone title change to revision history story
* fix milestones display in preview
* allow archived proposals to be queried
* implement archived proposal page
* fix tsc
* implement archived proposal get route
* move styling into less
* remove proposal archive parent id
* handle archived proposal status
* cleanup
* remove contributions, switch to USD, implement quarters
* use Qs to preserve formatting
* handle edit only kyc
* prevent ARCHIVED proposals from being sent to admin
* display latest revision first
* admin - proposal & ccr reject permanently
* backend - proposal & ccr reject permanently
* frontend - proposal & ccr reject permanently
* fix tsc
* use $ in milestone payout email
* introduce custom filters to proposal listview
* hide archive link on first revision
* upgrade packages
* add bech32 implementation
* add z address validation with tests
* fix tslint
* use local address validation
* fix tests, remove blockchain mock gets
* add additional bad addresses
* update briefs to include page break message
* remove contributions routes, menu entry
* disable countribution count admin stats
* remove matching and pretty print in finance
* fix tslint
* separate out rejected permanently proposals
* make removing proposals generic
* allow linked tabs to be ignored
* remove rejected permanently, bugfix
* update preview link to point to rejected tab
* implement rejected permanently tab, add tab message
* refactor variable
* fix tslint
* fix tslint
* send ccr reject permanently email on rejection
* fix preview message
* wire up proposal arbiter and rejected emails
* disable tip jar in proposal and profile
* sync ccr/proposal drafts on create form init
* check invites on submit modal open
* update team invite language
* update team text when edit
* fix ccr rejected permanently tag
* text changes, email preview fix
* display changes requested tag when in discussion with changes requested
* enable social share on open for discussion proposals, update language
* place sort below filter
* derive filter from query string
* use better filter names in query params
* fix tslint
* create snapshot of original proposal on first revision
* clear invites between edits, account for additional changes not tracked in revisions
* update tests
* fix test
* remove print
* SameSite Fixes (#150)
* QA Fixes 2 (#151)
* set filters as query strings on change
* remove rejected permanently tags
* add dollar sign in financials legend
* fix tsc
* Copy Touchups (#152)
* Email Fixes (#155)
* fix ZEC in milestone payout emails
* fix links in rejected permanently CCR/proposal emails
* Poll for Team and Invite Changes in Create Flow (#153)
* poll for team and invite changes in create flow
* fix tslint
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* pretty print payouts by quarter (#156)
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* Remove Blockchain Module (#154)
* remove blockchain route from backend, remove calls to node
* revert blockchain_get removal
* Add Tags to Proposal Cards (#157)
* add tag to proposals and dynamically set v1 card height
* listen on window resize
* make card height props optional
* set tag in bottom right, remove dynamic card resize, add dynamic tag resize
* cleanup
* cleanup
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* Improve Frontend Address Validation (#158)
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* Remove blockchain module (#162)
* remove blockchain route from backend, remove calls to node
* revert blockchain_get removal
* Remove Blockchain App (#160)
* remove blockchain app
* remove blockchain app from travis
Co-authored-by: Danny Skubak <skubakdj@gmail.com>
* Proposal Edit Fixes (#161)
* fe - display error if edit creation fails
* be - restrict live draft publish
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* Restrict Arbiter Assignment (#159)
Co-authored-by: Daniel Ternyak <dternyak@gmail.com>
* Email Copy updates
* Remove Admin Financials Card
* Hookup 'proposal_approved_without_funding' to admin email example
* bump various package versions
* Update yarn.lock files
* Attach 'proposal_approved_without_funding' to backend example email
* bump package versions
Co-authored-by: Danny Skubak <skubakdj@gmail.com>
2020-04-07 19:56:32 -07:00
|
|
|
changesRequestedDiscussion: null,
|
|
|
|
changesRequestedDiscussionReason: null,
|
|
|
|
liveDraftId: null,
|
2019-11-20 13:37:26 -08:00
|
|
|
tipJarAddress: null,
|
|
|
|
tipJarViewKey: null,
|
2021-02-01 23:42:07 -08:00
|
|
|
fundedByZomg: false,
|
2019-02-09 19:03:19 -08:00
|
|
|
arbiter: {
|
|
|
|
status: PROPOSAL_ARBITER_STATUS.ACCEPTED,
|
|
|
|
user: {
|
|
|
|
userid: 999,
|
|
|
|
displayName: 'Test Arbiter',
|
|
|
|
title: '',
|
|
|
|
emailAddress: 'test@arbiter.com',
|
|
|
|
avatar: null,
|
|
|
|
socialMedias: [],
|
|
|
|
},
|
|
|
|
},
|
2019-10-16 20:43:20 -07:00
|
|
|
acceptedWithFunding: null,
|
|
|
|
isVersionTwo: false,
|
2018-09-25 12:02:29 -07:00
|
|
|
team: [
|
|
|
|
{
|
2018-11-16 15:05:17 -08:00
|
|
|
userid: 123,
|
|
|
|
displayName: 'Test Proposer',
|
2018-09-25 12:02:29 -07:00
|
|
|
title: '',
|
2018-09-27 13:39:37 -07:00
|
|
|
emailAddress: '',
|
2018-11-16 15:05:17 -08:00
|
|
|
avatar: null,
|
|
|
|
socialMedias: [],
|
2018-09-25 12:02:29 -07:00
|
|
|
},
|
|
|
|
{
|
2018-11-16 15:05:17 -08:00
|
|
|
userid: 456,
|
|
|
|
displayName: 'Test Proposer',
|
2018-09-25 12:02:29 -07:00
|
|
|
title: '',
|
2018-09-27 13:39:37 -07:00
|
|
|
emailAddress: '',
|
2018-11-16 15:05:17 -08:00
|
|
|
avatar: null,
|
|
|
|
socialMedias: [],
|
2018-09-25 12:02:29 -07:00
|
|
|
},
|
|
|
|
{
|
2018-11-16 15:05:17 -08:00
|
|
|
userid: 789,
|
|
|
|
displayName: 'Test Proposer',
|
2018-09-25 12:02:29 -07:00
|
|
|
title: '',
|
2018-09-27 13:39:37 -07:00
|
|
|
emailAddress: '',
|
2018-11-16 15:05:17 -08:00
|
|
|
avatar: null,
|
|
|
|
socialMedias: [],
|
2018-09-25 12:02:29 -07:00
|
|
|
},
|
|
|
|
],
|
|
|
|
milestones,
|
|
|
|
};
|
|
|
|
|
|
|
|
const props = {
|
|
|
|
sendLoading: false,
|
|
|
|
proposal,
|
|
|
|
...proposal, // yeah...
|
|
|
|
};
|
|
|
|
|
|
|
|
return props;
|
|
|
|
}
|