Browse Source

Merge #733

733: Create CloseButton component that non-collaboratively closes when the… r=rishflab a=rishflab



Co-authored-by: rishflab <rishflab@hotmail.com>
chore/leaner-release-process
bors[bot] 3 years ago
committed by GitHub
parent
commit
ad46fd7a62
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      taker-frontend/src/App.tsx
  2. 76
      taker-frontend/src/components/CloseButton.tsx
  3. 76
      taker-frontend/src/components/History.tsx

2
taker-frontend/src/App.tsx

@ -132,6 +132,7 @@ export const App = () => {
isLongSubmitting={isCreatingNewOrderRequest} isLongSubmitting={isCreatingNewOrderRequest}
/> />
<History <History
connectedToMaker={connectedToMaker}
cfds={cfds.filter((cfd) => cfd.state.getGroup() !== StateGroupKey.CLOSED)} cfds={cfds.filter((cfd) => cfd.state.getGroup() !== StateGroupKey.CLOSED)}
title={"Open Positions"} title={"Open Positions"}
/> />
@ -152,6 +153,7 @@ export const App = () => {
cfds={cfds.filter((cfd) => cfds={cfds.filter((cfd) =>
cfd.state.getGroup() === StateGroupKey.CLOSED cfd.state.getGroup() === StateGroupKey.CLOSED
)} )}
connectedToMaker
/> />
</AccordionPanel> </AccordionPanel>
</AccordionItem> </AccordionItem>

76
taker-frontend/src/components/CloseButton.tsx

@ -0,0 +1,76 @@
import {
Box,
Button,
Popover,
PopoverArrow,
PopoverBody,
PopoverCloseButton,
PopoverContent,
PopoverFooter,
PopoverHeader,
PopoverTrigger,
Text,
} from "@chakra-ui/react";
import * as React from "react";
import { Cfd, StateGroupKey, StateKey } from "../types";
interface Props {
cfd: Cfd;
request: (req: any) => void;
status: boolean;
action: String;
}
/// Button that can be used to trigger non-collaborative close if the maker is offline and collaborative close if the
/// maker is online.
export default function CloseButton({ cfd, request, status, action }: Props) {
const disableCloseButton = cfd.state.getGroup() === StateGroupKey.CLOSED
|| !(cfd.state.key === StateKey.OPEN);
return <Box w={"45%"}>
<Popover
placement="bottom"
closeOnBlur={true}
>
{({ onClose }) => (<>
<PopoverTrigger>
<Button colorScheme={"blue"} disabled={disableCloseButton}>{action}</Button>
</PopoverTrigger>
<PopoverContent color="white" bg="blue.800" borderColor="blue.800">
<PopoverHeader pt={4} fontWeight="bold" border="0">
{action} your position
</PopoverHeader>
<PopoverArrow />
<PopoverCloseButton />
<PopoverBody>
<Text>
This will {action} your position with the counterparty. The exchange rate at {cfd
.expiry_timestamp}
will determine your profit/losses. It is likely that the rate will change until then.
</Text>
</PopoverBody>
<PopoverFooter
border="0"
d="flex"
alignItems="center"
justifyContent="space-between"
pb={4}
>
<Button
size="sm"
colorScheme="red"
onClick={() => {
console.log(`Closing CFD ${cfd.order_id}`);
request({});
onClose();
}}
isLoading={status}
>
{action}
</Button>
</PopoverFooter>
</PopoverContent>
</>)}
</Popover>
</Box>;
}

76
taker-frontend/src/components/History.tsx

@ -1,22 +1,12 @@
import { ExternalLinkIcon, Icon } from "@chakra-ui/icons"; import { ExternalLinkIcon, Icon } from "@chakra-ui/icons";
import { import {
Badge, Badge,
Box,
Button,
Center, Center,
Divider, Divider,
GridItem, GridItem,
Heading, Heading,
HStack, HStack,
Link, Link,
Popover,
PopoverArrow,
PopoverBody,
PopoverCloseButton,
PopoverContent,
PopoverFooter,
PopoverHeader,
PopoverTrigger,
SimpleGrid, SimpleGrid,
Spinner, Spinner,
Table, Table,
@ -28,15 +18,17 @@ import {
VStack, VStack,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import * as React from "react"; import * as React from "react";
import { Cfd, StateGroupKey, StateKey, Tx, TxLabel } from "../types"; import { Cfd, Tx, TxLabel } from "../types";
import usePostRequest from "../usePostRequest"; import usePostRequest from "../usePostRequest";
import CloseButton from "./CloseButton";
interface HistoryProps { interface HistoryProps {
cfds: Cfd[]; cfds: Cfd[];
title?: string; title?: string;
connectedToMaker: Boolean;
} }
const History = ({ cfds, title }: HistoryProps) => { const History = ({ cfds, title, connectedToMaker }: HistoryProps) => {
return ( return (
<VStack spacing={3}> <VStack spacing={3}>
{title {title
@ -47,7 +39,7 @@ const History = ({ cfds, title }: HistoryProps) => {
> >
{cfds.map((cfd) => { {cfds.map((cfd) => {
return (<GridItem rowSpan={1} colSpan={2} key={cfd.order_id}> return (<GridItem rowSpan={1} colSpan={2} key={cfd.order_id}>
<CfdDetails cfd={cfd} /> <CfdDetails cfd={cfd} connectedToMaker={connectedToMaker} />
</GridItem>); </GridItem>);
})} })}
</SimpleGrid> </SimpleGrid>
@ -59,9 +51,10 @@ export default History;
interface CfdDetailsProps { interface CfdDetailsProps {
cfd: Cfd; cfd: Cfd;
connectedToMaker: Boolean;
} }
const CfdDetails = ({ cfd }: CfdDetailsProps) => { const CfdDetails = ({ cfd, connectedToMaker }: CfdDetailsProps) => {
const initialPrice = `$${cfd.initial_price.toLocaleString()}`; const initialPrice = `$${cfd.initial_price.toLocaleString()}`;
const quantity = `$${cfd.quantity_usd}`; const quantity = `$${cfd.quantity_usd}`;
const margin = `${Math.round((cfd.margin) * 1_000_000) / 1_000_000}`; const margin = `${Math.round((cfd.margin) * 1_000_000) / 1_000_000}`;
@ -70,7 +63,6 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
const pAndLNumber = Math.round((cfd.profit_btc) * 1_000_000) / 1_000_000; const pAndLNumber = Math.round((cfd.profit_btc) * 1_000_000) / 1_000_000;
const pAndL = pAndLNumber < 0 ? `-₿${Math.abs(pAndLNumber)}` : `${Math.abs(pAndLNumber)}`; const pAndL = pAndLNumber < 0 ? `-₿${Math.abs(pAndLNumber)}` : `${Math.abs(pAndLNumber)}`;
const expiry = cfd.expiry_timestamp;
const payout = `${Math.round((cfd.margin + cfd.profit_btc) * 1_000_000) / 1_000_000}`; const payout = `${Math.round((cfd.margin + cfd.profit_btc) * 1_000_000) / 1_000_000}`;
const txLock = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Lock); const txLock = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Lock);
@ -80,9 +72,11 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
const txSettled = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Collaborative); const txSettled = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Collaborative);
let [settle, isSettling] = usePostRequest(`/api/cfd/${cfd.order_id}/settle`); let [settle, isSettling] = usePostRequest(`/api/cfd/${cfd.order_id}/settle`);
let [commit, isCommiting] = usePostRequest(`/api/cfd/${cfd.order_id}/commit`);
const disableCloseButton = cfd.state.getGroup() === StateGroupKey.CLOSED const closeButton = connectedToMaker
|| !(cfd.state.key === StateKey.OPEN); ? <CloseButton request={settle} status={isSettling} cfd={cfd} action="Close" />
: <CloseButton request={commit} status={isCommiting} cfd={cfd} action="Force Close" />;
return ( return (
<HStack bg={useColorModeValue("gray.100", "gray.700")} rounded={5} padding={2}> <HStack bg={useColorModeValue("gray.100", "gray.700")} rounded={5} padding={2}>
@ -157,53 +151,7 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
</>} </>}
</HStack> </HStack>
<HStack> <HStack>
<Box w={"45%"}> {closeButton}
<Popover
placement="bottom"
closeOnBlur={true}
>
{({ onClose }) => (<>
<PopoverTrigger>
<Button colorScheme={"blue"} disabled={disableCloseButton}>Close</Button>
</PopoverTrigger>
<PopoverContent color="white" bg="blue.800" borderColor="blue.800">
<PopoverHeader pt={4} fontWeight="bold" border="0">
Close your position
</PopoverHeader>
<PopoverArrow />
<PopoverCloseButton />
<PopoverBody>
<Text>
This will force-close your position if your counterparty cannot be reached.
The exchange rate at {expiry}
will determine your profit/losses. It is likely that the rate will change
until then.
</Text>
</PopoverBody>
<PopoverFooter
border="0"
d="flex"
alignItems="center"
justifyContent="space-between"
pb={4}
>
<Button
size="sm"
colorScheme="red"
onClick={() => {
console.log(`Settling CFD ${cfd.order_id}`);
settle({});
onClose();
}}
isLoading={isSettling}
>
Close
</Button>
</PopoverFooter>
</PopoverContent>
</>)}
</Popover>
</Box>
</HStack> </HStack>
</VStack> </VStack>
</HStack> </HStack>

Loading…
Cancel
Save