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 all 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
4 changes: 3 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 All @@ -41,6 +42,7 @@ export type RawOrder = {
kind: OrderKind
partiallyFillable: boolean
signature: string
status: RawOrderStatusFromAPI
}

/**
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
8 changes: 7 additions & 1 deletion src/utils/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@ function isOrderPartiallyFilled(order: RawOrder): boolean {
}
}

function isOrderPresigning(order: RawOrder): boolean {
return order.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
1 change: 1 addition & 0 deletions test/data/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const RAW_ORDER: RawOrder = {
partiallyFillable: false,
signature:
'0x04dca25f59e9ac744c4093530a38f1719c4e0b1ce8e4b68c8018b6b05fd4a6944e1dcf2a009df2d5932f7c034b4a24da0999f9309dd5108d51d54236b605ed991c',
status: 'open',
}

export const RICH_ORDER: Order = {
Expand Down
54 changes: 50 additions & 4 deletions test/utils/operator/orderStatus.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RawOrder } from 'api/operator'
import { RawOrder, RawOrderStatusFromAPI } from 'api/operator'

import { getOrderStatus } from 'utils'

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: RawOrder = {
...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: RawOrder = {
...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: RawOrder = {
...RAW_ORDER,
kind: 'sell',
status: statusFetched,
sellAmount: '10000',
executedSellAmount: '0',
validTo: _getCurrentTimestamp(),
}
expect(getOrderStatus(order)).toEqual('signing')
})
})
})