feat: add additional hook to handle order creation if not existing

This commit is contained in:
Matthew Russell
2023-03-02 09:50:51 -08:00
parent a563a87daa
commit 6ffc22a940
6 changed files with 50 additions and 32 deletions
@@ -13,7 +13,7 @@ export interface DealTicketAmountProps {
market: Market;
sizeError?: string;
priceError?: string;
update: (obj: Partial<OrderObj> & { marketId: string }) => void;
update: (obj: Partial<OrderObj>) => void;
size: string;
price: string;
}
@@ -68,9 +68,7 @@ export const DealTicketLimitAmount = ({
className="w-full"
type="number"
value={size}
onChange={(e) =>
update({ marketId: market.id, size: e.target.value })
}
onChange={(e) => update({ size: e.target.value })}
step={sizeStep}
min={sizeStep}
data-testid="order-size"
@@ -109,9 +107,7 @@ export const DealTicketLimitAmount = ({
className="w-full"
type="number"
value={price}
onChange={(e) =>
update({ marketId: market.id, price: e.target.value })
}
onChange={(e) => update({ price: e.target.value })}
step={priceStep}
data-testid="order-price"
onWheel={(e) => e.currentTarget.blur()}
@@ -67,9 +67,7 @@ export const DealTicketMarketAmount = ({
className="w-full"
type="number"
value={size}
onChange={(e) =>
update({ marketId: market.id, size: e.target.value })
}
onChange={(e) => update({ size: e.target.value })}
step={sizeStep}
min={sizeStep}
onWheel={(e) => e.currentTarget.blur()}
@@ -61,7 +61,8 @@ export const DealTicket = ({
onClickCollateral,
}: DealTicketProps) => {
const { pubKey, isReadOnly } = useVegaWallet();
// store last used tif for market
// store last used tif for market so that when chaning OrderType the previous TIF
// selection for that type is used when switching back
const [lastTIF, setLastTIF] = useState({
[OrderType.TYPE_MARKET]: OrderTimeInForce.TIME_IN_FORCE_IOC,
[OrderType.TYPE_LIMIT]: OrderTimeInForce.TIME_IN_FORCE_GTC,
@@ -156,8 +157,7 @@ export const DealTicket = ({
[checkForErrors, submit, market.decimalPlaces, market.positionDecimalPlaces]
);
console.log('render');
// just return null, if an order doesn't exist one will be created by the store
if (!order) return null;
return (
@@ -181,7 +181,6 @@ export const DealTicket = ({
onSelect={(type) => {
if (type === OrderType.TYPE_NETWORK) return;
update({
marketId: market.id,
type,
timeInForce: lastTIF[type] || order.timeInForce,
});
@@ -199,7 +198,7 @@ export const DealTicket = ({
<SideSelector
value={order.side}
onSelect={(side) => {
update({ marketId: market.id, side });
update({ side });
}}
/>
)}
@@ -229,7 +228,7 @@ export const DealTicket = ({
value={order.timeInForce}
orderType={order.type}
onSelect={(timeInForce) => {
update({ marketId: market.id, timeInForce });
update({ timeInForce });
setLastTIF((curr) => ({ ...curr, [order.type]: timeInForce }));
}}
market={market}
@@ -248,7 +247,6 @@ export const DealTicket = ({
value={order.expiresAt}
onSelect={(expiresAt) =>
update({
marketId: market.id,
expiresAt: expiresAt || undefined,
})
}
+5 -13
View File
@@ -1,5 +1,5 @@
import type { OrderObj } from '@vegaprotocol/orders';
import { createOrder, useOrderStore } from '@vegaprotocol/orders';
import { createOrder, useOrder } from '@vegaprotocol/orders';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
@@ -8,9 +8,7 @@ export type OrderFormFields = OrderObj & {
};
export const useOrderForm = (marketId: string) => {
const [order, update] = useOrderStore((store) => {
return [store.orders[marketId], store.update];
});
const [order, update] = useOrder(marketId);
const {
control,
formState: { errors },
@@ -23,15 +21,9 @@ export const useOrderForm = (marketId: string) => {
defaultValues: order || createOrder(marketId),
});
// add new order to store if it doesn exist
useEffect(() => {
if (!order) {
console.log('update here');
update(createOrder(marketId));
}
}, [order, marketId, update]);
// update useForm field state with values on change of html input
// Keep form fields in sync with the store values,
// inputs are updating the store, fields need updating
// to ensure validation rules are applied
useEffect(() => {
const currOrder = getValues();
for (const k in order) {
@@ -1,5 +1,6 @@
import { OrderTimeInForce, Side } from '@vegaprotocol/types';
import { OrderType } from '@vegaprotocol/types';
import { useCallback, useEffect } from 'react';
import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware';
@@ -13,10 +14,13 @@ export interface OrderObj {
expiresAt: string | undefined;
}
type UpdateOrder = (order: Partial<OrderObj> & { marketId: string }) => void;
interface Store {
orders: { [marketId: string]: OrderObj };
update: (order: Partial<OrderObj> & { marketId: string }) => void;
orders: { [marketId: string]: OrderObj | undefined };
update: UpdateOrder;
}
export const useOrderStore = create<Store>()(
persist(
subscribeWithSelector((set) => ({
@@ -42,6 +46,36 @@ export const useOrderStore = create<Store>()(
)
);
/**
* Retrieves an order from the store and creates one if it doesn't
* exist
*/
export const useOrder = (marketId: string) => {
const [order, _update] = useOrderStore((store) => {
return [store.orders[marketId], store.update];
});
const update = useCallback(
(o: Partial<OrderObj>) => {
_update({
marketId,
...o,
});
},
[marketId, _update]
);
// add new order to store if it doesn exist
useEffect(() => {
if (!order) {
console.log('update here');
update(createOrder(marketId));
}
}, [order, marketId, update]);
return [order, update] as const; // make result a tuple
};
export const createOrder = (marketId: string): OrderObj => ({
marketId,
type: OrderType.TYPE_MARKET,