Merge branch 'develop' into anonymous-contributions
This commit is contained in:
commit
6f7de989e7
|
@ -50,7 +50,7 @@
|
|||
"@types/showdown": "^1.7.5",
|
||||
"@types/webpack": "4.4.17",
|
||||
"@types/webpack-env": "^1.13.6",
|
||||
"ant-design-pro": "2.0.0",
|
||||
"ant-design-pro": "2.2.1",
|
||||
"antd": "3.12.1",
|
||||
"axios": "^0.18.0",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
Button,
|
||||
Collapse,
|
||||
Popconfirm,
|
||||
Modal,
|
||||
Input,
|
||||
Switch,
|
||||
message,
|
||||
|
@ -29,14 +28,13 @@ import Back from 'components/Back';
|
|||
import Info from 'components/Info';
|
||||
import Markdown from 'components/Markdown';
|
||||
import ArbiterControl from 'components/ArbiterControl';
|
||||
import './index.less';
|
||||
import { toZat, fromZat } from 'src/util/units';
|
||||
import FeedbackModal from '../FeedbackModal';
|
||||
import './index.less';
|
||||
|
||||
type Props = RouteComponentProps<any>;
|
||||
|
||||
const STATE = {
|
||||
showRejectModal: false,
|
||||
rejectReason: '',
|
||||
paidTxId: '',
|
||||
};
|
||||
|
||||
|
@ -50,8 +48,7 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
}
|
||||
render() {
|
||||
const id = this.getIdFromQuery();
|
||||
const { proposalDetail: p, proposalDetailFetching, proposalDetailApproving } = store;
|
||||
const { rejectReason, showRejectModal } = this.state;
|
||||
const { proposalDetail: p, proposalDetailFetching } = store;
|
||||
|
||||
if (!p || (p && p.proposalId !== id) || proposalDetailFetching) {
|
||||
return 'loading proposal...';
|
||||
|
@ -65,7 +62,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
return m.datePaid ? prev - parseFloat(m.payoutPercent) : prev;
|
||||
}, 100);
|
||||
|
||||
|
||||
const renderDeleteControl = () => (
|
||||
<Popconfirm
|
||||
onConfirm={this.handleDelete}
|
||||
|
@ -81,13 +77,13 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
|
||||
const renderCancelControl = () => (
|
||||
<Popconfirm
|
||||
title={(
|
||||
title={
|
||||
<p>
|
||||
Are you sure you want to cancel proposal and begin
|
||||
<br />
|
||||
the refund process? This cannot be undone.
|
||||
</p>
|
||||
)}
|
||||
}
|
||||
placement="left"
|
||||
cancelText="cancel"
|
||||
okText="confirm"
|
||||
|
@ -181,35 +177,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
/>
|
||||
);
|
||||
|
||||
const rejectModal = (
|
||||
<Modal
|
||||
visible={showRejectModal}
|
||||
title="Reject this proposal"
|
||||
onOk={this.handleReject}
|
||||
onCancel={() => this.setState({ showRejectModal: false })}
|
||||
okButtonProps={{
|
||||
disabled: rejectReason.length === 0,
|
||||
loading: proposalDetailApproving,
|
||||
}}
|
||||
cancelButtonProps={{
|
||||
loading: proposalDetailApproving,
|
||||
}}
|
||||
>
|
||||
Please provide a reason ({!!rejectReason.length && `${rejectReason.length}/`}
|
||||
250 chars max):
|
||||
<Input.TextArea
|
||||
ref={ta => (this.rejectInput = ta)}
|
||||
rows={4}
|
||||
maxLength={250}
|
||||
required={true}
|
||||
value={rejectReason}
|
||||
onChange={e => {
|
||||
this.setState({ rejectReason: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
const renderReview = () =>
|
||||
p.status === PROPOSAL_STATUS.PENDING && (
|
||||
<Alert
|
||||
|
@ -232,16 +199,16 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
icon="close"
|
||||
type="danger"
|
||||
onClick={() => {
|
||||
this.setState({ showRejectModal: true });
|
||||
// hacky way of waiting for modal to render in before focus
|
||||
setTimeout(() => {
|
||||
if (this.rejectInput) this.rejectInput.focus();
|
||||
}, 200);
|
||||
FeedbackModal.open({
|
||||
title: 'Reject this proposal?',
|
||||
label: 'Please provide a reason:',
|
||||
okText: 'Reject',
|
||||
onOk: this.handleReject,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Reject
|
||||
</Button>
|
||||
{rejectModal}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
@ -357,21 +324,22 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
<Alert
|
||||
showIcon
|
||||
type="error"
|
||||
message={p.stage === PROPOSAL_STAGE.FAILED ? 'Proposal failed' : 'Proposal canceled'}
|
||||
message={
|
||||
p.stage === PROPOSAL_STAGE.FAILED ? 'Proposal failed' : 'Proposal canceled'
|
||||
}
|
||||
description={
|
||||
p.stage === PROPOSAL_STAGE.FAILED ? (
|
||||
<>
|
||||
This proposal failed to reach its funding goal of <b>{p.target} ZEC</b> by{' '}
|
||||
<b>{formatDateSeconds(p.datePublished + p.deadlineDuration)}</b>. All contributors
|
||||
will need to be refunded.
|
||||
<b>{formatDateSeconds(p.datePublished + p.deadlineDuration)}</b>. All
|
||||
contributors will need to be refunded.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
This proposal was canceled by an admin, and will be refunding contributors
|
||||
{' '}<b>{refundablePct}%</b> of their contributions.
|
||||
This proposal was canceled by an admin, and will be refunding contributors{' '}
|
||||
<b>{refundablePct}%</b> of their contributions.
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
@ -421,7 +389,6 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
{renderCancelControl()}
|
||||
{renderArbiterControl()}
|
||||
{renderMatchingControl()}
|
||||
{/* TODO - other actions */}
|
||||
</Card>
|
||||
|
||||
{/* DETAILS */}
|
||||
|
@ -502,9 +469,9 @@ class ProposalDetailNaked extends React.Component<Props, State> {
|
|||
store.approveProposal(true);
|
||||
};
|
||||
|
||||
private handleReject = async () => {
|
||||
await store.approveProposal(false, this.state.rejectReason);
|
||||
this.setState({ showRejectModal: false });
|
||||
private handleReject = async (reason: string) => {
|
||||
await store.approveProposal(false, reason);
|
||||
message.info('Proposal rejected');
|
||||
};
|
||||
|
||||
private handleToggleMatching = async () => {
|
||||
|
|
4385
admin/yarn.lock
4385
admin/yarn.lock
File diff suppressed because it is too large
Load Diff
|
@ -162,7 +162,7 @@ class ProposalContribution(db.Model):
|
|||
self.status = ContributionStatus.CONFIRMED
|
||||
self.tx_id = tx_id
|
||||
self.amount = amount
|
||||
|
||||
|
||||
@hybrid_property
|
||||
def refund_address(self):
|
||||
return self.user.settings.refund_address if self.user else None
|
||||
|
@ -218,7 +218,7 @@ class Proposal(db.Model):
|
|||
category = db.Column(db.String(255), nullable=False)
|
||||
date_approved = db.Column(db.DateTime)
|
||||
date_published = db.Column(db.DateTime)
|
||||
reject_reason = db.Column(db.String(255))
|
||||
reject_reason = db.Column(db.String())
|
||||
|
||||
# Payment info
|
||||
target = db.Column(db.String(255), nullable=False)
|
||||
|
|
|
@ -83,6 +83,7 @@ def get_user(user_id, with_proposals, with_comments, with_funded, with_pending,
|
|||
contributions = ProposalContribution.get_by_userid(user_id)
|
||||
if not authed_user or user.id != authed_user.id:
|
||||
contributions = [c for c in contributions if c.status == ContributionStatus.CONFIRMED]
|
||||
contributions = [c for c in contributions if c.proposal.status == ProposalStatus.LIVE]
|
||||
contributions_dump = user_proposal_contributions_schema.dump(contributions)
|
||||
result["contributions"] = contributions_dump
|
||||
if with_comments:
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
"""remove linkedin social_media items
|
||||
|
||||
Revision ID: 332a15eba9d8
|
||||
Revises: 7c7cecfe5e6c
|
||||
Create Date: 2019-02-23 19:51:16.284007
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '332a15eba9d8'
|
||||
down_revision = '7c7cecfe5e6c'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
connection = op.get_bind()
|
||||
connection.execute("DELETE FROM social_media WHERE service = 'LINKEDIN'")
|
||||
|
||||
|
||||
def downgrade():
|
||||
# there is no going back, all your precious linkedin profiles are gone now
|
||||
pass
|
|
@ -28,7 +28,7 @@ def upgrade():
|
|||
sa.Column('category', sa.String(length=255), nullable=False),
|
||||
sa.Column('date_approved', sa.DateTime(), nullable=True),
|
||||
sa.Column('date_published', sa.DateTime(), nullable=True),
|
||||
sa.Column('reject_reason', sa.String(length=255), nullable=True),
|
||||
sa.Column('reject_reason', sa.String(), nullable=True),
|
||||
sa.Column('target', sa.String(length=255), nullable=False),
|
||||
sa.Column('payout_address', sa.String(length=255), nullable=False),
|
||||
sa.Column('deadline_duration', sa.Integer(), nullable=False),
|
||||
|
|
|
@ -164,8 +164,7 @@ class ProfileEdit extends React.PureComponent<Props, State> {
|
|||
loading={loading}
|
||||
block
|
||||
>
|
||||
{!loading && s.icon}
|
||||
Connect to {s.name}
|
||||
{!loading && s.icon} <>Connect to {s.name}</>
|
||||
</Button>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
|
|
@ -125,7 +125,7 @@ class Profile extends React.Component<Props, State> {
|
|||
/>
|
||||
</Switch>
|
||||
<div className="Profile-tabs">
|
||||
<LinkableTabs defaultActiveKey="pending">
|
||||
<LinkableTabs defaultActiveKey={(isAuthedUser && 'pending') || 'created'}>
|
||||
{isAuthedUser && (
|
||||
<Tabs.TabPane
|
||||
tab={TabTitle('Pending', pendingProposals.length)}
|
||||
|
|
|
@ -16,12 +16,6 @@ export const SOCIAL_INFO: { [key in SOCIAL_SERVICE]: SocialInfo } = {
|
|||
format: `https://twitter.com/${accountNameRegex}`,
|
||||
icon: <Icon type="twitter" />,
|
||||
},
|
||||
[SOCIAL_SERVICE.LINKEDIN]: {
|
||||
service: SOCIAL_SERVICE.LINKEDIN,
|
||||
name: 'LinkedIn',
|
||||
format: `https://linkedin.com/in/${accountNameRegex}`,
|
||||
icon: <Icon type="linkedin" />,
|
||||
},
|
||||
};
|
||||
|
||||
export function socialMediaToUrl(service: SOCIAL_SERVICE, username: string): string {
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
"@types/webpack": "4.4.17",
|
||||
"@types/webpack-env": "^1.13.6",
|
||||
"@types/winston": "^2.4.4",
|
||||
"ant-design-pro": "2.0.0",
|
||||
"ant-design-pro": "2.2.1",
|
||||
"antd": "3.13.0",
|
||||
"axios": "^0.18.0",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
|
|
|
@ -18,5 +18,4 @@ export interface SocialInfo {
|
|||
export enum SOCIAL_SERVICE {
|
||||
GITHUB = 'GITHUB',
|
||||
TWITTER = 'TWITTER',
|
||||
LINKEDIN = 'LINKEDIN',
|
||||
}
|
||||
|
|
3494
frontend/yarn.lock
3494
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue