Compare commits
No commits in common. "2f87d9617115f24f8e0a0271f9fd130df126e913" and "cfd38e91b718de6a7bd5189975a3a8159b645f4b" have entirely different histories.
2f87d96171
...
cfd38e91b7
|
@ -1,32 +0,0 @@
|
|||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cd frontend && yarn && && yarn run lint && yarn run tsc
|
|
@ -1,32 +0,0 @@
|
|||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
||||
|
||||
name: Python application
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
cd backend && pip install -r requirements/dev.txt
|
||||
- name: Test with flask test
|
||||
run: |
|
||||
cd backend && cp .env.example .env && flask test
|
|
@ -2,19 +2,34 @@ import React from 'react';
|
|||
import BN from 'bn.js';
|
||||
import { view } from 'react-easy-state';
|
||||
import { RouteComponentProps, withRouter } from 'react-router';
|
||||
import { Alert, Button, Card, Col, Collapse, Input, message, Popconfirm, Row, Switch, Tag } from 'antd';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
Alert,
|
||||
Button,
|
||||
Collapse,
|
||||
Popconfirm,
|
||||
Input,
|
||||
Tag,
|
||||
message,
|
||||
} from 'antd';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
import store from 'src/store';
|
||||
import { formatDateSeconds, formatDurationSeconds } from 'util/time';
|
||||
import { MILESTONE_STAGE, PROPOSAL_ARBITER_STATUS, PROPOSAL_STAGE, PROPOSAL_STATUS } from 'src/types';
|
||||
import {
|
||||
PROPOSAL_STATUS,
|
||||
PROPOSAL_ARBITER_STATUS,
|
||||
MILESTONE_STAGE,
|
||||
PROPOSAL_STAGE,
|
||||
} from 'src/types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Back from 'components/Back';
|
||||
import Markdown from 'components/Markdown';
|
||||
import ArbiterControl from 'components/ArbiterControl';
|
||||
import { fromZat, toZat } from 'src/util/units';
|
||||
import { toZat, fromZat } from 'src/util/units';
|
||||
import FeedbackModal from '../FeedbackModal';
|
||||
import { formatUsd } from 'util/formatters';
|
||||
|
||||
import './index.less';
|
||||
|
||||
type Props = RouteComponentProps<any>;
|
||||
|
@ -30,11 +45,9 @@ type State = typeof STATE;
|
|||
class ProposalDetailNaked extends React.Component<Props, State> {
|
||||
state = STATE;
|
||||
rejectInput: null | TextArea = null;
|
||||
|
||||
componentDidMount() {
|
||||
this.loadDetail();
|
||||
}
|
||||
|
||||
render() {
|
||||
const id = this.getIdFromQuery();
|
||||
const { proposalDetail: p, proposalDetailFetching } = store;
|
||||
|
@ -43,8 +56,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
return 'loading proposal...';
|
||||
}
|
||||
|
||||
console.log(p.fundedByZomg);
|
||||
|
||||
const needsArbiter =
|
||||
PROPOSAL_ARBITER_STATUS.MISSING === p.arbiter.status &&
|
||||
p.status === PROPOSAL_STATUS.LIVE &&
|
||||
|
@ -81,9 +92,9 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
</p>
|
||||
)
|
||||
}
|
||||
placement='left'
|
||||
cancelText='cancel'
|
||||
okText='confirm'
|
||||
placement="left"
|
||||
cancelText="cancel"
|
||||
okText="confirm"
|
||||
visible={this.state.showCancelAndRefundPopover}
|
||||
okButtonProps={{
|
||||
loading: store.proposalDetailCanceling,
|
||||
|
@ -92,8 +103,8 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
onConfirm={this.handleConfirmCancel}
|
||||
>
|
||||
<Button
|
||||
icon='close-circle'
|
||||
className='ProposalDetail-controls-control'
|
||||
icon="close-circle"
|
||||
className="ProposalDetail-controls-control"
|
||||
loading={store.proposalDetailCanceling}
|
||||
onClick={this.handleCancelAndRefundClick}
|
||||
disabled={disabled}
|
||||
|
@ -115,9 +126,9 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
with funding? This cannot be undone.
|
||||
</p>
|
||||
}
|
||||
placement='left'
|
||||
cancelText='cancel'
|
||||
okText='confirm'
|
||||
placement="left"
|
||||
cancelText="cancel"
|
||||
okText="confirm"
|
||||
visible={this.state.showChangeToAcceptedWithFundingPopover}
|
||||
okButtonProps={{
|
||||
loading: store.proposalDetailCanceling,
|
||||
|
@ -126,8 +137,8 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
onConfirm={this.handleChangeToAcceptWithFundingConfirm}
|
||||
>
|
||||
<Button
|
||||
icon='close-circle'
|
||||
className='ProposalDetail-controls-control'
|
||||
icon="close-circle"
|
||||
className="ProposalDetail-controls-control"
|
||||
loading={store.proposalDetailChangingToAcceptedWithFunding}
|
||||
onClick={this.handleChangeToAcceptedWithFunding}
|
||||
block
|
||||
|
@ -157,7 +168,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
p.status === PROPOSAL_STATUS.APPROVED && (
|
||||
<Alert
|
||||
showIcon
|
||||
type='success'
|
||||
type="success"
|
||||
message={`Approved on ${formatDateSeconds(p.dateApproved)}`}
|
||||
description={`
|
||||
This proposal has been approved and will become live when a team-member
|
||||
|
@ -172,7 +183,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
<Alert
|
||||
showIcon
|
||||
type={p.rfpOptIn ? 'success' : 'error'}
|
||||
message={p.rfpOptIn ? 'KYC Accepted by user' : 'KYC rejected'}
|
||||
message={p.rfpOptIn ? 'KYC accepted' : 'KYC rejected'}
|
||||
description={
|
||||
<div>
|
||||
{p.rfpOptIn ? (
|
||||
|
@ -193,25 +204,25 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
<Col span={isVersionTwo ? 16 : 24}>
|
||||
<Alert
|
||||
showIcon
|
||||
type='warning'
|
||||
message='Review Discussion'
|
||||
type="warning"
|
||||
message="Review Discussion"
|
||||
description={
|
||||
<div>
|
||||
<p>Please review this proposal and render your judgment.</p>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailApprovingDiscussion}
|
||||
icon='check'
|
||||
type='primary'
|
||||
icon="check"
|
||||
type="primary"
|
||||
onClick={() => this.handleApproveDiscussion()}
|
||||
>
|
||||
Open for Public Review
|
||||
</Button>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailApprovingDiscussion}
|
||||
icon='warning'
|
||||
type='default'
|
||||
icon="warning"
|
||||
type="default"
|
||||
onClick={() => {
|
||||
FeedbackModal.open({
|
||||
title: 'Request changes to this proposal?',
|
||||
|
@ -224,10 +235,10 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
Request Changes
|
||||
</Button>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailRejectingPermanently}
|
||||
icon='close'
|
||||
type='danger'
|
||||
icon="close"
|
||||
type="danger"
|
||||
onClick={() => {
|
||||
FeedbackModal.open({
|
||||
title: 'Reject this proposal permanently?',
|
||||
|
@ -256,38 +267,34 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
<Col span={isVersionTwo ? 16 : 24}>
|
||||
<Alert
|
||||
showIcon
|
||||
type='warning'
|
||||
message='Review Pending'
|
||||
type="warning"
|
||||
message="Review Pending"
|
||||
description={
|
||||
<div>
|
||||
<p>Please review this proposal and render your judgment.</p>
|
||||
|
||||
<>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailAcceptingProposal}
|
||||
icon='check'
|
||||
type='primary'
|
||||
icon="check"
|
||||
type="primary"
|
||||
onClick={() => this.handleAcceptProposal(true, true)}
|
||||
>
|
||||
Approve With Funding
|
||||
</Button>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailAcceptingProposal}
|
||||
icon='check'
|
||||
type='default'
|
||||
icon="check"
|
||||
type="default"
|
||||
onClick={() => this.handleAcceptProposal(true, false)}
|
||||
>
|
||||
Approve Without Funding
|
||||
</Button>
|
||||
</>
|
||||
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={store.proposalDetailMarkingChangesAsResolved}
|
||||
icon='close'
|
||||
type='danger'
|
||||
icon="close"
|
||||
type="danger"
|
||||
onClick={() => {
|
||||
FeedbackModal.open({
|
||||
title: 'Request changes to this proposal?',
|
||||
|
@ -312,8 +319,8 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
p.status === PROPOSAL_STATUS.REJECTED && (
|
||||
<Alert
|
||||
showIcon
|
||||
type='error'
|
||||
message='Changes requested'
|
||||
type="error"
|
||||
message="Changes requested"
|
||||
description={
|
||||
<div>
|
||||
<p>
|
||||
|
@ -333,8 +340,8 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
p.changesRequestedDiscussion && (
|
||||
<Alert
|
||||
showIcon
|
||||
type='error'
|
||||
message='Changes requested'
|
||||
type="error"
|
||||
message="Changes requested"
|
||||
description={
|
||||
<div>
|
||||
<p>
|
||||
|
@ -347,10 +354,10 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
<br />
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
className="ProposalDetail-review"
|
||||
loading={false}
|
||||
icon='check'
|
||||
type='danger'
|
||||
icon="check"
|
||||
type="danger"
|
||||
onClick={this.handleMarkChangesAsResolved}
|
||||
>
|
||||
Mark Request as Resolved
|
||||
|
@ -364,35 +371,10 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
const renderNominateArbiter = () =>
|
||||
needsArbiter &&
|
||||
shouldShowArbiter && (
|
||||
<>
|
||||
{!p.kycApproved ? (
|
||||
<Alert
|
||||
showIcon
|
||||
type='error'
|
||||
message='KYC approval required'
|
||||
description={
|
||||
<div>
|
||||
<p>
|
||||
Please wait until an Admin has marked KYC approved before proceeding
|
||||
with payouts.
|
||||
</p>
|
||||
<Button
|
||||
className='ProposalDetail-review'
|
||||
loading={store.proposalDetailApprovingKyc}
|
||||
icon='check'
|
||||
type='primary'
|
||||
onClick={() => this.handleApproveKYC()}
|
||||
>
|
||||
KYC Approved
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Alert
|
||||
showIcon
|
||||
type='warning'
|
||||
message='No arbiter on live proposal'
|
||||
type="warning"
|
||||
message="No arbiter on live proposal"
|
||||
description={
|
||||
<div>
|
||||
<p>An arbiter is required to review milestone payout requests.</p>
|
||||
|
@ -400,8 +382,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
</div>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
const renderNominatedArbiter = () =>
|
||||
|
@ -409,8 +389,8 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
p.status === PROPOSAL_STATUS.LIVE && (
|
||||
<Alert
|
||||
showIcon
|
||||
type='info'
|
||||
message='Arbiter has been nominated'
|
||||
type="info"
|
||||
message="Arbiter has been nominated"
|
||||
description={
|
||||
<div>
|
||||
<p>
|
||||
|
@ -456,9 +436,9 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
|
||||
return (
|
||||
<Alert
|
||||
className='ProposalDetail-alert'
|
||||
className="ProposalDetail-alert"
|
||||
showIcon
|
||||
type='warning'
|
||||
type="warning"
|
||||
message={null}
|
||||
description={
|
||||
<div>
|
||||
|
@ -474,9 +454,9 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
</p>{' '}
|
||||
<pre>{p.payoutAddress}</pre>
|
||||
<Input.Search
|
||||
placeholder='please enter payment txid'
|
||||
placeholder="please enter payment txid"
|
||||
value={this.state.paidTxId}
|
||||
enterButton='Mark Paid'
|
||||
enterButton="Mark Paid"
|
||||
onChange={e => this.setState({ paidTxId: e.target.value })}
|
||||
onSearch={this.handlePaidMilestone}
|
||||
/>
|
||||
|
@ -490,7 +470,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
p.isFailed && (
|
||||
<Alert
|
||||
showIcon
|
||||
type='error'
|
||||
type="error"
|
||||
message={
|
||||
p.stage === PROPOSAL_STAGE.FAILED ? 'Proposal failed' : 'Proposal canceled'
|
||||
}
|
||||
|
@ -512,16 +492,15 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
);
|
||||
|
||||
const renderDeetItem = (name: string, val: any) => (
|
||||
<div className='ProposalDetail-deet'>
|
||||
<div className="ProposalDetail-deet">
|
||||
<span>{name}</span>
|
||||
{val}
|
||||
</div>
|
||||
);
|
||||
|
||||
// @ts-ignore
|
||||
return (
|
||||
<div className='ProposalDetail'>
|
||||
<Back to='/proposals' text='Proposals' />
|
||||
<div className="ProposalDetail">
|
||||
<Back to="/proposals" text="Proposals" />
|
||||
<h1>{p.title}</h1>
|
||||
<Row gutter={16}>
|
||||
{/* MAIN */}
|
||||
|
@ -536,22 +515,22 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
{renderMilestoneAccepted()}
|
||||
{renderFailed()}
|
||||
<Collapse defaultActiveKey={['brief', 'content', 'milestones']}>
|
||||
<Collapse.Panel key='brief' header='brief'>
|
||||
<Collapse.Panel key="brief" header="brief">
|
||||
{p.brief}
|
||||
</Collapse.Panel>
|
||||
|
||||
<Collapse.Panel key='content' header='content'>
|
||||
<Collapse.Panel key="content" header="content">
|
||||
<Markdown source={p.content} />
|
||||
</Collapse.Panel>
|
||||
|
||||
<Collapse.Panel key='milestones' header='milestones'>
|
||||
<Collapse.Panel key="milestones" header="milestones">
|
||||
{p.milestones.map((milestone, i) => (
|
||||
<Card
|
||||
title={
|
||||
<>
|
||||
{milestone.title + ' '}
|
||||
{milestone.immediatePayout && (
|
||||
<Tag color='magenta'>Immediate Payout</Tag>
|
||||
<Tag color="magenta">Immediate Payout</Tag>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
|
@ -576,7 +555,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
))}
|
||||
</Collapse.Panel>
|
||||
|
||||
<Collapse.Panel key='json' header='json'>
|
||||
<Collapse.Panel key="json" header="json">
|
||||
<pre>{JSON.stringify(p, null, 4)}</pre>
|
||||
</Collapse.Panel>
|
||||
</Collapse>
|
||||
|
@ -588,35 +567,23 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
!p.acceptedWithFunding &&
|
||||
p.stage === PROPOSAL_STAGE.WIP && (
|
||||
<Alert
|
||||
message='Accepted without funding'
|
||||
message="Accepted without funding"
|
||||
description="This proposal has been posted publicly, but isn't being funded by the Zcash Foundation."
|
||||
type='info'
|
||||
type="info"
|
||||
showIcon
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* ACTIONS */}
|
||||
<Card size='small' className='ProposalDetail-controls'>
|
||||
<Card size="small" className="ProposalDetail-controls">
|
||||
{renderCancelControl()}
|
||||
{renderArbiterControl()}
|
||||
|
||||
{
|
||||
p.acceptedWithFunding &&
|
||||
<div style={{ marginTop: '10px' }}>
|
||||
<Switch checkedChildren='Funded by ZOMG'
|
||||
unCheckedChildren='Funded by ZF'
|
||||
onChange={this.handleSwitchFunder}
|
||||
loading={store.proposalDetailSwitchingFunder}
|
||||
checked={p.fundedByZomg} />
|
||||
</div>
|
||||
}
|
||||
|
||||
{shouldShowChangeToAcceptedWithFunding &&
|
||||
renderChangeToAcceptedWithFundingControl()}
|
||||
</Card>
|
||||
|
||||
{/* DETAILS */}
|
||||
<Card title='Details' size='small'>
|
||||
<Card title="Details" size="small">
|
||||
{renderDeetItem('id', p.proposalId)}
|
||||
{renderDeetItem('created', formatDateSeconds(p.dateCreated))}
|
||||
{renderDeetItem(
|
||||
|
@ -667,7 +634,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
</Card>
|
||||
|
||||
{/* TEAM */}
|
||||
<Card title='Team' size='small'>
|
||||
<Card title="Team" size="small">
|
||||
{p.team.map(t => (
|
||||
<div key={t.userid}>
|
||||
<Link to={`/users/${t.userid}`}>{t.displayName}</Link>
|
||||
|
@ -749,11 +716,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
message.info('Proposal rejected permanently');
|
||||
};
|
||||
|
||||
private handleApproveKYC = async () => {
|
||||
await store.approveProposalKYC();
|
||||
message.info(`Proposal KYC approved`);
|
||||
};
|
||||
|
||||
private handleAcceptProposal = async (
|
||||
isAccepted: boolean,
|
||||
withFunding: boolean,
|
||||
|
@ -781,10 +743,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
await store.markMilestonePaid(pid, mid, this.state.paidTxId);
|
||||
message.success('Marked milestone paid.');
|
||||
};
|
||||
|
||||
private handleSwitchFunder = async (checkValue: boolean) => {
|
||||
store.switchProposalFunder(checkValue);
|
||||
};
|
||||
}
|
||||
|
||||
const ProposalDetail = withRouter(view(ProposalDetailNaked));
|
||||
|
|
|
@ -2,17 +2,17 @@ import { pick } from 'lodash';
|
|||
import { store } from 'react-easy-state';
|
||||
import axios, { AxiosError } from 'axios';
|
||||
import {
|
||||
User,
|
||||
Proposal,
|
||||
CCR,
|
||||
CommentArgs,
|
||||
Contribution,
|
||||
ContributionArgs,
|
||||
EmailExample,
|
||||
PageData,
|
||||
PageQuery,
|
||||
Proposal,
|
||||
RFP,
|
||||
RFPArgs,
|
||||
User,
|
||||
EmailExample,
|
||||
PageQuery,
|
||||
PageData,
|
||||
CommentArgs,
|
||||
} from './types';
|
||||
|
||||
// API
|
||||
|
@ -142,16 +142,6 @@ async function approveDiscussion(
|
|||
return data;
|
||||
}
|
||||
|
||||
async function switchProposalFunder(id: number, fundedByZomg: boolean) {
|
||||
const { data } = await api.put(`/admin/proposals/${id}/adjust-funder`, {fundedByZomg});
|
||||
return data;
|
||||
}
|
||||
|
||||
async function approveProposalKYC(id: number) {
|
||||
const { data } = await api.put(`/admin/proposals/${id}/approve-kyc`);
|
||||
return data;
|
||||
}
|
||||
|
||||
async function acceptProposal(
|
||||
id: number,
|
||||
isAccepted: boolean,
|
||||
|
@ -355,8 +345,6 @@ const app = store({
|
|||
proposalDetailApprovingDiscussion: false,
|
||||
proposalDetailMarkingChangesAsResolved: false,
|
||||
proposalDetailAcceptingProposal: false,
|
||||
proposalDetailApprovingKyc: false,
|
||||
proposalDetailSwitchingFunder: false,
|
||||
proposalDetailMarkingMilestonePaid: false,
|
||||
proposalDetailCanceling: false,
|
||||
proposalDetailUpdating: false,
|
||||
|
@ -700,43 +688,6 @@ const app = store({
|
|||
handleApiError(e);
|
||||
}
|
||||
},
|
||||
|
||||
async switchProposalFunder(fundedByZomg: boolean) {
|
||||
if (!app.proposalDetail) {
|
||||
const m = 'store.acceptProposal(): Expected proposalDetail to be populated!';
|
||||
app.generalError.push(m);
|
||||
console.error(m);
|
||||
return;
|
||||
}
|
||||
app.proposalDetailSwitchingFunder = true;
|
||||
try {
|
||||
const { proposalId } = app.proposalDetail;
|
||||
const res = await switchProposalFunder(proposalId, fundedByZomg);
|
||||
app.updateProposalInStore(res);
|
||||
} catch (e) {
|
||||
handleApiError(e);
|
||||
}
|
||||
app.proposalDetailSwitchingFunder = false;
|
||||
},
|
||||
|
||||
async approveProposalKYC() {
|
||||
if (!app.proposalDetail) {
|
||||
const m = 'store.acceptProposal(): Expected proposalDetail to be populated!';
|
||||
app.generalError.push(m);
|
||||
console.error(m);
|
||||
return;
|
||||
}
|
||||
app.proposalDetailApprovingKyc = true;
|
||||
try {
|
||||
const { proposalId } = app.proposalDetail;
|
||||
const res = await approveProposalKYC(proposalId);
|
||||
app.updateProposalInStore(res);
|
||||
} catch (e) {
|
||||
handleApiError(e);
|
||||
}
|
||||
app.proposalDetailApprovingKyc = false;
|
||||
},
|
||||
|
||||
async acceptProposal(
|
||||
isAccepted: boolean,
|
||||
withFunding: boolean,
|
||||
|
@ -1024,7 +975,6 @@ function createDefaultPageData<T>(sort: string): PageData<T> {
|
|||
}
|
||||
|
||||
type FNFetchPage = (params: PageQuery) => Promise<any>;
|
||||
|
||||
interface PageParent<T> {
|
||||
page: PageData<T>;
|
||||
}
|
||||
|
|
|
@ -123,8 +123,6 @@ export interface Proposal {
|
|||
isVersionTwo: boolean;
|
||||
changesRequestedDiscussion: boolean | null;
|
||||
changesRequestedDiscussionReason: string | null;
|
||||
kycApproved: null | boolean;
|
||||
fundedByZomg: boolean;
|
||||
}
|
||||
export interface Comment {
|
||||
id: number;
|
||||
|
|
|
@ -5414,7 +5414,7 @@ minimist@^1.2.0, minimist@~1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
|
||||
minimist@^1.2.3:
|
||||
minimist@^1.2.2:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
|
|
@ -4,7 +4,7 @@ from functools import reduce
|
|||
|
||||
from flask import Blueprint, request
|
||||
from marshmallow import fields, validate
|
||||
from sqlalchemy import func, text
|
||||
from sqlalchemy import func, or_, text
|
||||
|
||||
import grant.utils.admin as admin
|
||||
import grant.utils.auth as auth
|
||||
|
@ -25,7 +25,7 @@ from grant.proposal.models import (
|
|||
admin_proposal_contributions_schema,
|
||||
)
|
||||
from grant.rfp.models import RFP, admin_rfp_schema, admin_rfps_schema
|
||||
from grant.user.models import User, admin_users_schema, admin_user_schema
|
||||
from grant.user.models import User, UserSettings, admin_users_schema, admin_user_schema
|
||||
from grant.utils import pagination
|
||||
from grant.utils.enums import (
|
||||
ProposalStatus,
|
||||
|
@ -377,35 +377,6 @@ def open_proposal_for_discussion(proposal_id, is_open_for_discussion, reject_rea
|
|||
return proposal_schema.dump(proposal)
|
||||
|
||||
|
||||
@blueprint.route('/proposals/<id>/approve-kyc', methods=['PUT'])
|
||||
@admin.admin_auth_required
|
||||
def approve_proposal_kyc(id):
|
||||
proposal = Proposal.query.get(id)
|
||||
if not proposal:
|
||||
return {"message": "No proposal found."}, 404
|
||||
|
||||
proposal.kyc_approved = True
|
||||
db.session.add(proposal)
|
||||
db.session.commit()
|
||||
return proposal_schema.dump(proposal)
|
||||
|
||||
|
||||
@blueprint.route('/proposals/<id>/adjust-funder', methods=['PUT'])
|
||||
@body({
|
||||
"fundedByZomg": fields.Bool(required=True),
|
||||
})
|
||||
@admin.admin_auth_required
|
||||
def adjust_funder(id, funded_by_zomg):
|
||||
proposal = Proposal.query.get(id)
|
||||
if not proposal:
|
||||
return {"message": "No proposal found."}, 404
|
||||
|
||||
proposal.funded_by_zomg = funded_by_zomg
|
||||
db.session.add(proposal)
|
||||
db.session.commit()
|
||||
return proposal_schema.dump(proposal)
|
||||
|
||||
|
||||
@blueprint.route('/proposals/<id>/accept', methods=['PUT'])
|
||||
@body({
|
||||
"isAccepted": fields.Bool(required=True),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import datetime
|
||||
import json
|
||||
from typing import Optional
|
||||
from decimal import Decimal, ROUND_DOWN
|
||||
from functools import reduce
|
||||
from typing import Optional
|
||||
|
||||
from marshmallow import post_dump
|
||||
from sqlalchemy import func, or_, select, ForeignKey
|
||||
|
@ -10,14 +10,15 @@ from sqlalchemy.ext.hybrid import hybrid_property
|
|||
from sqlalchemy.orm import column_property
|
||||
|
||||
from grant.comment.models import Comment
|
||||
from grant.milestone.models import Milestone
|
||||
from grant.email.send import send_email
|
||||
from grant.extensions import ma, db
|
||||
from grant.milestone.models import Milestone
|
||||
from grant.settings import PROPOSAL_STAKING_AMOUNT, PROPOSAL_TARGET_MAX
|
||||
from grant.task.jobs import ContributionExpired
|
||||
from grant.utils.enums import (
|
||||
ProposalStatus,
|
||||
ProposalStage,
|
||||
Category,
|
||||
ContributionStatus,
|
||||
ProposalArbiterStatus,
|
||||
MilestoneStage,
|
||||
|
@ -331,49 +332,43 @@ class ProposalRevision(db.Model):
|
|||
if old_proposal.title != new_proposal.title:
|
||||
proposal_changes.append({"type": ProposalChange.PROPOSAL_EDIT_TITLE})
|
||||
|
||||
milestone_changes = ProposalRevision.calculate_milestone_changes(old_proposal.milestones,
|
||||
new_proposal.milestones)
|
||||
milestone_changes = ProposalRevision.calculate_milestone_changes(old_proposal.milestones, new_proposal.milestones)
|
||||
|
||||
return proposal_changes + milestone_changes
|
||||
|
||||
|
||||
def default_proposal_content():
|
||||
return """### If you have any doubts about the questions below, please reach out to anyone on the ZOMG on the [Zcash forums](https://forum.zcashcommunity.com/).
|
||||
return """# Applicant background
|
||||
|
||||
# Description of Problem or Opportunity
|
||||
In addition to describing the problem/opportunity, please give a sense of how serious or urgent of a need you believe this to be. What evidence do you have? What validation have you already done, or how do you think you could validate this?
|
||||
Summarize you and/or your team’s background and experience. Demonstrate that you have the skills and expertise necessary for the project that you’re proposing. Institutional bona fides are not required, but we want to hear about your track record.
|
||||
|
||||
# Proposed Solution
|
||||
Describe the solution at a high level. Please be specific about who the users and stakeholders are and how they would interact with your solution. E.g. retail ZEC holders, Zcash core devs, wallet devs, DeFi users, potential Zcash community participants.
|
||||
# Motivation and overview
|
||||
|
||||
# Solution Format
|
||||
What is the exact form of the deliverable you’re creating? E.g. code shipped within the zcashd and zebra code bases, a website, a feature within a wallet, a text/markdown file, user manuals, etc.
|
||||
What are your high-level goals? Why are they important? How is your project connected to [ZF’s mission](https://www.zfnd.org/about/#mission) and priorities? Whose needs will it serve?
|
||||
|
||||
# Technical approach
|
||||
|
||||
Dive into the _how_ of your project. Describe your approaches, components, workflows, methodology, etc. Bullet points and diagrams are appreciated!
|
||||
|
||||
# How big of a problem would it be to not solve this problem?
|
||||
|
||||
# Execution risks
|
||||
What obstacles do you expect? What is most likely to go wrong? Which unknown factors or dependencies could jeopardize success? Who would have to incorporate your work in order for it to be usable?
|
||||
|
||||
What obstacles do you expect? What is most likely to go wrong? Which unknown factors or dependencies could jeopardize success? What are your contingency plans? Will subsequent activities be required to maximize impact?
|
||||
|
||||
# Downsides
|
||||
|
||||
# Unintended Consequences Downsides
|
||||
What are the negative ramifications if your project is successful? Consider usability, stability, privacy, integrity, availability, decentralization, interoperability, maintainability, technical debt, requisite education, etc.
|
||||
|
||||
# Evaluation plan
|
||||
What metrics for success can you share with the community once you’re done? In addition to quantitative metrics, what qualitative metrics do you think you could report?
|
||||
|
||||
What will your project look like if successful? How will we be able to tell? Include quantifiable metrics if possible.
|
||||
|
||||
# Tasks and schedule
|
||||
|
||||
# Schedule and Milestones
|
||||
What is your timeline for the project? Include concrete milestones and the major tasks required to complete each milestone.
|
||||
|
||||
# Budget and Payout Timeline
|
||||
# Budget and justification
|
||||
|
||||
How much funding do you need, and how will it be allocated (e.g., compensation for your effort, specific equipment, specific external services)? Please tie your payout timelines to the milestones presented in the previous step. Convention has been for applicants to base their budget on hours of work and an hourly rate, but we are open to proposals based on the value of outcomes instead.
|
||||
|
||||
# Applicant background
|
||||
Summarize you and/or your team’s background and experience. Demonstrate that you have the skills and expertise necessary for the project that you’re proposing. Institutional bona fides are not required, but we want to hear about your track record.
|
||||
How much funding do you need, and how will it be allocated (e.g., compensation for your effort, specific equipment, specific external services)? Specify a total cost, break it up into budget items, and explain the rationale for each. Feel free to present multiple options in terms of scope and cost.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -396,9 +391,6 @@ class Proposal(db.Model):
|
|||
date_approved = db.Column(db.DateTime)
|
||||
date_published = db.Column(db.DateTime)
|
||||
reject_reason = db.Column(db.String())
|
||||
kyc_approved = db.Column(db.Boolean(), nullable=True, default=False)
|
||||
funded_by_zomg = db.Column(db.Boolean(), nullable=True, default=False)
|
||||
|
||||
accepted_with_funding = db.Column(db.Boolean(), nullable=True)
|
||||
changes_requested_discussion = db.Column(db.Boolean(), nullable=True)
|
||||
changes_requested_discussion_reason = db.Column(db.String(255), nullable=True)
|
||||
|
@ -440,11 +432,9 @@ class Proposal(db.Model):
|
|||
.correlate_except(proposal_liker)
|
||||
)
|
||||
live_draft_parent_id = db.Column(db.Integer, ForeignKey('proposal.id'))
|
||||
live_draft = db.relationship("Proposal", uselist=False,
|
||||
backref=db.backref('live_draft_parent', remote_side=[id], uselist=False))
|
||||
live_draft = db.relationship("Proposal", uselist=False, backref=db.backref('live_draft_parent', remote_side=[id], uselist=False))
|
||||
|
||||
revisions = db.relationship(ProposalRevision, foreign_keys=[ProposalRevision.proposal_id], lazy=True,
|
||||
cascade="all, delete-orphan")
|
||||
revisions = db.relationship(ProposalRevision, foreign_keys=[ProposalRevision.proposal_id], lazy=True, cascade="all, delete-orphan")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -470,7 +460,6 @@ class Proposal(db.Model):
|
|||
self.deadline_duration = deadline_duration
|
||||
self.stage = stage
|
||||
self.version = '2'
|
||||
self.funded_by_zomg = True
|
||||
|
||||
@staticmethod
|
||||
def simple_validate(proposal):
|
||||
|
@ -544,6 +533,7 @@ class Proposal(db.Model):
|
|||
# Then run through regular validation
|
||||
Proposal.simple_validate(vars(self))
|
||||
|
||||
|
||||
def validate_milestone_days(self):
|
||||
for milestone in self.milestones:
|
||||
if milestone.immediate_payout:
|
||||
|
@ -1106,9 +1096,7 @@ class ProposalSchema(ma.Schema):
|
|||
"tip_jar_view_key",
|
||||
"changes_requested_discussion",
|
||||
"changes_requested_discussion_reason",
|
||||
"live_draft_id",
|
||||
"kyc_approved",
|
||||
"funded_by_zomg"
|
||||
"live_draft_id"
|
||||
)
|
||||
|
||||
date_created = ma.Method("get_date_created")
|
||||
|
@ -1118,7 +1106,6 @@ class ProposalSchema(ma.Schema):
|
|||
is_version_two = ma.Method("get_is_version_two")
|
||||
tip_jar_view_key = ma.Method("get_tip_jar_view_key")
|
||||
live_draft_id = ma.Method("get_live_draft_id")
|
||||
funded_by_zomg = ma.Method("get_funded_by_zomg")
|
||||
|
||||
updates = ma.Nested("ProposalUpdateSchema", many=True)
|
||||
team = ma.Nested("UserSchema", many=True)
|
||||
|
@ -1128,14 +1115,6 @@ class ProposalSchema(ma.Schema):
|
|||
rfp = ma.Nested("RFPSchema", exclude=["accepted_proposals"])
|
||||
arbiter = ma.Nested("ProposalArbiterSchema", exclude=["proposal"])
|
||||
|
||||
def get_funded_by_zomg(self, obj):
|
||||
if obj.funded_by_zomg is None:
|
||||
return False
|
||||
elif obj.funded_by_zomg is False:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_proposal_id(self, obj):
|
||||
return obj.id
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<p style="margin: 0;">
|
||||
Congratulations, your proposal has been funded by the Zcash Foundation! Once an arbiter is selected by the Foundation, you'll be able to request payouts according to your grant's milestone schedule. <a href='https://grants.zfnd.org/kyc'>Click here</a> for instructions on documentation you need to submit before the Zcash Foundation can transfer funds.
|
||||
Congratulations, your proposal has been funded by the Zcash Foundation! Once an arbiter is selected by the Foundation, you'll be able to request payouts according to your grant's milestone schedule.
|
||||
</p>
|
||||
|
||||
{% if args.admin_note %}
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
<tr>
|
||||
<td align="center" style="padding: 40px 10px 40px 10px;" valign="top">
|
||||
<a href="{{ args.home_url }}" target="_blank">
|
||||
<img alt="ZF Grants logo" border="0" height="44" src="https://i.imgur.com/tYx0apf.png"
|
||||
<img alt="ZF Grants logo" border="0" height="44" src="https://s3.us-east-2.amazonaws.com/zf-grants-prod/email-logo.png"
|
||||
style="display: block; width: 220px; max-width: 220px; min-width: 220px; font-family: 'Nunito Sans', Helvetica, Arial, sans-serif; color: #ffffff; font-size: 18px;"
|
||||
width="220">
|
||||
</a>
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 91b16dc2fd74
|
||||
Revises: d03c91f3038d
|
||||
Create Date: 2021-02-01 17:00:23.721765
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '91b16dc2fd74'
|
||||
down_revision = 'd03c91f3038d'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('proposal', sa.Column('funded_by_zomg', sa.Boolean(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('proposal', 'funded_by_zomg')
|
||||
# ### end Alembic commands ###
|
|
@ -1,28 +0,0 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: d03c91f3038d
|
||||
Revises: bea5c35d0cd6
|
||||
Create Date: 2020-12-27 15:48:36.787259
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd03c91f3038d'
|
||||
down_revision = 'bea5c35d0cd6'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('proposal', sa.Column('kyc_approved', sa.Boolean(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('proposal', 'kyc_approved')
|
||||
# ### end Alembic commands ###
|
|
@ -37,7 +37,6 @@ const Tos = loadable(() => import('pages/tos'));
|
|||
const ProposalTutorial = loadable(() => import('pages/proposal-tutorial'));
|
||||
const About = loadable(() => import('pages/about'), opts);
|
||||
const Privacy = loadable(() => import('pages/privacy'), opts);
|
||||
const Kyc = loadable(() => import('pages/kyc'), opts);
|
||||
const Contact = loadable(() => import('pages/contact'), opts);
|
||||
const CodeOfConduct = loadable(() => import('pages/code-of-conduct'), opts);
|
||||
const VerifyEmail = loadable(() => import('pages/email-verify'), opts);
|
||||
|
@ -255,18 +254,6 @@ const routeConfigs: RouteConfig[] = [
|
|||
},
|
||||
onlyLoggedIn: false,
|
||||
},
|
||||
{
|
||||
// Privacy page
|
||||
route: {
|
||||
path: '/kyc',
|
||||
component: Kyc,
|
||||
exact: true,
|
||||
},
|
||||
template: {
|
||||
title: 'KYC',
|
||||
},
|
||||
onlyLoggedIn: false,
|
||||
},
|
||||
{
|
||||
// Privacy page
|
||||
route: {
|
||||
|
|
|
@ -86,11 +86,11 @@ export const STAGE_UI: { [key in PROPOSAL_FILTERS]: StageUI } = {
|
|||
color: '#8e44ad',
|
||||
},
|
||||
ACCEPTED_WITH_FUNDING: {
|
||||
label: 'Funded',
|
||||
label: 'Funded by ZF',
|
||||
color: '#8e44ad',
|
||||
},
|
||||
ACCEPTED_WITHOUT_FUNDING: {
|
||||
label: 'Not Funded',
|
||||
label: 'Not Funded by ZF',
|
||||
color: '#8e44ad',
|
||||
},
|
||||
WIP: {
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
.KYCModal {
|
||||
&.ant-modal {
|
||||
width: 50vw !important;
|
||||
|
||||
}
|
||||
|
||||
& .ant-modal-body {
|
||||
padding-right: 2.5vw;
|
||||
padding-left: 2.5vw;
|
||||
}
|
||||
|
||||
& ::marker {
|
||||
content: counters(list-item, '.') ':';
|
||||
color: #CF8A00;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& ol ol {
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
& li {
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
margin-bottom: 5px;
|
||||
|
||||
}
|
||||
|
||||
& li li {
|
||||
counter-reset: section
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,16 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Alert, Form, Input, message, Modal, Popconfirm, Radio } from 'antd';
|
||||
import { Input, Form, Alert, Popconfirm, message, Radio } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib/radio';
|
||||
import { ProposalDraft, RFP } from 'types';
|
||||
import { getCreateErrors } from 'modules/create/utils';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { unlinkProposalRFP } from 'modules/create/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import './Basics.less';
|
||||
|
||||
interface OwnProps {
|
||||
proposalId: number;
|
||||
initialState?: Partial<State>;
|
||||
|
||||
updateForm(form: Partial<ProposalDraft>): void;
|
||||
}
|
||||
|
||||
|
@ -32,7 +30,6 @@ interface State extends Partial<ProposalDraft> {
|
|||
brief: string;
|
||||
target: string;
|
||||
rfp?: RFP;
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
class CreateFlowBasics extends React.Component<Props, State> {
|
||||
|
@ -42,29 +39,10 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
title: '',
|
||||
brief: '',
|
||||
target: '',
|
||||
visible: false,
|
||||
...(props.initialState || {}),
|
||||
};
|
||||
}
|
||||
|
||||
showModal = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
});
|
||||
};
|
||||
|
||||
handleOk = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
const { unlinkProposalRFPError, isUnlinkingProposalRFP } = this.props;
|
||||
if (
|
||||
|
@ -94,21 +72,21 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<Form layout='vertical' style={{ maxWidth: 600, margin: '0 auto' }}>
|
||||
<Form layout="vertical" style={{ maxWidth: 600, margin: '0 auto' }}>
|
||||
{rfp && (
|
||||
<Alert
|
||||
className='CreateFlow-rfpAlert'
|
||||
type='info'
|
||||
message='This proposal is linked to a request'
|
||||
className="CreateFlow-rfpAlert"
|
||||
type="info"
|
||||
message="This proposal is linked to a request"
|
||||
description={
|
||||
<>
|
||||
This proposal is for the open request{' '}
|
||||
<Link to={`/requests/${rfp.id}`} target='_blank'>
|
||||
<Link to={`/requests/${rfp.id}`} target="_blank">
|
||||
{rfp.title}
|
||||
</Link>
|
||||
. If you didn’t mean to do this, or want to unlink it,{' '}
|
||||
<Popconfirm
|
||||
title='Are you sure? This cannot be undone.'
|
||||
title="Are you sure? This cannot be undone."
|
||||
onConfirm={this.unlinkRfp}
|
||||
okButtonProps={{ loading: isUnlinkingProposalRFP }}
|
||||
>
|
||||
|
@ -122,9 +100,9 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
)}
|
||||
|
||||
<Alert
|
||||
className='CreateFlow-rfpAlert'
|
||||
type='warning'
|
||||
message='KYC (know your customer)'
|
||||
className="CreateFlow-rfpAlert"
|
||||
type="warning"
|
||||
message="KYC (know your customer)"
|
||||
description={
|
||||
<>
|
||||
<div>
|
||||
|
@ -132,12 +110,12 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
provide identifying information to the Zcash Foundation.
|
||||
<Radio.Group onChange={this.handleRfpOptIn}>
|
||||
<Radio value={true} checked={rfpOptIn && rfpOptIn === true}>
|
||||
<b>Yes</b>, I am willing to provide KYC information as outlined by the <span
|
||||
onClick={() => this.showModal()} style={{ color: 'CF8A00', textDecoration: 'underline' }}>ZF KYC requirements</span>
|
||||
<b>Yes</b>, I am willing to provide KYC information
|
||||
</Radio>
|
||||
<Radio value={false} checked={rfpOptIn !== null && rfpOptIn === false}>
|
||||
<b>No</b>, I do not wish to provide KYC information and understand I will not be able to submit my
|
||||
proposal.
|
||||
<b>No</b>, I do not wish to provide KYC information and understand my
|
||||
proposal may still be posted on ZF Grants, but I will not be eligible
|
||||
to funding from the Zcash Foundation.
|
||||
</Radio>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
|
@ -145,82 +123,16 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
title='Know Your Customer (KYC) Compliance'
|
||||
visible={this.state.visible}
|
||||
onOk={this.handleOk}
|
||||
onCancel={this.handleCancel}
|
||||
className={'KYCModal'}
|
||||
>
|
||||
<ol>
|
||||
<li>To execute a transfer of funds, the Zcash Foundation is legally required to obtain the following
|
||||
information
|
||||
from you: [Privacy guarantee]
|
||||
<ol>
|
||||
<li>A photocopy of your state-issued identification (passport, driver's license, etc.)</li>
|
||||
|
||||
<li>A filled-out form <a href={'https://www.irs.gov/pub/irs-pdf/fw9.pdf'}>W-9</a> (if US taxpayer) or <a
|
||||
href={'https://www.irs.gov/pub/irs-pdf/fw8ben.pdf'}>W-8BEN</a> (if nonresident alien individual), or
|
||||
a <a href={'https://www.irs.gov/pub/irs-pdf/fw8bene.pdf'}>W-8BEN-E</a> (if foreign corporation)
|
||||
</li>
|
||||
|
||||
<li>The Foundation will run a Sanctions Screening and Fraud Monitoring on each recipient of its funds.
|
||||
As a condition of receiving the funds you represent to us, now and until the latter of the submission of a
|
||||
report on the status of the work covered by the proposal or the use of all of the funds, (i) that you are not
|
||||
in violation of any law relating to terrorism or money laundering (“Anti-Terrorism Laws”), including
|
||||
Executive Order No. 13224 on Terrorist Financing, effective September 24, 2001 (the “Executive Order”), and the
|
||||
Uniting and Strengthening America by Providing Appropriate Tools Required to Intercept and Obstruct
|
||||
Terrorism Act of 2001(Title III of P.L. No. 107-56) (known as the “PATRIOT Act”). (ii) neither you or any affiliated
|
||||
person or entity is a person that is listed in the annex to, or is otherwise subject to the provisions of,
|
||||
the Executive Order or a person that is named as a “specially designated national and blocked person” on
|
||||
the most current list published by the US Department of the Treasury, Office of Foreign Assets Control (“OFAC”) at its
|
||||
official website or any replacement website or other replacement official publication of such list;
|
||||
(iii) neither you or any affiliated person or entity is subject to blocking provisions or otherwise a target of
|
||||
sanctions imposed under any sanctions program administered by OFAC; and (iv) neither you or any affiliate person
|
||||
or entity deals in, or otherwise engages in any transaction relating to any property or interests in
|
||||
property blocked pursuant to the Executive Order.
|
||||
</li>
|
||||
|
||||
<li>With certain limited exceptions, in the following January the Zcash Foundation will report the value
|
||||
of the funds as taxable income on either US tax form 1099-MISC (for US taxpayers) or 1042-S (for foreign
|
||||
persons). These forms will report the value of the award in USD at the date it was distributed. You may need to
|
||||
include this income when filing your taxes, and it may affect your total tax due and estimated tax
|
||||
payments. Here are more details on <a href={'https://www.irs.gov/forms-pubs/about-form-1099-misc'}>filing the
|
||||
1099-MISC</a> in the US, and its tax implications.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Your funds will be disbursed in a shielded Zcash cryptocurrency (ZEC), then it will be via an
|
||||
on-blockchain
|
||||
fund transfer transaction. The Foundation will use this third-party service and market for converting ZEC
|
||||
to
|
||||
other currencies are listed here based on the price of the agreed-upon date close of day at :
|
||||
<a href={'https://messari.io/asset/zcash'}>https://messari.io/asset/zcash</a>. For all grants, the
|
||||
agreed-upon date will be the date that the grant was
|
||||
approved, as noted in the grant platform. Note that the Zcash Foundation understands the regulatory and
|
||||
compliance risks associated with transacting in cryptocurrencies.
|
||||
</li>
|
||||
|
||||
<li>Tax Implications: Please be aware that in some countries, taxes will be due on the ZEC grant you receive
|
||||
(for the receipt of ZEC, when you sell/exchange it, or both). Specifically:
|
||||
|
||||
<ol>
|
||||
<li>Capital gain tax may be due if you later sell/exchange your ZEC for a higher price</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
</Modal>
|
||||
|
||||
<Form.Item
|
||||
label='Title'
|
||||
label="Title"
|
||||
validateStatus={errors.title ? 'error' : undefined}
|
||||
help={errors.title}
|
||||
>
|
||||
<Input
|
||||
size='large'
|
||||
name='title'
|
||||
placeholder='Short and sweet'
|
||||
type='text'
|
||||
size="large"
|
||||
name="title"
|
||||
placeholder="Short and sweet"
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={this.handleInputChange}
|
||||
maxLength={200}
|
||||
|
@ -228,13 +140,13 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label='Brief'
|
||||
label="Brief"
|
||||
validateStatus={errors.brief ? 'error' : undefined}
|
||||
help={errors.brief}
|
||||
>
|
||||
<Input.TextArea
|
||||
name='brief'
|
||||
placeholder='A one-liner elevator-pitch version of your proposal, max 140 chars.'
|
||||
name="brief"
|
||||
placeholder="A one-liner elevator-pitch version of your proposal, max 140 chars."
|
||||
value={brief}
|
||||
onChange={this.handleInputChange}
|
||||
rows={3}
|
||||
|
@ -243,7 +155,7 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label='Target amount'
|
||||
label="Target amount"
|
||||
validateStatus={errors.target ? 'error' : undefined}
|
||||
help={
|
||||
errors.target ||
|
||||
|
@ -251,13 +163,13 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
>
|
||||
<Input
|
||||
size='large'
|
||||
name='target'
|
||||
placeholder='1.5'
|
||||
type='number'
|
||||
size="large"
|
||||
name="target"
|
||||
placeholder="1.5"
|
||||
type="number"
|
||||
value={target}
|
||||
onChange={this.handleInputChange}
|
||||
addonBefore='$'
|
||||
addonBefore="$"
|
||||
maxLength={16}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
|
@ -80,17 +80,17 @@ class HeaderDrawer extends React.Component<Props> {
|
|||
<Menu.Item key="/proposals">
|
||||
<Link to="/proposals">Browse proposals</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="/create">
|
||||
<Link to="/create">Start a proposal</Link>
|
||||
</Menu.Item>
|
||||
{/*<Menu.Item key="/create">*/}
|
||||
{/* <Link to="/create">Start a proposal</Link>*/}
|
||||
{/*</Menu.Item>*/}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.ItemGroup title="Requests">
|
||||
<Menu.Item key="/requests">
|
||||
<Link to="/requests">Browse requests</Link>
|
||||
</Menu.Item>
|
||||
{/*<Menu.Item key="/create-request">*/}
|
||||
{/* <Link to="/create-request">Create a Request</Link>*/}
|
||||
{/*</Menu.Item>*/}
|
||||
<Menu.Item key="/create-request">
|
||||
<Link to="/create-request">Create a Request</Link>
|
||||
</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu>
|
||||
</Drawer>
|
||||
|
|
|
@ -105,6 +105,15 @@ class Header extends React.Component<Props, State> {
|
|||
)}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="Header-links-button is-desktop">
|
||||
<Link to="/create-request">
|
||||
{Array.isArray(ccrDrafts) && ccrDrafts.length > 0 ? (
|
||||
<Button type={'primary'}>My Requests</Button>
|
||||
) : (
|
||||
<Button type={'primary'}>Create a Request</Button>
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<HeaderAuth/>
|
||||
</div>
|
||||
|
|
|
@ -63,11 +63,11 @@
|
|||
&-logo {
|
||||
height: 2rem;
|
||||
width: auto;
|
||||
transform: scale(1.6) translateY(-7%);
|
||||
transform: translateY(-7%);
|
||||
transition: transform @header-transition ease;
|
||||
|
||||
.is-transparent & {
|
||||
transform: scale(2) translateY(18%);
|
||||
transform: scale(1.4) translateY(18%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ const HomeIntro: React.SFC<Props> = ({ t, authUser }) => (
|
|||
{t('home.intro.signup')}
|
||||
</Link>
|
||||
)}
|
||||
<Link className="HomeIntro-content-buttons-button" to="/create">
|
||||
Create a Proposal
|
||||
<Link className="HomeIntro-content-buttons-button" to="/create-request">
|
||||
{t('home.intro.ccr')}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { STATUS, UserProposal } from 'types';
|
||||
import { UserProposal, STATUS } from 'types';
|
||||
import './ProfileProposal.less';
|
||||
import UserRow from 'components/UserRow';
|
||||
import UnitDisplay from 'components/UnitDisplay';
|
||||
|
@ -23,8 +23,7 @@ export default class Profile extends React.Component<OwnProps> {
|
|||
isVersionTwo,
|
||||
acceptedWithFunding,
|
||||
status,
|
||||
changesRequestedDiscussionReason,
|
||||
fundedByZomg,
|
||||
changesRequestedDiscussionReason
|
||||
} = this.props.proposal;
|
||||
|
||||
// pulled from `variables.less`
|
||||
|
@ -32,24 +31,18 @@ export default class Profile extends React.Component<OwnProps> {
|
|||
const secondaryColor = '#2D2A26';
|
||||
|
||||
const isOpenForDiscussion = status === STATUS.DISCUSSION;
|
||||
const discussionColor = changesRequestedDiscussionReason ? 'red' : infoColor;
|
||||
const discussionTag = changesRequestedDiscussionReason
|
||||
? 'Changes Requested'
|
||||
: 'Open for Public Review';
|
||||
const discussionColor = changesRequestedDiscussionReason ? 'red' : infoColor
|
||||
const discussionTag = changesRequestedDiscussionReason ? 'Changes Requested' : 'Open for Public Review'
|
||||
|
||||
let tagColor = infoColor;
|
||||
let tagMessage = 'Open for Contributions';
|
||||
let tagColor = infoColor
|
||||
let tagMessage = 'Open for Contributions'
|
||||
|
||||
if (acceptedWithFunding) {
|
||||
tagColor = secondaryColor;
|
||||
if (!fundedByZomg) {
|
||||
tagMessage = 'Funded by ZF';
|
||||
} else {
|
||||
tagMessage = 'Funded by ZOMG';
|
||||
}
|
||||
tagColor = secondaryColor
|
||||
tagMessage = 'Funded by ZF'
|
||||
} else if (isOpenForDiscussion) {
|
||||
tagColor = discussionColor;
|
||||
tagMessage = discussionTag;
|
||||
tagColor = discussionColor
|
||||
tagMessage = discussionTag
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { Alert, Icon, Popover, Tooltip } from 'antd';
|
||||
import { Icon, Popover, Tooltip, Alert } from 'antd';
|
||||
import { Proposal, STATUS } from 'types';
|
||||
import classnames from 'classnames';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -12,8 +12,6 @@ import Loader from 'components/Loader';
|
|||
import { PROPOSAL_STAGE } from 'api/constants';
|
||||
import { formatUsd } from 'utils/formatters';
|
||||
import ZFGrantsLogo from 'static/images/logo-name-light.svg';
|
||||
import ZomgLogo from 'static/images/zomg-logo.png';
|
||||
|
||||
import './style.less';
|
||||
|
||||
interface OwnProps {
|
||||
|
@ -136,11 +134,7 @@ export class ProposalCampaignBlock extends React.Component<Props, State> {
|
|||
isAcceptedWithFunding && (
|
||||
<div className="ProposalCampaignBlock-with-funding">
|
||||
Funded through
|
||||
{proposal.fundedByZomg ? (
|
||||
<img src={ZomgLogo} alt={'Zomg logo'} style={{ height: '1.5rem' }} />
|
||||
) : (
|
||||
<ZFGrantsLogo style={{ height: '1.5rem' }} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ export class ProposalCard extends React.Component<Proposal> {
|
|||
percentFunded,
|
||||
acceptedWithFunding,
|
||||
status,
|
||||
fundedByZomg,
|
||||
} = this.props;
|
||||
|
||||
// pulled from `variables.less`
|
||||
|
@ -47,11 +46,7 @@ export class ProposalCard extends React.Component<Proposal> {
|
|||
if (isVersionTwo && status === STATUS.LIVE) {
|
||||
if (acceptedWithFunding) {
|
||||
tagColor = secondaryColor;
|
||||
if (!fundedByZomg) {
|
||||
tagMessage = 'Funded by ZF';
|
||||
} else {
|
||||
tagMessage = 'Funded by ZOMG';
|
||||
}
|
||||
} else {
|
||||
tagColor = infoColor;
|
||||
tagMessage = 'Not Funded';
|
||||
|
|
|
@ -83,8 +83,8 @@ export function getCreateErrors(
|
|||
}
|
||||
|
||||
// RFP opt-in
|
||||
if (!rfpOptIn) {
|
||||
errors.rfpOptIn = 'Please accept KYC to submit.';
|
||||
if (rfpOptIn === null) {
|
||||
errors.rfpOptIn = 'Please accept or decline KYC';
|
||||
}
|
||||
|
||||
// Title
|
||||
|
@ -260,7 +260,6 @@ export function makeProposalPreviewFromDraft(draft: ProposalDraft): ProposalDeta
|
|||
authedLiked: false,
|
||||
likesCount: 0,
|
||||
isVersionTwo: true,
|
||||
fundedByZomg: false,
|
||||
milestones: draft.milestones.map((m, idx) => ({
|
||||
id: idx,
|
||||
index: idx,
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import React from 'react';
|
||||
import MarkdownPage from 'components/MarkdownPage';
|
||||
import KYC from 'static/markdown/KYC.md';
|
||||
|
||||
const Kyc = () => <MarkdownPage markdown={KYC} />;
|
||||
|
||||
export default Kyc;
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 56 KiB |
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1300.8 419.2" style="enable-background:new 0 0 1300.8 419.2;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{display:none;}
|
||||
.st1{display:inline;fill:#100400;}
|
||||
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#0F7000;}
|
||||
.st4{fill:#FFFFFF;}
|
||||
.st5{fill:#F8BB14;}
|
||||
.st6{fill:none;stroke:#FFFFFF;stroke-width:24.24;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;}
|
||||
.st7{font-family:'Roboto-Medium';}
|
||||
.st8{font-size:304.0703px;}
|
||||
</style>
|
||||
<g id="Layer_2" class="st0">
|
||||
<rect x="-102.5" y="-82" class="st1" width="1515.7" height="567.6"/>
|
||||
</g>
|
||||
<g id="Layer_1" xmlns:serif="http://www.serif.com/">
|
||||
<g>
|
||||
<g transform="matrix(0.347046,-4.1523e-17,-1.03807e-17,0.347046,307.53,12.3394)">
|
||||
<g id="Color">
|
||||
<g>
|
||||
<g id="Color1" transform="matrix(1.09544,1.31066e-16,3.27664e-17,1.09544,-953.204,-33.2755)" serif:id="Color">
|
||||
<g transform="matrix(1.19303,-3.26522e-48,2.90837e-48,1.06265,-101.088,-115.302)">
|
||||
<rect x="572.7" y="564.3" class="st2" width="37.4" height="265.4"/>
|
||||
</g>
|
||||
<g transform="matrix(1,-2.73691e-48,2.73691e-48,1,0,-21.0434)">
|
||||
<path class="st3" d="M970,472.4c-7.7-25.6-24.4,55.7-167.7,79.1c-112.6,18.3-168.6,129.2-148.5,161.9
|
||||
c13.1,21.4,111.2,52.7,194.7-8.3C931.7,644.3,977.7,498,970,472.4z M651.6,707c3,5.4,78.8-15.7,123.6-40.6
|
||||
c52.8-29.3,108.9-79.9,104.4-85.7c-2.9-3.8-63.8,23.9-123.7,57.7C704.1,667.6,646.4,697.7,651.6,707z"/>
|
||||
</g>
|
||||
<g transform="matrix(1,-2.73691e-48,2.73691e-48,1,0,-21.0434)">
|
||||
<path class="st3" d="M295.5,443.5C308,424.7,306.9,490,436.7,528c102,29.9,131.7,123.6,106.1,146.1
|
||||
c-16.7,14.7-115.4,25.3-181.2-33.5C295.9,581.9,283,462.2,295.5,443.5z M544.7,672c-2.8,3.9-52.5-14.7-91.1-39
|
||||
c-30-19-76.9-55.4-64.6-63.8c5.6-3.8,41.1,21,77.6,44.2C504.4,637.4,550.2,664.4,544.7,672z"/>
|
||||
</g>
|
||||
<g transform="matrix(0.927915,-1.11022e-16,-2.77556e-17,0.927915,854.005,46.6736)">
|
||||
<g transform="matrix(1,0,0,1,-581.95,-44.2319)">
|
||||
<path class="st4" d="M312.2,514.8c-131.2,0-238-106.8-238-238c0-131.2,106.8-238,238-238c131.2,0,238,106.8,238,238
|
||||
C550.2,408,443.4,514.8,312.2,514.8z M312.2-8.3C155-8.3,27.1,119.6,27.1,276.8S155,561.9,312.2,561.9
|
||||
S597.3,434,597.3,276.8S469.4-8.3,312.2-8.3z"/>
|
||||
</g>
|
||||
<path class="st5" d="M-269.8,7.8c-123.9,0-224.7,100.8-224.7,224.7c0,123.9,100.8,224.7,224.7,224.7S-45.1,356.4-45.1,232.5
|
||||
C-45.1,108.6-145.9,7.8-269.8,7.8z M-168.1,143.7l-22,27.9l-98.6,135.7h120.6v57.6h-77.8v47.6h-5.7v0.2h-36.3v-0.2h-5.7
|
||||
v-47.6h-77.8v-43.5l22-27.9l98.6-135.7h-120.6v-57.6h77.8V52.5h47.8v47.7h77.8V143.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Hand" transform="matrix(1.23479,1.47739e-16,3.95e-17,1.32055,-1023.9,-346.117)">
|
||||
<path class="st6" d="M139.9,880c0,0,93-1.5,138.8-9.1c48.9-8.1,105.2-39.7,154.8-39.4c49.5,0.3,87.5,32.1,142.6,41.4
|
||||
c59,10,156.2,9.9,180.2,27.8c19.8,14.7,5.2,49.9-32.8,64c-26,9.7-73.4,19.4-110.9,19.1c-53.6-0.5-217.9-23.2-210.9-21.8
|
||||
c7,1.4,168.5,39.2,252.9,30.2c84.8-9,192.9-67.4,256.1-84.4c40-10.7,92.5-19.5,123.1-17.3c38.6,2.8,64,22.1,47.7,32.5
|
||||
c-57.7,36.8-263.6,156-393.9,188.1c-86.5,21.3-273,9.5-313,4.2c-60.9-8-98.3-24.4-139.4-53.2c-23.7-16.6-95.3-45.2-95.3-45.2
|
||||
V880z"/>
|
||||
</g>
|
||||
<g transform="matrix(121.473,1.45339e-14,3.31689e-15,110.889,-21599.6,-106761)">
|
||||
<text transform="matrix(2.598518e-02 0 0 2.598510e-02 181.6097 969.9001)" class="st4 st7 st8">zomg</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.7 KiB |
|
@ -1,6 +0,0 @@
|
|||
# KYC Policy
|
||||
|
||||
To execute a transfer of funds, the Zcash Foundation is legally required to comply with the requirements [described here](https://www.zfnd.org/about/aml-kyc-requirements/). Please send the following to <a href="mailto:grants@zfnd.org">grants@zfnd.org</a>, we are unable to send money until we receive this documentation:
|
||||
|
||||
- A photocopy of your state-issued identification (passport, driver’s license, etc.).
|
||||
- A filled-out form [W-9](https://www.irs.gov/pub/irs-pdf/fw9.pdf) (if US taxpayer) or [W-8BEN](https://www.irs.gov/pub/irs-pdf/fw8ben.pdf) (if nonresident alien individual), or a [W-8BEN-E](https://www.irs.gov/pub/irs-pdf/fw8bene.pdf) (if foreign corporation).
|
|
@ -43,6 +43,7 @@
|
|||
ul,
|
||||
ol {
|
||||
padding-left: 30px;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
|
@ -190,7 +190,6 @@
|
|||
"@types/storybook__react": "^3.0.9",
|
||||
"rimraf": "2.6.2",
|
||||
"string-hash": "1.1.3",
|
||||
"webapp-webpack-plugin": "2.3.1",
|
||||
"https-proxy-agent": "^2.2.3"
|
||||
"webapp-webpack-plugin": "2.3.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,7 +170,6 @@ export function generateProposal({
|
|||
liveDraftId: null,
|
||||
tipJarAddress: null,
|
||||
tipJarViewKey: null,
|
||||
fundedByZomg: false,
|
||||
arbiter: {
|
||||
status: PROPOSAL_ARBITER_STATUS.ACCEPTED,
|
||||
user: {
|
||||
|
|
|
@ -81,7 +81,6 @@ export interface Proposal extends Omit<ProposalDraft, 'target' | 'invites'> {
|
|||
liveDraftId: string | null;
|
||||
isTeamMember?: boolean; // FE derived
|
||||
isArbiter?: boolean; // FE derived
|
||||
fundedByZomg: boolean;
|
||||
}
|
||||
|
||||
export interface TeamInviteWithProposal extends TeamInvite {
|
||||
|
@ -125,7 +124,6 @@ export interface UserProposal {
|
|||
changesRequestedDiscussionReason: string | null;
|
||||
acceptedWithFunding: boolean | null;
|
||||
isVersionTwo: boolean;
|
||||
fundedByZomg: boolean;
|
||||
}
|
||||
|
||||
// NOTE: sync with backend/grant/proposal/models.py STATUSES
|
||||
|
|
|
@ -2438,13 +2438,6 @@ agent-base@^4.1.0:
|
|||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
"airbnb-js-shims@^1 || ^2":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.1.1.tgz#a509611480db7e6d9db62fe2acfaeb473b6842ac"
|
||||
|
@ -6537,14 +6530,6 @@ https-proxy-agent@2.2.1:
|
|||
agent-base "^4.1.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
dependencies:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
https-proxy@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy/-/https-proxy-0.0.2.tgz#9e7d542f1ce8d37c06e1f940a8a9a227bb48ddf0"
|
||||
|
|