Skip to content
This repository has been archived by the owner on Dec 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2534 from Giveth/F_2533_Add_filters_to_my-delegat…
Browse files Browse the repository at this point in the history
…ions

F 2533 add filters to my delegations
  • Loading branch information
aminlatifi authored Sep 8, 2021
2 parents e587c44 + e350232 commit 46e1bda
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 138 deletions.
5 changes: 2 additions & 3 deletions src/components/layout/MainMenu/ManageMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const ManageMenu = () => {
return (
<nav id="manage_menu">
<div className="px-3 d-flex align-items-center">
<div style={{ flex: '0 0 10%', fontWeight: '500', fontSize: '24px' }}>Manage</div>
<div className="d-flex justify-content-center" style={{ flex: '0 0 80%' }}>
<div style={{ fontWeight: '500', fontSize: '24px' }}>Manage</div>
<div className="d-flex justify-content-center w-100">
<Menu theme="dark" mode="horizontal" selectedKeys={[pathname]}>
<Menu.Item key="/my-traces">
<Link to="/my-traces">Traces</Link>
Expand All @@ -29,7 +29,6 @@ const ManageMenu = () => {
</Menu.Item>
</Menu>
</div>
<div className="d-none d-sm-block" style={{ flex: '0 0 10%' }} />
</div>
</nav>
);
Expand Down
112 changes: 61 additions & 51 deletions src/components/views/myDelegations/DelegateButton.jsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,92 @@
import React, { Component } from 'react';
import BigNumber from 'bignumber.js';
import React, { Fragment, useContext, useState } from 'react';
import { Modal } from 'antd';
import Web3 from 'web3';
import PropTypes from 'prop-types';

import Donation from 'models/Donation';
import { authenticateUser, checkBalance } from '../../../lib/middleware';
import User from '../../../models/User';
import DelegateButtonModal from './DelegateButtonModal';
import ErrorHandler from '../../../lib/ErrorHandler';
import { Context as Web3Context } from '../../../contextProviders/Web3Provider';
import { Context as ConversionRateContext } from '../../../contextProviders/ConversionRateProvider';
import { Context as UserContext } from '../../../contextProviders/UserProvider';

const modalStyles = {
minWidth: '60%',
maxWidth: '800px',
};

// FIXME: We need slider component that uses bignumbers, there are some precision issues here
class DelegateButton extends Component {
constructor(props) {
super(props);
const bodyElement = document.getElementsByTagName('body');

this.state = {
modalVisible: false,
};
this.closeDialog = this.closeDialog.bind(this);
}
// FIXME: We need slider component that uses bignumber, there are some precision issues here
const DelegateButton = props => {
const {
state: { web3, isForeignNetwork, balance },
actions: { displayForeignNetRequiredWarning },
} = useContext(Web3Context);
const {
actions: { getConversionRates },
} = useContext(ConversionRateContext);
const {
state: { currentUser },
} = useContext(UserContext);

async openDialog() {
const authenticated = await authenticateUser(this.props.currentUser, false, this.props.web3);
const [modalVisible, setModalVisible] = useState(false);

const openDialog = async () => {
const authenticated = await authenticateUser(currentUser, false, web3);
if (!authenticated) {
return;
}
checkBalance(this.props.balance)

if (!isForeignNetwork) {
displayForeignNetRequiredWarning();
return;
}

checkBalance(balance)
.then(() => {
this.setState({
modalVisible: true,
});
// Hide overflow when modal opens due to Ant select dropdown bug
bodyElement[0].classList.add('overflow-hidden');
setModalVisible(true);
})
.catch(err => ErrorHandler(err, 'Something went wrong on getting user balance.'));
}

closeDialog() {
this.setState({
modalVisible: false,
});
}
};

render() {
const style = { display: 'inline-block' };
const closeDialog = () => {
// Show overflow when modal closes due to Ant select dropdown bug
bodyElement[0].classList.remove('overflow-hidden');
setModalVisible(false);
};

return (
<span style={style}>
<button type="button" className="btn btn-success btn-sm" onClick={() => this.openDialog()}>
Delegate
</button>
return (
<Fragment>
<button type="button" className="btn btn-success btn-sm" onClick={openDialog}>
Delegate
</button>

<Modal
visible={this.state.modalVisible}
onCancel={this.closeDialog}
footer={null}
centered
destroyOnClose
className="pb-0 custom-ant-modal"
style={modalStyles}
>
<DelegateButtonModal {...this.props} closeDialog={this.closeDialog} />
</Modal>
</span>
);
}
}
<Modal
visible={modalVisible}
onCancel={closeDialog}
footer={null}
centered
destroyOnClose
className="pb-0 custom-ant-modal"
style={modalStyles}
>
<DelegateButtonModal
{...props}
web3={web3}
closeDialog={closeDialog}
getConversionRates={getConversionRates}
/>
</Modal>
</Fragment>
);
};

DelegateButton.propTypes = {
balance: PropTypes.instanceOf(BigNumber).isRequired,
traceOnly: PropTypes.bool,
donation: PropTypes.instanceOf(Donation).isRequired,
currentUser: PropTypes.instanceOf(User).isRequired,
web3: PropTypes.instanceOf(Web3).isRequired,
};

DelegateButton.defaultProps = {
Expand Down
32 changes: 2 additions & 30 deletions src/components/views/myDelegations/DelegationsItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,12 @@ import DelegateButton from './DelegateButton';
import config from '../../../configuration';
import { convertEthHelper, getUserAvatar, getUserName } from '../../../lib/helpers';
import { Context as UserContext } from '../../../contextProviders/UserProvider';
import { Context as Web3Provider } from '../../../contextProviders/Web3Provider';
import { Context as ConversionRateContext } from '../../../contextProviders/ConversionRateProvider';
import Campaign from '../../../models/Campaign';

function DelegationsItem({ donation }) {
const {
state: { currentUser },
} = useContext(UserContext);
const {
state: { balance, isForeignNetwork, web3 },
} = useContext(Web3Provider);
const {
actions: { getConversionRates },
} = useContext(ConversionRateContext);

return (
<tr>
Expand All @@ -30,34 +22,14 @@ function DelegationsItem({ donation }) {
to campaigns and traces */}
{(donation.delegateId > 0 ||
(currentUser.address && donation.ownerTypeId === currentUser.address)) &&
isForeignNetwork &&
donation.status === Donation.WAITING &&
donation.amountRemaining > 0 && (
<DelegateButton
web3={web3}
donation={donation}
balance={balance}
currentUser={currentUser}
symbol={(donation.token && donation.token.symbol) || config.nativeTokenName}
getConversionRates={getConversionRates}
/>
)}
donation.amountRemaining > 0 && <DelegateButton donation={donation} />}

{/* When donated to a campaign, only allow delegation
to traces of that campaign */}
{donation.ownerType === Campaign.type &&
isForeignNetwork &&
donation.status === Donation.COMMITTED &&
donation.amountRemaining > 0 && (
<DelegateButton
web3={web3}
donation={donation}
getConversionRates={getConversionRates}
balance={balance}
currentUser={currentUser}
traceOnly
/>
)}
donation.amountRemaining > 0 && <DelegateButton donation={donation} traceOnly />}
</td>

<td className="td-date">{moment(donation.createdAt).format('MM/DD/YYYY')}</td>
Expand Down
22 changes: 10 additions & 12 deletions src/components/views/myDelegations/DelegationsTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function DelegationsTable({
<div className="dashboard-table-view">
{delegations && delegations.length > 0 && (
<div className="table-container">
<table className="table table-responsive table-striped table-hover">
<table className="table table-responsive table-striped table-hover mt-3">
<thead>
<tr>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
Expand Down Expand Up @@ -50,17 +50,15 @@ function DelegationsTable({
</div>
)}
{delegations && delegations.length === 0 && (
<div>
<div className="text-center">
<h3>There&apos;s nothing to delegate (yet)!</h3>
<img
className="empty-state-img"
src={`${process.env.PUBLIC_URL}/img/delegation.svg`}
width="200px"
height="200px"
alt="no-delegations-icon"
/>
</div>
<div className="text-center mt-5">
<h3>There&apos;s nothing to delegate (yet)!</h3>
<img
className="empty-state-img"
src={`${process.env.PUBLIC_URL}/img/delegation.svg`}
width="200px"
height="200px"
alt="no-delegations-icon"
/>
</div>
)}
</div>
Expand Down
57 changes: 35 additions & 22 deletions src/components/views/myDelegations/GetDonations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,58 @@ const GetDonations = ({
skipPages,
onResult,
onError,
subscribe = false,
subscribe,
}) => {
// here we get all the ids.
// TODO: less overhead here if we move it all to a single service.
// NOTE: This will not rerun, meaning after any dac/campaign/trace is added

if (userAddress) {
const communitiesIds = communities.map(c => c._id);
const campaignIds = campaigns.map(c => c._id);
const communitiesIds = communities && communities.map(c => c._id);
const campaignIds = campaigns && campaigns.map(c => c._id);

const $or = [];

if (campaignIds)
$or.push({
ownerTypeId: { $in: campaignIds },
status: Donation.COMMITTED,
});

if (communitiesIds)
$or.push({
delegateTypeId: { $in: communitiesIds },
status: { $in: [Donation.WAITING, Donation.TO_APPROVE] },
});

if ((!campaignIds && !communitiesIds) || (campaignIds && communitiesIds))
$or.push(
{
ownerTypeId: userAddress,
delegateId: { $exists: false },
status: Donation.WAITING,
},
// {
// ownerTypeId: userAddress,
// delegateTypeId: { $gt: 0 },
// },
);

const query = paramsForServer({
query: {
lessThanCutoff: { $ne: true },
$or: [
{ ownerTypeId: { $in: campaignIds }, status: Donation.COMMITTED },
{
delegateTypeId: { $in: communitiesIds },
status: { $in: [Donation.WAITING, Donation.TO_APPROVE] },
},
{
ownerTypeId: userAddress,
delegateId: { $exists: false },
status: Donation.WAITING,
},
// {
// ownerTypeId: userAddress,
// delegateTypeId: { $gt: 0 },
// },
],
$sort: { createdAt: 1 },
$or,
$sort: { createdAt: -1 },
$limit: itemsPerPage,
$skip: skipPages * itemsPerPage,
},
schema: 'includeTypeAndGiverDetails',
});

if (subscribe) DonationService.subscribe(query, onResult, onError);
else DonationService.getDonations(query, onResult, onError);
if (subscribe) return DonationService.subscribe(query, onResult, onError);
return DonationService.getDonations(query, onResult, onError);
}
return null;
};

export default GetDonations;
2 changes: 1 addition & 1 deletion src/components/views/myDelegations/LoadProjectsInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const LoadProjectsInfo = async userAddress => {
query: {
status: Community.ACTIVE,
ownerAddress: userAddress,
$select: ['_id'],
$select: ['_id', 'title'],
$limit: 100,
$sort: {
createdAt: -1,
Expand Down
Loading

0 comments on commit 46e1bda

Please sign in to comment.