Skip to content

Commit

Permalink
#29 Improve user open orders functionality:
Browse files Browse the repository at this point in the history
 - add order cancelling
 - allow select user open order group
 - add assertions and tests
  • Loading branch information
priecint committed Jul 19, 2016
1 parent 4de46bf commit 589a60a
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 110 deletions.
14 changes: 7 additions & 7 deletions build/components.jsx

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/styles.css

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export default function (appElement, selectors) {
sideOptions={p.sideOptions}
updateSelectedOutcome={p.selectedOutcome.updateSelectedOutcome}
selectedOutcomeID={p.selectedOutcome.selectedOutcomeID}
updateSelectedUserOpenOrdersGroup={p.selectedUserOpenOrdersGroup.updateSelectedUserOpenOrdersGroup}
selectedUserOpenOrdersGroupID={p.selectedUserOpenOrdersGroup.selectedUserOpenOrdersGroupID}
cancelOrder={p.cancelOrder}
market={p.market}
numPendingReports={p.marketsTotals.numPendingReports}
/>
Expand Down
6 changes: 5 additions & 1 deletion src/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import siteHeader from '../test/assertions/site-header';
import transactions from '../test/assertions/transactions';
import transactionsTotals from '../test/assertions/transactions-totals';
import url from '../test/assertions/url';
import selectedUserOpenOrdersGroup from '../test/assertions/selected-user-open-orders-group';
import cancelOrder from '../test/assertions/cancel-order';

export default {
activePage,
Expand All @@ -45,5 +47,7 @@ export default {
siteHeader,
transactions,
transactionsTotals,
url
url,
selectedUserOpenOrdersGroup,
cancelOrder
};
8 changes: 7 additions & 1 deletion src/modules/market/components/market-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ export default class MarketPage extends Component {
sideOptions: PropTypes.array,
market: PropTypes.object,
priceTimeSeries: PropTypes.array,
numPendingReports: PropTypes.number
numPendingReports: PropTypes.number,
updateSelectedUserOpenOrdersGroup: PropTypes.func.isRequired,
cancelOrder: PropTypes.func.isRequired,
selectedUserOpenOrdersGroupID: PropTypes.string
};
constructor(props) {
super(props);
Expand Down Expand Up @@ -80,6 +83,9 @@ export default class MarketPage extends Component {
<OpenOrders
key="open-orders"
outcomes={p.market.outcomes}
selectedUserOpenOrdersGroupID={p.selectedUserOpenOrdersGroupID}
updateSelectedUserOpenOrdersGroup={p.updateSelectedUserOpenOrdersGroup}
cancelOrder={p.cancelOrder}
/>
);

Expand Down
10 changes: 8 additions & 2 deletions src/modules/market/components/open-orders.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const OpenOrders = (p) => (
<h2>Open orders</h2>
{
p.outcomes.map(outcome => {
if (outcome.userOpenOrders.items.length === 0) {
if (outcome.userOpenOrders.length === 0) {
return null;
}

Expand All @@ -17,6 +17,9 @@ const OpenOrders = (p) => (
id={outcome.id}
name={outcome.name}
userOpenOrders={outcome.userOpenOrders}
selectedUserOpenOrdersGroupID={p.selectedUserOpenOrdersGroupID}
updateSelectedUserOpenOrdersGroup={p.updateSelectedUserOpenOrdersGroup}
cancelOrder={p.cancelOrder}
/>
);
})
Expand All @@ -25,7 +28,10 @@ const OpenOrders = (p) => (
);

OpenOrders.propTypes = {
outcomes: React.PropTypes.array
outcomes: React.PropTypes.array,
updateSelectedUserOpenOrdersGroup: React.PropTypes.func.isRequired,
cancelOrder: React.PropTypes.func.isRequired,
selectedUserOpenOrdersGroupID: React.PropTypes.string
};

export default OpenOrders;
24 changes: 13 additions & 11 deletions src/modules/open-orders/components/open-order.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import classnames from 'classnames';
import ValueDenomination from '../../common/components/value-denomination';

const OpenOrder = (p) => (
<tr className={classnames('open-order', { isCancelling: p.isCancelling })}>
<tr className={classnames('open-order', { isDisabled: p.isCancelling || p.isCancelled })}>
<td>
{p.type}
</td>
Expand All @@ -27,24 +27,26 @@ const OpenOrder = (p) => (
<td>
<button
className="button cancel-order-action"
disabled={p.isCancelling}
disabled={p.isCancelling || p.isCancelled}
title="Cancel order"
onClick={(event) => { p.cancelOrder(p.id); }}
onClick={(event) => { p.cancelOrder(p.id, p.marketID, p.type); }}
>x</button>

</td>
</tr>
);

OpenOrder.propTypes = {
id: React.PropTypes.string,
type: React.PropTypes.string,
originalShares: React.PropTypes.object,
avgPrice: React.PropTypes.object,
matchedShares: React.PropTypes.object,
unmatchedShares: React.PropTypes.object,
isCancelling: React.PropTypes.bool,
onCancelOrder: React.PropTypes.func
id: React.PropTypes.string.isRequired,
marketID: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
originalShares: React.PropTypes.object.isRequired,
avgPrice: React.PropTypes.object.isRequired,
matchedShares: React.PropTypes.object.isRequired,
unmatchedShares: React.PropTypes.object.isRequired,
isCancelling: React.PropTypes.bool.isRequired,
isCancelled: React.PropTypes.bool.isRequired,
cancelOrder: React.PropTypes.func.isRequired
};

export default OpenOrder;
15 changes: 9 additions & 6 deletions src/modules/open-orders/components/open-orders-group.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import OpenOrder from '../../open-orders/components/open-order';

const OpenOrdersGroup = (p) => (
<div>
<Clickable component="h3" onClick={(event) => p.userOpenOrders.updateSelectedOpenOrdersGroup(p.id)}>
<Clickable component="h3" onClick={(event) => p.updateSelectedUserOpenOrdersGroup(p.id)}>
{p.name}
</Clickable>

<Collapse isOpen={p.id === p.userOpenOrders.selectedUserOpenOrdersGroup}>
<Collapse isOpen={p.id === p.selectedUserOpenOrdersGroupID}>
<table>
<tbody>
<tr>
Expand All @@ -27,11 +27,11 @@ const OpenOrdersGroup = (p) => (
<th>&nbsp;</th>
</tr>
{
p.userOpenOrders.items.map(openOrder => (
p.userOpenOrders.map(openOrder => (
<OpenOrder
key={openOrder.id}
{...openOrder}
cancelOrder={p.userOpenOrders.cancelOrder}
cancelOrder={p.cancelOrder}
/>
)
)
Expand All @@ -43,8 +43,11 @@ const OpenOrdersGroup = (p) => (
);

OpenOrdersGroup.propTypes = {
userOpenOrders: React.PropTypes.object,
name: React.PropTypes.string
userOpenOrders: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
name: React.PropTypes.string.isRequired,
updateSelectedUserOpenOrdersGroup: React.PropTypes.func.isRequired,
cancelOrder: React.PropTypes.func.isRequired,
selectedUserOpenOrdersGroupID: React.PropTypes.string
};

export default OpenOrdersGroup;
2 changes: 1 addition & 1 deletion src/modules/open-orders/less/open-order.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
display: none;
}

.open-order.isCancelling {
.open-order.isDisabled {
text-decoration: line-through;
}
}
30 changes: 29 additions & 1 deletion src/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import marketsTotals from './selectors/markets-totals';
import positionsMarkets from './selectors/positions-markets';
import positionsSummary from './selectors/positions-summary';
import url from './selectors/url';
import selectedUserOpenOrdersGroup from './selectors/selected-user-open-orders-group';

import { BID, ASK } from './modules/transactions/constants/types';

Expand All @@ -26,7 +27,8 @@ const selectors = {
marketsTotals,
positionsSummary,
positionsMarkets,
url
url,
selectedUserOpenOrdersGroup
};

// add update helper fn to selectors object
Expand Down Expand Up @@ -69,6 +71,32 @@ selectors.selectedOutcome = {
selectedOutcomeID: null
};

selectors.cancelOrder = (orderId) => {
setTimeout(() => {
selectors.markets.forEach((market) => {
market.outcomes.forEach(outcome => {
const order = outcome.userOpenOrders.find(openOrder => openOrder.id === orderId);
if (order != null) {
order.isCancelling = true;
module.exports.update({});
}
});
});
setTimeout(() => {
selectors.markets.forEach((market) => {
market.outcomes.forEach(outcome => {
const order = outcome.userOpenOrders.find(openOrder => openOrder.id === orderId);
if (order != null) {
const index = outcome.userOpenOrders.findIndex(openOrder => openOrder.id === orderId);
outcome.userOpenOrders.splice(index, 1);
module.exports.update({});
}
});
});
}, 2000);
}, 1);
};

selectors.searchSort.onChangeSort = (prop, isDesc) => {
let isDescending = isDesc;
if (isDesc !== false && isDesc !== true) {
Expand Down
90 changes: 39 additions & 51 deletions src/selectors/markets.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,59 +308,47 @@ function makeMarkets(numMarkets = 25) {
orderBook
};

outcome.userOpenOrders = {
selectedUserOpenOrdersGroup: null,
bidsCount: 2,
asksCount: 1,
items: [
{
id: 'order1',
type: 'sell',
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
},
{
id: 'order2',
type: 'buy',
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
},
{
id: 'order3',
type: 'buy',
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
}
],
updateSelectedOpenOrdersGroup: () => {
outcome.userOpenOrders.selectedUserOpenOrdersGroup = !outcome.userOpenOrders.selectedUserOpenOrdersGroup;
require('../selectors').update({});
outcome.userOpenOrders = [
{
id: `${m.id}${outcome.id}order1`,
type: 'sell',
marketID: m.id,
isCancelling: false,
isCancelled: false,
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
},
cancelOrder: (orderId) => {
console.log('cancelling order %o', orderId);
setTimeout(() => {
outcome.userOpenOrders.items.find(openOrder => openOrder.id === orderId).isCancelling = true;
require('../selectors').update({});
setTimeout(() => {
const index = outcome.userOpenOrders.items.findIndex(openOrder => openOrder.id === orderId);
outcome.userOpenOrders.items.splice(index, 1);
require('../selectors').update({});
}, 2000);
}, 1);
{
id: `${m.id}${outcome.id}order2`,
type: 'buy',
marketID: m.id,
isCancelling: false,
isCancelled: false,
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
},
{
id: `${m.id}${outcome.id}order3`,
type: 'buy',
marketID: m.id,
isCancelling: false,
isCancelled: false,
originalShares: makeNumber(5, 'shares'),
avgPrice: makeNumber(0.7, 'ether'),
matchedShares: makeNumber(3, 'shares'),
unmatchedShares: makeNumber(2, 'shares'),
outcome: 'outcomeasdf123',
owner: '0x45a153fdd97836c2b349a5f53970dc44b0ef1efa'
}
};
];

return outcome;

Expand Down
12 changes: 12 additions & 0 deletions src/selectors/selected-user-open-orders-group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default {
selectedUserOpenOrdersGroupID: null,
updateSelectedUserOpenOrdersGroup: (selectedUserOpenOrdersGroupID) => {
const selectors = require('../selectors');
selectors.update({
selectedUserOpenOrdersGroup: {
...selectors.selectedUserOpenOrdersGroup,
selectedUserOpenOrdersGroupID
}
});
}
};
9 changes: 9 additions & 0 deletions test/assertions/cancel-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { assert } from 'chai';

export default function (cancelOrder) {
describe('augur-ui-react-components cancelOrder', () => {
it('should exist', () => {
assert.isFunction(cancelOrder, `cancelOrder is not function.`);
});
});
};
30 changes: 2 additions & 28 deletions test/assertions/market.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,34 +338,8 @@ export default function(market) {
assert.isDefined(userOpenOrders);
});

it('should be object', () => {
assert.isObject(userOpenOrders);
});

describe('items', () => {
it('should be array', () => {
assert.isArray(userOpenOrders.items);
});
});

describe('selectedUserOpenOrdersGroup', () => {
it('should be null or string', () => {
const isNull = userOpenOrders.selectedUserOpenOrdersGroup === null;
const isString = typeof userOpenOrders.selectedUserOpenOrdersGroup === 'string';
assert(isNull || isString, 'selectedUserOpenOrdersGroup is not null or string');
});
});

describe('updateSelectedOpenOrdersGroup', () => {
it('should be function', () => {
assert.isFunction(userOpenOrders.updateSelectedOpenOrdersGroup);
});
});

describe('cancelOrder', () => {
it('should be function', () => {
assert.isFunction(userOpenOrders.cancelOrder);
});
it('should be array', () => {
assert.isArray(userOpenOrders);
});
});
});
Expand Down
Loading

0 comments on commit 589a60a

Please sign in to comment.