Skip to content
This repository was archived by the owner on Apr 4, 2022. It is now read-only.

Adding signature pending orderStatus #826

Merged
merged 7 commits into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
3 changes: 2 additions & 1 deletion src/api/operator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface FeeInformation {

export type OrderKind = 'sell' | 'buy'

export type OrderStatus = 'open' | 'filled' | 'canceled' | 'expired'
export type OrderStatus = 'open' | 'filled' | 'cancelled' | 'expired' | 'signing'
export type RawOrderStatusFromAPI = 'presignaturePending' | 'open' | 'fullfilled' | 'cancelled' | 'expired'

// Raw API response
export type RawOrder = {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/explorer/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AnalyticsDimension, Network } from 'types'

/** Explorer app constants */
export const ORDER_QUERY_INTERVAL = 10000 // in ms
export const ORDERS_QUERY_INTERVAL = 30000 // in ms
export const ORDERS_QUERY_INTERVAL = 25000 // in ms
export const ORDERS_HISTORY_MINUTES_AGO = 10 // in minutes

export const DISPLAY_TEXT_COPIED_CHECK = 1000 // in ms
Expand Down
11 changes: 7 additions & 4 deletions src/components/orders/StatusLabel/StatusLabel.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ Filled.args = { status: 'filled' }
export const Expired = Template.bind({})
Expired.args = { status: 'expired' }

export const Canceled = Template.bind({})
Canceled.args = { status: 'canceled' }
export const Cancelled = Template.bind({})
Cancelled.args = { status: 'cancelled' }

export const Open = Template.bind({})
Open.args = { status: 'open' }

export const Signing = Template.bind({})
Signing.args = { status: 'signing' }

export const OpenPartiallyFilled = Template.bind({})
OpenPartiallyFilled.args = { status: 'open', partiallyFilled: true }
export const ExpiredPartiallyFilled = Template.bind({})
ExpiredPartiallyFilled.args = { status: 'expired', partiallyFilled: true }
export const CanceledPartiallyFilled = Template.bind({})
CanceledPartiallyFilled.args = { status: 'canceled', partiallyFilled: true }
export const CancelledPartiallyFilled = Template.bind({})
CancelledPartiallyFilled.args = { status: 'cancelled', partiallyFilled: true }
42 changes: 36 additions & 6 deletions src/components/orders/StatusLabel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import React from 'react'
import styled, { DefaultTheme } from 'styled-components'
import styled, { DefaultTheme, css, keyframes, FlattenSimpleInterpolation } from 'styled-components'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCheckCircle, faCircleNotch, faClock, faTimesCircle, IconDefinition } from '@fortawesome/free-solid-svg-icons'
import {
faCheckCircle,
faCircleNotch,
faClock,
faTimesCircle,
IconDefinition,
faKey,
} from '@fortawesome/free-solid-svg-icons'

import { OrderStatus } from 'api/operator'

Expand All @@ -12,7 +19,7 @@ function setStatusColors({ theme, status }: { theme: DefaultTheme; status: Order

switch (status) {
case 'expired':
case 'canceled':
case 'cancelled':
text = theme.orange
background = theme.orangeOpacity
break
Expand All @@ -21,6 +28,7 @@ function setStatusColors({ theme, status }: { theme: DefaultTheme; status: Order
background = theme.greenOpacity
break
case 'open':
case 'signing':
text = theme.labelTextOpen
background = theme.labelBgOpen
break
Expand All @@ -37,8 +45,16 @@ const Wrapper = styled.div`
align-items: center;
font-size: ${({ theme }): string => theme.fontSizeDefault};
`
const frameAnimation = keyframes`
100% {
-webkit-mask-position: left;
}
`
type ShimmingProps = {
shimming?: boolean
}

const Label = styled.div<DisplayProps>`
const Label = styled.div<DisplayProps & ShimmingProps>`
font-weight: ${({ theme }): string => theme.fontBold};
text-transform: capitalize;
border-radius: 0.4rem;
Expand All @@ -47,6 +63,17 @@ const Label = styled.div<DisplayProps>`
display: flex;
align-items: center;
${({ theme, status }): string => setStatusColors({ theme, status })}
${({ shimming }): FlattenSimpleInterpolation | null =>
shimming
? css`
display: inline-block;
-webkit-mask: linear-gradient(-60deg, #000 30%, #0005, #000 70%) right/300% 100%;
mask: linear-gradient(-60deg, #000 30%, #0005, #000 70%) right/300% 100%;
background-repeat: no-repeat;
animation: shimmer 1.5s infinite;
animation-name: ${frameAnimation};
`
: null}
`

const StyledFAIcon = styled(FontAwesomeIcon)`
Expand All @@ -65,8 +92,10 @@ function getStatusIcon(status: OrderStatus): IconDefinition {
return faClock
case 'filled':
return faCheckCircle
case 'canceled':
case 'cancelled':
return faTimesCircle
case 'signing':
return faKey
case 'open':
return faCircleNotch
}
Expand All @@ -83,10 +112,11 @@ export type Props = DisplayProps & { partiallyFilled: boolean }

export function StatusLabel(props: Props): JSX.Element {
const { status, partiallyFilled } = props
const shimming = status === 'signing'

return (
<Wrapper>
<Label status={status}>
<Label status={status} shimming={shimming}>
<StatusIcon status={status} />
{status}
</Label>
Expand Down
14 changes: 12 additions & 2 deletions src/utils/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { calculatePrice, invertPrice, TokenErc20 } from '@gnosis.pm/dex-js'

import { FILLED_ORDER_EPSILON, ONE_BIG_NUMBER, ZERO_BIG_NUMBER } from 'const'

import { Order, OrderStatus, RawOrder, RawTrade, Trade } from 'api/operator/types'
import { Order, OrderStatus, RawOrderStatusFromAPI, RawOrder, RawTrade, Trade } from 'api/operator/types'

import { formattingAmountPrecision, formatSmartMaxPrecision } from 'utils'

Expand Down Expand Up @@ -40,13 +40,23 @@ function isOrderPartiallyFilled(order: RawOrder): boolean {
}
}

export interface RawOrderWithStatus extends RawOrder {
status: RawOrderStatusFromAPI
}

function isOrderPresigning(order: RawOrder): boolean {
return (order as RawOrderWithStatus).status === 'presignaturePending'
}

export function getOrderStatus(order: RawOrder): OrderStatus {
if (isOrderFilled(order)) {
return 'filled'
} else if (order.invalidated) {
return 'canceled'
return 'cancelled'
} else if (isOrderExpired(order)) {
return 'expired'
} else if (isOrderPresigning(order)) {
return 'signing'
} else {
return 'open'
}
Expand Down
56 changes: 51 additions & 5 deletions test/utils/operator/orderStatus.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RawOrder } from 'api/operator'
import { RawOrder, RawOrderStatusFromAPI } from 'api/operator'

import { getOrderStatus } from 'utils'
import { getOrderStatus, RawOrderWithStatus } from 'utils'

import { RAW_ORDER } from '../../data'
import { mockTimes, DATE } from '../../testHelpers'
Expand Down Expand Up @@ -121,7 +121,7 @@ describe('Canceled status', () => {
buyAmount: '10000',
invalidated: true,
}
expect(getOrderStatus(order)).toEqual('canceled')
expect(getOrderStatus(order)).toEqual('cancelled')
})
test('Sell order', () => {
const order: RawOrder = {
Expand All @@ -130,7 +130,7 @@ describe('Canceled status', () => {
sellAmount: '10000',
invalidated: true,
}
expect(getOrderStatus(order)).toEqual('canceled')
expect(getOrderStatus(order)).toEqual('cancelled')
})
test('Expired and invalidated', () => {
const order: RawOrder = {
Expand All @@ -140,7 +140,7 @@ describe('Canceled status', () => {
invalidated: true,
validTo: _getPastTimestamp(),
}
expect(getOrderStatus(order)).toEqual('canceled')
expect(getOrderStatus(order)).toEqual('cancelled')
})
})

Expand Down Expand Up @@ -241,3 +241,49 @@ describe('Open status', () => {
})
})
})

describe('Presignature pending status', () => {
describe('Buy order', () => {
test('signature is pending', () => {
const statusFetched: RawOrderStatusFromAPI = 'presignaturePending'

const order: RawOrderWithStatus = {
...RAW_ORDER,
kind: 'buy',
status: statusFetched,
buyAmount: '10000',
executedBuyAmount: '0',
validTo: _getCurrentTimestamp(),
}
expect(getOrderStatus(order)).toEqual('signing')
})
test('signature is not pending', () => {
const statusFetched: RawOrderStatusFromAPI = 'open'

const order: RawOrderWithStatus = {
...RAW_ORDER,
kind: 'buy',
status: statusFetched,
buyAmount: '10000',
executedBuyAmount: '0',
validTo: _getCurrentTimestamp(),
}
expect(getOrderStatus(order)).not.toEqual('signing')
})
})
describe('Sell order', () => {
test('signature is pending', () => {
const statusFetched: RawOrderStatusFromAPI = 'presignaturePending'

const order: RawOrderWithStatus = {
...RAW_ORDER,
kind: 'sell',
status: statusFetched,
sellAmount: '10000',
executedSellAmount: '0',
validTo: _getCurrentTimestamp(),
}
expect(getOrderStatus(order)).toEqual('signing')
})
})
})