Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to see orders of all coins in the order panel [WIP] #377

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions orko-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions orko-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"reconnecting-websocket": "^4.1.10",
"redux": "^4.0.1",
"redux-batched-actions": "^0.4.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"seamless-immutable": "^7.1.4",
Expand Down
3 changes: 2 additions & 1 deletion orko-ui/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ import * as socket from "./store/socket/connect"
import ErrorContainer from "./containers/ErrorContainer"
import AuthContainer from "./containers/AuthContainer"
import FrameworkContainer from "./FrameworkContainer"
import { composeWithDevTools } from "redux-devtools-extension"

import * as authActions from "./store/auth/actions"

const history = createHistory()

const store = createStore(
enableBatching(createRootReducer(history)),
compose(
composeWithDevTools(
applyMiddleware(routerMiddleware(history), thunk.withExtraArgument(socket))
)
)
Expand Down
43 changes: 43 additions & 0 deletions orko-ui/src/components/OpenOrders.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Href from "../components/primitives/Href"
import * as dateUtils from "../util/dateUtils"
import Price from "../components/primitives/Price"
import Amount from "../components/primitives/Amount"
import { Link } from "react-router-dom"

const textStyle = {
textAlign: "left"
Expand Down Expand Up @@ -83,6 +84,46 @@ const runningAtColumn = {
width: 32
}

const exchangeColumn = {
id: "exchange",
Header: "Exchange",
accessor: "exchange",
Cell: ({ original }) => (
<Link
data-orko={original.coin.key + "/exchange"}
to={"/coin/" + original.coin.key}
title="Open coin"
>
{original.exchangeMeta
? original.exchangeMeta.name
: original.coin.exchange}
</Link>
),
headerStyle: textStyle,
style: textStyle,
resizable: true,
minWidth: 40
}

const nameColumn = {
id: "name",
Header: "Name",
accessor: "shortName",
Cell: ({ original }) => (
<Link
data-orko={original.coin.key + "/name"}
to={"/coin/" + original.coin.key}
title="Open coin"
>
{original.coin.shortName}
</Link>
),
headerStyle: textStyle,
style: textStyle,
resizable: true,
minWidth: 50
}

const createdDateColumn = {
id: "createdDate",
accessor: "timestamp",
Expand Down Expand Up @@ -228,6 +269,8 @@ const OpenOrders = props => (
cancelColumn(props.onCancelExchange, props.onCancelServer),
orderTypeColumn,
runningAtColumn,
exchangeColumn,
nameColumn,
createdDateColumn,
limitPriceColumn(props.coin),
stopPriceColumn(props.coin),
Expand Down
50 changes: 36 additions & 14 deletions orko-ui/src/selectors/coins.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { createSelector } from "reselect"
import { getRouterLocation } from "./router"
import { getAlertJobs, getStopJobs } from "./jobs"
import { coinFromKey } from "../util/coinUtils"
import { coinFromKey, coinFromTicker } from "../util/coinUtils"

const getCoins = state => state.coins.coins
const getReferencePrices = state => state.coins.referencePrices
Expand Down Expand Up @@ -65,7 +65,14 @@ function jobTriggerMatchesCoin(job, coin) {
)
}

function serverJobDecorate(job) {
function orderDecorate(order, exchanges) {
return {
...order,
exchangeMeta: exchanges.find(e => e.code === order.coin.exchange)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do this find once and pass it to both decorate methods.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but for all coins' order, still need to find for each order, so I just left it there.

}
}

function serverJobDecorate(job, exchanges) {
return {
runningAt: "SERVER",
jobId: job.id,
Expand All @@ -85,40 +92,55 @@ function serverJobDecorate(job) {
originalAmount: job.high
? Number(job.high.job.amount)
: Number(job.low.job.amount),
cumulativeAmount: "--"
cumulativeAmount: "--",
coin: coinFromTicker(job.tickTrigger),
exchangeMeta: exchanges.find(e => e.code === job.tickTrigger.exchange)
}
}

export const getOrdersForSelectedCoin = createSelector(
[getOrders, getStopJobs, getSelectedCoin],
(orders, stopJobs, selectedCoin) => {
[getOrders, getStopJobs, getExchanges, getSelectedCoin],
(orders, stopJobs, exchanges, selectedCoin) => {
if (!selectedCoin) return null

var result = !orders ? [] : orders.filter(o => !o.deleted)
var result = !(orders && orders[selectedCoin.key])
? []
: orders[selectedCoin.key]
.filter(o => !o.deleted)
.map(order => orderDecorate(order, exchanges))

const server = stopJobs
.filter(job => jobTriggerMatchesCoin(job, selectedCoin))
.map(job => serverJobDecorate(job))
.map(job => serverJobDecorate(job, exchanges))

result = result.concat(server)

if (result.length === 0 && !orders) return null

return result
}
)

export const getOrdersForAllCoin = createSelector(
[getOrders, getStopJobs],
(orders, stopJobs) => {
var result = !orders ? [] : orders.filter(o => !o.deleted)
[getOrders, getStopJobs, getExchanges],
(orders, stopJobs, exchanges) => {
if (!orders) return null
let mergeOrders = []
Object.keys(orders).forEach(function(key) {
orders[key].forEach(function(item) {
mergeOrders.push(item)
})
})

const server = stopJobs.map(job => serverJobDecorate(job))
var result = !mergeOrders
? []
: mergeOrders
.filter(o => !o.deleted)
.map(order => orderDecorate(order, exchanges))

const server = stopJobs.map(job => serverJobDecorate(job, exchanges))

result = result.concat(server)

if (result.length === 0 && !orders) return null

return result
}
)
Expand Down
4 changes: 2 additions & 2 deletions orko-ui/src/store/coin/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function clearBalances() {
return { type: types.CLEAR_BALANCES }
}

export function orderUpdated(order, timestamp) {
return { type: types.ORDER_UPDATED, payload: { order, timestamp } }
export function orderUpdated(coin, order, timestamp) {
return { type: types.ORDER_UPDATED, payload: { coin, order, timestamp } }
}

export function clearOrders() {
Expand Down
97 changes: 68 additions & 29 deletions orko-ui/src/store/coin/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ export default function reduce(state = initialState, action = {}) {
userTradeHistory: undefined
})
case types.ORDER_UPDATED:
return orderUpdated(state, action.payload.order, action.payload.timestamp)
return orderUpdated(
state,
action.payload.coin,
action.payload.order,
action.payload.timestamp
)
case types.CLEAR_ORDERS:
return Immutable.merge(state, {
orders: undefined
Expand All @@ -90,71 +95,105 @@ export default function reduce(state = initialState, action = {}) {
})
}

function orderUpdated(state, order, timestamp) {
function orderUpdated(state, coin, order, timestamp) {
if (order === null) {
return Immutable.merge(state, {
orders: []
})
return Immutable.merge(
state,
{
orders: {
[coin.key]: []
}
},
{ deep: true }
)
}

// add coin property to order
order.coin = coin

const isRemoval =
order.status === "EXPIRED" ||
order.status === "CANCELED" ||
order.status === "FILLED"

// No orders at all yet
if (!state.orders) {
// No orders for this con at all yet
if (!state.orders[coin.key]) {
if (isRemoval) return state
return Immutable.merge(state, {
orders: [
{
...order,
deleted: false,
serverTimestamp: timestamp
return Immutable.merge(
state,
{
orders: {
[coin.key]: [
{
...order,
deleted: false,
serverTimestamp: timestamp
}
]
}
]
})
},
{ deep: true }
)
}

// This order never seen before
const index = state.orders.findIndex(o => o.id === order.id)
const index = state.orders[coin.key].findIndex(o => o.id === order.id)
if (index === -1) {
if (isRemoval) return state
return Immutable.merge(state, {
orders: state.orders.concat({
...order,
deleted: false,
serverTimestamp: timestamp
})
})
return Immutable.merge(
state,
{
orders: {
[coin.key]: [
state.orders[coin.key].concat({
...order,
deleted: false,
serverTimestamp: timestamp
})
]
}
},
{ deep: true }
)
}

// If we've previously registered the order as removed, then assume
// this update is late and stop
const prevVersion = state.orders[index]
const prevVersion = state.orders[coin.key][index]
if (prevVersion.deleted) return state

// If it's a removal, remove
if (isRemoval) return replaceOrderContent(index, { deleted: true })
if (isRemoval) return replaceOrderContent(index, coin, { deleted: true })

// If the previous version is derived from a later timestamp than
// this update, stop
if (prevVersion.serverTimestamp > timestamp) return state

// Overwrite existing state with any values provided in the
// update
return replaceOrderContent(index, { ...order, serverTimestamp: timestamp })
return replaceOrderContent(index, coin, {
...order,
serverTimestamp: timestamp
})
}

function replaceOrderContent(index, replacement) {
const orders = Immutable.asMutable(state.orders, { deep: true })
function replaceOrderContent(index, coin, replacement) {
const orders = Immutable.asMutable(state.orders[coin.key], { deep: true })
const existing = orders[index]
for (const key of Object.keys(replacement)) {
const val = replacement[key]
if (val !== undefined && val !== null) {
existing[key] = val
}
}
return Immutable.merge(state, { orders })
return Immutable.merge(
state,
{
orders: {
[coin.key]: orders
}
},
{ deep: true }
)
}
}
Loading