Integrate Storybook (#98)

* add missing static alias + include ./stories in tsconfig

* add storybook dep + script + babel-core bridge dep.

* storybook setup

* expose unconnected Component for storybook

* fix discovered styling issue

* dummy props (ProposalWithCrowdFund)

* Basic stories.
This commit is contained in:
AMStrix 2018-09-25 14:02:29 -05:00 committed by William O'Beirne
parent a8266eb4ac
commit 8be518fff7
18 changed files with 2329 additions and 50 deletions

View File

@ -0,0 +1,11 @@
import { configure } from '@storybook/react';
import '@babel/polyfill'; // fix regeneratorruntime undefined
// automatically import all files ending in *.stories.tsx
const req = require.context('../stories', true, /.stories.tsx$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);

View File

@ -0,0 +1,11 @@
const paths = require('../config/paths');
const { client: clientLoaders } = require('../config/webpack.config.js/loaders');
const { alias } = require('../config/webpack.config.js/resolvers');
module.exports = (baseConfig, env, defaultConfig) => {
const rules = [...baseConfig.module.rules, ...clientLoaders];
baseConfig.module.rules = rules;
baseConfig.resolve.extensions.push('.ts', '.tsx', '.json');
baseConfig.resolve.alias = alias;
return baseConfig;
};

View File

@ -40,7 +40,7 @@ interface State {
amountError: string | null;
}
class ProposalCampaignBlock extends React.Component<Props, State> {
export class ProposalCampaignBlock extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {

View File

@ -29,7 +29,7 @@ interface ActionProps {
type Props = OwnProps & Web3Props & StateProps & ActionProps;
class Milestones extends React.Component<Props> {
export class Milestones extends React.Component<Props> {
render() {
const {
proposal,

View File

@ -31,10 +31,6 @@
text-align: center;
margin: 0 2rem 0.5rem 0;
.ant-progress-circle-path {
stroke: inherit;
}
&.is-starting {
.ant-progress-circle-path {
stroke: #1890ff;

View File

@ -18,7 +18,7 @@ interface Props extends ProposalWithCrowdFund {
web3: AppState['web3']['web3'];
}
class ProposalCard extends React.Component<Props> {
export class ProposalCard extends React.Component<Props> {
state = { redirect: '' };
render() {
if (this.state.redirect) {

View File

@ -11,6 +11,7 @@ module.exports = {
lib: `${paths.srcClient}/lib`,
modules: `${paths.srcClient}/modules`,
pages: `${paths.srcClient}/pages`,
static: `${paths.srcClient}/static`,
store: `${paths.srcClient}/store`,
styles: `${paths.srcClient}/styles`,
typings: `${paths.srcClient}/typings`,

View File

@ -12,7 +12,8 @@
"tsc": "tsc",
"link-contracts": "cd client/lib && ln -s ../../build/contracts contracts",
"ganache": "ganache-cli -b 5",
"truffle": "truffle exec ./bin/init-truffle.js && cd client/lib/contracts && truffle console"
"truffle": "truffle exec ./bin/init-truffle.js && cd client/lib/contracts && truffle console",
"storybook": "start-storybook -p 9001 -c .storybook"
},
"husky": {
"hooks": {
@ -64,6 +65,7 @@
"ant-design-pro": "^2.0.0-beta.2",
"antd": "^3.7.1",
"axios": "^0.18.0",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "^8.0.2",
"babel-plugin-dynamic-import-node": "^2.1.0",
"babel-plugin-dynamic-import-webpack": "^1.0.2",
@ -147,10 +149,12 @@
"xss": "1.0.3"
},
"devDependencies": {
"@storybook/react": "4.0.0-alpha.22",
"@types/bn.js": "4.11.1",
"@types/ethereumjs-util": "5.2.0",
"@types/query-string": "6.1.0",
"@types/showdown": "1.7.5",
"@types/storybook__react": "^3.0.9",
"@types/web3": "1.0.3",
"rimraf": "2.6.2"
}

View File

@ -0,0 +1,40 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import MarkdownEditor from 'components/MarkdownEditor';
import { MARKDOWN_TYPE } from 'utils/markdown';
const initialMarkdown = `
### Initial Markdown
Ut enim ad **minima** veniam, quis nostrum _exercitationem_ ullam
corporis suscipit ~~laboriosam~~, nisi ut aliquid ex ea commodi
consequatur?
1. Dog
1. Cat
1. Stomatopoda
- Orange
- Apple
- Durian
`;
storiesOf('MarkdownEditor', module)
.add('basic', () => (
<div style={{ padding: '2em' }}>
<MarkdownEditor onChange={_ => null} />
</div>
))
.add('initial markdown', () => (
<div style={{ padding: '2em' }}>
<MarkdownEditor initialMarkdown={initialMarkdown} onChange={_ => null} />
</div>
))
.add('type - reduced', () => (
<div style={{ padding: '2em' }}>
<MarkdownEditor
type={MARKDOWN_TYPE.REDUCED}
initialMarkdown={initialMarkdown}
onChange={_ => null}
/>
</div>
));

View File

@ -0,0 +1,23 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import Placeholder from '../client/components/Placeholder';
storiesOf('Placeholder', module)
.add('basic', () => (
<div style={{ padding: '2em' }}>
<Placeholder
title="This Is a Placeholder Title"
subtitle="Subtitle. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo."
/>
</div>
))
.add('styled', () => (
<div style={{ padding: '2em' }}>
<Placeholder
style={{ borderColor: 'green', width: '35em' }}
title="Styled Placeholder Title"
subtitle="Subtitle. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo."
/>
</div>
));

View File

@ -0,0 +1,262 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import { ProposalCampaignBlock } from 'components/Proposal/CampaignBlock';
import Contributors from 'components/Proposal/Contributors';
import { Milestones as GovernanceMilestones } from 'components/Proposal/Governance/Milestones';
import Milestones from 'components/Proposal/Milestones';
import { MILESTONE_STATE } from 'modules/proposals/reducers';
const { WAITING, ACTIVE, PAID, REJECTED } = MILESTONE_STATE;
import 'styles/style.less';
import 'components/Proposal/style.less';
import 'components/Proposal/Governance/style.less';
import { getProposalWithCrowdFund, getGovernanceMilestonesProps } from './props';
const propsNoFunding = getProposalWithCrowdFund({
amount: 5,
funded: 0,
});
const propsHalfFunded = getProposalWithCrowdFund({
amount: 5,
funded: 2.5,
});
const propsFunded = getProposalWithCrowdFund({
amount: 5,
funded: 5,
});
const propsNotFundedExpired = getProposalWithCrowdFund({
created: Date.now() - 10,
deadline: Date.now() - 1,
});
const msWaiting = { state: WAITING, isPaid: false };
const msPaid = { state: PAID, isPaid: true };
const msActive = { state: ACTIVE, isPaid: false };
const msRejected = { state: REJECTED, isPaid: false };
const propsMilestoneActive = getProposalWithCrowdFund({
milestoneOverrides: [msPaid, msActive, msWaiting],
});
const propsMilestoneActiveOneVote = getProposalWithCrowdFund({
milestoneOverrides: [
msPaid,
{ state: ACTIVE, isPaid: false, percentAgainstPayout: 33 },
msWaiting,
],
contributorOverrides: [{ milestoneNoVotes: [false, true, false] }],
});
const propsMilestoneRejected = getProposalWithCrowdFund({
milestoneOverrides: [msPaid, msPaid, msRejected],
});
const propsMilestoneFirstPaid = getProposalWithCrowdFund({
milestoneOverrides: [msPaid, msWaiting, msWaiting],
});
const propsMilestoneSecondUncollected = getProposalWithCrowdFund({
milestoneOverrides: [msPaid, { state: PAID, isPaid: false }, msWaiting],
});
const propsMilestoneInitialSuccessNotPaid = getProposalWithCrowdFund({
milestoneOverrides: [
{ state: ACTIVE, isPaid: false, payoutRequestVoteDeadline: Date.now() },
],
});
const propsMilestoneAllPaid = getProposalWithCrowdFund({
milestoneOverrides: [msPaid, msPaid, msPaid],
});
const trusteeInactiveFirstImmediateGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsFunded,
);
const trusteeActiveNotPaidFirstImmediateGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsMilestoneInitialSuccessNotPaid,
);
const trusteeInactiveFirstPaidGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsMilestoneFirstPaid,
);
const trusteeUncollectedSecondGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsMilestoneSecondUncollected,
);
const trusteeActiveFirstPaidGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsMilestoneActive,
);
const trusteeAllPaidGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({ isContributor: false }),
propsMilestoneAllPaid,
);
const contributorInactiveGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({}),
propsFunded,
);
const contributorActiveGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({}),
propsMilestoneActive,
);
const contributorActiveOneVoteGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({}),
propsMilestoneActiveOneVote,
);
const contributorAllPaidGovernanceMilestoneProps = Object.assign(
getGovernanceMilestonesProps({}),
propsMilestoneAllPaid,
);
const CampaignBlocks = ({ style }: { style: any }) => (
<React.Fragment>
<div style={style}>
<ProposalCampaignBlock {...propsNoFunding} />
</div>
<div style={style}>
<ProposalCampaignBlock {...propsHalfFunded} />
</div>
<div style={style}>
<ProposalCampaignBlock {...propsFunded} />
</div>
<div style={style}>
<ProposalCampaignBlock {...propsNotFundedExpired} />
</div>
</React.Fragment>
);
storiesOf('Proposal', module)
.add('CampaignBlock - narrow', () => (
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<CampaignBlocks style={{ width: '19rem', margin: '0 12px' }} />
</div>
))
.add('CampaignBlock - wide', () => (
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<CampaignBlocks style={{ margin: '0 12px' }} />
</div>
))
.add('Contributors', () => (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Contributors crowdFund={propsFunded.proposal.crowdFund} />
</div>
))
.add('Governance/Milestones trustee', () => {
const style = {
maxWidth: '500px',
margin: '0 0 1.5em',
padding: '0.5em',
border: '1px solid #cccccc',
flex: '1 1 0%',
};
return (
<div
className="ProposalGovernance"
style={{
display: 'flex',
flex: '1 1 0%',
flexDirection: 'column',
justifyContent: 'center',
padding: '2em',
}}
>
<div>
Trustee - immediate initial payout
<div style={style}>
<GovernanceMilestones
{...trusteeInactiveFirstImmediateGovernanceMilestoneProps}
/>
</div>
</div>
<div>
Trustee - immediate initial payout, accepted not paid
<div style={style}>
<GovernanceMilestones
{...trusteeActiveNotPaidFirstImmediateGovernanceMilestoneProps}
/>
</div>
</div>
<div>
Trustee - first milestone paid
<div style={style}>
<GovernanceMilestones {...trusteeInactiveFirstPaidGovernanceMilestoneProps} />
</div>
</div>
<div>
Trustee - second milestone active
<div style={style}>
<GovernanceMilestones {...trusteeActiveFirstPaidGovernanceMilestoneProps} />
</div>
</div>
<div>
Trustee - second milestone uncollected
<div style={style}>
<GovernanceMilestones {...trusteeUncollectedSecondGovernanceMilestoneProps} />
</div>
</div>
<div>
Trustee - all paid
<div style={style}>
<GovernanceMilestones {...trusteeAllPaidGovernanceMilestoneProps} />
</div>
</div>
</div>
);
})
.add('Governance/Milestones contributor', () => {
const style = {
maxWidth: '500px',
margin: '0 0 1.5em',
padding: '0.5em',
border: '1px solid #cccccc',
};
return (
<div
className="ProposalGovernance"
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
padding: '2em',
}}
>
<div>
Contributor - innactive milestones
<div style={style}>
<GovernanceMilestones {...contributorInactiveGovernanceMilestoneProps} />
</div>
</div>
<div>
Contributor - active milestone
<div style={style}>
<GovernanceMilestones {...contributorActiveGovernanceMilestoneProps} />
</div>
</div>
<div>
Contributor - active milestone - voted against
<div style={style}>
<GovernanceMilestones {...contributorActiveOneVoteGovernanceMilestoneProps} />
</div>
</div>
<div>
Contributor - all paid
<div style={style}>
<GovernanceMilestones {...contributorAllPaidGovernanceMilestoneProps} />
</div>
</div>
</div>
);
})
.add('Milestones - waiting', () => (
<div style={{ paddingTop: '2em', display: 'flex', justifyContent: 'center' }}>
<Milestones {...propsFunded} />
</div>
))
.add('Milestones - active', () => (
<div style={{ paddingTop: '2em', display: 'flex', justifyContent: 'center' }}>
<Milestones {...propsMilestoneActive} />
</div>
))
.add('Milestones - rejected', () => (
<div style={{ paddingTop: '2em', display: 'flex', justifyContent: 'center' }}>
<Milestones {...propsMilestoneRejected} />
</div>
));

View File

@ -0,0 +1,95 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import { ProposalCard } from 'components/Proposals/ProposalCard';
import 'styles/style.less';
import 'components/Proposal/style.less';
import 'components/Proposal/Governance/style.less';
import { getProposalWithCrowdFund } from './props';
const propsNoFunding = getProposalWithCrowdFund({
amount: 5,
funded: 0,
});
const propsHalfFunded = getProposalWithCrowdFund({
amount: 5,
funded: 2.5,
});
const propsFunded = getProposalWithCrowdFund({
amount: 5,
funded: 5,
});
const propsNotFundedExpired = getProposalWithCrowdFund({
created: Date.now() - 1000 * 60 * 60 * 10,
deadline: Date.now() - 1,
});
storiesOf('Proposals', module)
.add('ProposalCard - narrow', () => {
const style = {
width: '300px',
padding: '0 0.5em 0.5em 0',
};
return (
<div
className="ProposalGovernance"
style={{
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
padding: '2em',
}}
>
<div style={style}>
Started - no funding
<ProposalCard {...propsNoFunding} />
</div>
<div style={style}>
Started - half funded
<ProposalCard {...propsHalfFunded} />
</div>
<div style={style}>
Started - fully funded
<ProposalCard {...propsFunded} />
</div>
<div style={style}>
Started - expired
<ProposalCard {...propsNotFundedExpired} />
</div>
</div>
);
})
.add('ProposalCard - wide', () => {
const style = {
padding: '0 0.5em 0.5em 0',
};
return (
<div
className="ProposalGovernance"
style={{
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
padding: '2em',
}}
>
<div style={style}>
Started - no funding
<ProposalCard {...propsNoFunding} />
</div>
<div style={style}>
Started - half funded
<ProposalCard {...propsHalfFunded} />
</div>
<div style={style}>
Started - fully funded
<ProposalCard {...propsFunded} />
</div>
<div style={style}>
Started - expired
<ProposalCard {...propsNotFundedExpired} />
</div>
</div>
);
});

View File

@ -0,0 +1,19 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import ShortAddress from '../client/components/ShortAddress';
const containerWidths = ['100px', '150px', '200px', '300px', '400px'];
storiesOf('ShortAddress', module).add('widths', () => (
<div style={{ padding: '2em' }}>
{containerWidths.map(width => (
<div key={width} style={{ padding: '5px' }}>
<div style={{ fontSize: '0.8em', color: 'gray' }}>{width}</div>
<div style={{ width, border: '1px solid gray' }}>
<ShortAddress address="0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0" />
</div>
</div>
))}
</div>
));

View File

@ -0,0 +1,83 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import BN from 'bn.js';
import UnitDisplay from '../client/components/UnitDisplay';
const oneEth = new BN('1000000000000000000');
const cases = [
{
disp: 'basic',
props: { value: oneEth.mul(new BN(25)), symbol: 'ETH' },
},
{
disp: 'fraction',
props: { value: oneEth.div(new BN(3)), symbol: 'ETH' },
},
{
disp: 'fraction - displayShortBalance: true',
props: { value: oneEth.div(new BN(3)), symbol: 'ETH', displayShortBalance: true },
},
{
disp: 'fraction - displayShortBalance: 2',
props: { value: oneEth.div(new BN(3)), symbol: 'ETH', displayShortBalance: 2 },
},
{
disp: 'fraction - displayShortBalance: 4, displayTrailingZeros: false',
props: {
value: oneEth.div(new BN(2)),
symbol: 'ETH',
displayShortBalance: 4,
displayTrailingZeroes: false,
},
},
{
disp: 'fraction - displayShortBalance: 4, displayTrailingZeros: true',
props: {
value: oneEth.div(new BN(2)),
symbol: 'ETH',
displayShortBalance: 4,
displayTrailingZeroes: true,
},
},
{
disp: 'tiny',
props: { value: new BN(1), symbol: 'ETH' },
},
{
disp: 'tiny - displayShortBalance: true',
props: {
value: new BN(1),
symbol: 'ETH',
displayShortBalance: true,
},
},
{
disp: 'tiny - displayShortBalance: 2',
props: {
value: new BN(1),
symbol: 'ETH',
displayShortBalance: 2,
},
},
];
storiesOf('UnitDisplay', module).add('all', () => (
<div style={{ padding: '2em' }}>
{cases.map(c => (
<div key={c.disp}>
<div style={{ fontSize: '0.9em', paddingTop: '0.6em' }}>{`${c.disp}`}</div>
<div
style={{
padding: '0 0.5em',
border: '1px solid gray',
display: 'inline-block',
}}
>
<UnitDisplay {...c.props} />
</div>
</div>
))}
</div>
));

View File

@ -0,0 +1,2 @@
const req = require.context('./', true, /.story.tsx$/);
req.keys().forEach(filename => req(filename));

221
frontend/stories/props.tsx Normal file
View File

@ -0,0 +1,221 @@
import { Contributor, Milestone, MILESTONE_STATE } from 'modules/proposals/reducers';
import { PROPOSAL_CATEGORY } from 'api/constants';
import {
fundCrowdFund,
requestMilestonePayout,
payMilestonePayout,
voteMilestonePayout,
} from 'modules/web3/actions';
import Web3 from 'web3';
import BN from 'bn.js';
const oneEth = new BN('1000000000000000000');
export function getGovernanceMilestonesProps({
isContributor = true,
}: {
isContributor?: boolean;
}) {
return {
accounts: [
isContributor
? '0xAAA91bde2303f2f43325b2108d26f1eaba1e32b'
: '0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
],
isMilestoneActionPending: false,
milestoneActionError: '',
requestMilestonePayout,
payMilestonePayout,
voteMilestonePayout,
};
}
export function getProposalWithCrowdFund({
amount = 10,
funded = 5,
created = Date.now(),
deadline = Date.now() + 1000 * 60 * 60 * 10,
milestoneOverrides = [],
contributorOverrides = [],
}: {
amount?: number;
funded?: number;
created?: number;
deadline?: number;
milestoneOverrides?: Array<Partial<Milestone>>;
contributorOverrides?: Array<Partial<Contributor>>;
}) {
const amountBn = oneEth.mul(new BN(amount));
const fundedBn = oneEth.mul(new BN(funded));
const contributors = [
{
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);
});
const milestones = [
{
title: 'Milestone A',
body: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.`,
content: '',
dateCreated: '2018-09-23T19:06:15.844399+00:00',
dateEstimated: '2018-10-01T00:00:00+00:00',
immediatePayout: true,
index: 0,
state: MILESTONE_STATE.WAITING,
amount: amountBn,
amountAgainstPayout: new BN(0),
percentAgainstPayout: 0,
payoutRequestVoteDeadline: 0,
isPaid: false,
isImmediatePayout: true,
payoutPercent: '33',
stage: 'NOT_REQUESTED',
},
{
title: 'Milestone B',
body: `Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.`,
content: '',
dateCreated: '2018-09-23T19:06:15.844399+00:00',
dateEstimated: '2018-11-01T00:00:00+00:00',
immediatePayout: false,
index: 1,
state: MILESTONE_STATE.WAITING,
amount: amountBn,
amountAgainstPayout: new BN(0),
percentAgainstPayout: 0,
payoutRequestVoteDeadline: Date.now(),
isPaid: false,
isImmediatePayout: false,
payoutPercent: '33',
stage: 'NOT_REQUESTED',
},
{
title: 'Milestone C',
body: `Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.`,
content: '',
dateCreated: '2018-09-23T19:06:15.844399+00:00',
dateEstimated: '2018-12-01T00:00:00+00:00',
immediatePayout: false,
index: 2,
state: MILESTONE_STATE.WAITING,
amount: amountBn,
amountAgainstPayout: new BN(0),
percentAgainstPayout: 0,
payoutRequestVoteDeadline: Date.now(),
isPaid: false,
isImmediatePayout: false,
payoutPercent: '33',
stage: 'NOT_REQUESTED',
},
];
const eachMilestoneAmount = fundedBn.div(new BN(milestones.length));
milestones.forEach(ms => (ms.amount = eachMilestoneAmount));
milestoneOverrides.forEach((mso, idx) => {
Object.assign(milestones[idx], mso);
});
const proposal = {
proposalId: '0x033fDc6C01DC2385118C7bAAB88093e22B8F0710',
dateCreated: created / 1000,
title: 'Crowdfund Title',
body: 'body',
stage: 'FUNDING_REQUIRED',
category: PROPOSAL_CATEGORY.COMMUNITY,
team: [
{
accountAddress: '0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
title: '',
userid: 1,
username: '',
avatar: { '120x120': '' },
},
{
accountAddress: '0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
title: '',
userid: 2,
username: '',
avatar: { '120x120': '' },
},
{
accountAddress: '0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520',
title: '',
userid: 3,
username: '',
avatar: { '120x120': '' },
},
],
milestones,
crowdFund: {
beneficiary: '0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
trustees: [
'0x0c7C6178AD0618Bf289eFd5E1Ff9Ada25fC3bDE7',
'0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520',
],
contributors,
milestones,
deadline,
milestoneVotingPeriod: 3600000,
isFrozen: false,
isRaiseGoalReached: amount <= funded,
immediateFirstMilestonePayout: true,
balance: new BN(0),
funded: fundedBn,
percentFunded: (funded / amount) * 100,
target: amountBn,
amountVotingForRefund: new BN(0),
percentVotingForRefund: 0,
},
crowdFundContract: {},
};
const props = {
sendLoading: false,
fundCrowdFund,
web3: new Web3(),
proposal,
...proposal, // yeah...
};
return props;
}

View File

@ -24,6 +24,7 @@
"lib/*": ["./client/lib/*"],
"modules/*": ["./client/modules/*"],
"pages/*": ["./client/pages/*"],
"static/*": ["./client/static/*"],
"store/*": ["./client/store/*"],
"styles/*": ["./client/styles/*"],
"typings/*": ["./client/typings/*"],
@ -31,6 +32,6 @@
"web3interact/*": ["./client/web3interact/*"]
}
},
"include": ["./client/**/*", "./server/**/*"],
"include": ["./client/**/*", "./server/**/*", "./stories/**/*"],
"exclude": ["./client/static"]
}

File diff suppressed because it is too large Load Diff