diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-stop-order.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-stop-order.tsx index 4e481a509..8c7e84e05 100644 --- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-stop-order.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-stop-order.tsx @@ -35,8 +35,15 @@ import { normalizeOrderSubmission } from '@vegaprotocol/wallet'; import { ExpirySelector } from './expiry-selector'; import { SideSelector } from './side-selector'; import { timeInForceLabel } from '@vegaprotocol/orders'; -import { SummaryValidationType } from '../../constants'; import { NoWalletWarning } from './deal-ticket'; +import { + create, + type Mutate, + type StateCreator, + type StoreApi, + type UseBoundStore, +} from 'zustand'; +import { persist, subscribeWithSelector } from 'zustand/middleware'; export interface StopOrderFormValues { side: Side; @@ -55,10 +62,54 @@ export interface StopOrderFormValues { expire: boolean; expiryStrategy?: 'submit' | 'cancel'; expiresAt?: string; - - summary: undefined; } +type StopOrderFormValuesMap = { + [marketId: string]: Partial | undefined; +}; + +type Update = ( + marketId: string, + formValues: Partial, + persist?: boolean +) => void; + +interface Store { + formValues: StopOrderFormValuesMap; + update: Update; +} + +export const STORAGE_KEY = 'vega_stop_order_store'; + +const orderStateCreator: StateCreator = (set) => ({ + formValues: {}, + update: (marketId, formValues, persist = true) => { + set((state) => { + return { + formValues: { + ...state.formValues, + [marketId]: { + ...state.formValues[marketId], + ...formValues, + }, + }, + }; + }); + }, +}); + +let store: UseBoundStore, []>> | null = null; +const getFormValuesStore = () => { + if (!store) { + store = create()( + persist(subscribeWithSelector(orderStateCreator), { + name: STORAGE_KEY, + }) + ); + } + return store as UseBoundStore, []>>; +}; + export const mapInputToStopOrdersSubmission = ( data: StopOrderFormValues, marketId: string, @@ -161,25 +212,32 @@ const toggles = [ { label: t('Market'), value: Schema.OrderType.TYPE_MARKET }, ]; +const defaultValues: Partial = { + type: Schema.OrderType.TYPE_MARKET, + side: Schema.Side.SIDE_SELL, + timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK, + trigger: 'price', + direction: 'risesAbove', + expiryStrategy: 'submit', +}; + export const StopOrder = ({ market, submit }: StopOrderProps) => { const { pubKey, isReadOnly } = useVegaWallet(); + const useFormValuesStoreRef = useRef(getFormValuesStore()); + const updateStoredFormValues = useFormValuesStoreRef.current( + (state) => state.update + ); + const storedFormValues = useFormValuesStoreRef.current( + (state) => state.formValues[market.id] + ); const { // register, handleSubmit, watch, control, formState, - setError, - clearErrors, } = useForm({ - defaultValues: { - type: Schema.OrderType.TYPE_MARKET, - side: Schema.Side.SIDE_SELL, - timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK, - trigger: 'price', - direction: 'risesAbove', - expiryStrategy: 'submit', - }, + defaultValues: { ...defaultValues, ...storedFormValues }, }); const { errors } = formState; const lastSubmitTime = useRef(0); @@ -207,6 +265,13 @@ export const StopOrder = ({ market, submit }: StopOrderProps) => { const triggerPrice = watch('triggerPrice'); const type = watch('type'); + useEffect(() => { + const subscription = watch((value, { name, type }) => { + updateStoredFormValues(market.id, value); + }); + return () => subscription.unsubscribe(); + }, [watch, market.id, updateStoredFormValues]); + const { quoteName, settlementAsset } = market.tradableInstrument.instrument.product; const { symbol: assetSymbol } = settlementAsset; @@ -219,18 +284,6 @@ export const StopOrder = ({ market, submit }: StopOrderProps) => { trigger === 'price' && triggerPrice ? formatNumber(triggerPrice, market.decimalPlaces) : undefined; - useEffect(() => { - if (!pubKey) { - setError('summary', { - message: t('No public key selected'), - type: SummaryValidationType.NoPubKey, - }); - return; - } - - // No error found above clear the error in case it was active on a previous render - clearErrors('summary'); - }, [pubKey, setError, clearErrors]); return (
{ [marketId, _update] ); - // add new order to store if it doesnt exist, but don't + // add new order to store if it doesn't exist, but don't // persist until user has edited useEffect(() => { if (!order) { update( getDefaultOrder(marketId), - false // dont persist the order + false // don't persist the order ); } }, [order, marketId, update]);