@orderly.network/ui-tpsl 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
package/dist/index.d.mts
CHANGED
|
@@ -15,7 +15,9 @@ type TPSLBuilderOptions = {
|
|
|
15
15
|
*/
|
|
16
16
|
onConfirm?: (order: ComputedAlgoOrder, options: {
|
|
17
17
|
position: API.Position;
|
|
18
|
-
submit: (
|
|
18
|
+
submit: (params?: {
|
|
19
|
+
accountId?: string;
|
|
20
|
+
}) => Promise<any>;
|
|
19
21
|
cancel: () => Promise<any>;
|
|
20
22
|
}) => Promise<boolean>;
|
|
21
23
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,9 @@ type TPSLBuilderOptions = {
|
|
|
15
15
|
*/
|
|
16
16
|
onConfirm?: (order: ComputedAlgoOrder, options: {
|
|
17
17
|
position: API.Position;
|
|
18
|
-
submit: (
|
|
18
|
+
submit: (params?: {
|
|
19
|
+
accountId?: string;
|
|
20
|
+
}) => Promise<any>;
|
|
19
21
|
cancel: () => Promise<any>;
|
|
20
22
|
}) => Promise<boolean>;
|
|
21
23
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
|
-
var ui = require('@orderly.network/ui');
|
|
5
4
|
var hooks = require('@orderly.network/hooks');
|
|
6
|
-
var utils = require('@orderly.network/utils');
|
|
7
5
|
var i18n = require('@orderly.network/i18n');
|
|
8
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
-
var types = require('@orderly.network/types');
|
|
10
6
|
var reactApp = require('@orderly.network/react-app');
|
|
7
|
+
var types = require('@orderly.network/types');
|
|
8
|
+
var ui = require('@orderly.network/ui');
|
|
9
|
+
var utils = require('@orderly.network/utils');
|
|
10
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
11
11
|
|
|
12
|
-
var J=e=>{let{type:t,values:o}=e,[i,a]=hooks.useLocalStorage("TP/SL_Mode","Offset%"),[l,p]=react.useState(true),{t:g}=i18n.useTranslation(),r=react.useMemo(()=>{switch(i){case "Offset":return `${t.toLowerCase()}_offset`;case "Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[i]),P=react.useMemo(()=>o[i],[o,i]),_=react.useMemo(()=>[{label:g("tpsl.pnl"),value:"PnL",testId:"PnL_menu_item"},{label:g("tpsl.offset"),value:"Offset",testId:"Offset_mneu_item"},{label:`${g("tpsl.offset")}%`,value:"Offset%",testId:"Offset%_menu_item"}],[g]),m=react.useRef(""),T=c=>{e.onChange(r,c);},x=c=>{let{dp:u=2}=c;return {onRenderBefore:(s,L)=>(s=`${s}`,l&&t==="SL"&&i==="PnL"&&(s=s.startsWith("-")?s:"-"+s),s===""||s==="-"?"":i==="Offset%"?`${new utils.Decimal(s.replace(new RegExp(m.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${m.current}`:(i==="Offset"&&(s=utils.todpIfNeed(s,u)),`${s}`)),onSendBefore:s=>{if(/^\-?0{2,}$/.test(s))return "0";if(i==="Offset%"){if(s!==""){s=utils.todpIfNeed(s,2);let L=s.match(/\.0{0,2}$/);L?m.current=L[0]:m.current="",s=new utils.Decimal(s).div(100).toString(),s=`${s}${m.current}`;}}else i==="PnL"&&t==="SL"&&l?s=s.startsWith("-")?s:"-"+s:s=utils.todpIfNeed(s,u);return s===""||s==="-"?"":s}}};return {mode:i,modes:_,type:e.type,formatter:x,onModeChange:c=>{a(c);},value:P,pnl:o.PnL,onValueChange:T,quote_dp:e.quote_dp,setFocus:p}};var te=e=>{let{mode:t,modes:o,onModeChange:i,onValueChange:a,quote:l,quote_dp:p,value:g,pnl:r}=e,{t:P}=i18n.useTranslation(),[_,m]=react.useState(t),[T,x]=react.useState(t==="Offset%"?"%":l),c=react.useMemo(()=>{let u=Number(r);if(isNaN(u)||u===0)return "";if(u>0)return "oui-text-trade-profit";if(u<0)return "oui-text-trade-loss"},[r]);return react.useEffect(()=>{let u=o.find(s=>s.value===t)?.label;m(u),x(t==="Offset%"?"%":l);},[t,o]),jsxRuntime.jsx(ui.Input,{prefix:_,size:{initial:"lg",lg:"md"},placeholder:T,align:"right",value:g,"data-testid":e.testId,autoComplete:"off",onValueChange:a,formatters:[e.formatter({dp:p,mode:t}),ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter],classNames:{input:c,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{x(""),e.setFocus(true);},onBlur:()=>{x(t==="Offset%"?"%":l),e.setFocus(false);},suffix:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t==="Offset%"&&!!g&&jsxRuntime.jsx(ui.Text,{size:"2xs",color:"inherit",className:ui.cn("oui-ml-[2px]",c),children:"%"}),jsxRuntime.jsx(Ae,{mode:t,modes:o,onModeChange:u=>i(u.value)})]})})},Ae=e=>jsxRuntime.jsx(ui.SimpleDropdownMenu,{currentValue:e.mode,menu:e.modes,align:"end",size:"xs",className:"oui-min-w-[80px]",onSelect:t=>e.onModeChange(t),children:jsxRuntime.jsx("button",{className:"oui-p-2",children:jsxRuntime.jsx(ui.CaretDownIcon,{size:12,color:"white"})})});var U=e=>{let{testId:t,quote:o,...i}=e,a=J(i);return jsxRuntime.jsx(te,{...a,testId:t,quote:o})};var le=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:i,onComplete:a,status:l,errors:p,isPosition:g}=e,{t:r}=i18n.useTranslation(),{parseErrorMsg:P}=reactApp.useOrderEntryFormErrorMsg(p);return jsxRuntime.jsxs("div",{id:"orderly-tp_sl-order-edit-content",children:[(!e.isEditing||e.isEditing&&!e.isPosition)&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Ke,{maxQty:e.maxQty,quantity:e.orderQuantity??e.maxQty,baseTick:o("base_tick"),dp:o("base_dp"),onQuantityChange:e.setQuantity,quote:o("base"),isEditing:e.isEditing,isPosition:g,errorMsg:P("quantity")}),jsxRuntime.jsx(ui.Divider,{my:4,intensity:8})]}),jsxRuntime.jsx(Ye,{sl_pnl:t.sl_pnl,tp_pnl:t.tp_pnl,quote:o("quote"),quote_dp:o("quote_dp"),onPriceChange:e.setOrderPrice,onPnLChange:e.setPnL,errors:p,tp_values:{PnL:`${t.tp_pnl??""}`,Offset:`${t.tp_offset??""}`,"Offset%":`${t.tp_offset_percentage??""}`},sl_values:{PnL:`${t.sl_pnl??""}`,Offset:`${t.sl_offset??""}`,"Offset%":`${t.sl_offset_percentage??""}`},tp_trigger_price:t.tp_trigger_price??"",sl_trigger_price:t.sl_trigger_price??""}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:3,mt:4,children:[jsxRuntime.jsx(ui.Button,{size:"md",color:"secondary","data-testid":"tpsl-cancel",onClick:()=>{i?.();},children:r("common.cancel")}),jsxRuntime.jsx(ui.ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||l.isCreateMutating,loading:l.isCreateMutating||l.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{a?.();},()=>{});},children:r("common.confirm")})]})]})},Ke=e=>{let{isPosition:t}=e,o=react.useRef(null),i=ui.convertValueToPercentage(e.quantity,0,e.maxQty)/100,{t:a}=i18n.useTranslation(),l=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},p=r=>{if(e.baseTick>0){e.onQuantityChange?.(hooks.utils.formatNumber(r,e.baseTick)??r);}},g=(t?"":e.quantity).toString().length>0?e.errorMsg:void 0;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(ui.Flex,{gap:2,children:[jsxRuntime.jsx("div",{className:"oui-flex-1",children:jsxRuntime.jsx(ui.Input.tooltip,{"data-testid":"oui-testid-tpsl-popUp-quantity-input",ref:o,prefix:a("common.quantity"),size:{initial:"lg",lg:"md"},align:"right",value:t?"":e.quantity,autoComplete:"off",classNames:{prefix:"oui-text-base-contrast-54",root:ui.cn("oui-bg-base-5 oui-outline-line-12",g&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:g,color:g?"danger":void 0,formatters:[ui.inputFormatter.dpFormatter(e.dp),ui.inputFormatter.numberFormatter,ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter],onValueChange:r=>{e.onQuantityChange?.(r);let P=Number(r);if(P&&P>e.maxQty){let _=t?0:e.maxQty;e.onQuantityChange?.(_),o.current?.blur();}},onBlur:r=>p(r.target.value),suffix:t?jsxRuntime.jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{l();},children:a("tpsl.entirePosition")}):jsxRuntime.jsx("span",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",children:e.quote})})}),!e.isEditing&&jsxRuntime.jsx(ui.Button,{onClick:()=>{let r=t?0:e.maxQty;e.onQuantityChange?.(r),r===0&&l();},variant:"outlined",className:ui.cn("oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]",t?"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20":"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5"),children:a("common.position")})]}),jsxRuntime.jsx(ui.Flex,{mt:2,itemAlign:"center",height:"15px",children:jsxRuntime.jsx(ui.Slider.single,{markCount:5,color:"primary",max:e.maxQty,min:0,showTip:true,step:e.baseTick,value:e.quantity,onValueCommit:r=>{p(`${r}`);},onValueChange:r=>{e.onQuantityChange?.(r);}})}),jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text.numeral,{rule:"percentages",color:"primary",size:"2xs",children:i}),jsxRuntime.jsxs(ui.Flex,{itemAlign:"center",gap:1,children:[jsxRuntime.jsx("button",{className:"oui-leading-none",style:{lineHeight:0},onClick:()=>{e.onQuantityChange?.(e.maxQty);},children:jsxRuntime.jsx(ui.Text,{color:"primary",size:"2xs",children:a("common.max")})}),jsxRuntime.jsx(ui.Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},Ye=e=>{let{t}=i18n.useTranslation(),{parseErrorMsg:o}=reactApp.useOrderEntryFormErrorMsg(e.errors),i=(a,l)=>{e.onPnLChange(a,l);};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:80,children:t("tpsl.takeProfit")}),jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(re,{type:"TP",value:e.tp_trigger_price,error:o("tp_trigger_price"),onValueChange:a=>{e.onPriceChange("tp_trigger_price",a);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(U,{type:"TP",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:80,children:t("tpsl.stopLoss")}),jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(re,{type:"SL",value:e.sl_trigger_price,error:o("sl_trigger_price"),onValueChange:a=>{e.onPriceChange("sl_trigger_price",a);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(U,{type:"SL",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},re=e=>{let[t,o]=react.useState("USDC"),{t:i}=i18n.useTranslation();return jsxRuntime.jsx(ui.Input.tooltip,{"data-testid":`oui-testid-tpsl-popUp-${e.type.toLowerCase()}-input`,prefix:i("common.markPrice"),size:{initial:"lg",lg:"md"},tooltip:e.error,placeholder:t,align:"right",autoComplete:"off",value:e.value,color:e.error?"danger":void 0,classNames:{prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onValueChange:e.onValueChange,onFocus:()=>{o("");},onBlur:()=>{o("USDC");},formatters:[ui.inputFormatter.numberFormatter,ui.inputFormatter.dpFormatter(e.quote_dp),ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter]})},B=e=>{let{symbol:t,tpPrice:o,slPrice:i,qty:a,maxQty:l,side:p,quoteDP:g,baseDP:r,isEditing:P,isPositionTPSL:_}=e,{t:m}=i18n.useTranslation(),[T,x]=hooks.useLocalStorage("orderly_order_confirm",true),c=ui.textVariants({size:"xs",intensity:54}),u=_??a>=l;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[P&&jsxRuntime.jsx(ui.Text,{as:"div",size:"2xs",intensity:80,className:"oui-mb-3",children:`You agree to edit your ${utils.transSymbolformString(t)} order.`}),jsxRuntime.jsxs(ui.Flex,{pb:4,children:[jsxRuntime.jsx(ui.Box,{grow:true,children:jsxRuntime.jsx(ui.Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:true,as:"div",intensity:80,children:t})}),jsxRuntime.jsxs(ui.Flex,{gap:1,children:[u&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primary",children:m("common.position")}),jsxRuntime.jsx(Xe,{tpPrice:o,slPrice:i}),p===types.OrderSide.SELL?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"success",children:m("common.buy")}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"danger",children:m("common.sell")})]})]}),jsxRuntime.jsx(ui.Divider,{}),jsxRuntime.jsxs(ui.Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:ui.cn(c,"oui-pb-4 xl:oui-pb-5"),children:[jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("common.qty")}),jsxRuntime.jsx("div",{children:u?jsxRuntime.jsx("span",{className:"oui-text-base-contrast",children:m("tpsl.entirePosition")}):jsxRuntime.jsx(ui.Text.numeral,{intensity:98,dp:r,padding:false,children:a})})]}),typeof o=="number"&&o>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("tpsl.tpPrice")}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof i=="number"&&i>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("tpsl.slPrice")}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:i})]}):null,jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("common.price")}),jsxRuntime.jsx("div",{className:"oui-text-base-contrast",children:m("common.marketPrice")})]})]}),jsxRuntime.jsx(ui.Box,{pt:2,children:jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Checkbox,{id:"disabledConfirm",color:"white",checked:!T,onCheckedChange:s=>{x(!s);}}),jsxRuntime.jsx("label",{htmlFor:"disabledConfirm",className:ui.textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:m("orderEntry.disableOrderConfirm")})]})})]})},Xe=e=>{let{tpPrice:t,slPrice:o}=e,{t:i}=i18n.useTranslation();return t&&o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("common.tpsl")}):t?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("tpsl.tp")}):o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("tpsl.sl")}):null};var ce=e=>{let{position:t,order:o,isEditing:i}=e;if(i&&!o)throw new types.SDKError("order is required when isEditing is true");let a=i?o.symbol:t.symbol,l=hooks.useSymbolsInfo(),p=react.useRef(types.AlgoOrderRootType.TP_SL),[g]=hooks.useLocalStorage("orderly_order_confirm",true),[r,{submit:P,deleteOrder:_,setValue:m,validate:T,errors:x,isCreateMutating:c,isUpdateMutating:u}]=hooks.useTPSLOrder({symbol:a,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:i}),s=f=>{m("quantity",f);},L=(f,h)=>{m(f,h);},$=(f,h)=>{m(f,h);},C=react.useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),Y=react.useMemo(()=>{let f=o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL?C:o?.quantity,h=0;if((Number(r.quantity)!==f||!i&&r.quantity)&&(h=1),o&&i){let Te=o.child_orders.find(D=>D.algo_type===types.AlgoOrderType.TAKE_PROFIT),Le=o.child_orders.find(D=>D.algo_type===types.AlgoOrderType.STOP_LOSS);Te?.trigger_price!==Number(r.tp_trigger_price)&&typeof typeof r.tp_trigger_price<"u"&&(h=2),Le?.trigger_price!==Number(r.sl_trigger_price)&&typeof r.sl_trigger_price<"u"&&(h=3);}return h===1&&!r.tp_trigger_price&&!r.sl_trigger_price&&(h=-1),h},[r.tp_trigger_price,r.sl_trigger_price,r.quantity,o,i]),_e=react.useMemo(()=>o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&Number(r.quantity)<C&&!r.tp_trigger_price&&!r.sl_trigger_price?false:Y>0&&!!r.quantity&&!x,[r.quantity,C,Y,x]),V=react.useMemo(()=>i?o&&o.algo_type!==types.AlgoOrderRootType.POSITIONAL_TP_SL?false:r.algo_order_id&&r.quantity==0?true:Number(r.quantity)>=C:Number(r.quantity)>=C,[r.quantity,C,o?.algo_type,i]);react.useEffect(()=>{if(!i&&V){let f=hooks.utils.findTPSLFromOrder(o);!r.tp_trigger_price&&f.tp_trigger_price&&L("tp_trigger_price",f.tp_trigger_price),!r.sl_trigger_price&&f.sl_trigger_price&&L("sl_trigger_price",f.sl_trigger_price);}},[i,V,r]),react.useEffect(()=>{let f=Number(r.quantity)<C?types.AlgoOrderRootType.TP_SL:types.AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&p.current!==f&&e.onTPSLTypeChange(f),p.current=f;},[r.quantity,C]);let be=()=>o?.algo_order_id&&o?.symbol?_(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),xe=async()=>Promise.resolve().then(()=>typeof e.onConfirm!="function"||!g?P().then(()=>true,f=>(f?.message&&ui.toast.error(f.message),Promise.reject(false))):e.onConfirm(r,{position:t,submit:P,cancel:be})).then(f=>{});return {isEditing:i,symbolInfo:l[a],maxQty:C,setQuantity:s,orderQuantity:r.quantity,isPosition:V,TPSL_OrderEntity:r,setOrderValue:m,setPnL:$,setOrderPrice:L,onSubmit:xe,valid:_e,errors:x,status:{isCreateMutating:c,isUpdateMutating:u}}};var M=e=>{let{onCancel:t,onComplete:o,...i}=e,a=ce(i);return jsxRuntime.jsx(le,{...a,onCancel:t,onComplete:o})};var pt=e=>{let{position:t,order:o,baseDP:i,quoteDP:a,buttonProps:l,isEditing:p}=e,[g,r]=react.useState(false),[P,_]=react.useState(true),[m]=hooks.useLocalStorage("orderly_order_confirm",true),{t:T}=i18n.useTranslation(),x=p?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxRuntime.jsxs(ui.PopoverRoot,{onOpenChange:c=>{P&&r(c);},open:g,children:[jsxRuntime.jsx(ui.PopoverTrigger,{asChild:true,onClick:()=>{r(true);},children:e.children||jsxRuntime.jsx(ui.Button,{variant:"outlined",size:"sm",color:"secondary",...l,children:e.label})}),jsxRuntime.jsx(ui.PopoverContent,{className:ui.cn("oui-w-[360px]",P?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsxRuntime.jsx(M,{position:t,order:o,isEditing:p,onComplete:()=>{r(false);},onCancel:()=>{r(false);},onConfirm:(c,u)=>{if(!m)return Promise.resolve(true);_(false);let s=Math.abs(Number(t.position_qty));if(`${c.tp_trigger_price??""}`.length===0&&`${c.sl_trigger_price??""}`.length===0)return ui.modal.confirm({title:T("orders.cancelOrder"),content:T("tpsl.cancelOrder.description"),onOk:()=>u.cancel()}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)));let L=p||!!c&&c.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&c.quantity===s;return ui.modal.confirm({title:T(L?"orders.editOrder":"tpsl.confirmOrder"),onOk:()=>u.submit(),classNames:{body:"!oui-pb-0"},content:jsxRuntime.jsx(B,{isPositionTPSL:x,isEditing:L,symbol:c.symbol,qty:Number(c.quantity),maxQty:s,tpPrice:Number(c.tp_trigger_price),slPrice:Number(c.sl_trigger_price),side:c.side,quoteDP:a??2,baseDP:i??2})}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)))}})})]})};var Lt=e=>{let{position:t,order:o,symbolInfo:i,isEditing:a}=e,{resolve:l,hide:p,updateArgs:g}=ui.useModal(),[r]=hooks.useLocalStorage("orderly_order_confirm",true),{t:P}=i18n.useTranslation(),_=a?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0,m=u=>{a||g({title:u});},T=()=>{l(),p();},{quote_dp:x,base_dp:c}=i;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(St,{position:t,symbolInfo:i}),jsxRuntime.jsx(M,{...e,onTPSLTypeChange:u=>{m(u===types.AlgoOrderRootType.TP_SL?P("common.tpsl"):P("tpsl.positionTpsl"));},onComplete:T,onConfirm:(u,s)=>{if(!r)return Promise.resolve(true);let L=Math.abs(Number(t.position_qty)),$=a||!!u&&u.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&u.quantity===L;return ui.modal.confirm({title:P($?"orders.editOrder":"tpsl.confirmOrder"),bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:()=>s.submit(),content:jsxRuntime.jsx(B,{isPositionTPSL:_,isEditing:a,symbol:u.symbol,qty:Number(u.quantity),maxQty:L,tpPrice:Number(u.tp_trigger_price),slPrice:Number(u.sl_trigger_price),side:u.side,quoteDP:x??2,baseDP:c??2})}).then(()=>true,C=>(C?.message&&ui.toast.error(C.message),Promise.reject(false)))},onCancel:()=>{p();}})]})};var St=e=>{let{position:t,symbolInfo:o}=e,{data:i}=hooks.useMarkPrice(t.symbol),a=ui.useModal(),{t:l}=i18n.useTranslation(),p=react.useMemo(()=>a.args?.title===l("tpsl.positionTpsl"),[a.args?.title,l]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",pb:3,itemAlign:"center",children:[jsxRuntime.jsx(ui.Text.formatted,{rule:"symbol",className:"oui-text-xs",showIcon:true,children:t.symbol}),jsxRuntime.jsxs(ui.Flex,{gapX:1,children:[p&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primary",children:l("common.position")}),jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:l("common.tpsl")}),t.position_qty<0?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"buy",children:l("common.buy")}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"sell",children:l("common.sell")})]})]}),jsxRuntime.jsx(ui.Divider,{intensity:8}),jsxRuntime.jsxs(ui.Box,{py:3,className:"oui-space-y-1",children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:54,children:l("common.avgOpen")}),jsxRuntime.jsx(ui.Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:t.average_open_price})]}),jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:54,children:l("common.markPrice")}),jsxRuntime.jsx(ui.Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:i})]})]})]})};
|
|
12
|
+
var Z=e=>{let{type:t,values:o}=e,[i,a]=hooks.useLocalStorage("TP/SL_Mode","Offset%"),[u,p]=react.useState(true),{t:g}=i18n.useTranslation(),r=react.useMemo(()=>{switch(i){case "Offset":return `${t.toLowerCase()}_offset`;case "Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[i]),P=react.useMemo(()=>o[i],[o,i]),_=react.useMemo(()=>[{label:g("tpsl.pnl"),value:"PnL",testId:"PnL_menu_item"},{label:g("tpsl.offset"),value:"Offset",testId:"Offset_mneu_item"},{label:`${g("tpsl.offset")}%`,value:"Offset%",testId:"Offset%_menu_item"}],[g]),m=react.useRef(""),L=c=>{e.onChange(r,c);},T=c=>{let{dp:l=2}=c;return {onRenderBefore:(s,S)=>(s=`${s}`,u&&t==="SL"&&i==="PnL"&&(s=s.startsWith("-")?s:"-"+s),s===""||s==="-"?"":i==="Offset%"?`${new utils.Decimal(s.replace(new RegExp(m.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${m.current}`:(i==="Offset"&&(s=utils.todpIfNeed(s,l)),`${s}`)),onSendBefore:s=>{if(/^\-?0{2,}$/.test(s))return "0";if(i==="Offset%"){if(s!==""){s=utils.todpIfNeed(s,2);let S=s.match(/\.0{0,2}$/);S?m.current=S[0]:m.current="",s=new utils.Decimal(s).div(100).toString(),s=`${s}${m.current}`;}}else i==="PnL"&&t==="SL"&&u?s=s.startsWith("-")?s:"-"+s:s=utils.todpIfNeed(s,l);return s===""||s==="-"?"":s}}};return {mode:i,modes:_,type:e.type,formatter:T,onModeChange:c=>{a(c);},value:P,pnl:o.PnL,onValueChange:L,quote_dp:e.quote_dp,setFocus:p}};var oe=e=>{let{mode:t,modes:o,onModeChange:i,onValueChange:a,quote:u,quote_dp:p,value:g,pnl:r}=e,{t:P}=i18n.useTranslation(),[_,m]=react.useState(t),[L,T]=react.useState(t==="Offset%"?"%":u),c=react.useMemo(()=>{let l=Number(r);if(isNaN(l)||l===0)return "";if(l>0)return "oui-text-trade-profit";if(l<0)return "oui-text-trade-loss"},[r]);return react.useEffect(()=>{let l=o.find(s=>s.value===t)?.label;m(l),T(t==="Offset%"?"%":u);},[t,o]),jsxRuntime.jsx(ui.Input,{prefix:_,size:{initial:"lg",lg:"md"},placeholder:L,align:"right",value:g,"data-testid":e.testId,autoComplete:"off",onValueChange:a,formatters:[e.formatter({dp:p,mode:t}),ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter],classNames:{input:c,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{T(""),e.setFocus(true);},onBlur:()=>{T(t==="Offset%"?"%":u),e.setFocus(false);},suffix:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t==="Offset%"&&!!g&&jsxRuntime.jsx(ui.Text,{size:"2xs",color:"inherit",className:ui.cn("oui-ml-[2px]",c),children:"%"}),jsxRuntime.jsx(ze,{mode:t,modes:o,onModeChange:l=>i(l.value)})]})})},ze=e=>jsxRuntime.jsx(ui.SimpleDropdownMenu,{currentValue:e.mode,menu:e.modes,align:"end",size:"xs",className:"oui-min-w-[80px]",onSelect:t=>e.onModeChange(t),children:jsxRuntime.jsx("button",{className:"oui-p-2",children:jsxRuntime.jsx(ui.CaretDownIcon,{size:12,color:"white"})})});var U=e=>{let{testId:t,quote:o,...i}=e,a=Z(i);return jsxRuntime.jsx(oe,{...a,testId:t,quote:o})};var le=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:i,onComplete:a,status:u,errors:p,isPosition:g}=e,{t:r}=i18n.useTranslation(),{parseErrorMsg:P}=reactApp.useOrderEntryFormErrorMsg(p);return jsxRuntime.jsxs("div",{id:"orderly-tp_sl-order-edit-content",children:[(!e.isEditing||e.isEditing&&!e.isPosition)&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Xe,{maxQty:e.maxQty,quantity:e.orderQuantity??e.maxQty,baseTick:o("base_tick"),dp:o("base_dp"),onQuantityChange:e.setQuantity,quote:o("base"),isEditing:e.isEditing,isPosition:g,errorMsg:P("quantity")}),jsxRuntime.jsx(ui.Divider,{my:4,intensity:8})]}),jsxRuntime.jsx(Je,{sl_pnl:t.sl_pnl,tp_pnl:t.tp_pnl,quote:o("quote"),quote_dp:o("quote_dp"),onPriceChange:e.setOrderPrice,onPnLChange:e.setPnL,errors:p,tp_values:{PnL:`${t.tp_pnl??""}`,Offset:`${t.tp_offset??""}`,"Offset%":`${t.tp_offset_percentage??""}`},sl_values:{PnL:`${t.sl_pnl??""}`,Offset:`${t.sl_offset??""}`,"Offset%":`${t.sl_offset_percentage??""}`},tp_trigger_price:t.tp_trigger_price??"",sl_trigger_price:t.sl_trigger_price??""}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:3,mt:4,children:[jsxRuntime.jsx(ui.Button,{size:"md",color:"secondary","data-testid":"tpsl-cancel",onClick:()=>{i?.();},children:r("common.cancel")}),jsxRuntime.jsx(ui.ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||u.isCreateMutating,loading:u.isCreateMutating||u.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{a?.();}).catch(_=>{});},children:r("common.confirm")})]})]})},Xe=e=>{let{isPosition:t}=e,o=react.useRef(null),i=ui.convertValueToPercentage(e.quantity,0,e.maxQty)/100,{t:a}=i18n.useTranslation(),u=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},p=r=>{if(e.baseTick>0){e.onQuantityChange?.(hooks.utils.formatNumber(r,e.baseTick)??r);}},g=(t?"":e.quantity).toString().length>0?e.errorMsg:void 0;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(ui.Flex,{gap:2,children:[jsxRuntime.jsx("div",{className:"oui-flex-1",children:jsxRuntime.jsx(ui.Input.tooltip,{"data-testid":"oui-testid-tpsl-popUp-quantity-input",ref:o,prefix:a("common.quantity"),size:{initial:"lg",lg:"md"},align:"right",value:t?"":e.quantity,autoComplete:"off",classNames:{prefix:"oui-text-base-contrast-54",root:ui.cn("oui-bg-base-5 oui-outline-line-12",g&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:g,color:g?"danger":void 0,formatters:[ui.inputFormatter.dpFormatter(e.dp),ui.inputFormatter.numberFormatter,ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter],onValueChange:r=>{e.onQuantityChange?.(r);let P=Number(r);if(P&&P>e.maxQty){let _=t?0:e.maxQty;e.onQuantityChange?.(_),o.current?.blur();}},onBlur:r=>p(r.target.value),suffix:t?jsxRuntime.jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{u();},children:a("tpsl.entirePosition")}):jsxRuntime.jsx("span",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",children:e.quote})})}),!e.isEditing&&jsxRuntime.jsx(ui.Button,{onClick:()=>{let r=t?0:e.maxQty;e.onQuantityChange?.(r),r===0&&u();},variant:"outlined",className:ui.cn("oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]",t?"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20":"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5"),children:a("common.position")})]}),jsxRuntime.jsx(ui.Flex,{mt:2,itemAlign:"center",height:"15px",children:jsxRuntime.jsx(ui.Slider.single,{markCount:5,color:"primary",max:e.maxQty,min:0,showTip:true,step:e.baseTick,value:e.quantity,onValueCommit:r=>{p(`${r}`);},onValueChange:r=>{e.onQuantityChange?.(r);}})}),jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text.numeral,{rule:"percentages",color:"primary",size:"2xs",children:i}),jsxRuntime.jsxs(ui.Flex,{itemAlign:"center",gap:1,children:[jsxRuntime.jsx("button",{className:"oui-leading-none",style:{lineHeight:0},onClick:()=>{e.onQuantityChange?.(e.maxQty);},children:jsxRuntime.jsx(ui.Text,{color:"primary",size:"2xs",children:a("common.max")})}),jsxRuntime.jsx(ui.Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},Je=e=>{let{t}=i18n.useTranslation(),{parseErrorMsg:o}=reactApp.useOrderEntryFormErrorMsg(e.errors),i=(a,u)=>{e.onPnLChange(a,u);};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:80,children:t("tpsl.takeProfit")}),jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(ie,{type:"TP",value:e.tp_trigger_price,error:o("tp_trigger_price"),onValueChange:a=>{e.onPriceChange("tp_trigger_price",a);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(U,{type:"TP",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:80,children:t("tpsl.stopLoss")}),jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(ie,{type:"SL",value:e.sl_trigger_price,error:o("sl_trigger_price"),onValueChange:a=>{e.onPriceChange("sl_trigger_price",a);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(U,{type:"SL",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},ie=e=>{let[t,o]=react.useState("USDC"),{t:i}=i18n.useTranslation();return jsxRuntime.jsx(ui.Input.tooltip,{"data-testid":`oui-testid-tpsl-popUp-${e.type.toLowerCase()}-input`,prefix:i("common.markPrice"),size:{initial:"lg",lg:"md"},tooltip:e.error,placeholder:t,align:"right",autoComplete:"off",value:e.value,color:e.error?"danger":void 0,classNames:{prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onValueChange:e.onValueChange,onFocus:()=>{o("");},onBlur:()=>{o("USDC");},formatters:[ui.inputFormatter.numberFormatter,ui.inputFormatter.dpFormatter(e.quote_dp),ui.inputFormatter.currencyFormatter,ui.inputFormatter.decimalPointFormatter]})},M=e=>{let{symbol:t,tpPrice:o,slPrice:i,qty:a,maxQty:u,side:p,quoteDP:g,baseDP:r,isEditing:P,isPositionTPSL:_}=e,{t:m}=i18n.useTranslation(),[L,T]=hooks.useLocalStorage("orderly_order_confirm",true),c=ui.textVariants({size:"xs",intensity:54}),l=_??a>=u;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[P&&jsxRuntime.jsx(ui.Text,{as:"div",size:"2xs",intensity:80,className:"oui-mb-3",children:`You agree to edit your ${utils.transSymbolformString(t)} order.`}),jsxRuntime.jsxs(ui.Flex,{pb:4,children:[jsxRuntime.jsx(ui.Box,{grow:true,children:jsxRuntime.jsx(ui.Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:true,as:"div",intensity:80,children:t})}),jsxRuntime.jsxs(ui.Flex,{gap:1,children:[l&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primary",children:m("common.position")}),jsxRuntime.jsx(Ze,{tpPrice:o,slPrice:i}),p===types.OrderSide.SELL?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"success",children:m("common.buy")}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"danger",children:m("common.sell")})]})]}),jsxRuntime.jsx(ui.Divider,{}),jsxRuntime.jsxs(ui.Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:ui.cn(c,"oui-pb-4 xl:oui-pb-5"),children:[jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("common.qty")}),jsxRuntime.jsx("div",{children:l?jsxRuntime.jsx("span",{className:"oui-text-base-contrast",children:m("tpsl.entirePosition")}):jsxRuntime.jsx(ui.Text.numeral,{intensity:98,dp:r,padding:false,children:a})})]}),typeof o=="number"&&o>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("tpsl.tpPrice")}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof i=="number"&&i>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("tpsl.slPrice")}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:i})]}):null,jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:true,children:m("common.price")}),jsxRuntime.jsx("div",{className:"oui-text-base-contrast",children:m("common.marketPrice")})]})]}),jsxRuntime.jsx(ui.Box,{pt:2,children:jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Checkbox,{id:"disabledConfirm",color:"white",checked:!L,onCheckedChange:s=>{T(!s);}}),jsxRuntime.jsx("label",{htmlFor:"disabledConfirm",className:ui.textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:m("orderEntry.disableOrderConfirm")})]})})]})},Ze=e=>{let{tpPrice:t,slPrice:o}=e,{t:i}=i18n.useTranslation();return t&&o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("common.tpsl")}):t?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("tpsl.tp")}):o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:i("tpsl.sl")}):null};var de=e=>{let{position:t,order:o,isEditing:i}=e;if(i&&!o)throw new types.SDKError("order is required when isEditing is true");let a=i?o.symbol:t.symbol,u=hooks.useSymbolsInfo(),p=react.useRef(types.AlgoOrderRootType.TP_SL),[g]=hooks.useLocalStorage("orderly_order_confirm",true),[r,{submit:P,deleteOrder:_,setValue:m,validate:L,errors:T,isCreateMutating:c,isUpdateMutating:l}]=hooks.useTPSLOrder({symbol:a,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:i}),s=y=>{m("quantity",y);},S=(y,N)=>{m(y,N);},h=(y,N)=>{m(y,N);},f=react.useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),X=react.useMemo(()=>{let y=o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL?f:o?.quantity,N=0;if((Number(r.quantity)!==y||!i&&r.quantity)&&(N=1),o&&i){let Se=o.child_orders.find(D=>D.algo_type===types.AlgoOrderType.TAKE_PROFIT),Ce=o.child_orders.find(D=>D.algo_type===types.AlgoOrderType.STOP_LOSS);Se?.trigger_price!==Number(r.tp_trigger_price)&&typeof typeof r.tp_trigger_price<"u"&&(N=2),Ce?.trigger_price!==Number(r.sl_trigger_price)&&typeof r.sl_trigger_price<"u"&&(N=3);}return N===1&&!r.tp_trigger_price&&!r.sl_trigger_price&&(N=-1),N},[r.tp_trigger_price,r.sl_trigger_price,r.quantity,o,i]),xe=react.useMemo(()=>o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&Number(r.quantity)<f&&!r.tp_trigger_price&&!r.sl_trigger_price?false:X>0&&!!r.quantity&&!T,[r.quantity,f,X,T]),V=react.useMemo(()=>i?o&&o.algo_type!==types.AlgoOrderRootType.POSITIONAL_TP_SL?false:r.algo_order_id&&r.quantity==0?true:Number(r.quantity)>=f:Number(r.quantity)>=f,[r.quantity,f,o?.algo_type,i]);react.useEffect(()=>{if(!i&&V){let y=hooks.utils.findTPSLFromOrder(o);!r.tp_trigger_price&&y.tp_trigger_price&&S("tp_trigger_price",y.tp_trigger_price),!r.sl_trigger_price&&y.sl_trigger_price&&S("sl_trigger_price",y.sl_trigger_price);}},[i,V,r]),react.useEffect(()=>{let y=Number(r.quantity)<f?types.AlgoOrderRootType.TP_SL:types.AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&p.current!==y&&e.onTPSLTypeChange(y),p.current=y;},[r.quantity,f]);let Te=()=>o?.algo_order_id&&o?.symbol?_(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),Le=async()=>typeof e.onConfirm!="function"||!g?P({accountId:t.account_id}).then(()=>true).catch(y=>{throw y?.message&&ui.toast.error(y.message),false}):e.onConfirm(r,{position:t,submit:P,cancel:Te});return {isEditing:i,symbolInfo:u[a],maxQty:f,setQuantity:s,orderQuantity:r.quantity,isPosition:V,TPSL_OrderEntity:r,setOrderValue:m,setPnL:h,setOrderPrice:S,onSubmit:Le,valid:xe,errors:T,status:{isCreateMutating:c,isUpdateMutating:l}}};var A=e=>{let{onCancel:t,onComplete:o,...i}=e,a=de(i);return jsxRuntime.jsx(le,{...a,onCancel:t,onComplete:o})};var Pt=e=>{let{position:t,order:o,baseDP:i,quoteDP:a,buttonProps:u,isEditing:p}=e,[g,r]=react.useState(false),[P,_]=react.useState(true),[m]=hooks.useLocalStorage("orderly_order_confirm",true),{t:L}=i18n.useTranslation(),T=p?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxRuntime.jsxs(ui.PopoverRoot,{onOpenChange:c=>{P&&r(c);},open:g,children:[jsxRuntime.jsx(ui.PopoverTrigger,{asChild:true,onClick:()=>{r(true);},children:e.children||jsxRuntime.jsx(ui.Button,{variant:"outlined",size:"sm",color:"secondary",...u,children:e.label})}),jsxRuntime.jsx(ui.PopoverContent,{className:ui.cn("oui-w-[360px]",P?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsxRuntime.jsx(A,{position:t,order:o,isEditing:p,onComplete:()=>{r(false);},onCancel:()=>{r(false);},onConfirm:(c,l)=>{if(!m)return Promise.resolve(true);_(false);let s=Math.abs(Number(t.position_qty));if(`${c.tp_trigger_price??""}`.length===0&&`${c.sl_trigger_price??""}`.length===0)return ui.modal.confirm({title:L("orders.cancelOrder"),content:L("tpsl.cancelOrder.description"),onOk:()=>l.cancel()}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)));let S=p||!!c&&c.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&c.quantity===s;return ui.modal.confirm({title:L(S?"orders.editOrder":"tpsl.confirmOrder"),onOk:async()=>{try{let h=await l.submit({accountId:t.account_id});return h.success?h:(h.message&&ui.toast.error(h.message),!1)}catch(h){return h?.message&&ui.toast.error(h.message),false}},classNames:{body:"!oui-pb-0"},content:jsxRuntime.jsx(M,{isPositionTPSL:T,isEditing:S,symbol:c.symbol,qty:Number(c.quantity),maxQty:s,tpPrice:Number(c.tp_trigger_price),slPrice:Number(c.sl_trigger_price),side:c.side,quoteDP:a??2,baseDP:i??2})}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)))}})})]})};var St=e=>{let{position:t,order:o,symbolInfo:i,isEditing:a}=e,{resolve:u,hide:p,updateArgs:g}=ui.useModal(),[r]=hooks.useLocalStorage("orderly_order_confirm",true),{t:P}=i18n.useTranslation(),_=a?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0,m=l=>{a||g({title:l});},L=()=>{u(),p();},{quote_dp:T,base_dp:c}=i;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Ct,{position:t,symbolInfo:i}),jsxRuntime.jsx(A,{...e,onTPSLTypeChange:l=>{m(l===types.AlgoOrderRootType.TP_SL?P("common.tpsl"):P("tpsl.positionTpsl"));},onComplete:L,onConfirm:(l,s)=>{if(!r)return Promise.resolve(true);let S=Math.abs(Number(t.position_qty)),h=a||!!l&&l.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&l.quantity===S;return ui.modal.confirm({title:P(h?"orders.editOrder":"tpsl.confirmOrder"),bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:async()=>{try{let f=await s.submit({accountId:t.account_id});return f.success?f:(f.message&&ui.toast.error(f.message),!1)}catch(f){return f?.message&&ui.toast.error(f.message),false}},content:jsxRuntime.jsx(M,{isPositionTPSL:_,isEditing:a,symbol:l.symbol,qty:Number(l.quantity),maxQty:S,tpPrice:Number(l.tp_trigger_price),slPrice:Number(l.sl_trigger_price),side:l.side,quoteDP:T??2,baseDP:c??2})}).then(()=>true,f=>(f?.message&&ui.toast.error(f.message),Promise.reject(false)))},onCancel:()=>{p();}})]})};var Ct=e=>{let{position:t,symbolInfo:o}=e,{data:i}=hooks.useMarkPrice(t.symbol),a=ui.useModal(),{t:u}=i18n.useTranslation(),p=react.useMemo(()=>a.args?.title===u("tpsl.positionTpsl"),[a.args?.title,u]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",pb:3,itemAlign:"center",children:[jsxRuntime.jsx(ui.Text.formatted,{rule:"symbol",className:"oui-text-xs",showIcon:true,children:t.symbol}),jsxRuntime.jsxs(ui.Flex,{gapX:1,children:[p&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primary",children:u("common.position")}),jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:u("common.tpsl")}),t.position_qty<0?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"buy",children:u("common.buy")}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"sell",children:u("common.sell")})]})]}),jsxRuntime.jsx(ui.Divider,{intensity:8}),jsxRuntime.jsxs(ui.Box,{py:3,className:"oui-space-y-1",children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:54,children:u("common.avgOpen")}),jsxRuntime.jsx(ui.Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:t.average_open_price})]}),jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:54,children:u("common.markPrice")}),jsxRuntime.jsx(ui.Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:i})]})]})]})};
|
|
13
13
|
|
|
14
|
-
exports.PositionTPSLConfirm =
|
|
15
|
-
exports.PositionTPSLPopover =
|
|
16
|
-
exports.PositionTPSLSheet =
|
|
17
|
-
exports.TPSLWidget =
|
|
14
|
+
exports.PositionTPSLConfirm = M;
|
|
15
|
+
exports.PositionTPSLPopover = Pt;
|
|
16
|
+
exports.PositionTPSLSheet = St;
|
|
17
|
+
exports.TPSLWidget = A;
|
|
18
18
|
//# sourceMappingURL=out.js.map
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tpsl.ui.tsx","../src/pnlInput/pnlInput.ui.tsx","../src/pnlInput/useBuilder.script.ts","../src/pnlInput/pnlInput.widget.tsx","../src/useTPSL.script.ts","../src/tpsl.widget.tsx","../src/editorPopover.tsx","../src/editorSheet.tsx"],"names":["useRef","useState","Badge","Box","Button","Divider","Flex","Grid","Input","Slider","Text","textVariants","cn","inputFormatter","Checkbox","convertValueToPercentage","ThrottledButton","CaretDownIcon","SimpleDropdownMenu","useMemo","useLocalStorage","Decimal","todpIfNeed","useTranslation","usePNLInputBuilder","props","type","values","mode","setMode","focus","setFocus","t","key","value","modes","percentageSuffix","onValueChange","formatter","options","dp","endStr","useEffect","Fragment","jsx","jsxs","PNLInput","onModeChange","quote","quote_dp","pnl","prefix","setPrefix","placeholder","setPlaceholder","color","num","label","item","PNLMenus","PnlInputWidget","testId","rest","state","utils","OrderSide","transSymbolformString","useOrderEntryFormErrorMsg","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","parseErrorMsg","TPSLQuantity","TPSLPrice","inputRef","currentQtyPercentage","setTPSL","formatQuantity","qty","quantity","errorMsg","e","onPnLChange","PriceInput","PositionTPSLConfirm","symbol","tpPrice","slPrice","maxQty","side","quoteDP","baseDP","isEditing","_isPositionTPSL","needConfirm","setNeedConfirm","textClassName","isPositionTPSL","TPSLOrderType","check","useSymbolsInfo","useTPSLOrder","SDKError","AlgoOrderRootType","AlgoOrderType","toast","useTPSLBuilder","position","order","prevTPSLType","tpslOrder","submit","deleteOrder","setValue","validate","isCreateMutating","isUpdateMutating","setQuantity","setOrderPrice","name","setPnL","dirty","diff","tp","o","sl","valid","trigger_prices","cancel","onSubmit","reject","isSuccess","TPSLWidget","modal","PopoverContent","PopoverRoot","PopoverTrigger","PositionTPSLPopover","buttonProps","open","setOpen","visible","setVisible","isOpen","finalIsEditing","useModal","useMarkPrice","PositionTPSLSheet","resolve","hide","updateArgs","updateSheetTitle","title","onCompleted","base_dp","PositionInfo","markPrice"],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\nimport {\n Badge,\n Box,\n Button,\n Divider,\n Flex,\n Grid,\n Input,\n Slider,\n Text,\n textVariants,\n cn,\n inputFormatter,\n Checkbox,\n convertValueToPercentage,\n ThrottledButton,\n} from \"@orderly.network/ui\";\nimport { PnlInputWidget } from \"./pnlInput/pnlInput.widget\";\nimport { TPSLBuilderState } from \"./useTPSL.script\";\nimport type { PNL_Values } from \"./pnlInput/useBuilder.script\";\nimport { useLocalStorage, utils } from \"@orderly.network/hooks\";\nimport { API, OrderSide } from \"@orderly.network/types\";\nimport { transSymbolformString } from \"@orderly.network/utils\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useOrderEntryFormErrorMsg } from \"@orderly.network/react-app\";\nimport { OrderValidationResult } from \"@orderly.network/hooks\";\n\nexport type TPSLProps = {\n onCancel?: () => void;\n onComplete?: () => void;\n};\n\n//------------- TPSL form start ---------------\nexport const TPSL = (props: TPSLBuilderState & TPSLProps) => {\n const {\n TPSL_OrderEntity,\n symbolInfo,\n onCancel,\n onComplete,\n status,\n errors,\n isPosition,\n } = props;\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(errors);\n\n return (\n <div id=\"orderly-tp_sl-order-edit-content\">\n {(!props.isEditing || (props.isEditing && !props.isPosition)) && (\n <>\n <TPSLQuantity\n maxQty={props.maxQty}\n quantity={(props.orderQuantity ?? props.maxQty) as number}\n baseTick={symbolInfo(\"base_tick\")}\n dp={symbolInfo(\"base_dp\")}\n onQuantityChange={props.setQuantity}\n quote={symbolInfo(\"base\")}\n isEditing={props.isEditing}\n isPosition={isPosition}\n errorMsg={parseErrorMsg(\"quantity\")}\n />\n <Divider my={4} intensity={8} />\n </>\n )}\n\n <TPSLPrice\n sl_pnl={TPSL_OrderEntity.sl_pnl}\n tp_pnl={TPSL_OrderEntity.tp_pnl}\n quote={symbolInfo(\"quote\")}\n quote_dp={symbolInfo(\"quote_dp\")}\n onPriceChange={props.setOrderPrice}\n onPnLChange={props.setPnL}\n errors={errors}\n tp_values={{\n PnL: `${TPSL_OrderEntity.tp_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.tp_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.tp_offset_percentage ?? \"\"}`,\n }}\n sl_values={{\n PnL: `${TPSL_OrderEntity.sl_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.sl_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.sl_offset_percentage ?? \"\"}`,\n }}\n tp_trigger_price={TPSL_OrderEntity.tp_trigger_price ?? \"\"}\n sl_trigger_price={TPSL_OrderEntity.sl_trigger_price ?? \"\"}\n />\n <Grid cols={2} gap={3} mt={4}>\n <Button\n size={\"md\"}\n color={\"secondary\"}\n data-testid={\"tpsl-cancel\"}\n onClick={() => {\n onCancel?.();\n }}\n >\n {t(\"common.cancel\")}\n </Button>\n <ThrottledButton\n size={\"md\"}\n data-testid={\"tpsl-confirm\"}\n disabled={!props.valid || status.isCreateMutating}\n loading={status.isCreateMutating || status.isUpdateMutating}\n onClick={() => {\n props.onSubmit().then(\n () => {\n onComplete?.();\n },\n () => {\n console.log(\"--->>>cancel order\");\n }\n );\n }}\n >\n {t(\"common.confirm\")}\n </ThrottledButton>\n </Grid>\n </div>\n );\n};\n\n//----------\n\n// ------------- Quantity input start------------\nconst TPSLQuantity = (props: {\n maxQty: number;\n baseTick: number;\n dp: number;\n quote: string;\n onQuantityChange?: (value: number | string) => void;\n quantity: number;\n isEditing?: boolean;\n isPosition?: boolean;\n setOrderValue?: (key: string, value: number | string) => void;\n errorMsg?: string;\n}) => {\n // const isPosition = props.quantity === props.maxQty;\n const { isPosition } = props;\n const inputRef = useRef<HTMLInputElement>(null);\n const currentQtyPercentage =\n convertValueToPercentage(props.quantity, 0, props.maxQty) / 100;\n const { t } = useTranslation();\n\n const setTPSL = () => {\n props.onQuantityChange?.(0);\n inputRef.current?.focus();\n\n setTimeout(() => {\n inputRef.current?.setSelectionRange(0, 1);\n }, 0);\n };\n\n const formatQuantity = (qty: string) => {\n if (props.baseTick > 0) {\n const quantity = Number(qty);\n // if (quantity) {\n // props.onQuantityChange?.(Math.min(props.maxQty, quantity));\n // } else {\n props.onQuantityChange?.(utils.formatNumber(qty, props.baseTick) ?? qty);\n // }\n }\n };\n\n const errorMsg =\n (isPosition ? \"\" : props.quantity).toString().length > 0\n ? props.errorMsg\n : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n data-testid=\"oui-testid-tpsl-popUp-quantity-input\"\n ref={inputRef}\n prefix={t(\"common.quantity\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n align=\"right\"\n value={isPosition ? \"\" : props.quantity}\n autoComplete=\"off\"\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: cn(\n \"oui-bg-base-5 oui-outline-line-12\",\n errorMsg && \"oui-outline-danger\"\n ),\n }}\n tooltipProps={{\n content: {\n className: \"oui-bg-base-6 oui-text-base-contrast-80\",\n },\n arrow: {\n className: \"oui-fill-base-6\",\n },\n }}\n tooltip={errorMsg}\n color={errorMsg ? \"danger\" : undefined}\n formatters={[\n inputFormatter.dpFormatter(props.dp),\n inputFormatter.numberFormatter,\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n const qty = Number(value);\n if (qty && qty > props.maxQty) {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n inputRef.current?.blur();\n }\n }}\n onBlur={(e) => formatQuantity(e.target.value)}\n suffix={\n isPosition ? (\n <button\n className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\"\n onClick={() => {\n setTPSL();\n }}\n >\n {t(\"tpsl.entirePosition\")}\n </button>\n ) : (\n <span className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\">\n {props.quote}\n </span>\n )\n }\n />\n </div>\n {!props.isEditing && (\n <Button\n onClick={() => {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n if (qty === 0) {\n setTPSL();\n }\n }}\n variant={\"outlined\"}\n // size={{\n // lg: \"md\",\n // md: \"lg\",\n // }}\n className={cn(\n \"oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]\",\n isPosition\n ? \"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20\"\n : \"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5\"\n )}\n >\n {t(\"common.position\")}\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primary\"\n max={props.maxQty}\n min={0}\n showTip\n step={props.baseTick}\n value={props.quantity}\n onValueCommit={(value) => {\n formatQuantity(`${value}`);\n }}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n }}\n />\n </Flex>\n <Flex justify={\"between\"}>\n <Text.numeral rule={\"percentages\"} color={\"primary\"} size={\"2xs\"}>\n {currentQtyPercentage}\n </Text.numeral>\n <Flex itemAlign={\"center\"} gap={1}>\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={() => {\n props.onQuantityChange?.(props.maxQty);\n }}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {t(\"common.max\")}\n </Text>\n </button>\n\n <Text.numeral\n rule={\"price\"}\n size={\"2xs\"}\n intensity={54}\n tick={props.baseTick}\n >\n {props.maxQty}\n </Text.numeral>\n </Flex>\n </Flex>\n </>\n );\n};\n// ------------- Quantity input end------------\n\n// ------------ TP/SL Price and PNL input start------------\nconst TPSLPrice = (props: {\n tp_pnl?: number;\n sl_pnl?: number;\n quote: string;\n quote_dp?: number;\n onPriceChange: TPSLBuilderState[\"setOrderPrice\"];\n onPnLChange: TPSLBuilderState[\"setPnL\"];\n tp_values: PNL_Values;\n sl_values: PNL_Values;\n tp_trigger_price?: number | string;\n sl_trigger_price?: number | string;\n errors: OrderValidationResult | null;\n}) => {\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(props.errors);\n\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.takeProfit\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.tp_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"TP\"}\n value={props.tp_trigger_price}\n error={parseErrorMsg(\"tp_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"tp_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"TP\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.tp_values}\n />\n </Grid>\n </div>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.stopLoss\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.sl_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"SL\"}\n value={props.sl_trigger_price}\n error={parseErrorMsg(\"sl_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"sl_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"SL\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.sl_values}\n />\n </Grid>\n </div>\n </>\n );\n};\n// ------------ TP/SL Price and PNL input end------------\n// ------------ TP/SL Price input start------------\nconst PriceInput = (props: {\n type: string;\n value?: string | number;\n error?: string;\n onValueChange: (value: string) => void;\n quote_dp: number;\n}) => {\n const [placeholder, setPlaceholder] = useState<string>(\"USDC\");\n const { t } = useTranslation();\n\n return (\n <Input.tooltip\n data-testid={`oui-testid-tpsl-popUp-${props.type.toLowerCase()}-input`}\n // prefix={`${props.type} price`}\n prefix={t(\"common.markPrice\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n tooltip={props.error}\n placeholder={placeholder}\n align={\"right\"}\n autoComplete={\"off\"}\n value={props.value}\n color={props.error ? \"danger\" : undefined}\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onValueChange={props.onValueChange}\n onFocus={() => {\n setPlaceholder(\"\");\n }}\n onBlur={() => {\n setPlaceholder(\"USDC\");\n }}\n formatters={[\n inputFormatter.numberFormatter,\n inputFormatter.dpFormatter(props.quote_dp),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n />\n );\n};\n\nexport type PositionTPSLConfirmProps = {\n symbol: string;\n // isPosition: boolean;\n qty: number;\n tpPrice?: number;\n slPrice?: number;\n maxQty: number;\n side: OrderSide;\n // symbolConfig:API.SymbolExt\n baseDP: number;\n quoteDP: number;\n isEditing?: boolean;\n isPositionTPSL?: boolean;\n};\n\n// ------------ Position TP/SL Confirm dialog start------------\nexport const PositionTPSLConfirm = (props: PositionTPSLConfirmProps) => {\n const {\n symbol,\n tpPrice,\n slPrice,\n qty,\n maxQty,\n side,\n quoteDP,\n baseDP,\n isEditing,\n isPositionTPSL: _isPositionTPSL,\n } = props;\n const { t } = useTranslation();\n\n const [needConfirm, setNeedConfirm] = useLocalStorage(\n \"orderly_order_confirm\",\n true\n );\n const textClassName = textVariants({\n size: \"xs\",\n intensity: 54,\n });\n\n // console.log(\"PositionTPSLConfirm\", qty, maxQty, quoteDP);\n\n const isPositionTPSL = _isPositionTPSL ?? qty >= maxQty;\n\n return (\n <>\n {isEditing && (\n <Text\n as=\"div\"\n size=\"2xs\"\n intensity={80}\n className=\"oui-mb-3\"\n >{`You agree to edit your ${transSymbolformString(\n symbol\n )} order.`}</Text>\n )}\n\n <Flex pb={4}>\n <Box grow>\n <Text.formatted\n rule={\"symbol\"}\n formatString=\"base-type\"\n size=\"base\"\n showIcon\n as=\"div\"\n intensity={80}\n >\n {symbol}\n </Text.formatted>\n </Box>\n <Flex gap={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color={\"primary\"}>\n {t(\"common.position\")}\n </Badge>\n )}\n\n {/* <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge> */}\n <TPSLOrderType tpPrice={tpPrice} slPrice={slPrice} />\n {side === OrderSide.SELL ? (\n <Badge size=\"xs\" color=\"success\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider />\n <Flex\n direction={\"column\"}\n itemAlign={\"stretch\"}\n gapY={1}\n pt={4}\n // pb={5}\n className={cn(textClassName, \"oui-pb-4 xl:oui-pb-5\")}\n >\n <Flex>\n <Box grow>{t(\"common.qty\")}</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">\n {t(\"tpsl.entirePosition\")}\n </span>\n ) : (\n <Text.numeral intensity={98} dp={baseDP} padding={false}>\n {qty}\n </Text.numeral>\n )}\n </div>\n </Flex>\n {typeof tpPrice === \"number\" && tpPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.tpPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {tpPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n {typeof slPrice === \"number\" && slPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.slPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n className=\"oui-text-trade-loss\"\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {slPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n\n <Flex>\n <Box grow>{t(\"common.price\")}</Box>\n <div className=\"oui-text-base-contrast\">\n {t(\"common.marketPrice\")}\n </div>\n </Flex>\n </Flex>\n <Box pt={2}>\n <Flex gap={1}>\n <Checkbox\n id=\"disabledConfirm\"\n color=\"white\"\n checked={!needConfirm}\n onCheckedChange={(check) => {\n setNeedConfirm(!check);\n }}\n />\n <label\n htmlFor=\"disabledConfirm\"\n className={textVariants({\n size: \"xs\",\n intensity: 54,\n className: \"oui-ml-1\",\n })}\n >\n {t(\"orderEntry.disableOrderConfirm\")}\n </label>\n </Flex>\n </Box>\n </>\n );\n};\n\n//------------- Position TP/SL Confirm dialog end------------\n\nconst TPSLOrderType = (props: { tpPrice?: number; slPrice?: number }) => {\n const { tpPrice, slPrice } = props;\n const { t } = useTranslation();\n\n if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.tp\")}\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.sl\")}\n </Badge>\n );\n }\n\n return null;\n};\n\nconst MaxQtyButton = (props: {\n onClick: () => void;\n children?: React.ReactNode;\n}) => {\n return (\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={props.onClick}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {props.children}\n </Text>\n </button>\n );\n};\n","import {\n CaretDownIcon,\n cn,\n Input,\n MenuItem,\n SimpleDropdownMenu,\n} from \"@orderly.network/ui\";\nimport { PNLInputState, PnLMode } from \"./useBuilder.script\";\nimport { inputFormatter, Text } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport type PNLInputProps = PNLInputState & { testId?: string; quote: string };\n\nexport const PNLInput = (props: PNLInputProps) => {\n const {\n mode,\n modes,\n onModeChange,\n onValueChange,\n quote,\n quote_dp,\n value,\n pnl,\n } = props;\n const { t } = useTranslation();\n\n const [prefix, setPrefix] = useState<string>(mode);\n const [placeholder, setPlaceholder] = useState<string>(\n mode === PnLMode.PERCENTAGE ? \"%\" : quote\n );\n\n const color = useMemo(() => {\n const num = Number(pnl);\n\n if (isNaN(num) || num === 0) return \"\";\n\n if (num > 0) return \"oui-text-trade-profit\";\n if (num < 0) return \"oui-text-trade-loss\";\n }, [pnl]);\n\n useEffect(() => {\n const label = modes.find((item) => item.value === mode)?.label;\n setPrefix(label!);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode, modes]);\n\n return (\n <Input\n prefix={prefix}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n placeholder={placeholder}\n align={\"right\"}\n value={value}\n data-testid={props.testId}\n autoComplete={\"off\"}\n onValueChange={onValueChange}\n formatters={[\n // inputFormatter.numberFormatter,\n props.formatter({ dp: quote_dp, mode }),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n // className={color}\n classNames={{\n input: color,\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onFocus={() => {\n setPlaceholder(\"\");\n props.setFocus(true);\n }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n props.setFocus(false);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text\n size={\"2xs\"}\n color=\"inherit\"\n className={cn(\"oui-ml-[2px]\", color)}\n >\n %\n </Text>\n )}\n <PNLMenus\n mode={mode}\n modes={modes}\n onModeChange={(item) => onModeChange(item.value as PnLMode)}\n />\n </>\n }\n />\n );\n};\n\nconst PNLMenus = (props: {\n mode?: string;\n modes: MenuItem[];\n onModeChange: (value: MenuItem) => void;\n}) => {\n return (\n <SimpleDropdownMenu\n currentValue={props.mode}\n menu={props.modes}\n align={\"end\"}\n size={\"xs\"}\n className={\"oui-min-w-[80px]\"}\n onSelect={(item) => props.onModeChange(item as MenuItem)}\n >\n <button className={\"oui-p-2\"}>\n <CaretDownIcon size={12} color={\"white\"} />\n </button>\n </SimpleDropdownMenu>\n );\n};\n","import { useMemo, useRef, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { MenuItem } from \"@orderly.network/ui\";\nimport { Decimal, todpIfNeed } from \"@orderly.network/utils\";\nimport type {\n InputFormatter,\n InputFormatterOptions,\n} from \"@orderly.network/ui\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport enum PnLMode {\n PnL = \"PnL\",\n OFFSET = \"Offset\",\n PERCENTAGE = \"Offset%\",\n}\n\nexport type PNL_Values = {\n PnL: string;\n Offset: string;\n \"Offset%\": string;\n};\n\nexport type BuilderProps = {\n type: \"TP\" | \"SL\";\n\n quote_dp?: number;\n onChange: (key: string, value: number | string) => void;\n\n values: PNL_Values;\n};\n\nexport const usePNLInputBuilder = (props: BuilderProps) => {\n const { type, values } = props;\n const [mode, setMode] = useLocalStorage<PnLMode>(\n \"TP/SL_Mode\",\n PnLMode.PERCENTAGE\n );\n const [focus, setFocus] = useState(true);\n\n const { t } = useTranslation();\n\n const key = useMemo(() => {\n switch (mode) {\n case PnLMode.OFFSET:\n return `${type.toLowerCase()}_offset`;\n case PnLMode.PERCENTAGE:\n return `${type.toLowerCase()}_offset_percentage`;\n default:\n return `${type.toLowerCase()}_pnl`;\n }\n }, [mode]);\n\n const value = useMemo(() => {\n return values[mode as keyof PNL_Values];\n }, [values, mode]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n {\n label: t(\"tpsl.pnl\"),\n value: PnLMode.PnL,\n testId: `${PnLMode.PnL}_menu_item`,\n },\n {\n label: t(\"tpsl.offset\"),\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: `${t(\"tpsl.offset\")}%`,\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, [t]);\n\n const percentageSuffix = useRef<string>(\"\");\n\n const onValueChange = (value: string) => {\n console.log(\"onValueChange\", value);\n props.onChange(key, value);\n };\n\n const formatter = (options: {\n dp?: number;\n mode: PnLMode;\n }): InputFormatter => {\n const { dp = 2 } = options;\n return {\n onRenderBefore: (\n value: string | number,\n options: InputFormatterOptions\n ) => {\n value = `${value}`; // convert to string\n\n if (focus) {\n if (type === \"SL\" && mode === PnLMode.PnL) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n }\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n // if (mode === PnLMode.PnL || mode === PnLMode.OFFSET) {\n // return commify(value);\n // }\n\n if (mode === PnLMode.PERCENTAGE) {\n return `${new Decimal(\n value.replace(\n new RegExp(percentageSuffix.current.replace(\".\", \"\\\\.\") + \"$\"),\n \"\"\n )\n )\n .mul(100)\n .todp(2, 4)\n .toString()}${percentageSuffix.current}`;\n } else if (mode === PnLMode.OFFSET) {\n value = todpIfNeed(value, dp);\n } else {\n // value = new Decimal(value).todp(2).toString();\n }\n\n return `${value}`;\n },\n onSendBefore: (value: string) => {\n if (/^\\-?0{2,}$/.test(value)) {\n return \"0\";\n }\n\n if (mode === PnLMode.PERCENTAGE) {\n // console.log(\"value\", value);\n if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n value = todpIfNeed(value, 2);\n const endStr = value.match(/\\.0{0,2}$/);\n if (!!endStr) {\n percentageSuffix.current = endStr[0];\n } else {\n percentageSuffix.current = \"\";\n }\n value = new Decimal(value).div(100).toString();\n value = `${value}${percentageSuffix.current}`;\n }\n } else if (mode === PnLMode.PnL && type === \"SL\" && focus) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n } else {\n value = todpIfNeed(value, dp);\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n\n return value;\n },\n };\n // return {\n // onRenderBefore: (\n // value: string | number,\n // options: InputFormatterOptions\n // ) => {\n // // console.log(\"???\", options);\n // const { isFocused } = options;\n // value = `${value}`;\n // if (value === \"\" || value === \"-\") return \"\";\n\n // // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (isFocused) {\n // // value = value.startsWith(\"-\") ? value : \"-\" + value;\n // // }\n // // }\n\n // if (mode === PnLMode.PERCENTAGE) {\n // return `${todpIfNeed(new Decimal(value).mul(100).toString(), 2)}${\n // percentageSuffix.current\n // }`;\n // // return (Number(value) * 100).toFixed(2);\n // } else if (mode === PnLMode.OFFSET) {\n // value = todpIfNeed(value, 2);\n // } else {\n // // value = new Decimal(value).todp(2).toString();\n // }\n\n // return value;\n // },\n // onSendBefore: (value: string, options: InputFormatterOptions) => {\n // const { isFocused } = options;\n\n // if (mode === PnLMode.PERCENTAGE) {\n // if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n // value = new Decimal(value).div(100).toString();\n // value = todpIfNeed(value, 4);\n // }\n // } else {\n // // value = todpIfNeed(value, quote_dp);\n // if (isFocused) {\n // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (\n // // typeof values[PnLMode.PnL] !== \"undefined\" &&\n // // values[PnLMode.PnL] !== \"\"\n // // )\n // // return value;\n // const num = Number(value);\n // if (!isNaN(num) && num !== 0) {\n // value = (Math.abs(num) * -1).toString();\n // } else {\n // value = \"\";\n // }\n // }\n // }\n // }\n\n // return value;\n // },\n // };\n };\n\n return {\n mode,\n modes,\n type: props.type,\n formatter,\n onModeChange: (mode: PnLMode) => {\n setMode(mode);\n },\n value,\n pnl: values[PnLMode.PnL],\n onValueChange,\n quote_dp: props.quote_dp,\n setFocus,\n };\n};\n\nexport type PNLInputState = ReturnType<typeof usePNLInputBuilder>;\n","import { PNLInput } from \"./pnlInput.ui\";\nimport { BuilderProps, usePNLInputBuilder } from \"./useBuilder.script\";\n\nexport const PnlInputWidget = (\n props: BuilderProps & {\n testId?: string;\n quote: string;\n }\n) => {\n const { testId, quote, ...rest } = props;\n const state = usePNLInputBuilder(rest);\n return <PNLInput {...state} testId={testId} quote={quote} />;\n};\n","import {\n type ComputedAlgoOrder,\n useLocalStorage,\n useSymbolsInfo,\n useTPSLOrder,\n utils,\n} from \"@orderly.network/hooks\";\nimport { SDKError } from \"@orderly.network/types\";\nimport { AlgoOrderRootType, AlgoOrderType, API } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useRef } from \"react\";\n\nexport type TPSLBuilderOptions = {\n position: API.Position;\n order?: API.AlgoOrder;\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n isEditing?: boolean;\n /**\n * either show the confirm dialog or not,\n * if the Promise reject or return false, cancel the submit action\n */\n onConfirm?: (\n order: ComputedAlgoOrder,\n options: {\n position: API.Position;\n submit: () => Promise<any>;\n cancel: () => Promise<any>;\n }\n ) => Promise<boolean>;\n};\n\nexport const useTPSLBuilder = (options: TPSLBuilderOptions) => {\n const { position, order, isEditing } = options;\n // const isEditing = !!order;\n if (isEditing && !order) {\n throw new SDKError(\"order is required when isEditing is true\");\n }\n const symbol = isEditing ? order!.symbol : position.symbol;\n const symbolInfo = useSymbolsInfo();\n const prevTPSLType = useRef<AlgoOrderRootType>(AlgoOrderRootType.TP_SL);\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const [\n tpslOrder,\n {\n submit,\n deleteOrder,\n setValue,\n validate,\n errors,\n isCreateMutating,\n isUpdateMutating,\n },\n ] = useTPSLOrder(\n {\n symbol,\n position_qty: position.position_qty,\n average_open_price: position.average_open_price,\n },\n {\n defaultOrder: order,\n isEditing,\n }\n );\n\n const setQuantity = (value: number | string) => {\n setValue(\"quantity\", value);\n };\n\n const setOrderPrice = (\n name: \"tp_trigger_price\" | \"sl_trigger_price\",\n value: number | string\n ) => {\n setValue(name, value);\n };\n\n const setPnL = (type: string, value: number | string) => {\n setValue(type, value);\n };\n\n const maxQty = useMemo(\n () => Math.abs(Number(position.position_qty)),\n [position.position_qty]\n );\n\n const dirty = useMemo(() => {\n const quantity =\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n ? maxQty\n : order?.quantity;\n\n let diff: number = 0;\n\n if (Number(tpslOrder.quantity) !== quantity) {\n diff = 1;\n } else if (!isEditing && !!tpslOrder.quantity) {\n diff = 1;\n }\n\n if (order && isEditing) {\n const tp = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.TAKE_PROFIT\n );\n const sl = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.STOP_LOSS\n );\n\n if (\n tp?.trigger_price !== Number(tpslOrder.tp_trigger_price) &&\n typeof typeof tpslOrder.tp_trigger_price !== \"undefined\"\n ) {\n // return true;\n diff = 2;\n }\n\n if (\n sl?.trigger_price !== Number(tpslOrder.sl_trigger_price) &&\n typeof tpslOrder.sl_trigger_price !== \"undefined\"\n ) {\n diff = 3;\n }\n }\n\n if (\n diff === 1 &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n diff = -1;\n }\n\n return diff;\n }, [\n tpslOrder.tp_trigger_price,\n tpslOrder.sl_trigger_price,\n tpslOrder.quantity,\n order,\n isEditing,\n ]);\n\n const valid = useMemo(() => {\n /**\n * if the order is a POSITIONAL_TP_SL and the quantity is less than the maxQty,\n * and the tp/sl trigger price is not set, then the order is not valid\n */\n if (\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n Number(tpslOrder.quantity) < maxQty &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n return false;\n }\n\n return dirty > 0 && !!tpslOrder.quantity && !errors;\n }, [tpslOrder.quantity, maxQty, dirty, errors]);\n\n const isPositionTPSL = useMemo(() => {\n if (!isEditing) return Number(tpslOrder.quantity) >= maxQty;\n /**\n * if current order is not a POSITIONAL_TP_SL, then it's always a general TP/SL\n */\n if (!!order && order.algo_type !== AlgoOrderRootType.POSITIONAL_TP_SL) {\n return false;\n }\n if (tpslOrder.algo_order_id && tpslOrder.quantity == 0) return true;\n return Number(tpslOrder.quantity) >= maxQty;\n }, [tpslOrder.quantity, maxQty, order?.algo_type, isEditing]);\n\n useEffect(() => {\n if (!isEditing && isPositionTPSL) {\n const trigger_prices = utils.findTPSLFromOrder(order!);\n if (!tpslOrder.tp_trigger_price && trigger_prices.tp_trigger_price) {\n setOrderPrice(\"tp_trigger_price\", trigger_prices.tp_trigger_price);\n }\n if (!tpslOrder.sl_trigger_price && trigger_prices.sl_trigger_price) {\n setOrderPrice(\"sl_trigger_price\", trigger_prices.sl_trigger_price);\n }\n }\n }, [isEditing, isPositionTPSL, tpslOrder]);\n\n useEffect(() => {\n const type =\n Number(tpslOrder.quantity) < maxQty\n ? AlgoOrderRootType.TP_SL\n : AlgoOrderRootType.POSITIONAL_TP_SL;\n if (\n typeof options.onTPSLTypeChange === \"function\" &&\n prevTPSLType.current !== type\n ) {\n options.onTPSLTypeChange(type);\n }\n\n prevTPSLType.current = type;\n }, [tpslOrder.quantity, maxQty]);\n\n const cancel = (): Promise<void> => {\n if (order?.algo_order_id && order?.symbol) {\n return deleteOrder(order?.algo_order_id, order?.symbol);\n }\n return Promise.reject(\"order id or symbol is invalid\");\n };\n\n const onSubmit = async () => {\n return Promise.resolve()\n .then(() => {\n if (typeof options.onConfirm !== \"function\" || !needConfirm) {\n return submit().then(\n () => true,\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n return Promise.reject(false);\n }\n );\n }\n return options.onConfirm(tpslOrder, {\n position,\n submit,\n cancel,\n });\n })\n .then((isSuccess) => {\n console.log(\"result\", isSuccess);\n });\n };\n\n return {\n isEditing,\n symbolInfo: symbolInfo[symbol],\n maxQty,\n setQuantity,\n orderQuantity: tpslOrder.quantity,\n isPosition: isPositionTPSL,\n\n TPSL_OrderEntity: tpslOrder,\n setOrderValue: setValue,\n setPnL,\n setOrderPrice,\n // needConfirm,\n onSubmit,\n valid,\n errors,\n status: {\n isCreateMutating,\n isUpdateMutating,\n },\n } as const;\n};\n\nexport type TPSLBuilderState = ReturnType<typeof useTPSLBuilder>;\n","import { type AlgoOrderRootType } from \"@orderly.network/types\";\nimport { TPSL, TPSLProps } from \"./tpsl.ui\";\nimport { TPSLBuilderOptions, useTPSLBuilder } from \"./useTPSL.script\";\n\nexport type TPSLWidgetProps = {\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n} & TPSLBuilderOptions &\n TPSLProps;\n\nexport const TPSLWidget = (props: TPSLWidgetProps) => {\n const { onCancel, onComplete, ...rest } = props;\n const state = useTPSLBuilder(rest);\n\n return <TPSL {...state} onCancel={onCancel} onComplete={onComplete} />;\n};\n","import { ReactNode, useState } from \"react\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n} from \"@orderly.network/ui\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { TPSLWidget } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport { ButtonProps } from \"@orderly.network/ui\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport const PositionTPSLPopover = (props: {\n position: API.Position;\n order?: API.AlgoOrder;\n label?: string;\n baseDP?: number;\n quoteDP?: number;\n /**\n * Button props\n */\n buttonProps?: ButtonProps;\n isEditing?: boolean;\n children?: ReactNode;\n}) => {\n const { position, order, baseDP, quoteDP, buttonProps, isEditing } = props;\n const [open, setOpen] = useState(false);\n const [visible, setVisible] = useState(true);\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n return (\n <PopoverRoot\n onOpenChange={(isOpen) => {\n // console.log(\"isOpen\", isOpen);\n if (visible) {\n setOpen(isOpen);\n }\n }}\n open={open}\n >\n <PopoverTrigger\n asChild\n onClick={() => {\n setOpen(true);\n }}\n >\n {props.children || (\n <Button\n variant=\"outlined\"\n size=\"sm\"\n color=\"secondary\"\n {...buttonProps}\n // onClick={() => {\n // setOpen(true);\n // }}\n >\n {props.label}\n </Button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"oui-w-[360px]\",\n visible ? \"oui-visible\" : \"oui-invisible\"\n )}\n align=\"end\"\n side={\"top\"}\n >\n <TPSLWidget\n position={position}\n order={order}\n isEditing={isEditing}\n onComplete={() => {\n // console.log(\"tpsl order completed\");\n setOpen(false);\n }}\n onCancel={() => {\n setOpen(false);\n }}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n setVisible(false);\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n // console.log(\n // \"order\",\n // order,\n // isEditing ||\n // (!!order &&\n // order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n // order.quantity === maxQty)\n // );\n\n if (\n `${order.tp_trigger_price ?? \"\"}`.length === 0 &&\n `${order.sl_trigger_price ?? \"\"}`.length === 0\n ) {\n return modal\n .confirm({\n title: t(\"orders.cancelOrder\"),\n content: t(\"tpsl.cancelOrder.description\"),\n onOk: () => {\n return options.cancel();\n },\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n }\n );\n }\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n // bodyClassName: \"lg:oui-py-0\",\n onOk: () => {\n return options.submit();\n },\n classNames: {\n body: \"!oui-pb-0\",\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={finalIsEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quoteDP ?? 2}\n baseDP={baseDP ?? 2}\n />\n ),\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n }\n );\n }}\n />\n </PopoverContent>\n </PopoverRoot>\n );\n};\n","import { useMemo } from \"react\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Flex,\n modal,\n useModal,\n Text,\n Box,\n Badge,\n Divider,\n toast,\n} from \"@orderly.network/ui\";\nimport { TPSLWidget, TPSLWidgetProps } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\ntype TPSLSheetProps = {\n position: API.Position;\n order?: API.AlgoOrder;\n // label: string;\n // baseDP?: number;\n // quoteDP?: number;\n symbolInfo: API.SymbolExt;\n isEditing?: boolean;\n};\n\nexport const PositionTPSLSheet = (props: TPSLWidgetProps & TPSLSheetProps) => {\n const { position, order, symbolInfo, isEditing } = props;\n const { resolve, hide, updateArgs } = useModal();\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n const updateSheetTitle = (title: string) => {\n if (isEditing) return;\n updateArgs({ title });\n };\n\n const onCompleted = () => {\n resolve();\n hide();\n };\n\n const { quote_dp, base_dp } = symbolInfo;\n\n return (\n <>\n <PositionInfo position={position} symbolInfo={symbolInfo} />\n\n <TPSLWidget\n {...props}\n onTPSLTypeChange={(type) => {\n updateSheetTitle(\n type === AlgoOrderRootType.TP_SL\n ? t(\"common.tpsl\")\n : t(\"tpsl.positionTpsl\")\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n bodyClassName: \"oui-pb-0 lg:oui-pb-0\",\n onOk: () => {\n return options.submit();\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={isEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quote_dp ?? 2}\n baseDP={base_dp ?? 2}\n />\n ),\n })\n .then(\n () => {\n // setOpen(false);\n // setVisible(true);\n return true;\n },\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n\n // setVisible(true);\n return Promise.reject(false);\n }\n );\n }}\n onCancel={() => {\n hide();\n }}\n />\n </>\n );\n};\n\nexport const TPSLSheetTitle = () => {\n const modal = useModal();\n const { t } = useTranslation();\n\n const title = useMemo<string>(() => {\n return (modal.args?.title || t(\"common.tpsl\")) as string;\n }, [modal.args?.title, t]);\n\n return <span>{title}</span>;\n};\n\nexport const PositionInfo = (props: {\n position: API.Position;\n symbolInfo: API.SymbolExt;\n}) => {\n const { position, symbolInfo } = props;\n const { data: markPrice } = useMarkPrice(position.symbol);\n const modal = useModal();\n const { t } = useTranslation();\n\n const isPositionTPSL = useMemo(() => {\n return modal.args?.title === t(\"tpsl.positionTpsl\");\n }, [modal.args?.title, t]);\n return (\n <>\n <Flex justify={\"between\"} pb={3} itemAlign={\"center\"}>\n <Text.formatted rule=\"symbol\" className=\"oui-text-xs\" showIcon>\n {position.symbol}\n </Text.formatted>\n <Flex gapX={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color=\"primary\">\n {t(\"common.position\")}\n </Badge>\n )}\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider intensity={8} />\n <Box py={3} className=\"oui-space-y-1\">\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.avgOpen\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {position.average_open_price}\n </Text.numeral>\n </Flex>\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.markPrice\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {markPrice}\n </Text.numeral>\n </Flex>\n </Box>\n </>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tpsl.ui.tsx","../src/pnlInput/pnlInput.ui.tsx","../src/pnlInput/useBuilder.script.ts","../src/pnlInput/pnlInput.widget.tsx","../src/useTPSL.script.ts","../src/tpsl.widget.tsx","../src/editorPopover.tsx","../src/editorSheet.tsx"],"names":["useRef","useState","useLocalStorage","utils","useTranslation","useOrderEntryFormErrorMsg","OrderSide","Badge","Box","Button","Divider","Flex","Grid","Input","Slider","Text","textVariants","cn","inputFormatter","Checkbox","convertValueToPercentage","ThrottledButton","transSymbolformString","CaretDownIcon","SimpleDropdownMenu","useMemo","Decimal","todpIfNeed","usePNLInputBuilder","props","type","values","mode","setMode","focus","setFocus","t","key","value","modes","percentageSuffix","onValueChange","formatter","options","dp","endStr","useEffect","Fragment","jsx","jsxs","PNLInput","onModeChange","quote","quote_dp","pnl","prefix","setPrefix","placeholder","setPlaceholder","color","num","label","item","PNLMenus","PnlInputWidget","testId","rest","state","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","parseErrorMsg","TPSLQuantity","TPSLPrice","err","inputRef","currentQtyPercentage","setTPSL","formatQuantity","qty","quantity","errorMsg","e","onPnLChange","PriceInput","PositionTPSLConfirm","symbol","tpPrice","slPrice","maxQty","side","quoteDP","baseDP","isEditing","_isPositionTPSL","needConfirm","setNeedConfirm","textClassName","isPositionTPSL","TPSLOrderType","check","useSymbolsInfo","useTPSLOrder","SDKError","AlgoOrderRootType","AlgoOrderType","toast","useTPSLBuilder","position","order","prevTPSLType","tpslOrder","submit","deleteOrder","setValue","validate","isCreateMutating","isUpdateMutating","setQuantity","setOrderPrice","name","setPnL","dirty","diff","tp","o","sl","valid","trigger_prices","cancel","onSubmit","TPSLWidget","modal","PopoverContent","PopoverRoot","PopoverTrigger","PositionTPSLPopover","buttonProps","open","setOpen","visible","setVisible","isOpen","finalIsEditing","res","useMarkPrice","useModal","PositionTPSLSheet","resolve","hide","updateArgs","updateSheetTitle","title","onCompleted","base_dp","PositionInfo","reject","markPrice"],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\nimport { useLocalStorage, utils } from \"@orderly.network/hooks\";\nimport { OrderValidationResult } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useOrderEntryFormErrorMsg } from \"@orderly.network/react-app\";\nimport { API, OrderSide } from \"@orderly.network/types\";\nimport {\n Badge,\n Box,\n Button,\n Divider,\n Flex,\n Grid,\n Input,\n Slider,\n Text,\n textVariants,\n cn,\n inputFormatter,\n Checkbox,\n convertValueToPercentage,\n ThrottledButton,\n} from \"@orderly.network/ui\";\nimport { transSymbolformString } from \"@orderly.network/utils\";\nimport { PnlInputWidget } from \"./pnlInput/pnlInput.widget\";\nimport type { PNL_Values } from \"./pnlInput/useBuilder.script\";\nimport { TPSLBuilderState } from \"./useTPSL.script\";\n\nexport type TPSLProps = {\n onCancel?: () => void;\n onComplete?: () => void;\n};\n\n//------------- TPSL form start ---------------\nexport const TPSL = (props: TPSLBuilderState & TPSLProps) => {\n const {\n TPSL_OrderEntity,\n symbolInfo,\n onCancel,\n onComplete,\n status,\n errors,\n isPosition,\n } = props;\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(errors);\n\n return (\n <div id=\"orderly-tp_sl-order-edit-content\">\n {(!props.isEditing || (props.isEditing && !props.isPosition)) && (\n <>\n <TPSLQuantity\n maxQty={props.maxQty}\n quantity={(props.orderQuantity ?? props.maxQty) as number}\n baseTick={symbolInfo(\"base_tick\")}\n dp={symbolInfo(\"base_dp\")}\n onQuantityChange={props.setQuantity}\n quote={symbolInfo(\"base\")}\n isEditing={props.isEditing}\n isPosition={isPosition}\n errorMsg={parseErrorMsg(\"quantity\")}\n />\n <Divider my={4} intensity={8} />\n </>\n )}\n\n <TPSLPrice\n sl_pnl={TPSL_OrderEntity.sl_pnl}\n tp_pnl={TPSL_OrderEntity.tp_pnl}\n quote={symbolInfo(\"quote\")}\n quote_dp={symbolInfo(\"quote_dp\")}\n onPriceChange={props.setOrderPrice}\n onPnLChange={props.setPnL}\n errors={errors}\n tp_values={{\n PnL: `${TPSL_OrderEntity.tp_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.tp_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.tp_offset_percentage ?? \"\"}`,\n }}\n sl_values={{\n PnL: `${TPSL_OrderEntity.sl_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.sl_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.sl_offset_percentage ?? \"\"}`,\n }}\n tp_trigger_price={TPSL_OrderEntity.tp_trigger_price ?? \"\"}\n sl_trigger_price={TPSL_OrderEntity.sl_trigger_price ?? \"\"}\n />\n <Grid cols={2} gap={3} mt={4}>\n <Button\n size={\"md\"}\n color={\"secondary\"}\n data-testid={\"tpsl-cancel\"}\n onClick={() => {\n onCancel?.();\n }}\n >\n {t(\"common.cancel\")}\n </Button>\n <ThrottledButton\n size={\"md\"}\n data-testid={\"tpsl-confirm\"}\n disabled={!props.valid || status.isCreateMutating}\n loading={status.isCreateMutating || status.isUpdateMutating}\n onClick={() => {\n props\n .onSubmit()\n .then(() => {\n onComplete?.();\n })\n .catch((err) => {\n console.log(\"--->>>cancel order\", err);\n });\n }}\n >\n {t(\"common.confirm\")}\n </ThrottledButton>\n </Grid>\n </div>\n );\n};\n\n//----------\n\n// ------------- Quantity input start------------\nconst TPSLQuantity = (props: {\n maxQty: number;\n baseTick: number;\n dp: number;\n quote: string;\n onQuantityChange?: (value: number | string) => void;\n quantity: number;\n isEditing?: boolean;\n isPosition?: boolean;\n setOrderValue?: (key: string, value: number | string) => void;\n errorMsg?: string;\n}) => {\n // const isPosition = props.quantity === props.maxQty;\n const { isPosition } = props;\n const inputRef = useRef<HTMLInputElement>(null);\n const currentQtyPercentage =\n convertValueToPercentage(props.quantity, 0, props.maxQty) / 100;\n const { t } = useTranslation();\n\n const setTPSL = () => {\n props.onQuantityChange?.(0);\n inputRef.current?.focus();\n\n setTimeout(() => {\n inputRef.current?.setSelectionRange(0, 1);\n }, 0);\n };\n\n const formatQuantity = (qty: string) => {\n if (props.baseTick > 0) {\n const quantity = Number(qty);\n // if (quantity) {\n // props.onQuantityChange?.(Math.min(props.maxQty, quantity));\n // } else {\n props.onQuantityChange?.(utils.formatNumber(qty, props.baseTick) ?? qty);\n // }\n }\n };\n\n const errorMsg =\n (isPosition ? \"\" : props.quantity).toString().length > 0\n ? props.errorMsg\n : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n data-testid=\"oui-testid-tpsl-popUp-quantity-input\"\n ref={inputRef}\n prefix={t(\"common.quantity\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n align=\"right\"\n value={isPosition ? \"\" : props.quantity}\n autoComplete=\"off\"\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: cn(\n \"oui-bg-base-5 oui-outline-line-12\",\n errorMsg && \"oui-outline-danger\",\n ),\n }}\n tooltipProps={{\n content: {\n className: \"oui-bg-base-6 oui-text-base-contrast-80\",\n },\n arrow: {\n className: \"oui-fill-base-6\",\n },\n }}\n tooltip={errorMsg}\n color={errorMsg ? \"danger\" : undefined}\n formatters={[\n inputFormatter.dpFormatter(props.dp),\n inputFormatter.numberFormatter,\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n const qty = Number(value);\n if (qty && qty > props.maxQty) {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n inputRef.current?.blur();\n }\n }}\n onBlur={(e) => formatQuantity(e.target.value)}\n suffix={\n isPosition ? (\n <button\n className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\"\n onClick={() => {\n setTPSL();\n }}\n >\n {t(\"tpsl.entirePosition\")}\n </button>\n ) : (\n <span className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\">\n {props.quote}\n </span>\n )\n }\n />\n </div>\n {!props.isEditing && (\n <Button\n onClick={() => {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n if (qty === 0) {\n setTPSL();\n }\n }}\n variant={\"outlined\"}\n // size={{\n // lg: \"md\",\n // md: \"lg\",\n // }}\n className={cn(\n \"oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]\",\n isPosition\n ? \"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20\"\n : \"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5\",\n )}\n >\n {t(\"common.position\")}\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primary\"\n max={props.maxQty}\n min={0}\n showTip\n step={props.baseTick}\n value={props.quantity}\n onValueCommit={(value) => {\n formatQuantity(`${value}`);\n }}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n }}\n />\n </Flex>\n <Flex justify={\"between\"}>\n <Text.numeral rule={\"percentages\"} color={\"primary\"} size={\"2xs\"}>\n {currentQtyPercentage}\n </Text.numeral>\n <Flex itemAlign={\"center\"} gap={1}>\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={() => {\n props.onQuantityChange?.(props.maxQty);\n }}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {t(\"common.max\")}\n </Text>\n </button>\n\n <Text.numeral\n rule={\"price\"}\n size={\"2xs\"}\n intensity={54}\n tick={props.baseTick}\n >\n {props.maxQty}\n </Text.numeral>\n </Flex>\n </Flex>\n </>\n );\n};\n// ------------- Quantity input end------------\n\n// ------------ TP/SL Price and PNL input start------------\nconst TPSLPrice = (props: {\n tp_pnl?: number;\n sl_pnl?: number;\n quote: string;\n quote_dp?: number;\n onPriceChange: TPSLBuilderState[\"setOrderPrice\"];\n onPnLChange: TPSLBuilderState[\"setPnL\"];\n tp_values: PNL_Values;\n sl_values: PNL_Values;\n tp_trigger_price?: number | string;\n sl_trigger_price?: number | string;\n errors: OrderValidationResult | null;\n}) => {\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(props.errors);\n\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.takeProfit\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.tp_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"TP\"}\n value={props.tp_trigger_price}\n error={parseErrorMsg(\"tp_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"tp_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"TP\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.tp_values}\n />\n </Grid>\n </div>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.stopLoss\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.sl_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"SL\"}\n value={props.sl_trigger_price}\n error={parseErrorMsg(\"sl_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"sl_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"SL\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.sl_values}\n />\n </Grid>\n </div>\n </>\n );\n};\n// ------------ TP/SL Price and PNL input end------------\n// ------------ TP/SL Price input start------------\nconst PriceInput = (props: {\n type: string;\n value?: string | number;\n error?: string;\n onValueChange: (value: string) => void;\n quote_dp: number;\n}) => {\n const [placeholder, setPlaceholder] = useState<string>(\"USDC\");\n const { t } = useTranslation();\n\n return (\n <Input.tooltip\n data-testid={`oui-testid-tpsl-popUp-${props.type.toLowerCase()}-input`}\n // prefix={`${props.type} price`}\n prefix={t(\"common.markPrice\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n tooltip={props.error}\n placeholder={placeholder}\n align={\"right\"}\n autoComplete={\"off\"}\n value={props.value}\n color={props.error ? \"danger\" : undefined}\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onValueChange={props.onValueChange}\n onFocus={() => {\n setPlaceholder(\"\");\n }}\n onBlur={() => {\n setPlaceholder(\"USDC\");\n }}\n formatters={[\n inputFormatter.numberFormatter,\n inputFormatter.dpFormatter(props.quote_dp),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n />\n );\n};\n\nexport type PositionTPSLConfirmProps = {\n symbol: string;\n // isPosition: boolean;\n qty: number;\n tpPrice?: number;\n slPrice?: number;\n maxQty: number;\n side: OrderSide;\n // symbolConfig:API.SymbolExt\n baseDP: number;\n quoteDP: number;\n isEditing?: boolean;\n isPositionTPSL?: boolean;\n};\n\n// ------------ Position TP/SL Confirm dialog start------------\nexport const PositionTPSLConfirm = (props: PositionTPSLConfirmProps) => {\n const {\n symbol,\n tpPrice,\n slPrice,\n qty,\n maxQty,\n side,\n quoteDP,\n baseDP,\n isEditing,\n isPositionTPSL: _isPositionTPSL,\n } = props;\n const { t } = useTranslation();\n\n const [needConfirm, setNeedConfirm] = useLocalStorage(\n \"orderly_order_confirm\",\n true,\n );\n const textClassName = textVariants({\n size: \"xs\",\n intensity: 54,\n });\n\n // console.log(\"PositionTPSLConfirm\", qty, maxQty, quoteDP);\n\n const isPositionTPSL = _isPositionTPSL ?? qty >= maxQty;\n\n return (\n <>\n {isEditing && (\n <Text\n as=\"div\"\n size=\"2xs\"\n intensity={80}\n className=\"oui-mb-3\"\n >{`You agree to edit your ${transSymbolformString(\n symbol,\n )} order.`}</Text>\n )}\n\n <Flex pb={4}>\n <Box grow>\n <Text.formatted\n rule={\"symbol\"}\n formatString=\"base-type\"\n size=\"base\"\n showIcon\n as=\"div\"\n intensity={80}\n >\n {symbol}\n </Text.formatted>\n </Box>\n <Flex gap={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color={\"primary\"}>\n {t(\"common.position\")}\n </Badge>\n )}\n\n {/* <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge> */}\n <TPSLOrderType tpPrice={tpPrice} slPrice={slPrice} />\n {side === OrderSide.SELL ? (\n <Badge size=\"xs\" color=\"success\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider />\n <Flex\n direction={\"column\"}\n itemAlign={\"stretch\"}\n gapY={1}\n pt={4}\n // pb={5}\n className={cn(textClassName, \"oui-pb-4 xl:oui-pb-5\")}\n >\n <Flex>\n <Box grow>{t(\"common.qty\")}</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">\n {t(\"tpsl.entirePosition\")}\n </span>\n ) : (\n <Text.numeral intensity={98} dp={baseDP} padding={false}>\n {qty}\n </Text.numeral>\n )}\n </div>\n </Flex>\n {typeof tpPrice === \"number\" && tpPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.tpPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {tpPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n {typeof slPrice === \"number\" && slPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.slPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n className=\"oui-text-trade-loss\"\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {slPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n\n <Flex>\n <Box grow>{t(\"common.price\")}</Box>\n <div className=\"oui-text-base-contrast\">\n {t(\"common.marketPrice\")}\n </div>\n </Flex>\n </Flex>\n <Box pt={2}>\n <Flex gap={1}>\n <Checkbox\n id=\"disabledConfirm\"\n color=\"white\"\n checked={!needConfirm}\n onCheckedChange={(check) => {\n setNeedConfirm(!check);\n }}\n />\n <label\n htmlFor=\"disabledConfirm\"\n className={textVariants({\n size: \"xs\",\n intensity: 54,\n className: \"oui-ml-1\",\n })}\n >\n {t(\"orderEntry.disableOrderConfirm\")}\n </label>\n </Flex>\n </Box>\n </>\n );\n};\n\n//------------- Position TP/SL Confirm dialog end------------\n\nconst TPSLOrderType = (props: { tpPrice?: number; slPrice?: number }) => {\n const { tpPrice, slPrice } = props;\n const { t } = useTranslation();\n\n if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.tp\")}\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.sl\")}\n </Badge>\n );\n }\n\n return null;\n};\n\nconst MaxQtyButton = (props: {\n onClick: () => void;\n children?: React.ReactNode;\n}) => {\n return (\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={props.onClick}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {props.children}\n </Text>\n </button>\n );\n};\n","import {\n CaretDownIcon,\n cn,\n Input,\n MenuItem,\n SimpleDropdownMenu,\n} from \"@orderly.network/ui\";\nimport { PNLInputState, PnLMode } from \"./useBuilder.script\";\nimport { inputFormatter, Text } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport type PNLInputProps = PNLInputState & { testId?: string; quote: string };\n\nexport const PNLInput = (props: PNLInputProps) => {\n const {\n mode,\n modes,\n onModeChange,\n onValueChange,\n quote,\n quote_dp,\n value,\n pnl,\n } = props;\n const { t } = useTranslation();\n\n const [prefix, setPrefix] = useState<string>(mode);\n const [placeholder, setPlaceholder] = useState<string>(\n mode === PnLMode.PERCENTAGE ? \"%\" : quote\n );\n\n const color = useMemo(() => {\n const num = Number(pnl);\n\n if (isNaN(num) || num === 0) return \"\";\n\n if (num > 0) return \"oui-text-trade-profit\";\n if (num < 0) return \"oui-text-trade-loss\";\n }, [pnl]);\n\n useEffect(() => {\n const label = modes.find((item) => item.value === mode)?.label;\n setPrefix(label!);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode, modes]);\n\n return (\n <Input\n prefix={prefix}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n placeholder={placeholder}\n align={\"right\"}\n value={value}\n data-testid={props.testId}\n autoComplete={\"off\"}\n onValueChange={onValueChange}\n formatters={[\n // inputFormatter.numberFormatter,\n props.formatter({ dp: quote_dp, mode }),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n // className={color}\n classNames={{\n input: color,\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onFocus={() => {\n setPlaceholder(\"\");\n props.setFocus(true);\n }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n props.setFocus(false);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text\n size={\"2xs\"}\n color=\"inherit\"\n className={cn(\"oui-ml-[2px]\", color)}\n >\n %\n </Text>\n )}\n <PNLMenus\n mode={mode}\n modes={modes}\n onModeChange={(item) => onModeChange(item.value as PnLMode)}\n />\n </>\n }\n />\n );\n};\n\nconst PNLMenus = (props: {\n mode?: string;\n modes: MenuItem[];\n onModeChange: (value: MenuItem) => void;\n}) => {\n return (\n <SimpleDropdownMenu\n currentValue={props.mode}\n menu={props.modes}\n align={\"end\"}\n size={\"xs\"}\n className={\"oui-min-w-[80px]\"}\n onSelect={(item) => props.onModeChange(item as MenuItem)}\n >\n <button className={\"oui-p-2\"}>\n <CaretDownIcon size={12} color={\"white\"} />\n </button>\n </SimpleDropdownMenu>\n );\n};\n","import { useMemo, useRef, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { MenuItem } from \"@orderly.network/ui\";\nimport type {\n InputFormatter,\n InputFormatterOptions,\n} from \"@orderly.network/ui\";\nimport { Decimal, todpIfNeed } from \"@orderly.network/utils\";\n\nexport enum PnLMode {\n PnL = \"PnL\",\n OFFSET = \"Offset\",\n PERCENTAGE = \"Offset%\",\n}\n\nexport type PNL_Values = {\n PnL: string;\n Offset: string;\n \"Offset%\": string;\n};\n\nexport type BuilderProps = {\n type: \"TP\" | \"SL\";\n\n quote_dp?: number;\n onChange: (key: string, value: number | string) => void;\n\n values: PNL_Values;\n};\n\nexport const usePNLInputBuilder = (props: BuilderProps) => {\n const { type, values } = props;\n const [mode, setMode] = useLocalStorage<PnLMode>(\n \"TP/SL_Mode\",\n PnLMode.PERCENTAGE,\n );\n const [focus, setFocus] = useState(true);\n\n const { t } = useTranslation();\n\n const key = useMemo(() => {\n switch (mode) {\n case PnLMode.OFFSET:\n return `${type.toLowerCase()}_offset`;\n case PnLMode.PERCENTAGE:\n return `${type.toLowerCase()}_offset_percentage`;\n default:\n return `${type.toLowerCase()}_pnl`;\n }\n }, [mode]);\n\n const value = useMemo(() => {\n return values[mode as keyof PNL_Values];\n }, [values, mode]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n {\n label: t(\"tpsl.pnl\"),\n value: PnLMode.PnL,\n testId: `${PnLMode.PnL}_menu_item`,\n },\n {\n label: t(\"tpsl.offset\"),\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: `${t(\"tpsl.offset\")}%`,\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, [t]);\n\n const percentageSuffix = useRef<string>(\"\");\n\n const onValueChange = (value: string) => {\n props.onChange(key, value);\n };\n\n const formatter = (options: {\n dp?: number;\n mode: PnLMode;\n }): InputFormatter => {\n const { dp = 2 } = options;\n return {\n onRenderBefore: (\n value: string | number,\n options: InputFormatterOptions,\n ) => {\n value = `${value}`; // convert to string\n\n if (focus) {\n if (type === \"SL\" && mode === PnLMode.PnL) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n }\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n // if (mode === PnLMode.PnL || mode === PnLMode.OFFSET) {\n // return commify(value);\n // }\n\n if (mode === PnLMode.PERCENTAGE) {\n return `${new Decimal(\n value.replace(\n new RegExp(percentageSuffix.current.replace(\".\", \"\\\\.\") + \"$\"),\n \"\",\n ),\n )\n .mul(100)\n .todp(2, 4)\n .toString()}${percentageSuffix.current}`;\n } else if (mode === PnLMode.OFFSET) {\n value = todpIfNeed(value, dp);\n } else {\n // value = new Decimal(value).todp(2).toString();\n }\n\n return `${value}`;\n },\n onSendBefore: (value: string) => {\n if (/^\\-?0{2,}$/.test(value)) {\n return \"0\";\n }\n\n if (mode === PnLMode.PERCENTAGE) {\n // console.log(\"value\", value);\n if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n value = todpIfNeed(value, 2);\n const endStr = value.match(/\\.0{0,2}$/);\n if (!!endStr) {\n percentageSuffix.current = endStr[0];\n } else {\n percentageSuffix.current = \"\";\n }\n value = new Decimal(value).div(100).toString();\n value = `${value}${percentageSuffix.current}`;\n }\n } else if (mode === PnLMode.PnL && type === \"SL\" && focus) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n } else {\n value = todpIfNeed(value, dp);\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n\n return value;\n },\n };\n // return {\n // onRenderBefore: (\n // value: string | number,\n // options: InputFormatterOptions\n // ) => {\n // // console.log(\"???\", options);\n // const { isFocused } = options;\n // value = `${value}`;\n // if (value === \"\" || value === \"-\") return \"\";\n\n // // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (isFocused) {\n // // value = value.startsWith(\"-\") ? value : \"-\" + value;\n // // }\n // // }\n\n // if (mode === PnLMode.PERCENTAGE) {\n // return `${todpIfNeed(new Decimal(value).mul(100).toString(), 2)}${\n // percentageSuffix.current\n // }`;\n // // return (Number(value) * 100).toFixed(2);\n // } else if (mode === PnLMode.OFFSET) {\n // value = todpIfNeed(value, 2);\n // } else {\n // // value = new Decimal(value).todp(2).toString();\n // }\n\n // return value;\n // },\n // onSendBefore: (value: string, options: InputFormatterOptions) => {\n // const { isFocused } = options;\n\n // if (mode === PnLMode.PERCENTAGE) {\n // if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n // value = new Decimal(value).div(100).toString();\n // value = todpIfNeed(value, 4);\n // }\n // } else {\n // // value = todpIfNeed(value, quote_dp);\n // if (isFocused) {\n // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (\n // // typeof values[PnLMode.PnL] !== \"undefined\" &&\n // // values[PnLMode.PnL] !== \"\"\n // // )\n // // return value;\n // const num = Number(value);\n // if (!isNaN(num) && num !== 0) {\n // value = (Math.abs(num) * -1).toString();\n // } else {\n // value = \"\";\n // }\n // }\n // }\n // }\n\n // return value;\n // },\n // };\n };\n\n return {\n mode,\n modes,\n type: props.type,\n formatter,\n onModeChange: (mode: PnLMode) => {\n setMode(mode);\n },\n value,\n pnl: values[PnLMode.PnL],\n onValueChange,\n quote_dp: props.quote_dp,\n setFocus,\n };\n};\n\nexport type PNLInputState = ReturnType<typeof usePNLInputBuilder>;\n","import { PNLInput } from \"./pnlInput.ui\";\nimport { BuilderProps, usePNLInputBuilder } from \"./useBuilder.script\";\n\nexport const PnlInputWidget = (\n props: BuilderProps & {\n testId?: string;\n quote: string;\n }\n) => {\n const { testId, quote, ...rest } = props;\n const state = usePNLInputBuilder(rest);\n return <PNLInput {...state} testId={testId} quote={quote} />;\n};\n","import { useEffect, useMemo, useRef } from \"react\";\nimport {\n type ComputedAlgoOrder,\n useLocalStorage,\n useSymbolsInfo,\n useTPSLOrder,\n utils,\n} from \"@orderly.network/hooks\";\nimport { SDKError } from \"@orderly.network/types\";\nimport { AlgoOrderRootType, AlgoOrderType, API } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\n\nexport type TPSLBuilderOptions = {\n position: API.Position;\n order?: API.AlgoOrder;\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n isEditing?: boolean;\n /**\n * either show the confirm dialog or not,\n * if the Promise reject or return false, cancel the submit action\n */\n onConfirm?: (\n order: ComputedAlgoOrder,\n options: {\n position: API.Position;\n submit: (params?: { accountId?: string }) => Promise<any>;\n cancel: () => Promise<any>;\n },\n ) => Promise<boolean>;\n};\n\nexport const useTPSLBuilder = (options: TPSLBuilderOptions) => {\n const { position, order, isEditing } = options;\n // const isEditing = !!order;\n if (isEditing && !order) {\n throw new SDKError(\"order is required when isEditing is true\");\n }\n const symbol = isEditing ? order!.symbol : position.symbol;\n const symbolInfo = useSymbolsInfo();\n const prevTPSLType = useRef<AlgoOrderRootType>(AlgoOrderRootType.TP_SL);\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const [\n tpslOrder,\n {\n submit,\n deleteOrder,\n setValue,\n validate,\n errors,\n isCreateMutating,\n isUpdateMutating,\n },\n ] = useTPSLOrder(\n {\n symbol,\n position_qty: position.position_qty,\n average_open_price: position.average_open_price,\n },\n {\n defaultOrder: order,\n isEditing,\n },\n );\n\n const setQuantity = (value: number | string) => {\n setValue(\"quantity\", value);\n };\n\n const setOrderPrice = (\n name: \"tp_trigger_price\" | \"sl_trigger_price\",\n value: number | string,\n ) => {\n setValue(name, value);\n };\n\n const setPnL = (type: string, value: number | string) => {\n setValue(type, value);\n };\n\n const maxQty = useMemo(\n () => Math.abs(Number(position.position_qty)),\n [position.position_qty],\n );\n\n const dirty = useMemo(() => {\n const quantity =\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n ? maxQty\n : order?.quantity;\n\n let diff: number = 0;\n\n if (Number(tpslOrder.quantity) !== quantity) {\n diff = 1;\n } else if (!isEditing && !!tpslOrder.quantity) {\n diff = 1;\n }\n\n if (order && isEditing) {\n const tp = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.TAKE_PROFIT,\n );\n const sl = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.STOP_LOSS,\n );\n\n if (\n tp?.trigger_price !== Number(tpslOrder.tp_trigger_price) &&\n typeof typeof tpslOrder.tp_trigger_price !== \"undefined\"\n ) {\n // return true;\n diff = 2;\n }\n\n if (\n sl?.trigger_price !== Number(tpslOrder.sl_trigger_price) &&\n typeof tpslOrder.sl_trigger_price !== \"undefined\"\n ) {\n diff = 3;\n }\n }\n\n if (\n diff === 1 &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n diff = -1;\n }\n\n return diff;\n }, [\n tpslOrder.tp_trigger_price,\n tpslOrder.sl_trigger_price,\n tpslOrder.quantity,\n order,\n isEditing,\n ]);\n\n const valid = useMemo(() => {\n /**\n * if the order is a POSITIONAL_TP_SL and the quantity is less than the maxQty,\n * and the tp/sl trigger price is not set, then the order is not valid\n */\n if (\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n Number(tpslOrder.quantity) < maxQty &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n return false;\n }\n\n return dirty > 0 && !!tpslOrder.quantity && !errors;\n }, [tpslOrder.quantity, maxQty, dirty, errors]);\n\n const isPositionTPSL = useMemo(() => {\n if (!isEditing) return Number(tpslOrder.quantity) >= maxQty;\n /**\n * if current order is not a POSITIONAL_TP_SL, then it's always a general TP/SL\n */\n if (!!order && order.algo_type !== AlgoOrderRootType.POSITIONAL_TP_SL) {\n return false;\n }\n if (tpslOrder.algo_order_id && tpslOrder.quantity == 0) return true;\n return Number(tpslOrder.quantity) >= maxQty;\n }, [tpslOrder.quantity, maxQty, order?.algo_type, isEditing]);\n\n useEffect(() => {\n if (!isEditing && isPositionTPSL) {\n const trigger_prices = utils.findTPSLFromOrder(order!);\n if (!tpslOrder.tp_trigger_price && trigger_prices.tp_trigger_price) {\n setOrderPrice(\"tp_trigger_price\", trigger_prices.tp_trigger_price);\n }\n if (!tpslOrder.sl_trigger_price && trigger_prices.sl_trigger_price) {\n setOrderPrice(\"sl_trigger_price\", trigger_prices.sl_trigger_price);\n }\n }\n }, [isEditing, isPositionTPSL, tpslOrder]);\n\n useEffect(() => {\n const type =\n Number(tpslOrder.quantity) < maxQty\n ? AlgoOrderRootType.TP_SL\n : AlgoOrderRootType.POSITIONAL_TP_SL;\n if (\n typeof options.onTPSLTypeChange === \"function\" &&\n prevTPSLType.current !== type\n ) {\n options.onTPSLTypeChange(type);\n }\n\n prevTPSLType.current = type;\n }, [tpslOrder.quantity, maxQty]);\n\n const cancel = (): Promise<void> => {\n if (order?.algo_order_id && order?.symbol) {\n return deleteOrder(order?.algo_order_id, order?.symbol);\n }\n return Promise.reject(\"order id or symbol is invalid\");\n };\n\n const onSubmit = async () => {\n if (typeof options.onConfirm !== \"function\" || !needConfirm) {\n return submit({ accountId: position.account_id })\n .then(() => true)\n .catch((err) => {\n if (err?.message) {\n toast.error(err.message);\n }\n throw false;\n });\n }\n\n return options.onConfirm(tpslOrder, {\n position,\n submit,\n cancel,\n });\n };\n\n return {\n isEditing,\n symbolInfo: symbolInfo[symbol],\n maxQty,\n setQuantity,\n orderQuantity: tpslOrder.quantity,\n isPosition: isPositionTPSL,\n\n TPSL_OrderEntity: tpslOrder,\n setOrderValue: setValue,\n setPnL,\n setOrderPrice,\n // needConfirm,\n onSubmit,\n valid,\n errors,\n status: {\n isCreateMutating,\n isUpdateMutating,\n },\n } as const;\n};\n\nexport type TPSLBuilderState = ReturnType<typeof useTPSLBuilder>;\n","import { type AlgoOrderRootType } from \"@orderly.network/types\";\nimport { TPSL, TPSLProps } from \"./tpsl.ui\";\nimport { TPSLBuilderOptions, useTPSLBuilder } from \"./useTPSL.script\";\n\nexport type TPSLWidgetProps = {\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n} & TPSLBuilderOptions &\n TPSLProps;\n\nexport const TPSLWidget = (props: TPSLWidgetProps) => {\n const { onCancel, onComplete, ...rest } = props;\n const state = useTPSLBuilder(rest);\n\n return <TPSL {...state} onCancel={onCancel} onComplete={onComplete} />;\n};\n","import { ReactNode, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n toast,\n} from \"@orderly.network/ui\";\nimport { ButtonProps } from \"@orderly.network/ui\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { TPSLWidget } from \"./tpsl.widget\";\n\nexport const PositionTPSLPopover = (props: {\n position: API.Position;\n order?: API.AlgoOrder;\n label?: string;\n baseDP?: number;\n quoteDP?: number;\n /**\n * Button props\n */\n buttonProps?: ButtonProps;\n isEditing?: boolean;\n children?: ReactNode;\n}) => {\n const { position, order, baseDP, quoteDP, buttonProps, isEditing } = props;\n const [open, setOpen] = useState(false);\n const [visible, setVisible] = useState(true);\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n return (\n <PopoverRoot\n onOpenChange={(isOpen) => {\n // console.log(\"isOpen\", isOpen);\n if (visible) {\n setOpen(isOpen);\n }\n }}\n open={open}\n >\n <PopoverTrigger\n asChild\n onClick={() => {\n setOpen(true);\n }}\n >\n {props.children || (\n <Button\n variant=\"outlined\"\n size=\"sm\"\n color=\"secondary\"\n {...buttonProps}\n // onClick={() => {\n // setOpen(true);\n // }}\n >\n {props.label}\n </Button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"oui-w-[360px]\",\n visible ? \"oui-visible\" : \"oui-invisible\",\n )}\n align=\"end\"\n side={\"top\"}\n >\n <TPSLWidget\n position={position}\n order={order}\n isEditing={isEditing}\n onComplete={() => {\n // console.log(\"tpsl order completed\");\n setOpen(false);\n }}\n onCancel={() => {\n setOpen(false);\n }}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n setVisible(false);\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n // console.log(\n // \"order\",\n // order,\n // isEditing ||\n // (!!order &&\n // order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n // order.quantity === maxQty)\n // );\n\n if (\n `${order.tp_trigger_price ?? \"\"}`.length === 0 &&\n `${order.sl_trigger_price ?? \"\"}`.length === 0\n ) {\n return modal\n .confirm({\n title: t(\"orders.cancelOrder\"),\n content: t(\"tpsl.cancelOrder.description\"),\n onOk: () => {\n return options.cancel();\n },\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n },\n );\n }\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n // bodyClassName: \"lg:oui-py-0\",\n onOk: async () => {\n try {\n const res = await options.submit({\n accountId: position.account_id,\n });\n\n if (res.success) {\n return res;\n }\n\n if (res.message) {\n toast.error(res.message);\n }\n\n return false;\n } catch (err: any) {\n if (err?.message) {\n toast.error(err.message);\n }\n return false;\n }\n },\n classNames: {\n body: \"!oui-pb-0\",\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={finalIsEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quoteDP ?? 2}\n baseDP={baseDP ?? 2}\n />\n ),\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n },\n );\n }}\n />\n </PopoverContent>\n </PopoverRoot>\n );\n};\n","import { useMemo } from \"react\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Flex,\n modal,\n useModal,\n Text,\n Box,\n Badge,\n Divider,\n toast,\n} from \"@orderly.network/ui\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { TPSLWidget, TPSLWidgetProps } from \"./tpsl.widget\";\n\ntype TPSLSheetProps = {\n position: API.Position;\n order?: API.AlgoOrder;\n // label: string;\n // baseDP?: number;\n // quoteDP?: number;\n symbolInfo: API.SymbolExt;\n isEditing?: boolean;\n};\n\nexport const PositionTPSLSheet = (props: TPSLWidgetProps & TPSLSheetProps) => {\n const { position, order, symbolInfo, isEditing } = props;\n const { resolve, hide, updateArgs } = useModal();\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n const updateSheetTitle = (title: string) => {\n if (isEditing) return;\n updateArgs({ title });\n };\n\n const onCompleted = () => {\n resolve();\n hide();\n };\n\n const { quote_dp, base_dp } = symbolInfo;\n\n return (\n <>\n <PositionInfo position={position} symbolInfo={symbolInfo} />\n\n <TPSLWidget\n {...props}\n onTPSLTypeChange={(type) => {\n updateSheetTitle(\n type === AlgoOrderRootType.TP_SL\n ? t(\"common.tpsl\")\n : t(\"tpsl.positionTpsl\"),\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n bodyClassName: \"oui-pb-0 lg:oui-pb-0\",\n onOk: async () => {\n try {\n const res = await options.submit({\n accountId: position.account_id,\n });\n\n if (res.success) {\n return res;\n }\n\n if (res.message) {\n toast.error(res.message);\n }\n\n return false;\n } catch (err: any) {\n if (err?.message) {\n toast.error(err.message);\n }\n return false;\n }\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={isEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quote_dp ?? 2}\n baseDP={base_dp ?? 2}\n />\n ),\n })\n .then(\n () => {\n // setOpen(false);\n // setVisible(true);\n return true;\n },\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n\n // setVisible(true);\n return Promise.reject(false);\n },\n );\n }}\n onCancel={() => {\n hide();\n }}\n />\n </>\n );\n};\n\nexport const TPSLSheetTitle = () => {\n const modal = useModal();\n const { t } = useTranslation();\n\n const title = useMemo<string>(() => {\n return (modal.args?.title || t(\"common.tpsl\")) as string;\n }, [modal.args?.title, t]);\n\n return <span>{title}</span>;\n};\n\nexport const PositionInfo = (props: {\n position: API.Position;\n symbolInfo: API.SymbolExt;\n}) => {\n const { position, symbolInfo } = props;\n const { data: markPrice } = useMarkPrice(position.symbol);\n const modal = useModal();\n const { t } = useTranslation();\n\n const isPositionTPSL = useMemo(() => {\n return modal.args?.title === t(\"tpsl.positionTpsl\");\n }, [modal.args?.title, t]);\n return (\n <>\n <Flex justify={\"between\"} pb={3} itemAlign={\"center\"}>\n <Text.formatted rule=\"symbol\" className=\"oui-text-xs\" showIcon>\n {position.symbol}\n </Text.formatted>\n <Flex gapX={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color=\"primary\">\n {t(\"common.position\")}\n </Badge>\n )}\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider intensity={8} />\n <Box py={3} className=\"oui-space-y-1\">\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.avgOpen\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {position.average_open_price}\n </Text.numeral>\n </Flex>\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.markPrice\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {markPrice}\n </Text.numeral>\n </Flex>\n </Box>\n </>\n );\n};\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useState, useMemo, useRef, useEffect } from 'react';
|
|
2
|
-
import { textVariants, Text, Flex, Box, Badge, Divider, cn, Checkbox, PopoverRoot, PopoverTrigger, Button, PopoverContent, modal, useModal, toast, Grid, ThrottledButton, convertValueToPercentage, Input, inputFormatter, Slider, SimpleDropdownMenu, CaretDownIcon } from '@orderly.network/ui';
|
|
3
2
|
import { useLocalStorage, useMarkPrice, useSymbolsInfo, useTPSLOrder, utils } from '@orderly.network/hooks';
|
|
4
|
-
import { transSymbolformString, Decimal, todpIfNeed } from '@orderly.network/utils';
|
|
5
3
|
import { useTranslation } from '@orderly.network/i18n';
|
|
6
|
-
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
7
|
-
import { OrderSide, AlgoOrderRootType, SDKError, AlgoOrderType } from '@orderly.network/types';
|
|
8
4
|
import { useOrderEntryFormErrorMsg } from '@orderly.network/react-app';
|
|
5
|
+
import { OrderSide, AlgoOrderRootType, SDKError, AlgoOrderType } from '@orderly.network/types';
|
|
6
|
+
import { textVariants, Text, Flex, Box, Badge, Divider, cn, Checkbox, PopoverRoot, PopoverTrigger, Button, PopoverContent, modal, toast, useModal, Grid, ThrottledButton, convertValueToPercentage, Input, inputFormatter, Slider, SimpleDropdownMenu, CaretDownIcon } from '@orderly.network/ui';
|
|
7
|
+
import { transSymbolformString, Decimal, todpIfNeed } from '@orderly.network/utils';
|
|
8
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
9
9
|
|
|
10
|
-
var J=e=>{let{type:t,values:o}=e,[i,a]=useLocalStorage("TP/SL_Mode","Offset%"),[l,p]=useState(true),{t:g}=useTranslation(),r=useMemo(()=>{switch(i){case "Offset":return `${t.toLowerCase()}_offset`;case "Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[i]),P=useMemo(()=>o[i],[o,i]),_=useMemo(()=>[{label:g("tpsl.pnl"),value:"PnL",testId:"PnL_menu_item"},{label:g("tpsl.offset"),value:"Offset",testId:"Offset_mneu_item"},{label:`${g("tpsl.offset")}%`,value:"Offset%",testId:"Offset%_menu_item"}],[g]),m=useRef(""),T=c=>{e.onChange(r,c);},x=c=>{let{dp:u=2}=c;return {onRenderBefore:(s,L)=>(s=`${s}`,l&&t==="SL"&&i==="PnL"&&(s=s.startsWith("-")?s:"-"+s),s===""||s==="-"?"":i==="Offset%"?`${new Decimal(s.replace(new RegExp(m.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${m.current}`:(i==="Offset"&&(s=todpIfNeed(s,u)),`${s}`)),onSendBefore:s=>{if(/^\-?0{2,}$/.test(s))return "0";if(i==="Offset%"){if(s!==""){s=todpIfNeed(s,2);let L=s.match(/\.0{0,2}$/);L?m.current=L[0]:m.current="",s=new Decimal(s).div(100).toString(),s=`${s}${m.current}`;}}else i==="PnL"&&t==="SL"&&l?s=s.startsWith("-")?s:"-"+s:s=todpIfNeed(s,u);return s===""||s==="-"?"":s}}};return {mode:i,modes:_,type:e.type,formatter:x,onModeChange:c=>{a(c);},value:P,pnl:o.PnL,onValueChange:T,quote_dp:e.quote_dp,setFocus:p}};var te=e=>{let{mode:t,modes:o,onModeChange:i,onValueChange:a,quote:l,quote_dp:p,value:g,pnl:r}=e,{t:P}=useTranslation(),[_,m]=useState(t),[T,x]=useState(t==="Offset%"?"%":l),c=useMemo(()=>{let u=Number(r);if(isNaN(u)||u===0)return "";if(u>0)return "oui-text-trade-profit";if(u<0)return "oui-text-trade-loss"},[r]);return useEffect(()=>{let u=o.find(s=>s.value===t)?.label;m(u),x(t==="Offset%"?"%":l);},[t,o]),jsx(Input,{prefix:_,size:{initial:"lg",lg:"md"},placeholder:T,align:"right",value:g,"data-testid":e.testId,autoComplete:"off",onValueChange:a,formatters:[e.formatter({dp:p,mode:t}),inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter],classNames:{input:c,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{x(""),e.setFocus(true);},onBlur:()=>{x(t==="Offset%"?"%":l),e.setFocus(false);},suffix:jsxs(Fragment,{children:[t==="Offset%"&&!!g&&jsx(Text,{size:"2xs",color:"inherit",className:cn("oui-ml-[2px]",c),children:"%"}),jsx(Ae,{mode:t,modes:o,onModeChange:u=>i(u.value)})]})})},Ae=e=>jsx(SimpleDropdownMenu,{currentValue:e.mode,menu:e.modes,align:"end",size:"xs",className:"oui-min-w-[80px]",onSelect:t=>e.onModeChange(t),children:jsx("button",{className:"oui-p-2",children:jsx(CaretDownIcon,{size:12,color:"white"})})});var U=e=>{let{testId:t,quote:o,...i}=e,a=J(i);return jsx(te,{...a,testId:t,quote:o})};var le=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:i,onComplete:a,status:l,errors:p,isPosition:g}=e,{t:r}=useTranslation(),{parseErrorMsg:P}=useOrderEntryFormErrorMsg(p);return jsxs("div",{id:"orderly-tp_sl-order-edit-content",children:[(!e.isEditing||e.isEditing&&!e.isPosition)&&jsxs(Fragment,{children:[jsx(Ke,{maxQty:e.maxQty,quantity:e.orderQuantity??e.maxQty,baseTick:o("base_tick"),dp:o("base_dp"),onQuantityChange:e.setQuantity,quote:o("base"),isEditing:e.isEditing,isPosition:g,errorMsg:P("quantity")}),jsx(Divider,{my:4,intensity:8})]}),jsx(Ye,{sl_pnl:t.sl_pnl,tp_pnl:t.tp_pnl,quote:o("quote"),quote_dp:o("quote_dp"),onPriceChange:e.setOrderPrice,onPnLChange:e.setPnL,errors:p,tp_values:{PnL:`${t.tp_pnl??""}`,Offset:`${t.tp_offset??""}`,"Offset%":`${t.tp_offset_percentage??""}`},sl_values:{PnL:`${t.sl_pnl??""}`,Offset:`${t.sl_offset??""}`,"Offset%":`${t.sl_offset_percentage??""}`},tp_trigger_price:t.tp_trigger_price??"",sl_trigger_price:t.sl_trigger_price??""}),jsxs(Grid,{cols:2,gap:3,mt:4,children:[jsx(Button,{size:"md",color:"secondary","data-testid":"tpsl-cancel",onClick:()=>{i?.();},children:r("common.cancel")}),jsx(ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||l.isCreateMutating,loading:l.isCreateMutating||l.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{a?.();},()=>{});},children:r("common.confirm")})]})]})},Ke=e=>{let{isPosition:t}=e,o=useRef(null),i=convertValueToPercentage(e.quantity,0,e.maxQty)/100,{t:a}=useTranslation(),l=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},p=r=>{if(e.baseTick>0){e.onQuantityChange?.(utils.formatNumber(r,e.baseTick)??r);}},g=(t?"":e.quantity).toString().length>0?e.errorMsg:void 0;return jsxs(Fragment,{children:[jsxs(Flex,{gap:2,children:[jsx("div",{className:"oui-flex-1",children:jsx(Input.tooltip,{"data-testid":"oui-testid-tpsl-popUp-quantity-input",ref:o,prefix:a("common.quantity"),size:{initial:"lg",lg:"md"},align:"right",value:t?"":e.quantity,autoComplete:"off",classNames:{prefix:"oui-text-base-contrast-54",root:cn("oui-bg-base-5 oui-outline-line-12",g&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:g,color:g?"danger":void 0,formatters:[inputFormatter.dpFormatter(e.dp),inputFormatter.numberFormatter,inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter],onValueChange:r=>{e.onQuantityChange?.(r);let P=Number(r);if(P&&P>e.maxQty){let _=t?0:e.maxQty;e.onQuantityChange?.(_),o.current?.blur();}},onBlur:r=>p(r.target.value),suffix:t?jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{l();},children:a("tpsl.entirePosition")}):jsx("span",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",children:e.quote})})}),!e.isEditing&&jsx(Button,{onClick:()=>{let r=t?0:e.maxQty;e.onQuantityChange?.(r),r===0&&l();},variant:"outlined",className:cn("oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]",t?"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20":"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5"),children:a("common.position")})]}),jsx(Flex,{mt:2,itemAlign:"center",height:"15px",children:jsx(Slider.single,{markCount:5,color:"primary",max:e.maxQty,min:0,showTip:true,step:e.baseTick,value:e.quantity,onValueCommit:r=>{p(`${r}`);},onValueChange:r=>{e.onQuantityChange?.(r);}})}),jsxs(Flex,{justify:"between",children:[jsx(Text.numeral,{rule:"percentages",color:"primary",size:"2xs",children:i}),jsxs(Flex,{itemAlign:"center",gap:1,children:[jsx("button",{className:"oui-leading-none",style:{lineHeight:0},onClick:()=>{e.onQuantityChange?.(e.maxQty);},children:jsx(Text,{color:"primary",size:"2xs",children:a("common.max")})}),jsx(Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},Ye=e=>{let{t}=useTranslation(),{parseErrorMsg:o}=useOrderEntryFormErrorMsg(e.errors),i=(a,l)=>{e.onPnLChange(a,l);};return jsxs(Fragment,{children:[jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsxs(Flex,{gap:1,children:[jsx(Text,{size:"2xs",intensity:80,children:t("tpsl.takeProfit")}),jsx(Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsx(Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(re,{type:"TP",value:e.tp_trigger_price,error:o("tp_trigger_price"),onValueChange:a=>{e.onPriceChange("tp_trigger_price",a);},quote_dp:e.quote_dp??2}),jsx(U,{type:"TP",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsxs(Flex,{gap:1,children:[jsx(Text,{size:"2xs",intensity:80,children:t("tpsl.stopLoss")}),jsx(Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsx(Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(re,{type:"SL",value:e.sl_trigger_price,error:o("sl_trigger_price"),onValueChange:a=>{e.onPriceChange("sl_trigger_price",a);},quote_dp:e.quote_dp??2}),jsx(U,{type:"SL",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},re=e=>{let[t,o]=useState("USDC"),{t:i}=useTranslation();return jsx(Input.tooltip,{"data-testid":`oui-testid-tpsl-popUp-${e.type.toLowerCase()}-input`,prefix:i("common.markPrice"),size:{initial:"lg",lg:"md"},tooltip:e.error,placeholder:t,align:"right",autoComplete:"off",value:e.value,color:e.error?"danger":void 0,classNames:{prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onValueChange:e.onValueChange,onFocus:()=>{o("");},onBlur:()=>{o("USDC");},formatters:[inputFormatter.numberFormatter,inputFormatter.dpFormatter(e.quote_dp),inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter]})},B=e=>{let{symbol:t,tpPrice:o,slPrice:i,qty:a,maxQty:l,side:p,quoteDP:g,baseDP:r,isEditing:P,isPositionTPSL:_}=e,{t:m}=useTranslation(),[T,x]=useLocalStorage("orderly_order_confirm",true),c=textVariants({size:"xs",intensity:54}),u=_??a>=l;return jsxs(Fragment,{children:[P&&jsx(Text,{as:"div",size:"2xs",intensity:80,className:"oui-mb-3",children:`You agree to edit your ${transSymbolformString(t)} order.`}),jsxs(Flex,{pb:4,children:[jsx(Box,{grow:true,children:jsx(Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:true,as:"div",intensity:80,children:t})}),jsxs(Flex,{gap:1,children:[u&&jsx(Badge,{size:"xs",color:"primary",children:m("common.position")}),jsx(Xe,{tpPrice:o,slPrice:i}),p===OrderSide.SELL?jsx(Badge,{size:"xs",color:"success",children:m("common.buy")}):jsx(Badge,{size:"xs",color:"danger",children:m("common.sell")})]})]}),jsx(Divider,{}),jsxs(Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:cn(c,"oui-pb-4 xl:oui-pb-5"),children:[jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("common.qty")}),jsx("div",{children:u?jsx("span",{className:"oui-text-base-contrast",children:m("tpsl.entirePosition")}):jsx(Text.numeral,{intensity:98,dp:r,padding:false,children:a})})]}),typeof o=="number"&&o>0?jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("tpsl.tpPrice")}),jsx(Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof i=="number"&&i>0?jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("tpsl.slPrice")}),jsx(Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:i})]}):null,jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("common.price")}),jsx("div",{className:"oui-text-base-contrast",children:m("common.marketPrice")})]})]}),jsx(Box,{pt:2,children:jsxs(Flex,{gap:1,children:[jsx(Checkbox,{id:"disabledConfirm",color:"white",checked:!T,onCheckedChange:s=>{x(!s);}}),jsx("label",{htmlFor:"disabledConfirm",className:textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:m("orderEntry.disableOrderConfirm")})]})})]})},Xe=e=>{let{tpPrice:t,slPrice:o}=e,{t:i}=useTranslation();return t&&o?jsx(Badge,{size:"xs",color:"neutral",children:i("common.tpsl")}):t?jsx(Badge,{size:"xs",color:"neutral",children:i("tpsl.tp")}):o?jsx(Badge,{size:"xs",color:"neutral",children:i("tpsl.sl")}):null};var ce=e=>{let{position:t,order:o,isEditing:i}=e;if(i&&!o)throw new SDKError("order is required when isEditing is true");let a=i?o.symbol:t.symbol,l=useSymbolsInfo(),p=useRef(AlgoOrderRootType.TP_SL),[g]=useLocalStorage("orderly_order_confirm",true),[r,{submit:P,deleteOrder:_,setValue:m,validate:T,errors:x,isCreateMutating:c,isUpdateMutating:u}]=useTPSLOrder({symbol:a,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:i}),s=f=>{m("quantity",f);},L=(f,h)=>{m(f,h);},$=(f,h)=>{m(f,h);},C=useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),Y=useMemo(()=>{let f=o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL?C:o?.quantity,h=0;if((Number(r.quantity)!==f||!i&&r.quantity)&&(h=1),o&&i){let Te=o.child_orders.find(D=>D.algo_type===AlgoOrderType.TAKE_PROFIT),Le=o.child_orders.find(D=>D.algo_type===AlgoOrderType.STOP_LOSS);Te?.trigger_price!==Number(r.tp_trigger_price)&&typeof typeof r.tp_trigger_price<"u"&&(h=2),Le?.trigger_price!==Number(r.sl_trigger_price)&&typeof r.sl_trigger_price<"u"&&(h=3);}return h===1&&!r.tp_trigger_price&&!r.sl_trigger_price&&(h=-1),h},[r.tp_trigger_price,r.sl_trigger_price,r.quantity,o,i]),_e=useMemo(()=>o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&Number(r.quantity)<C&&!r.tp_trigger_price&&!r.sl_trigger_price?false:Y>0&&!!r.quantity&&!x,[r.quantity,C,Y,x]),V=useMemo(()=>i?o&&o.algo_type!==AlgoOrderRootType.POSITIONAL_TP_SL?false:r.algo_order_id&&r.quantity==0?true:Number(r.quantity)>=C:Number(r.quantity)>=C,[r.quantity,C,o?.algo_type,i]);useEffect(()=>{if(!i&&V){let f=utils.findTPSLFromOrder(o);!r.tp_trigger_price&&f.tp_trigger_price&&L("tp_trigger_price",f.tp_trigger_price),!r.sl_trigger_price&&f.sl_trigger_price&&L("sl_trigger_price",f.sl_trigger_price);}},[i,V,r]),useEffect(()=>{let f=Number(r.quantity)<C?AlgoOrderRootType.TP_SL:AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&p.current!==f&&e.onTPSLTypeChange(f),p.current=f;},[r.quantity,C]);let be=()=>o?.algo_order_id&&o?.symbol?_(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),xe=async()=>Promise.resolve().then(()=>typeof e.onConfirm!="function"||!g?P().then(()=>true,f=>(f?.message&&toast.error(f.message),Promise.reject(false))):e.onConfirm(r,{position:t,submit:P,cancel:be})).then(f=>{});return {isEditing:i,symbolInfo:l[a],maxQty:C,setQuantity:s,orderQuantity:r.quantity,isPosition:V,TPSL_OrderEntity:r,setOrderValue:m,setPnL:$,setOrderPrice:L,onSubmit:xe,valid:_e,errors:x,status:{isCreateMutating:c,isUpdateMutating:u}}};var M=e=>{let{onCancel:t,onComplete:o,...i}=e,a=ce(i);return jsx(le,{...a,onCancel:t,onComplete:o})};var pt=e=>{let{position:t,order:o,baseDP:i,quoteDP:a,buttonProps:l,isEditing:p}=e,[g,r]=useState(false),[P,_]=useState(true),[m]=useLocalStorage("orderly_order_confirm",true),{t:T}=useTranslation(),x=p?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxs(PopoverRoot,{onOpenChange:c=>{P&&r(c);},open:g,children:[jsx(PopoverTrigger,{asChild:true,onClick:()=>{r(true);},children:e.children||jsx(Button,{variant:"outlined",size:"sm",color:"secondary",...l,children:e.label})}),jsx(PopoverContent,{className:cn("oui-w-[360px]",P?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsx(M,{position:t,order:o,isEditing:p,onComplete:()=>{r(false);},onCancel:()=>{r(false);},onConfirm:(c,u)=>{if(!m)return Promise.resolve(true);_(false);let s=Math.abs(Number(t.position_qty));if(`${c.tp_trigger_price??""}`.length===0&&`${c.sl_trigger_price??""}`.length===0)return modal.confirm({title:T("orders.cancelOrder"),content:T("tpsl.cancelOrder.description"),onOk:()=>u.cancel()}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)));let L=p||!!c&&c.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&c.quantity===s;return modal.confirm({title:T(L?"orders.editOrder":"tpsl.confirmOrder"),onOk:()=>u.submit(),classNames:{body:"!oui-pb-0"},content:jsx(B,{isPositionTPSL:x,isEditing:L,symbol:c.symbol,qty:Number(c.quantity),maxQty:s,tpPrice:Number(c.tp_trigger_price),slPrice:Number(c.sl_trigger_price),side:c.side,quoteDP:a??2,baseDP:i??2})}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)))}})})]})};var Lt=e=>{let{position:t,order:o,symbolInfo:i,isEditing:a}=e,{resolve:l,hide:p,updateArgs:g}=useModal(),[r]=useLocalStorage("orderly_order_confirm",true),{t:P}=useTranslation(),_=a?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0,m=u=>{a||g({title:u});},T=()=>{l(),p();},{quote_dp:x,base_dp:c}=i;return jsxs(Fragment,{children:[jsx(St,{position:t,symbolInfo:i}),jsx(M,{...e,onTPSLTypeChange:u=>{m(u===AlgoOrderRootType.TP_SL?P("common.tpsl"):P("tpsl.positionTpsl"));},onComplete:T,onConfirm:(u,s)=>{if(!r)return Promise.resolve(true);let L=Math.abs(Number(t.position_qty)),$=a||!!u&&u.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&u.quantity===L;return modal.confirm({title:P($?"orders.editOrder":"tpsl.confirmOrder"),bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:()=>s.submit(),content:jsx(B,{isPositionTPSL:_,isEditing:a,symbol:u.symbol,qty:Number(u.quantity),maxQty:L,tpPrice:Number(u.tp_trigger_price),slPrice:Number(u.sl_trigger_price),side:u.side,quoteDP:x??2,baseDP:c??2})}).then(()=>true,C=>(C?.message&&toast.error(C.message),Promise.reject(false)))},onCancel:()=>{p();}})]})};var St=e=>{let{position:t,symbolInfo:o}=e,{data:i}=useMarkPrice(t.symbol),a=useModal(),{t:l}=useTranslation(),p=useMemo(()=>a.args?.title===l("tpsl.positionTpsl"),[a.args?.title,l]);return jsxs(Fragment,{children:[jsxs(Flex,{justify:"between",pb:3,itemAlign:"center",children:[jsx(Text.formatted,{rule:"symbol",className:"oui-text-xs",showIcon:true,children:t.symbol}),jsxs(Flex,{gapX:1,children:[p&&jsx(Badge,{size:"xs",color:"primary",children:l("common.position")}),jsx(Badge,{size:"xs",color:"neutral",children:l("common.tpsl")}),t.position_qty<0?jsx(Badge,{size:"xs",color:"buy",children:l("common.buy")}):jsx(Badge,{size:"xs",color:"sell",children:l("common.sell")})]})]}),jsx(Divider,{intensity:8}),jsxs(Box,{py:3,className:"oui-space-y-1",children:[jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:54,children:l("common.avgOpen")}),jsx(Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:t.average_open_price})]}),jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:54,children:l("common.markPrice")}),jsx(Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:i})]})]})]})};
|
|
10
|
+
var Z=e=>{let{type:t,values:o}=e,[i,a]=useLocalStorage("TP/SL_Mode","Offset%"),[u,p]=useState(true),{t:g}=useTranslation(),r=useMemo(()=>{switch(i){case "Offset":return `${t.toLowerCase()}_offset`;case "Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[i]),P=useMemo(()=>o[i],[o,i]),_=useMemo(()=>[{label:g("tpsl.pnl"),value:"PnL",testId:"PnL_menu_item"},{label:g("tpsl.offset"),value:"Offset",testId:"Offset_mneu_item"},{label:`${g("tpsl.offset")}%`,value:"Offset%",testId:"Offset%_menu_item"}],[g]),m=useRef(""),L=c=>{e.onChange(r,c);},T=c=>{let{dp:l=2}=c;return {onRenderBefore:(s,S)=>(s=`${s}`,u&&t==="SL"&&i==="PnL"&&(s=s.startsWith("-")?s:"-"+s),s===""||s==="-"?"":i==="Offset%"?`${new Decimal(s.replace(new RegExp(m.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${m.current}`:(i==="Offset"&&(s=todpIfNeed(s,l)),`${s}`)),onSendBefore:s=>{if(/^\-?0{2,}$/.test(s))return "0";if(i==="Offset%"){if(s!==""){s=todpIfNeed(s,2);let S=s.match(/\.0{0,2}$/);S?m.current=S[0]:m.current="",s=new Decimal(s).div(100).toString(),s=`${s}${m.current}`;}}else i==="PnL"&&t==="SL"&&u?s=s.startsWith("-")?s:"-"+s:s=todpIfNeed(s,l);return s===""||s==="-"?"":s}}};return {mode:i,modes:_,type:e.type,formatter:T,onModeChange:c=>{a(c);},value:P,pnl:o.PnL,onValueChange:L,quote_dp:e.quote_dp,setFocus:p}};var oe=e=>{let{mode:t,modes:o,onModeChange:i,onValueChange:a,quote:u,quote_dp:p,value:g,pnl:r}=e,{t:P}=useTranslation(),[_,m]=useState(t),[L,T]=useState(t==="Offset%"?"%":u),c=useMemo(()=>{let l=Number(r);if(isNaN(l)||l===0)return "";if(l>0)return "oui-text-trade-profit";if(l<0)return "oui-text-trade-loss"},[r]);return useEffect(()=>{let l=o.find(s=>s.value===t)?.label;m(l),T(t==="Offset%"?"%":u);},[t,o]),jsx(Input,{prefix:_,size:{initial:"lg",lg:"md"},placeholder:L,align:"right",value:g,"data-testid":e.testId,autoComplete:"off",onValueChange:a,formatters:[e.formatter({dp:p,mode:t}),inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter],classNames:{input:c,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{T(""),e.setFocus(true);},onBlur:()=>{T(t==="Offset%"?"%":u),e.setFocus(false);},suffix:jsxs(Fragment,{children:[t==="Offset%"&&!!g&&jsx(Text,{size:"2xs",color:"inherit",className:cn("oui-ml-[2px]",c),children:"%"}),jsx(ze,{mode:t,modes:o,onModeChange:l=>i(l.value)})]})})},ze=e=>jsx(SimpleDropdownMenu,{currentValue:e.mode,menu:e.modes,align:"end",size:"xs",className:"oui-min-w-[80px]",onSelect:t=>e.onModeChange(t),children:jsx("button",{className:"oui-p-2",children:jsx(CaretDownIcon,{size:12,color:"white"})})});var U=e=>{let{testId:t,quote:o,...i}=e,a=Z(i);return jsx(oe,{...a,testId:t,quote:o})};var le=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:i,onComplete:a,status:u,errors:p,isPosition:g}=e,{t:r}=useTranslation(),{parseErrorMsg:P}=useOrderEntryFormErrorMsg(p);return jsxs("div",{id:"orderly-tp_sl-order-edit-content",children:[(!e.isEditing||e.isEditing&&!e.isPosition)&&jsxs(Fragment,{children:[jsx(Xe,{maxQty:e.maxQty,quantity:e.orderQuantity??e.maxQty,baseTick:o("base_tick"),dp:o("base_dp"),onQuantityChange:e.setQuantity,quote:o("base"),isEditing:e.isEditing,isPosition:g,errorMsg:P("quantity")}),jsx(Divider,{my:4,intensity:8})]}),jsx(Je,{sl_pnl:t.sl_pnl,tp_pnl:t.tp_pnl,quote:o("quote"),quote_dp:o("quote_dp"),onPriceChange:e.setOrderPrice,onPnLChange:e.setPnL,errors:p,tp_values:{PnL:`${t.tp_pnl??""}`,Offset:`${t.tp_offset??""}`,"Offset%":`${t.tp_offset_percentage??""}`},sl_values:{PnL:`${t.sl_pnl??""}`,Offset:`${t.sl_offset??""}`,"Offset%":`${t.sl_offset_percentage??""}`},tp_trigger_price:t.tp_trigger_price??"",sl_trigger_price:t.sl_trigger_price??""}),jsxs(Grid,{cols:2,gap:3,mt:4,children:[jsx(Button,{size:"md",color:"secondary","data-testid":"tpsl-cancel",onClick:()=>{i?.();},children:r("common.cancel")}),jsx(ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||u.isCreateMutating,loading:u.isCreateMutating||u.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{a?.();}).catch(_=>{});},children:r("common.confirm")})]})]})},Xe=e=>{let{isPosition:t}=e,o=useRef(null),i=convertValueToPercentage(e.quantity,0,e.maxQty)/100,{t:a}=useTranslation(),u=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},p=r=>{if(e.baseTick>0){e.onQuantityChange?.(utils.formatNumber(r,e.baseTick)??r);}},g=(t?"":e.quantity).toString().length>0?e.errorMsg:void 0;return jsxs(Fragment,{children:[jsxs(Flex,{gap:2,children:[jsx("div",{className:"oui-flex-1",children:jsx(Input.tooltip,{"data-testid":"oui-testid-tpsl-popUp-quantity-input",ref:o,prefix:a("common.quantity"),size:{initial:"lg",lg:"md"},align:"right",value:t?"":e.quantity,autoComplete:"off",classNames:{prefix:"oui-text-base-contrast-54",root:cn("oui-bg-base-5 oui-outline-line-12",g&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:g,color:g?"danger":void 0,formatters:[inputFormatter.dpFormatter(e.dp),inputFormatter.numberFormatter,inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter],onValueChange:r=>{e.onQuantityChange?.(r);let P=Number(r);if(P&&P>e.maxQty){let _=t?0:e.maxQty;e.onQuantityChange?.(_),o.current?.blur();}},onBlur:r=>p(r.target.value),suffix:t?jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{u();},children:a("tpsl.entirePosition")}):jsx("span",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",children:e.quote})})}),!e.isEditing&&jsx(Button,{onClick:()=>{let r=t?0:e.maxQty;e.onQuantityChange?.(r),r===0&&u();},variant:"outlined",className:cn("oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]",t?"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20":"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5"),children:a("common.position")})]}),jsx(Flex,{mt:2,itemAlign:"center",height:"15px",children:jsx(Slider.single,{markCount:5,color:"primary",max:e.maxQty,min:0,showTip:true,step:e.baseTick,value:e.quantity,onValueCommit:r=>{p(`${r}`);},onValueChange:r=>{e.onQuantityChange?.(r);}})}),jsxs(Flex,{justify:"between",children:[jsx(Text.numeral,{rule:"percentages",color:"primary",size:"2xs",children:i}),jsxs(Flex,{itemAlign:"center",gap:1,children:[jsx("button",{className:"oui-leading-none",style:{lineHeight:0},onClick:()=>{e.onQuantityChange?.(e.maxQty);},children:jsx(Text,{color:"primary",size:"2xs",children:a("common.max")})}),jsx(Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},Je=e=>{let{t}=useTranslation(),{parseErrorMsg:o}=useOrderEntryFormErrorMsg(e.errors),i=(a,u)=>{e.onPnLChange(a,u);};return jsxs(Fragment,{children:[jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsxs(Flex,{gap:1,children:[jsx(Text,{size:"2xs",intensity:80,children:t("tpsl.takeProfit")}),jsx(Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsx(Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(ie,{type:"TP",value:e.tp_trigger_price,error:o("tp_trigger_price"),onValueChange:a=>{e.onPriceChange("tp_trigger_price",a);},quote_dp:e.quote_dp??2}),jsx(U,{type:"TP",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsxs(Flex,{gap:1,children:[jsx(Text,{size:"2xs",intensity:80,children:t("tpsl.stopLoss")}),jsx(Text,{size:"2xs",intensity:36,children:`(${t("orderEntry.orderType.marketOrder")?.toLowerCase()})`})]}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:`${t("tpsl.estPnl")}:`}),jsx(Text.numeral,{size:"2xs",coloring:true,showIdentifier:true,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(ie,{type:"SL",value:e.sl_trigger_price,error:o("sl_trigger_price"),onValueChange:a=>{e.onPriceChange("sl_trigger_price",a);},quote_dp:e.quote_dp??2}),jsx(U,{type:"SL",onChange:i,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},ie=e=>{let[t,o]=useState("USDC"),{t:i}=useTranslation();return jsx(Input.tooltip,{"data-testid":`oui-testid-tpsl-popUp-${e.type.toLowerCase()}-input`,prefix:i("common.markPrice"),size:{initial:"lg",lg:"md"},tooltip:e.error,placeholder:t,align:"right",autoComplete:"off",value:e.value,color:e.error?"danger":void 0,classNames:{prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onValueChange:e.onValueChange,onFocus:()=>{o("");},onBlur:()=>{o("USDC");},formatters:[inputFormatter.numberFormatter,inputFormatter.dpFormatter(e.quote_dp),inputFormatter.currencyFormatter,inputFormatter.decimalPointFormatter]})},M=e=>{let{symbol:t,tpPrice:o,slPrice:i,qty:a,maxQty:u,side:p,quoteDP:g,baseDP:r,isEditing:P,isPositionTPSL:_}=e,{t:m}=useTranslation(),[L,T]=useLocalStorage("orderly_order_confirm",true),c=textVariants({size:"xs",intensity:54}),l=_??a>=u;return jsxs(Fragment,{children:[P&&jsx(Text,{as:"div",size:"2xs",intensity:80,className:"oui-mb-3",children:`You agree to edit your ${transSymbolformString(t)} order.`}),jsxs(Flex,{pb:4,children:[jsx(Box,{grow:true,children:jsx(Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:true,as:"div",intensity:80,children:t})}),jsxs(Flex,{gap:1,children:[l&&jsx(Badge,{size:"xs",color:"primary",children:m("common.position")}),jsx(Ze,{tpPrice:o,slPrice:i}),p===OrderSide.SELL?jsx(Badge,{size:"xs",color:"success",children:m("common.buy")}):jsx(Badge,{size:"xs",color:"danger",children:m("common.sell")})]})]}),jsx(Divider,{}),jsxs(Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:cn(c,"oui-pb-4 xl:oui-pb-5"),children:[jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("common.qty")}),jsx("div",{children:l?jsx("span",{className:"oui-text-base-contrast",children:m("tpsl.entirePosition")}):jsx(Text.numeral,{intensity:98,dp:r,padding:false,children:a})})]}),typeof o=="number"&&o>0?jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("tpsl.tpPrice")}),jsx(Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof i=="number"&&i>0?jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("tpsl.slPrice")}),jsx(Text.numeral,{as:"div",coloring:true,unit:"USDC",size:"sm",dp:g,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:i})]}):null,jsxs(Flex,{children:[jsx(Box,{grow:true,children:m("common.price")}),jsx("div",{className:"oui-text-base-contrast",children:m("common.marketPrice")})]})]}),jsx(Box,{pt:2,children:jsxs(Flex,{gap:1,children:[jsx(Checkbox,{id:"disabledConfirm",color:"white",checked:!L,onCheckedChange:s=>{T(!s);}}),jsx("label",{htmlFor:"disabledConfirm",className:textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:m("orderEntry.disableOrderConfirm")})]})})]})},Ze=e=>{let{tpPrice:t,slPrice:o}=e,{t:i}=useTranslation();return t&&o?jsx(Badge,{size:"xs",color:"neutral",children:i("common.tpsl")}):t?jsx(Badge,{size:"xs",color:"neutral",children:i("tpsl.tp")}):o?jsx(Badge,{size:"xs",color:"neutral",children:i("tpsl.sl")}):null};var de=e=>{let{position:t,order:o,isEditing:i}=e;if(i&&!o)throw new SDKError("order is required when isEditing is true");let a=i?o.symbol:t.symbol,u=useSymbolsInfo(),p=useRef(AlgoOrderRootType.TP_SL),[g]=useLocalStorage("orderly_order_confirm",true),[r,{submit:P,deleteOrder:_,setValue:m,validate:L,errors:T,isCreateMutating:c,isUpdateMutating:l}]=useTPSLOrder({symbol:a,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:i}),s=y=>{m("quantity",y);},S=(y,N)=>{m(y,N);},h=(y,N)=>{m(y,N);},f=useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),X=useMemo(()=>{let y=o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL?f:o?.quantity,N=0;if((Number(r.quantity)!==y||!i&&r.quantity)&&(N=1),o&&i){let Se=o.child_orders.find(D=>D.algo_type===AlgoOrderType.TAKE_PROFIT),Ce=o.child_orders.find(D=>D.algo_type===AlgoOrderType.STOP_LOSS);Se?.trigger_price!==Number(r.tp_trigger_price)&&typeof typeof r.tp_trigger_price<"u"&&(N=2),Ce?.trigger_price!==Number(r.sl_trigger_price)&&typeof r.sl_trigger_price<"u"&&(N=3);}return N===1&&!r.tp_trigger_price&&!r.sl_trigger_price&&(N=-1),N},[r.tp_trigger_price,r.sl_trigger_price,r.quantity,o,i]),xe=useMemo(()=>o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&Number(r.quantity)<f&&!r.tp_trigger_price&&!r.sl_trigger_price?false:X>0&&!!r.quantity&&!T,[r.quantity,f,X,T]),V=useMemo(()=>i?o&&o.algo_type!==AlgoOrderRootType.POSITIONAL_TP_SL?false:r.algo_order_id&&r.quantity==0?true:Number(r.quantity)>=f:Number(r.quantity)>=f,[r.quantity,f,o?.algo_type,i]);useEffect(()=>{if(!i&&V){let y=utils.findTPSLFromOrder(o);!r.tp_trigger_price&&y.tp_trigger_price&&S("tp_trigger_price",y.tp_trigger_price),!r.sl_trigger_price&&y.sl_trigger_price&&S("sl_trigger_price",y.sl_trigger_price);}},[i,V,r]),useEffect(()=>{let y=Number(r.quantity)<f?AlgoOrderRootType.TP_SL:AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&p.current!==y&&e.onTPSLTypeChange(y),p.current=y;},[r.quantity,f]);let Te=()=>o?.algo_order_id&&o?.symbol?_(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),Le=async()=>typeof e.onConfirm!="function"||!g?P({accountId:t.account_id}).then(()=>true).catch(y=>{throw y?.message&&toast.error(y.message),false}):e.onConfirm(r,{position:t,submit:P,cancel:Te});return {isEditing:i,symbolInfo:u[a],maxQty:f,setQuantity:s,orderQuantity:r.quantity,isPosition:V,TPSL_OrderEntity:r,setOrderValue:m,setPnL:h,setOrderPrice:S,onSubmit:Le,valid:xe,errors:T,status:{isCreateMutating:c,isUpdateMutating:l}}};var A=e=>{let{onCancel:t,onComplete:o,...i}=e,a=de(i);return jsx(le,{...a,onCancel:t,onComplete:o})};var Pt=e=>{let{position:t,order:o,baseDP:i,quoteDP:a,buttonProps:u,isEditing:p}=e,[g,r]=useState(false),[P,_]=useState(true),[m]=useLocalStorage("orderly_order_confirm",true),{t:L}=useTranslation(),T=p?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxs(PopoverRoot,{onOpenChange:c=>{P&&r(c);},open:g,children:[jsx(PopoverTrigger,{asChild:true,onClick:()=>{r(true);},children:e.children||jsx(Button,{variant:"outlined",size:"sm",color:"secondary",...u,children:e.label})}),jsx(PopoverContent,{className:cn("oui-w-[360px]",P?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsx(A,{position:t,order:o,isEditing:p,onComplete:()=>{r(false);},onCancel:()=>{r(false);},onConfirm:(c,l)=>{if(!m)return Promise.resolve(true);_(false);let s=Math.abs(Number(t.position_qty));if(`${c.tp_trigger_price??""}`.length===0&&`${c.sl_trigger_price??""}`.length===0)return modal.confirm({title:L("orders.cancelOrder"),content:L("tpsl.cancelOrder.description"),onOk:()=>l.cancel()}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)));let S=p||!!c&&c.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&c.quantity===s;return modal.confirm({title:L(S?"orders.editOrder":"tpsl.confirmOrder"),onOk:async()=>{try{let h=await l.submit({accountId:t.account_id});return h.success?h:(h.message&&toast.error(h.message),!1)}catch(h){return h?.message&&toast.error(h.message),false}},classNames:{body:"!oui-pb-0"},content:jsx(M,{isPositionTPSL:T,isEditing:S,symbol:c.symbol,qty:Number(c.quantity),maxQty:s,tpPrice:Number(c.tp_trigger_price),slPrice:Number(c.sl_trigger_price),side:c.side,quoteDP:a??2,baseDP:i??2})}).then(()=>(r(false),_(true),true),()=>(_(true),Promise.reject(false)))}})})]})};var St=e=>{let{position:t,order:o,symbolInfo:i,isEditing:a}=e,{resolve:u,hide:p,updateArgs:g}=useModal(),[r]=useLocalStorage("orderly_order_confirm",true),{t:P}=useTranslation(),_=a?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0,m=l=>{a||g({title:l});},L=()=>{u(),p();},{quote_dp:T,base_dp:c}=i;return jsxs(Fragment,{children:[jsx(Ct,{position:t,symbolInfo:i}),jsx(A,{...e,onTPSLTypeChange:l=>{m(l===AlgoOrderRootType.TP_SL?P("common.tpsl"):P("tpsl.positionTpsl"));},onComplete:L,onConfirm:(l,s)=>{if(!r)return Promise.resolve(true);let S=Math.abs(Number(t.position_qty)),h=a||!!l&&l.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&l.quantity===S;return modal.confirm({title:P(h?"orders.editOrder":"tpsl.confirmOrder"),bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:async()=>{try{let f=await s.submit({accountId:t.account_id});return f.success?f:(f.message&&toast.error(f.message),!1)}catch(f){return f?.message&&toast.error(f.message),false}},content:jsx(M,{isPositionTPSL:_,isEditing:a,symbol:l.symbol,qty:Number(l.quantity),maxQty:S,tpPrice:Number(l.tp_trigger_price),slPrice:Number(l.sl_trigger_price),side:l.side,quoteDP:T??2,baseDP:c??2})}).then(()=>true,f=>(f?.message&&toast.error(f.message),Promise.reject(false)))},onCancel:()=>{p();}})]})};var Ct=e=>{let{position:t,symbolInfo:o}=e,{data:i}=useMarkPrice(t.symbol),a=useModal(),{t:u}=useTranslation(),p=useMemo(()=>a.args?.title===u("tpsl.positionTpsl"),[a.args?.title,u]);return jsxs(Fragment,{children:[jsxs(Flex,{justify:"between",pb:3,itemAlign:"center",children:[jsx(Text.formatted,{rule:"symbol",className:"oui-text-xs",showIcon:true,children:t.symbol}),jsxs(Flex,{gapX:1,children:[p&&jsx(Badge,{size:"xs",color:"primary",children:u("common.position")}),jsx(Badge,{size:"xs",color:"neutral",children:u("common.tpsl")}),t.position_qty<0?jsx(Badge,{size:"xs",color:"buy",children:u("common.buy")}):jsx(Badge,{size:"xs",color:"sell",children:u("common.sell")})]})]}),jsx(Divider,{intensity:8}),jsxs(Box,{py:3,className:"oui-space-y-1",children:[jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:54,children:u("common.avgOpen")}),jsx(Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:t.average_open_price})]}),jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:54,children:u("common.markPrice")}),jsx(Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:i})]})]})]})};
|
|
11
11
|
|
|
12
|
-
export {
|
|
12
|
+
export { M as PositionTPSLConfirm, Pt as PositionTPSLPopover, St as PositionTPSLSheet, A as TPSLWidget };
|
|
13
13
|
//# sourceMappingURL=out.js.map
|
|
14
14
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tpsl.ui.tsx","../src/pnlInput/pnlInput.ui.tsx","../src/pnlInput/useBuilder.script.ts","../src/pnlInput/pnlInput.widget.tsx","../src/useTPSL.script.ts","../src/tpsl.widget.tsx","../src/editorPopover.tsx","../src/editorSheet.tsx"],"names":["useRef","useState","Badge","Box","Button","Divider","Flex","Grid","Input","Slider","Text","textVariants","cn","inputFormatter","Checkbox","convertValueToPercentage","ThrottledButton","CaretDownIcon","SimpleDropdownMenu","useMemo","useLocalStorage","Decimal","todpIfNeed","useTranslation","usePNLInputBuilder","props","type","values","mode","setMode","focus","setFocus","t","key","value","modes","percentageSuffix","onValueChange","formatter","options","dp","endStr","useEffect","Fragment","jsx","jsxs","PNLInput","onModeChange","quote","quote_dp","pnl","prefix","setPrefix","placeholder","setPlaceholder","color","num","label","item","PNLMenus","PnlInputWidget","testId","rest","state","utils","OrderSide","transSymbolformString","useOrderEntryFormErrorMsg","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","parseErrorMsg","TPSLQuantity","TPSLPrice","inputRef","currentQtyPercentage","setTPSL","formatQuantity","qty","quantity","errorMsg","e","onPnLChange","PriceInput","PositionTPSLConfirm","symbol","tpPrice","slPrice","maxQty","side","quoteDP","baseDP","isEditing","_isPositionTPSL","needConfirm","setNeedConfirm","textClassName","isPositionTPSL","TPSLOrderType","check","useSymbolsInfo","useTPSLOrder","SDKError","AlgoOrderRootType","AlgoOrderType","toast","useTPSLBuilder","position","order","prevTPSLType","tpslOrder","submit","deleteOrder","setValue","validate","isCreateMutating","isUpdateMutating","setQuantity","setOrderPrice","name","setPnL","dirty","diff","tp","o","sl","valid","trigger_prices","cancel","onSubmit","reject","isSuccess","TPSLWidget","modal","PopoverContent","PopoverRoot","PopoverTrigger","PositionTPSLPopover","buttonProps","open","setOpen","visible","setVisible","isOpen","finalIsEditing","useModal","useMarkPrice","PositionTPSLSheet","resolve","hide","updateArgs","updateSheetTitle","title","onCompleted","base_dp","PositionInfo","markPrice"],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\nimport {\n Badge,\n Box,\n Button,\n Divider,\n Flex,\n Grid,\n Input,\n Slider,\n Text,\n textVariants,\n cn,\n inputFormatter,\n Checkbox,\n convertValueToPercentage,\n ThrottledButton,\n} from \"@orderly.network/ui\";\nimport { PnlInputWidget } from \"./pnlInput/pnlInput.widget\";\nimport { TPSLBuilderState } from \"./useTPSL.script\";\nimport type { PNL_Values } from \"./pnlInput/useBuilder.script\";\nimport { useLocalStorage, utils } from \"@orderly.network/hooks\";\nimport { API, OrderSide } from \"@orderly.network/types\";\nimport { transSymbolformString } from \"@orderly.network/utils\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useOrderEntryFormErrorMsg } from \"@orderly.network/react-app\";\nimport { OrderValidationResult } from \"@orderly.network/hooks\";\n\nexport type TPSLProps = {\n onCancel?: () => void;\n onComplete?: () => void;\n};\n\n//------------- TPSL form start ---------------\nexport const TPSL = (props: TPSLBuilderState & TPSLProps) => {\n const {\n TPSL_OrderEntity,\n symbolInfo,\n onCancel,\n onComplete,\n status,\n errors,\n isPosition,\n } = props;\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(errors);\n\n return (\n <div id=\"orderly-tp_sl-order-edit-content\">\n {(!props.isEditing || (props.isEditing && !props.isPosition)) && (\n <>\n <TPSLQuantity\n maxQty={props.maxQty}\n quantity={(props.orderQuantity ?? props.maxQty) as number}\n baseTick={symbolInfo(\"base_tick\")}\n dp={symbolInfo(\"base_dp\")}\n onQuantityChange={props.setQuantity}\n quote={symbolInfo(\"base\")}\n isEditing={props.isEditing}\n isPosition={isPosition}\n errorMsg={parseErrorMsg(\"quantity\")}\n />\n <Divider my={4} intensity={8} />\n </>\n )}\n\n <TPSLPrice\n sl_pnl={TPSL_OrderEntity.sl_pnl}\n tp_pnl={TPSL_OrderEntity.tp_pnl}\n quote={symbolInfo(\"quote\")}\n quote_dp={symbolInfo(\"quote_dp\")}\n onPriceChange={props.setOrderPrice}\n onPnLChange={props.setPnL}\n errors={errors}\n tp_values={{\n PnL: `${TPSL_OrderEntity.tp_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.tp_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.tp_offset_percentage ?? \"\"}`,\n }}\n sl_values={{\n PnL: `${TPSL_OrderEntity.sl_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.sl_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.sl_offset_percentage ?? \"\"}`,\n }}\n tp_trigger_price={TPSL_OrderEntity.tp_trigger_price ?? \"\"}\n sl_trigger_price={TPSL_OrderEntity.sl_trigger_price ?? \"\"}\n />\n <Grid cols={2} gap={3} mt={4}>\n <Button\n size={\"md\"}\n color={\"secondary\"}\n data-testid={\"tpsl-cancel\"}\n onClick={() => {\n onCancel?.();\n }}\n >\n {t(\"common.cancel\")}\n </Button>\n <ThrottledButton\n size={\"md\"}\n data-testid={\"tpsl-confirm\"}\n disabled={!props.valid || status.isCreateMutating}\n loading={status.isCreateMutating || status.isUpdateMutating}\n onClick={() => {\n props.onSubmit().then(\n () => {\n onComplete?.();\n },\n () => {\n console.log(\"--->>>cancel order\");\n }\n );\n }}\n >\n {t(\"common.confirm\")}\n </ThrottledButton>\n </Grid>\n </div>\n );\n};\n\n//----------\n\n// ------------- Quantity input start------------\nconst TPSLQuantity = (props: {\n maxQty: number;\n baseTick: number;\n dp: number;\n quote: string;\n onQuantityChange?: (value: number | string) => void;\n quantity: number;\n isEditing?: boolean;\n isPosition?: boolean;\n setOrderValue?: (key: string, value: number | string) => void;\n errorMsg?: string;\n}) => {\n // const isPosition = props.quantity === props.maxQty;\n const { isPosition } = props;\n const inputRef = useRef<HTMLInputElement>(null);\n const currentQtyPercentage =\n convertValueToPercentage(props.quantity, 0, props.maxQty) / 100;\n const { t } = useTranslation();\n\n const setTPSL = () => {\n props.onQuantityChange?.(0);\n inputRef.current?.focus();\n\n setTimeout(() => {\n inputRef.current?.setSelectionRange(0, 1);\n }, 0);\n };\n\n const formatQuantity = (qty: string) => {\n if (props.baseTick > 0) {\n const quantity = Number(qty);\n // if (quantity) {\n // props.onQuantityChange?.(Math.min(props.maxQty, quantity));\n // } else {\n props.onQuantityChange?.(utils.formatNumber(qty, props.baseTick) ?? qty);\n // }\n }\n };\n\n const errorMsg =\n (isPosition ? \"\" : props.quantity).toString().length > 0\n ? props.errorMsg\n : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n data-testid=\"oui-testid-tpsl-popUp-quantity-input\"\n ref={inputRef}\n prefix={t(\"common.quantity\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n align=\"right\"\n value={isPosition ? \"\" : props.quantity}\n autoComplete=\"off\"\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: cn(\n \"oui-bg-base-5 oui-outline-line-12\",\n errorMsg && \"oui-outline-danger\"\n ),\n }}\n tooltipProps={{\n content: {\n className: \"oui-bg-base-6 oui-text-base-contrast-80\",\n },\n arrow: {\n className: \"oui-fill-base-6\",\n },\n }}\n tooltip={errorMsg}\n color={errorMsg ? \"danger\" : undefined}\n formatters={[\n inputFormatter.dpFormatter(props.dp),\n inputFormatter.numberFormatter,\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n const qty = Number(value);\n if (qty && qty > props.maxQty) {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n inputRef.current?.blur();\n }\n }}\n onBlur={(e) => formatQuantity(e.target.value)}\n suffix={\n isPosition ? (\n <button\n className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\"\n onClick={() => {\n setTPSL();\n }}\n >\n {t(\"tpsl.entirePosition\")}\n </button>\n ) : (\n <span className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\">\n {props.quote}\n </span>\n )\n }\n />\n </div>\n {!props.isEditing && (\n <Button\n onClick={() => {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n if (qty === 0) {\n setTPSL();\n }\n }}\n variant={\"outlined\"}\n // size={{\n // lg: \"md\",\n // md: \"lg\",\n // }}\n className={cn(\n \"oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]\",\n isPosition\n ? \"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20\"\n : \"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5\"\n )}\n >\n {t(\"common.position\")}\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primary\"\n max={props.maxQty}\n min={0}\n showTip\n step={props.baseTick}\n value={props.quantity}\n onValueCommit={(value) => {\n formatQuantity(`${value}`);\n }}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n }}\n />\n </Flex>\n <Flex justify={\"between\"}>\n <Text.numeral rule={\"percentages\"} color={\"primary\"} size={\"2xs\"}>\n {currentQtyPercentage}\n </Text.numeral>\n <Flex itemAlign={\"center\"} gap={1}>\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={() => {\n props.onQuantityChange?.(props.maxQty);\n }}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {t(\"common.max\")}\n </Text>\n </button>\n\n <Text.numeral\n rule={\"price\"}\n size={\"2xs\"}\n intensity={54}\n tick={props.baseTick}\n >\n {props.maxQty}\n </Text.numeral>\n </Flex>\n </Flex>\n </>\n );\n};\n// ------------- Quantity input end------------\n\n// ------------ TP/SL Price and PNL input start------------\nconst TPSLPrice = (props: {\n tp_pnl?: number;\n sl_pnl?: number;\n quote: string;\n quote_dp?: number;\n onPriceChange: TPSLBuilderState[\"setOrderPrice\"];\n onPnLChange: TPSLBuilderState[\"setPnL\"];\n tp_values: PNL_Values;\n sl_values: PNL_Values;\n tp_trigger_price?: number | string;\n sl_trigger_price?: number | string;\n errors: OrderValidationResult | null;\n}) => {\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(props.errors);\n\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.takeProfit\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.tp_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"TP\"}\n value={props.tp_trigger_price}\n error={parseErrorMsg(\"tp_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"tp_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"TP\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.tp_values}\n />\n </Grid>\n </div>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.stopLoss\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.sl_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"SL\"}\n value={props.sl_trigger_price}\n error={parseErrorMsg(\"sl_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"sl_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"SL\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.sl_values}\n />\n </Grid>\n </div>\n </>\n );\n};\n// ------------ TP/SL Price and PNL input end------------\n// ------------ TP/SL Price input start------------\nconst PriceInput = (props: {\n type: string;\n value?: string | number;\n error?: string;\n onValueChange: (value: string) => void;\n quote_dp: number;\n}) => {\n const [placeholder, setPlaceholder] = useState<string>(\"USDC\");\n const { t } = useTranslation();\n\n return (\n <Input.tooltip\n data-testid={`oui-testid-tpsl-popUp-${props.type.toLowerCase()}-input`}\n // prefix={`${props.type} price`}\n prefix={t(\"common.markPrice\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n tooltip={props.error}\n placeholder={placeholder}\n align={\"right\"}\n autoComplete={\"off\"}\n value={props.value}\n color={props.error ? \"danger\" : undefined}\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onValueChange={props.onValueChange}\n onFocus={() => {\n setPlaceholder(\"\");\n }}\n onBlur={() => {\n setPlaceholder(\"USDC\");\n }}\n formatters={[\n inputFormatter.numberFormatter,\n inputFormatter.dpFormatter(props.quote_dp),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n />\n );\n};\n\nexport type PositionTPSLConfirmProps = {\n symbol: string;\n // isPosition: boolean;\n qty: number;\n tpPrice?: number;\n slPrice?: number;\n maxQty: number;\n side: OrderSide;\n // symbolConfig:API.SymbolExt\n baseDP: number;\n quoteDP: number;\n isEditing?: boolean;\n isPositionTPSL?: boolean;\n};\n\n// ------------ Position TP/SL Confirm dialog start------------\nexport const PositionTPSLConfirm = (props: PositionTPSLConfirmProps) => {\n const {\n symbol,\n tpPrice,\n slPrice,\n qty,\n maxQty,\n side,\n quoteDP,\n baseDP,\n isEditing,\n isPositionTPSL: _isPositionTPSL,\n } = props;\n const { t } = useTranslation();\n\n const [needConfirm, setNeedConfirm] = useLocalStorage(\n \"orderly_order_confirm\",\n true\n );\n const textClassName = textVariants({\n size: \"xs\",\n intensity: 54,\n });\n\n // console.log(\"PositionTPSLConfirm\", qty, maxQty, quoteDP);\n\n const isPositionTPSL = _isPositionTPSL ?? qty >= maxQty;\n\n return (\n <>\n {isEditing && (\n <Text\n as=\"div\"\n size=\"2xs\"\n intensity={80}\n className=\"oui-mb-3\"\n >{`You agree to edit your ${transSymbolformString(\n symbol\n )} order.`}</Text>\n )}\n\n <Flex pb={4}>\n <Box grow>\n <Text.formatted\n rule={\"symbol\"}\n formatString=\"base-type\"\n size=\"base\"\n showIcon\n as=\"div\"\n intensity={80}\n >\n {symbol}\n </Text.formatted>\n </Box>\n <Flex gap={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color={\"primary\"}>\n {t(\"common.position\")}\n </Badge>\n )}\n\n {/* <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge> */}\n <TPSLOrderType tpPrice={tpPrice} slPrice={slPrice} />\n {side === OrderSide.SELL ? (\n <Badge size=\"xs\" color=\"success\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider />\n <Flex\n direction={\"column\"}\n itemAlign={\"stretch\"}\n gapY={1}\n pt={4}\n // pb={5}\n className={cn(textClassName, \"oui-pb-4 xl:oui-pb-5\")}\n >\n <Flex>\n <Box grow>{t(\"common.qty\")}</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">\n {t(\"tpsl.entirePosition\")}\n </span>\n ) : (\n <Text.numeral intensity={98} dp={baseDP} padding={false}>\n {qty}\n </Text.numeral>\n )}\n </div>\n </Flex>\n {typeof tpPrice === \"number\" && tpPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.tpPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {tpPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n {typeof slPrice === \"number\" && slPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.slPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n className=\"oui-text-trade-loss\"\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {slPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n\n <Flex>\n <Box grow>{t(\"common.price\")}</Box>\n <div className=\"oui-text-base-contrast\">\n {t(\"common.marketPrice\")}\n </div>\n </Flex>\n </Flex>\n <Box pt={2}>\n <Flex gap={1}>\n <Checkbox\n id=\"disabledConfirm\"\n color=\"white\"\n checked={!needConfirm}\n onCheckedChange={(check) => {\n setNeedConfirm(!check);\n }}\n />\n <label\n htmlFor=\"disabledConfirm\"\n className={textVariants({\n size: \"xs\",\n intensity: 54,\n className: \"oui-ml-1\",\n })}\n >\n {t(\"orderEntry.disableOrderConfirm\")}\n </label>\n </Flex>\n </Box>\n </>\n );\n};\n\n//------------- Position TP/SL Confirm dialog end------------\n\nconst TPSLOrderType = (props: { tpPrice?: number; slPrice?: number }) => {\n const { tpPrice, slPrice } = props;\n const { t } = useTranslation();\n\n if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.tp\")}\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.sl\")}\n </Badge>\n );\n }\n\n return null;\n};\n\nconst MaxQtyButton = (props: {\n onClick: () => void;\n children?: React.ReactNode;\n}) => {\n return (\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={props.onClick}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {props.children}\n </Text>\n </button>\n );\n};\n","import {\n CaretDownIcon,\n cn,\n Input,\n MenuItem,\n SimpleDropdownMenu,\n} from \"@orderly.network/ui\";\nimport { PNLInputState, PnLMode } from \"./useBuilder.script\";\nimport { inputFormatter, Text } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport type PNLInputProps = PNLInputState & { testId?: string; quote: string };\n\nexport const PNLInput = (props: PNLInputProps) => {\n const {\n mode,\n modes,\n onModeChange,\n onValueChange,\n quote,\n quote_dp,\n value,\n pnl,\n } = props;\n const { t } = useTranslation();\n\n const [prefix, setPrefix] = useState<string>(mode);\n const [placeholder, setPlaceholder] = useState<string>(\n mode === PnLMode.PERCENTAGE ? \"%\" : quote\n );\n\n const color = useMemo(() => {\n const num = Number(pnl);\n\n if (isNaN(num) || num === 0) return \"\";\n\n if (num > 0) return \"oui-text-trade-profit\";\n if (num < 0) return \"oui-text-trade-loss\";\n }, [pnl]);\n\n useEffect(() => {\n const label = modes.find((item) => item.value === mode)?.label;\n setPrefix(label!);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode, modes]);\n\n return (\n <Input\n prefix={prefix}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n placeholder={placeholder}\n align={\"right\"}\n value={value}\n data-testid={props.testId}\n autoComplete={\"off\"}\n onValueChange={onValueChange}\n formatters={[\n // inputFormatter.numberFormatter,\n props.formatter({ dp: quote_dp, mode }),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n // className={color}\n classNames={{\n input: color,\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onFocus={() => {\n setPlaceholder(\"\");\n props.setFocus(true);\n }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n props.setFocus(false);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text\n size={\"2xs\"}\n color=\"inherit\"\n className={cn(\"oui-ml-[2px]\", color)}\n >\n %\n </Text>\n )}\n <PNLMenus\n mode={mode}\n modes={modes}\n onModeChange={(item) => onModeChange(item.value as PnLMode)}\n />\n </>\n }\n />\n );\n};\n\nconst PNLMenus = (props: {\n mode?: string;\n modes: MenuItem[];\n onModeChange: (value: MenuItem) => void;\n}) => {\n return (\n <SimpleDropdownMenu\n currentValue={props.mode}\n menu={props.modes}\n align={\"end\"}\n size={\"xs\"}\n className={\"oui-min-w-[80px]\"}\n onSelect={(item) => props.onModeChange(item as MenuItem)}\n >\n <button className={\"oui-p-2\"}>\n <CaretDownIcon size={12} color={\"white\"} />\n </button>\n </SimpleDropdownMenu>\n );\n};\n","import { useMemo, useRef, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { MenuItem } from \"@orderly.network/ui\";\nimport { Decimal, todpIfNeed } from \"@orderly.network/utils\";\nimport type {\n InputFormatter,\n InputFormatterOptions,\n} from \"@orderly.network/ui\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport enum PnLMode {\n PnL = \"PnL\",\n OFFSET = \"Offset\",\n PERCENTAGE = \"Offset%\",\n}\n\nexport type PNL_Values = {\n PnL: string;\n Offset: string;\n \"Offset%\": string;\n};\n\nexport type BuilderProps = {\n type: \"TP\" | \"SL\";\n\n quote_dp?: number;\n onChange: (key: string, value: number | string) => void;\n\n values: PNL_Values;\n};\n\nexport const usePNLInputBuilder = (props: BuilderProps) => {\n const { type, values } = props;\n const [mode, setMode] = useLocalStorage<PnLMode>(\n \"TP/SL_Mode\",\n PnLMode.PERCENTAGE\n );\n const [focus, setFocus] = useState(true);\n\n const { t } = useTranslation();\n\n const key = useMemo(() => {\n switch (mode) {\n case PnLMode.OFFSET:\n return `${type.toLowerCase()}_offset`;\n case PnLMode.PERCENTAGE:\n return `${type.toLowerCase()}_offset_percentage`;\n default:\n return `${type.toLowerCase()}_pnl`;\n }\n }, [mode]);\n\n const value = useMemo(() => {\n return values[mode as keyof PNL_Values];\n }, [values, mode]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n {\n label: t(\"tpsl.pnl\"),\n value: PnLMode.PnL,\n testId: `${PnLMode.PnL}_menu_item`,\n },\n {\n label: t(\"tpsl.offset\"),\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: `${t(\"tpsl.offset\")}%`,\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, [t]);\n\n const percentageSuffix = useRef<string>(\"\");\n\n const onValueChange = (value: string) => {\n console.log(\"onValueChange\", value);\n props.onChange(key, value);\n };\n\n const formatter = (options: {\n dp?: number;\n mode: PnLMode;\n }): InputFormatter => {\n const { dp = 2 } = options;\n return {\n onRenderBefore: (\n value: string | number,\n options: InputFormatterOptions\n ) => {\n value = `${value}`; // convert to string\n\n if (focus) {\n if (type === \"SL\" && mode === PnLMode.PnL) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n }\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n // if (mode === PnLMode.PnL || mode === PnLMode.OFFSET) {\n // return commify(value);\n // }\n\n if (mode === PnLMode.PERCENTAGE) {\n return `${new Decimal(\n value.replace(\n new RegExp(percentageSuffix.current.replace(\".\", \"\\\\.\") + \"$\"),\n \"\"\n )\n )\n .mul(100)\n .todp(2, 4)\n .toString()}${percentageSuffix.current}`;\n } else if (mode === PnLMode.OFFSET) {\n value = todpIfNeed(value, dp);\n } else {\n // value = new Decimal(value).todp(2).toString();\n }\n\n return `${value}`;\n },\n onSendBefore: (value: string) => {\n if (/^\\-?0{2,}$/.test(value)) {\n return \"0\";\n }\n\n if (mode === PnLMode.PERCENTAGE) {\n // console.log(\"value\", value);\n if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n value = todpIfNeed(value, 2);\n const endStr = value.match(/\\.0{0,2}$/);\n if (!!endStr) {\n percentageSuffix.current = endStr[0];\n } else {\n percentageSuffix.current = \"\";\n }\n value = new Decimal(value).div(100).toString();\n value = `${value}${percentageSuffix.current}`;\n }\n } else if (mode === PnLMode.PnL && type === \"SL\" && focus) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n } else {\n value = todpIfNeed(value, dp);\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n\n return value;\n },\n };\n // return {\n // onRenderBefore: (\n // value: string | number,\n // options: InputFormatterOptions\n // ) => {\n // // console.log(\"???\", options);\n // const { isFocused } = options;\n // value = `${value}`;\n // if (value === \"\" || value === \"-\") return \"\";\n\n // // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (isFocused) {\n // // value = value.startsWith(\"-\") ? value : \"-\" + value;\n // // }\n // // }\n\n // if (mode === PnLMode.PERCENTAGE) {\n // return `${todpIfNeed(new Decimal(value).mul(100).toString(), 2)}${\n // percentageSuffix.current\n // }`;\n // // return (Number(value) * 100).toFixed(2);\n // } else if (mode === PnLMode.OFFSET) {\n // value = todpIfNeed(value, 2);\n // } else {\n // // value = new Decimal(value).todp(2).toString();\n // }\n\n // return value;\n // },\n // onSendBefore: (value: string, options: InputFormatterOptions) => {\n // const { isFocused } = options;\n\n // if (mode === PnLMode.PERCENTAGE) {\n // if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n // value = new Decimal(value).div(100).toString();\n // value = todpIfNeed(value, 4);\n // }\n // } else {\n // // value = todpIfNeed(value, quote_dp);\n // if (isFocused) {\n // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (\n // // typeof values[PnLMode.PnL] !== \"undefined\" &&\n // // values[PnLMode.PnL] !== \"\"\n // // )\n // // return value;\n // const num = Number(value);\n // if (!isNaN(num) && num !== 0) {\n // value = (Math.abs(num) * -1).toString();\n // } else {\n // value = \"\";\n // }\n // }\n // }\n // }\n\n // return value;\n // },\n // };\n };\n\n return {\n mode,\n modes,\n type: props.type,\n formatter,\n onModeChange: (mode: PnLMode) => {\n setMode(mode);\n },\n value,\n pnl: values[PnLMode.PnL],\n onValueChange,\n quote_dp: props.quote_dp,\n setFocus,\n };\n};\n\nexport type PNLInputState = ReturnType<typeof usePNLInputBuilder>;\n","import { PNLInput } from \"./pnlInput.ui\";\nimport { BuilderProps, usePNLInputBuilder } from \"./useBuilder.script\";\n\nexport const PnlInputWidget = (\n props: BuilderProps & {\n testId?: string;\n quote: string;\n }\n) => {\n const { testId, quote, ...rest } = props;\n const state = usePNLInputBuilder(rest);\n return <PNLInput {...state} testId={testId} quote={quote} />;\n};\n","import {\n type ComputedAlgoOrder,\n useLocalStorage,\n useSymbolsInfo,\n useTPSLOrder,\n utils,\n} from \"@orderly.network/hooks\";\nimport { SDKError } from \"@orderly.network/types\";\nimport { AlgoOrderRootType, AlgoOrderType, API } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useRef } from \"react\";\n\nexport type TPSLBuilderOptions = {\n position: API.Position;\n order?: API.AlgoOrder;\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n isEditing?: boolean;\n /**\n * either show the confirm dialog or not,\n * if the Promise reject or return false, cancel the submit action\n */\n onConfirm?: (\n order: ComputedAlgoOrder,\n options: {\n position: API.Position;\n submit: () => Promise<any>;\n cancel: () => Promise<any>;\n }\n ) => Promise<boolean>;\n};\n\nexport const useTPSLBuilder = (options: TPSLBuilderOptions) => {\n const { position, order, isEditing } = options;\n // const isEditing = !!order;\n if (isEditing && !order) {\n throw new SDKError(\"order is required when isEditing is true\");\n }\n const symbol = isEditing ? order!.symbol : position.symbol;\n const symbolInfo = useSymbolsInfo();\n const prevTPSLType = useRef<AlgoOrderRootType>(AlgoOrderRootType.TP_SL);\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const [\n tpslOrder,\n {\n submit,\n deleteOrder,\n setValue,\n validate,\n errors,\n isCreateMutating,\n isUpdateMutating,\n },\n ] = useTPSLOrder(\n {\n symbol,\n position_qty: position.position_qty,\n average_open_price: position.average_open_price,\n },\n {\n defaultOrder: order,\n isEditing,\n }\n );\n\n const setQuantity = (value: number | string) => {\n setValue(\"quantity\", value);\n };\n\n const setOrderPrice = (\n name: \"tp_trigger_price\" | \"sl_trigger_price\",\n value: number | string\n ) => {\n setValue(name, value);\n };\n\n const setPnL = (type: string, value: number | string) => {\n setValue(type, value);\n };\n\n const maxQty = useMemo(\n () => Math.abs(Number(position.position_qty)),\n [position.position_qty]\n );\n\n const dirty = useMemo(() => {\n const quantity =\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n ? maxQty\n : order?.quantity;\n\n let diff: number = 0;\n\n if (Number(tpslOrder.quantity) !== quantity) {\n diff = 1;\n } else if (!isEditing && !!tpslOrder.quantity) {\n diff = 1;\n }\n\n if (order && isEditing) {\n const tp = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.TAKE_PROFIT\n );\n const sl = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.STOP_LOSS\n );\n\n if (\n tp?.trigger_price !== Number(tpslOrder.tp_trigger_price) &&\n typeof typeof tpslOrder.tp_trigger_price !== \"undefined\"\n ) {\n // return true;\n diff = 2;\n }\n\n if (\n sl?.trigger_price !== Number(tpslOrder.sl_trigger_price) &&\n typeof tpslOrder.sl_trigger_price !== \"undefined\"\n ) {\n diff = 3;\n }\n }\n\n if (\n diff === 1 &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n diff = -1;\n }\n\n return diff;\n }, [\n tpslOrder.tp_trigger_price,\n tpslOrder.sl_trigger_price,\n tpslOrder.quantity,\n order,\n isEditing,\n ]);\n\n const valid = useMemo(() => {\n /**\n * if the order is a POSITIONAL_TP_SL and the quantity is less than the maxQty,\n * and the tp/sl trigger price is not set, then the order is not valid\n */\n if (\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n Number(tpslOrder.quantity) < maxQty &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n return false;\n }\n\n return dirty > 0 && !!tpslOrder.quantity && !errors;\n }, [tpslOrder.quantity, maxQty, dirty, errors]);\n\n const isPositionTPSL = useMemo(() => {\n if (!isEditing) return Number(tpslOrder.quantity) >= maxQty;\n /**\n * if current order is not a POSITIONAL_TP_SL, then it's always a general TP/SL\n */\n if (!!order && order.algo_type !== AlgoOrderRootType.POSITIONAL_TP_SL) {\n return false;\n }\n if (tpslOrder.algo_order_id && tpslOrder.quantity == 0) return true;\n return Number(tpslOrder.quantity) >= maxQty;\n }, [tpslOrder.quantity, maxQty, order?.algo_type, isEditing]);\n\n useEffect(() => {\n if (!isEditing && isPositionTPSL) {\n const trigger_prices = utils.findTPSLFromOrder(order!);\n if (!tpslOrder.tp_trigger_price && trigger_prices.tp_trigger_price) {\n setOrderPrice(\"tp_trigger_price\", trigger_prices.tp_trigger_price);\n }\n if (!tpslOrder.sl_trigger_price && trigger_prices.sl_trigger_price) {\n setOrderPrice(\"sl_trigger_price\", trigger_prices.sl_trigger_price);\n }\n }\n }, [isEditing, isPositionTPSL, tpslOrder]);\n\n useEffect(() => {\n const type =\n Number(tpslOrder.quantity) < maxQty\n ? AlgoOrderRootType.TP_SL\n : AlgoOrderRootType.POSITIONAL_TP_SL;\n if (\n typeof options.onTPSLTypeChange === \"function\" &&\n prevTPSLType.current !== type\n ) {\n options.onTPSLTypeChange(type);\n }\n\n prevTPSLType.current = type;\n }, [tpslOrder.quantity, maxQty]);\n\n const cancel = (): Promise<void> => {\n if (order?.algo_order_id && order?.symbol) {\n return deleteOrder(order?.algo_order_id, order?.symbol);\n }\n return Promise.reject(\"order id or symbol is invalid\");\n };\n\n const onSubmit = async () => {\n return Promise.resolve()\n .then(() => {\n if (typeof options.onConfirm !== \"function\" || !needConfirm) {\n return submit().then(\n () => true,\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n return Promise.reject(false);\n }\n );\n }\n return options.onConfirm(tpslOrder, {\n position,\n submit,\n cancel,\n });\n })\n .then((isSuccess) => {\n console.log(\"result\", isSuccess);\n });\n };\n\n return {\n isEditing,\n symbolInfo: symbolInfo[symbol],\n maxQty,\n setQuantity,\n orderQuantity: tpslOrder.quantity,\n isPosition: isPositionTPSL,\n\n TPSL_OrderEntity: tpslOrder,\n setOrderValue: setValue,\n setPnL,\n setOrderPrice,\n // needConfirm,\n onSubmit,\n valid,\n errors,\n status: {\n isCreateMutating,\n isUpdateMutating,\n },\n } as const;\n};\n\nexport type TPSLBuilderState = ReturnType<typeof useTPSLBuilder>;\n","import { type AlgoOrderRootType } from \"@orderly.network/types\";\nimport { TPSL, TPSLProps } from \"./tpsl.ui\";\nimport { TPSLBuilderOptions, useTPSLBuilder } from \"./useTPSL.script\";\n\nexport type TPSLWidgetProps = {\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n} & TPSLBuilderOptions &\n TPSLProps;\n\nexport const TPSLWidget = (props: TPSLWidgetProps) => {\n const { onCancel, onComplete, ...rest } = props;\n const state = useTPSLBuilder(rest);\n\n return <TPSL {...state} onCancel={onCancel} onComplete={onComplete} />;\n};\n","import { ReactNode, useState } from \"react\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n} from \"@orderly.network/ui\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { TPSLWidget } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport { ButtonProps } from \"@orderly.network/ui\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport const PositionTPSLPopover = (props: {\n position: API.Position;\n order?: API.AlgoOrder;\n label?: string;\n baseDP?: number;\n quoteDP?: number;\n /**\n * Button props\n */\n buttonProps?: ButtonProps;\n isEditing?: boolean;\n children?: ReactNode;\n}) => {\n const { position, order, baseDP, quoteDP, buttonProps, isEditing } = props;\n const [open, setOpen] = useState(false);\n const [visible, setVisible] = useState(true);\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n return (\n <PopoverRoot\n onOpenChange={(isOpen) => {\n // console.log(\"isOpen\", isOpen);\n if (visible) {\n setOpen(isOpen);\n }\n }}\n open={open}\n >\n <PopoverTrigger\n asChild\n onClick={() => {\n setOpen(true);\n }}\n >\n {props.children || (\n <Button\n variant=\"outlined\"\n size=\"sm\"\n color=\"secondary\"\n {...buttonProps}\n // onClick={() => {\n // setOpen(true);\n // }}\n >\n {props.label}\n </Button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"oui-w-[360px]\",\n visible ? \"oui-visible\" : \"oui-invisible\"\n )}\n align=\"end\"\n side={\"top\"}\n >\n <TPSLWidget\n position={position}\n order={order}\n isEditing={isEditing}\n onComplete={() => {\n // console.log(\"tpsl order completed\");\n setOpen(false);\n }}\n onCancel={() => {\n setOpen(false);\n }}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n setVisible(false);\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n // console.log(\n // \"order\",\n // order,\n // isEditing ||\n // (!!order &&\n // order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n // order.quantity === maxQty)\n // );\n\n if (\n `${order.tp_trigger_price ?? \"\"}`.length === 0 &&\n `${order.sl_trigger_price ?? \"\"}`.length === 0\n ) {\n return modal\n .confirm({\n title: t(\"orders.cancelOrder\"),\n content: t(\"tpsl.cancelOrder.description\"),\n onOk: () => {\n return options.cancel();\n },\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n }\n );\n }\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n // bodyClassName: \"lg:oui-py-0\",\n onOk: () => {\n return options.submit();\n },\n classNames: {\n body: \"!oui-pb-0\",\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={finalIsEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quoteDP ?? 2}\n baseDP={baseDP ?? 2}\n />\n ),\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n }\n );\n }}\n />\n </PopoverContent>\n </PopoverRoot>\n );\n};\n","import { useMemo } from \"react\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Flex,\n modal,\n useModal,\n Text,\n Box,\n Badge,\n Divider,\n toast,\n} from \"@orderly.network/ui\";\nimport { TPSLWidget, TPSLWidgetProps } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\ntype TPSLSheetProps = {\n position: API.Position;\n order?: API.AlgoOrder;\n // label: string;\n // baseDP?: number;\n // quoteDP?: number;\n symbolInfo: API.SymbolExt;\n isEditing?: boolean;\n};\n\nexport const PositionTPSLSheet = (props: TPSLWidgetProps & TPSLSheetProps) => {\n const { position, order, symbolInfo, isEditing } = props;\n const { resolve, hide, updateArgs } = useModal();\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n const updateSheetTitle = (title: string) => {\n if (isEditing) return;\n updateArgs({ title });\n };\n\n const onCompleted = () => {\n resolve();\n hide();\n };\n\n const { quote_dp, base_dp } = symbolInfo;\n\n return (\n <>\n <PositionInfo position={position} symbolInfo={symbolInfo} />\n\n <TPSLWidget\n {...props}\n onTPSLTypeChange={(type) => {\n updateSheetTitle(\n type === AlgoOrderRootType.TP_SL\n ? t(\"common.tpsl\")\n : t(\"tpsl.positionTpsl\")\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n bodyClassName: \"oui-pb-0 lg:oui-pb-0\",\n onOk: () => {\n return options.submit();\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={isEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quote_dp ?? 2}\n baseDP={base_dp ?? 2}\n />\n ),\n })\n .then(\n () => {\n // setOpen(false);\n // setVisible(true);\n return true;\n },\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n\n // setVisible(true);\n return Promise.reject(false);\n }\n );\n }}\n onCancel={() => {\n hide();\n }}\n />\n </>\n );\n};\n\nexport const TPSLSheetTitle = () => {\n const modal = useModal();\n const { t } = useTranslation();\n\n const title = useMemo<string>(() => {\n return (modal.args?.title || t(\"common.tpsl\")) as string;\n }, [modal.args?.title, t]);\n\n return <span>{title}</span>;\n};\n\nexport const PositionInfo = (props: {\n position: API.Position;\n symbolInfo: API.SymbolExt;\n}) => {\n const { position, symbolInfo } = props;\n const { data: markPrice } = useMarkPrice(position.symbol);\n const modal = useModal();\n const { t } = useTranslation();\n\n const isPositionTPSL = useMemo(() => {\n return modal.args?.title === t(\"tpsl.positionTpsl\");\n }, [modal.args?.title, t]);\n return (\n <>\n <Flex justify={\"between\"} pb={3} itemAlign={\"center\"}>\n <Text.formatted rule=\"symbol\" className=\"oui-text-xs\" showIcon>\n {position.symbol}\n </Text.formatted>\n <Flex gapX={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color=\"primary\">\n {t(\"common.position\")}\n </Badge>\n )}\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider intensity={8} />\n <Box py={3} className=\"oui-space-y-1\">\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.avgOpen\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {position.average_open_price}\n </Text.numeral>\n </Flex>\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.markPrice\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {markPrice}\n </Text.numeral>\n </Flex>\n </Box>\n </>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tpsl.ui.tsx","../src/pnlInput/pnlInput.ui.tsx","../src/pnlInput/useBuilder.script.ts","../src/pnlInput/pnlInput.widget.tsx","../src/useTPSL.script.ts","../src/tpsl.widget.tsx","../src/editorPopover.tsx","../src/editorSheet.tsx"],"names":["useRef","useState","useLocalStorage","utils","useTranslation","useOrderEntryFormErrorMsg","OrderSide","Badge","Box","Button","Divider","Flex","Grid","Input","Slider","Text","textVariants","cn","inputFormatter","Checkbox","convertValueToPercentage","ThrottledButton","transSymbolformString","CaretDownIcon","SimpleDropdownMenu","useMemo","Decimal","todpIfNeed","usePNLInputBuilder","props","type","values","mode","setMode","focus","setFocus","t","key","value","modes","percentageSuffix","onValueChange","formatter","options","dp","endStr","useEffect","Fragment","jsx","jsxs","PNLInput","onModeChange","quote","quote_dp","pnl","prefix","setPrefix","placeholder","setPlaceholder","color","num","label","item","PNLMenus","PnlInputWidget","testId","rest","state","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","parseErrorMsg","TPSLQuantity","TPSLPrice","err","inputRef","currentQtyPercentage","setTPSL","formatQuantity","qty","quantity","errorMsg","e","onPnLChange","PriceInput","PositionTPSLConfirm","symbol","tpPrice","slPrice","maxQty","side","quoteDP","baseDP","isEditing","_isPositionTPSL","needConfirm","setNeedConfirm","textClassName","isPositionTPSL","TPSLOrderType","check","useSymbolsInfo","useTPSLOrder","SDKError","AlgoOrderRootType","AlgoOrderType","toast","useTPSLBuilder","position","order","prevTPSLType","tpslOrder","submit","deleteOrder","setValue","validate","isCreateMutating","isUpdateMutating","setQuantity","setOrderPrice","name","setPnL","dirty","diff","tp","o","sl","valid","trigger_prices","cancel","onSubmit","TPSLWidget","modal","PopoverContent","PopoverRoot","PopoverTrigger","PositionTPSLPopover","buttonProps","open","setOpen","visible","setVisible","isOpen","finalIsEditing","res","useMarkPrice","useModal","PositionTPSLSheet","resolve","hide","updateArgs","updateSheetTitle","title","onCompleted","base_dp","PositionInfo","reject","markPrice"],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\nimport { useLocalStorage, utils } from \"@orderly.network/hooks\";\nimport { OrderValidationResult } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useOrderEntryFormErrorMsg } from \"@orderly.network/react-app\";\nimport { API, OrderSide } from \"@orderly.network/types\";\nimport {\n Badge,\n Box,\n Button,\n Divider,\n Flex,\n Grid,\n Input,\n Slider,\n Text,\n textVariants,\n cn,\n inputFormatter,\n Checkbox,\n convertValueToPercentage,\n ThrottledButton,\n} from \"@orderly.network/ui\";\nimport { transSymbolformString } from \"@orderly.network/utils\";\nimport { PnlInputWidget } from \"./pnlInput/pnlInput.widget\";\nimport type { PNL_Values } from \"./pnlInput/useBuilder.script\";\nimport { TPSLBuilderState } from \"./useTPSL.script\";\n\nexport type TPSLProps = {\n onCancel?: () => void;\n onComplete?: () => void;\n};\n\n//------------- TPSL form start ---------------\nexport const TPSL = (props: TPSLBuilderState & TPSLProps) => {\n const {\n TPSL_OrderEntity,\n symbolInfo,\n onCancel,\n onComplete,\n status,\n errors,\n isPosition,\n } = props;\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(errors);\n\n return (\n <div id=\"orderly-tp_sl-order-edit-content\">\n {(!props.isEditing || (props.isEditing && !props.isPosition)) && (\n <>\n <TPSLQuantity\n maxQty={props.maxQty}\n quantity={(props.orderQuantity ?? props.maxQty) as number}\n baseTick={symbolInfo(\"base_tick\")}\n dp={symbolInfo(\"base_dp\")}\n onQuantityChange={props.setQuantity}\n quote={symbolInfo(\"base\")}\n isEditing={props.isEditing}\n isPosition={isPosition}\n errorMsg={parseErrorMsg(\"quantity\")}\n />\n <Divider my={4} intensity={8} />\n </>\n )}\n\n <TPSLPrice\n sl_pnl={TPSL_OrderEntity.sl_pnl}\n tp_pnl={TPSL_OrderEntity.tp_pnl}\n quote={symbolInfo(\"quote\")}\n quote_dp={symbolInfo(\"quote_dp\")}\n onPriceChange={props.setOrderPrice}\n onPnLChange={props.setPnL}\n errors={errors}\n tp_values={{\n PnL: `${TPSL_OrderEntity.tp_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.tp_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.tp_offset_percentage ?? \"\"}`,\n }}\n sl_values={{\n PnL: `${TPSL_OrderEntity.sl_pnl ?? \"\"}`,\n Offset: `${TPSL_OrderEntity.sl_offset ?? \"\"}`,\n \"Offset%\": `${TPSL_OrderEntity.sl_offset_percentage ?? \"\"}`,\n }}\n tp_trigger_price={TPSL_OrderEntity.tp_trigger_price ?? \"\"}\n sl_trigger_price={TPSL_OrderEntity.sl_trigger_price ?? \"\"}\n />\n <Grid cols={2} gap={3} mt={4}>\n <Button\n size={\"md\"}\n color={\"secondary\"}\n data-testid={\"tpsl-cancel\"}\n onClick={() => {\n onCancel?.();\n }}\n >\n {t(\"common.cancel\")}\n </Button>\n <ThrottledButton\n size={\"md\"}\n data-testid={\"tpsl-confirm\"}\n disabled={!props.valid || status.isCreateMutating}\n loading={status.isCreateMutating || status.isUpdateMutating}\n onClick={() => {\n props\n .onSubmit()\n .then(() => {\n onComplete?.();\n })\n .catch((err) => {\n console.log(\"--->>>cancel order\", err);\n });\n }}\n >\n {t(\"common.confirm\")}\n </ThrottledButton>\n </Grid>\n </div>\n );\n};\n\n//----------\n\n// ------------- Quantity input start------------\nconst TPSLQuantity = (props: {\n maxQty: number;\n baseTick: number;\n dp: number;\n quote: string;\n onQuantityChange?: (value: number | string) => void;\n quantity: number;\n isEditing?: boolean;\n isPosition?: boolean;\n setOrderValue?: (key: string, value: number | string) => void;\n errorMsg?: string;\n}) => {\n // const isPosition = props.quantity === props.maxQty;\n const { isPosition } = props;\n const inputRef = useRef<HTMLInputElement>(null);\n const currentQtyPercentage =\n convertValueToPercentage(props.quantity, 0, props.maxQty) / 100;\n const { t } = useTranslation();\n\n const setTPSL = () => {\n props.onQuantityChange?.(0);\n inputRef.current?.focus();\n\n setTimeout(() => {\n inputRef.current?.setSelectionRange(0, 1);\n }, 0);\n };\n\n const formatQuantity = (qty: string) => {\n if (props.baseTick > 0) {\n const quantity = Number(qty);\n // if (quantity) {\n // props.onQuantityChange?.(Math.min(props.maxQty, quantity));\n // } else {\n props.onQuantityChange?.(utils.formatNumber(qty, props.baseTick) ?? qty);\n // }\n }\n };\n\n const errorMsg =\n (isPosition ? \"\" : props.quantity).toString().length > 0\n ? props.errorMsg\n : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n data-testid=\"oui-testid-tpsl-popUp-quantity-input\"\n ref={inputRef}\n prefix={t(\"common.quantity\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n align=\"right\"\n value={isPosition ? \"\" : props.quantity}\n autoComplete=\"off\"\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: cn(\n \"oui-bg-base-5 oui-outline-line-12\",\n errorMsg && \"oui-outline-danger\",\n ),\n }}\n tooltipProps={{\n content: {\n className: \"oui-bg-base-6 oui-text-base-contrast-80\",\n },\n arrow: {\n className: \"oui-fill-base-6\",\n },\n }}\n tooltip={errorMsg}\n color={errorMsg ? \"danger\" : undefined}\n formatters={[\n inputFormatter.dpFormatter(props.dp),\n inputFormatter.numberFormatter,\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n const qty = Number(value);\n if (qty && qty > props.maxQty) {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n inputRef.current?.blur();\n }\n }}\n onBlur={(e) => formatQuantity(e.target.value)}\n suffix={\n isPosition ? (\n <button\n className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\"\n onClick={() => {\n setTPSL();\n }}\n >\n {t(\"tpsl.entirePosition\")}\n </button>\n ) : (\n <span className=\"oui-text-2xs oui-text-base-contrast-54 oui-px-3\">\n {props.quote}\n </span>\n )\n }\n />\n </div>\n {!props.isEditing && (\n <Button\n onClick={() => {\n const qty = isPosition ? 0 : props.maxQty;\n props.onQuantityChange?.(qty);\n if (qty === 0) {\n setTPSL();\n }\n }}\n variant={\"outlined\"}\n // size={{\n // lg: \"md\",\n // md: \"lg\",\n // }}\n className={cn(\n \"oui-text-2xs oui-w-[68px] oui-h-[40px] xl:oui-h-[32px]\",\n isPosition\n ? \"oui-border-primary-light oui-text-primary-light hover:oui-bg-primary-light/20\"\n : \"oui-bg-base-6 oui-border-line-12 oui-text-base-contrast-54 hover:oui-bg-base-5\",\n )}\n >\n {t(\"common.position\")}\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primary\"\n max={props.maxQty}\n min={0}\n showTip\n step={props.baseTick}\n value={props.quantity}\n onValueCommit={(value) => {\n formatQuantity(`${value}`);\n }}\n onValueChange={(value) => {\n props.onQuantityChange?.(value);\n }}\n />\n </Flex>\n <Flex justify={\"between\"}>\n <Text.numeral rule={\"percentages\"} color={\"primary\"} size={\"2xs\"}>\n {currentQtyPercentage}\n </Text.numeral>\n <Flex itemAlign={\"center\"} gap={1}>\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={() => {\n props.onQuantityChange?.(props.maxQty);\n }}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {t(\"common.max\")}\n </Text>\n </button>\n\n <Text.numeral\n rule={\"price\"}\n size={\"2xs\"}\n intensity={54}\n tick={props.baseTick}\n >\n {props.maxQty}\n </Text.numeral>\n </Flex>\n </Flex>\n </>\n );\n};\n// ------------- Quantity input end------------\n\n// ------------ TP/SL Price and PNL input start------------\nconst TPSLPrice = (props: {\n tp_pnl?: number;\n sl_pnl?: number;\n quote: string;\n quote_dp?: number;\n onPriceChange: TPSLBuilderState[\"setOrderPrice\"];\n onPnLChange: TPSLBuilderState[\"setPnL\"];\n tp_values: PNL_Values;\n sl_values: PNL_Values;\n tp_trigger_price?: number | string;\n sl_trigger_price?: number | string;\n errors: OrderValidationResult | null;\n}) => {\n const { t } = useTranslation();\n\n const { parseErrorMsg } = useOrderEntryFormErrorMsg(props.errors);\n\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.takeProfit\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.tp_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"TP\"}\n value={props.tp_trigger_price}\n error={parseErrorMsg(\"tp_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"tp_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"TP\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.tp_values}\n />\n </Grid>\n </div>\n <div>\n <Flex justify={\"between\"}>\n <Flex gap={1}>\n <Text size={\"2xs\"} intensity={80}>\n {t(\"tpsl.stopLoss\")}\n </Text>\n <Text size={\"2xs\"} intensity={36}>\n {`(${(\n t(\"orderEntry.orderType.marketOrder\") as string\n )?.toLowerCase()})`}\n </Text>\n </Flex>\n\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n {`${t(\"tpsl.estPnl\")}:`}\n </Text>\n <Text.numeral\n size={\"2xs\"}\n coloring\n showIdentifier\n className=\"oui-ml-1\"\n >\n {props.sl_pnl ?? \"-\"}\n </Text.numeral>\n </Flex>\n </Flex>\n <Grid cols={2} gap={2} pt={2} pb={4}>\n <PriceInput\n type={\"SL\"}\n value={props.sl_trigger_price}\n error={parseErrorMsg(\"sl_trigger_price\")}\n onValueChange={(value) => {\n props.onPriceChange(\"sl_trigger_price\", value);\n }}\n quote_dp={props.quote_dp ?? 2}\n />\n <PnlInputWidget\n type={\"SL\"}\n onChange={onPnLChange}\n quote={props.quote}\n quote_dp={props.quote_dp}\n values={props.sl_values}\n />\n </Grid>\n </div>\n </>\n );\n};\n// ------------ TP/SL Price and PNL input end------------\n// ------------ TP/SL Price input start------------\nconst PriceInput = (props: {\n type: string;\n value?: string | number;\n error?: string;\n onValueChange: (value: string) => void;\n quote_dp: number;\n}) => {\n const [placeholder, setPlaceholder] = useState<string>(\"USDC\");\n const { t } = useTranslation();\n\n return (\n <Input.tooltip\n data-testid={`oui-testid-tpsl-popUp-${props.type.toLowerCase()}-input`}\n // prefix={`${props.type} price`}\n prefix={t(\"common.markPrice\")}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n tooltip={props.error}\n placeholder={placeholder}\n align={\"right\"}\n autoComplete={\"off\"}\n value={props.value}\n color={props.error ? \"danger\" : undefined}\n classNames={{\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onValueChange={props.onValueChange}\n onFocus={() => {\n setPlaceholder(\"\");\n }}\n onBlur={() => {\n setPlaceholder(\"USDC\");\n }}\n formatters={[\n inputFormatter.numberFormatter,\n inputFormatter.dpFormatter(props.quote_dp),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n />\n );\n};\n\nexport type PositionTPSLConfirmProps = {\n symbol: string;\n // isPosition: boolean;\n qty: number;\n tpPrice?: number;\n slPrice?: number;\n maxQty: number;\n side: OrderSide;\n // symbolConfig:API.SymbolExt\n baseDP: number;\n quoteDP: number;\n isEditing?: boolean;\n isPositionTPSL?: boolean;\n};\n\n// ------------ Position TP/SL Confirm dialog start------------\nexport const PositionTPSLConfirm = (props: PositionTPSLConfirmProps) => {\n const {\n symbol,\n tpPrice,\n slPrice,\n qty,\n maxQty,\n side,\n quoteDP,\n baseDP,\n isEditing,\n isPositionTPSL: _isPositionTPSL,\n } = props;\n const { t } = useTranslation();\n\n const [needConfirm, setNeedConfirm] = useLocalStorage(\n \"orderly_order_confirm\",\n true,\n );\n const textClassName = textVariants({\n size: \"xs\",\n intensity: 54,\n });\n\n // console.log(\"PositionTPSLConfirm\", qty, maxQty, quoteDP);\n\n const isPositionTPSL = _isPositionTPSL ?? qty >= maxQty;\n\n return (\n <>\n {isEditing && (\n <Text\n as=\"div\"\n size=\"2xs\"\n intensity={80}\n className=\"oui-mb-3\"\n >{`You agree to edit your ${transSymbolformString(\n symbol,\n )} order.`}</Text>\n )}\n\n <Flex pb={4}>\n <Box grow>\n <Text.formatted\n rule={\"symbol\"}\n formatString=\"base-type\"\n size=\"base\"\n showIcon\n as=\"div\"\n intensity={80}\n >\n {symbol}\n </Text.formatted>\n </Box>\n <Flex gap={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color={\"primary\"}>\n {t(\"common.position\")}\n </Badge>\n )}\n\n {/* <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge> */}\n <TPSLOrderType tpPrice={tpPrice} slPrice={slPrice} />\n {side === OrderSide.SELL ? (\n <Badge size=\"xs\" color=\"success\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider />\n <Flex\n direction={\"column\"}\n itemAlign={\"stretch\"}\n gapY={1}\n pt={4}\n // pb={5}\n className={cn(textClassName, \"oui-pb-4 xl:oui-pb-5\")}\n >\n <Flex>\n <Box grow>{t(\"common.qty\")}</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">\n {t(\"tpsl.entirePosition\")}\n </span>\n ) : (\n <Text.numeral intensity={98} dp={baseDP} padding={false}>\n {qty}\n </Text.numeral>\n )}\n </div>\n </Flex>\n {typeof tpPrice === \"number\" && tpPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.tpPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {tpPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n {typeof slPrice === \"number\" && slPrice > 0 ? (\n <Flex>\n <Box grow>{t(\"tpsl.slPrice\")}</Box>\n <Text.numeral\n as={\"div\"}\n coloring\n unit={\"USDC\"}\n size={\"sm\"}\n dp={quoteDP}\n className=\"oui-text-trade-loss\"\n unitClassName={\"oui-text-base-contrast-54 oui-ml-1\"}\n >\n {slPrice}\n </Text.numeral>\n </Flex>\n ) : null}\n\n <Flex>\n <Box grow>{t(\"common.price\")}</Box>\n <div className=\"oui-text-base-contrast\">\n {t(\"common.marketPrice\")}\n </div>\n </Flex>\n </Flex>\n <Box pt={2}>\n <Flex gap={1}>\n <Checkbox\n id=\"disabledConfirm\"\n color=\"white\"\n checked={!needConfirm}\n onCheckedChange={(check) => {\n setNeedConfirm(!check);\n }}\n />\n <label\n htmlFor=\"disabledConfirm\"\n className={textVariants({\n size: \"xs\",\n intensity: 54,\n className: \"oui-ml-1\",\n })}\n >\n {t(\"orderEntry.disableOrderConfirm\")}\n </label>\n </Flex>\n </Box>\n </>\n );\n};\n\n//------------- Position TP/SL Confirm dialog end------------\n\nconst TPSLOrderType = (props: { tpPrice?: number; slPrice?: number }) => {\n const { tpPrice, slPrice } = props;\n const { t } = useTranslation();\n\n if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.tp\")}\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"tpsl.sl\")}\n </Badge>\n );\n }\n\n return null;\n};\n\nconst MaxQtyButton = (props: {\n onClick: () => void;\n children?: React.ReactNode;\n}) => {\n return (\n <button\n className={\"oui-leading-none\"}\n style={{ lineHeight: 0 }}\n onClick={props.onClick}\n >\n <Text color={\"primary\"} size={\"2xs\"}>\n {props.children}\n </Text>\n </button>\n );\n};\n","import {\n CaretDownIcon,\n cn,\n Input,\n MenuItem,\n SimpleDropdownMenu,\n} from \"@orderly.network/ui\";\nimport { PNLInputState, PnLMode } from \"./useBuilder.script\";\nimport { inputFormatter, Text } from \"@orderly.network/ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\n\nexport type PNLInputProps = PNLInputState & { testId?: string; quote: string };\n\nexport const PNLInput = (props: PNLInputProps) => {\n const {\n mode,\n modes,\n onModeChange,\n onValueChange,\n quote,\n quote_dp,\n value,\n pnl,\n } = props;\n const { t } = useTranslation();\n\n const [prefix, setPrefix] = useState<string>(mode);\n const [placeholder, setPlaceholder] = useState<string>(\n mode === PnLMode.PERCENTAGE ? \"%\" : quote\n );\n\n const color = useMemo(() => {\n const num = Number(pnl);\n\n if (isNaN(num) || num === 0) return \"\";\n\n if (num > 0) return \"oui-text-trade-profit\";\n if (num < 0) return \"oui-text-trade-loss\";\n }, [pnl]);\n\n useEffect(() => {\n const label = modes.find((item) => item.value === mode)?.label;\n setPrefix(label!);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode, modes]);\n\n return (\n <Input\n prefix={prefix}\n size={{\n initial: \"lg\",\n lg: \"md\",\n }}\n placeholder={placeholder}\n align={\"right\"}\n value={value}\n data-testid={props.testId}\n autoComplete={\"off\"}\n onValueChange={onValueChange}\n formatters={[\n // inputFormatter.numberFormatter,\n props.formatter({ dp: quote_dp, mode }),\n inputFormatter.currencyFormatter,\n inputFormatter.decimalPointFormatter,\n ]}\n // className={color}\n classNames={{\n input: color,\n prefix: \"oui-text-base-contrast-54\",\n root: \"oui-outline-line-12 focus-within:oui-outline-primary-light\",\n }}\n onFocus={() => {\n setPlaceholder(\"\");\n props.setFocus(true);\n }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n props.setFocus(false);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text\n size={\"2xs\"}\n color=\"inherit\"\n className={cn(\"oui-ml-[2px]\", color)}\n >\n %\n </Text>\n )}\n <PNLMenus\n mode={mode}\n modes={modes}\n onModeChange={(item) => onModeChange(item.value as PnLMode)}\n />\n </>\n }\n />\n );\n};\n\nconst PNLMenus = (props: {\n mode?: string;\n modes: MenuItem[];\n onModeChange: (value: MenuItem) => void;\n}) => {\n return (\n <SimpleDropdownMenu\n currentValue={props.mode}\n menu={props.modes}\n align={\"end\"}\n size={\"xs\"}\n className={\"oui-min-w-[80px]\"}\n onSelect={(item) => props.onModeChange(item as MenuItem)}\n >\n <button className={\"oui-p-2\"}>\n <CaretDownIcon size={12} color={\"white\"} />\n </button>\n </SimpleDropdownMenu>\n );\n};\n","import { useMemo, useRef, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { MenuItem } from \"@orderly.network/ui\";\nimport type {\n InputFormatter,\n InputFormatterOptions,\n} from \"@orderly.network/ui\";\nimport { Decimal, todpIfNeed } from \"@orderly.network/utils\";\n\nexport enum PnLMode {\n PnL = \"PnL\",\n OFFSET = \"Offset\",\n PERCENTAGE = \"Offset%\",\n}\n\nexport type PNL_Values = {\n PnL: string;\n Offset: string;\n \"Offset%\": string;\n};\n\nexport type BuilderProps = {\n type: \"TP\" | \"SL\";\n\n quote_dp?: number;\n onChange: (key: string, value: number | string) => void;\n\n values: PNL_Values;\n};\n\nexport const usePNLInputBuilder = (props: BuilderProps) => {\n const { type, values } = props;\n const [mode, setMode] = useLocalStorage<PnLMode>(\n \"TP/SL_Mode\",\n PnLMode.PERCENTAGE,\n );\n const [focus, setFocus] = useState(true);\n\n const { t } = useTranslation();\n\n const key = useMemo(() => {\n switch (mode) {\n case PnLMode.OFFSET:\n return `${type.toLowerCase()}_offset`;\n case PnLMode.PERCENTAGE:\n return `${type.toLowerCase()}_offset_percentage`;\n default:\n return `${type.toLowerCase()}_pnl`;\n }\n }, [mode]);\n\n const value = useMemo(() => {\n return values[mode as keyof PNL_Values];\n }, [values, mode]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n {\n label: t(\"tpsl.pnl\"),\n value: PnLMode.PnL,\n testId: `${PnLMode.PnL}_menu_item`,\n },\n {\n label: t(\"tpsl.offset\"),\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: `${t(\"tpsl.offset\")}%`,\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, [t]);\n\n const percentageSuffix = useRef<string>(\"\");\n\n const onValueChange = (value: string) => {\n props.onChange(key, value);\n };\n\n const formatter = (options: {\n dp?: number;\n mode: PnLMode;\n }): InputFormatter => {\n const { dp = 2 } = options;\n return {\n onRenderBefore: (\n value: string | number,\n options: InputFormatterOptions,\n ) => {\n value = `${value}`; // convert to string\n\n if (focus) {\n if (type === \"SL\" && mode === PnLMode.PnL) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n }\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n // if (mode === PnLMode.PnL || mode === PnLMode.OFFSET) {\n // return commify(value);\n // }\n\n if (mode === PnLMode.PERCENTAGE) {\n return `${new Decimal(\n value.replace(\n new RegExp(percentageSuffix.current.replace(\".\", \"\\\\.\") + \"$\"),\n \"\",\n ),\n )\n .mul(100)\n .todp(2, 4)\n .toString()}${percentageSuffix.current}`;\n } else if (mode === PnLMode.OFFSET) {\n value = todpIfNeed(value, dp);\n } else {\n // value = new Decimal(value).todp(2).toString();\n }\n\n return `${value}`;\n },\n onSendBefore: (value: string) => {\n if (/^\\-?0{2,}$/.test(value)) {\n return \"0\";\n }\n\n if (mode === PnLMode.PERCENTAGE) {\n // console.log(\"value\", value);\n if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n value = todpIfNeed(value, 2);\n const endStr = value.match(/\\.0{0,2}$/);\n if (!!endStr) {\n percentageSuffix.current = endStr[0];\n } else {\n percentageSuffix.current = \"\";\n }\n value = new Decimal(value).div(100).toString();\n value = `${value}${percentageSuffix.current}`;\n }\n } else if (mode === PnLMode.PnL && type === \"SL\" && focus) {\n value = value.startsWith(\"-\") ? value : \"-\" + value;\n } else {\n value = todpIfNeed(value, dp);\n }\n\n if (value === \"\" || value === \"-\") return \"\";\n\n return value;\n },\n };\n // return {\n // onRenderBefore: (\n // value: string | number,\n // options: InputFormatterOptions\n // ) => {\n // // console.log(\"???\", options);\n // const { isFocused } = options;\n // value = `${value}`;\n // if (value === \"\" || value === \"-\") return \"\";\n\n // // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (isFocused) {\n // // value = value.startsWith(\"-\") ? value : \"-\" + value;\n // // }\n // // }\n\n // if (mode === PnLMode.PERCENTAGE) {\n // return `${todpIfNeed(new Decimal(value).mul(100).toString(), 2)}${\n // percentageSuffix.current\n // }`;\n // // return (Number(value) * 100).toFixed(2);\n // } else if (mode === PnLMode.OFFSET) {\n // value = todpIfNeed(value, 2);\n // } else {\n // // value = new Decimal(value).todp(2).toString();\n // }\n\n // return value;\n // },\n // onSendBefore: (value: string, options: InputFormatterOptions) => {\n // const { isFocused } = options;\n\n // if (mode === PnLMode.PERCENTAGE) {\n // if (value !== \"\") {\n // percentageSuffix.current = value.endsWith(\".\") ? \".\" : \"\";\n // value = new Decimal(value).div(100).toString();\n // value = todpIfNeed(value, 4);\n // }\n // } else {\n // // value = todpIfNeed(value, quote_dp);\n // if (isFocused) {\n // if (type === \"SL\" && mode === PnLMode.PnL) {\n // // if (\n // // typeof values[PnLMode.PnL] !== \"undefined\" &&\n // // values[PnLMode.PnL] !== \"\"\n // // )\n // // return value;\n // const num = Number(value);\n // if (!isNaN(num) && num !== 0) {\n // value = (Math.abs(num) * -1).toString();\n // } else {\n // value = \"\";\n // }\n // }\n // }\n // }\n\n // return value;\n // },\n // };\n };\n\n return {\n mode,\n modes,\n type: props.type,\n formatter,\n onModeChange: (mode: PnLMode) => {\n setMode(mode);\n },\n value,\n pnl: values[PnLMode.PnL],\n onValueChange,\n quote_dp: props.quote_dp,\n setFocus,\n };\n};\n\nexport type PNLInputState = ReturnType<typeof usePNLInputBuilder>;\n","import { PNLInput } from \"./pnlInput.ui\";\nimport { BuilderProps, usePNLInputBuilder } from \"./useBuilder.script\";\n\nexport const PnlInputWidget = (\n props: BuilderProps & {\n testId?: string;\n quote: string;\n }\n) => {\n const { testId, quote, ...rest } = props;\n const state = usePNLInputBuilder(rest);\n return <PNLInput {...state} testId={testId} quote={quote} />;\n};\n","import { useEffect, useMemo, useRef } from \"react\";\nimport {\n type ComputedAlgoOrder,\n useLocalStorage,\n useSymbolsInfo,\n useTPSLOrder,\n utils,\n} from \"@orderly.network/hooks\";\nimport { SDKError } from \"@orderly.network/types\";\nimport { AlgoOrderRootType, AlgoOrderType, API } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\n\nexport type TPSLBuilderOptions = {\n position: API.Position;\n order?: API.AlgoOrder;\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n isEditing?: boolean;\n /**\n * either show the confirm dialog or not,\n * if the Promise reject or return false, cancel the submit action\n */\n onConfirm?: (\n order: ComputedAlgoOrder,\n options: {\n position: API.Position;\n submit: (params?: { accountId?: string }) => Promise<any>;\n cancel: () => Promise<any>;\n },\n ) => Promise<boolean>;\n};\n\nexport const useTPSLBuilder = (options: TPSLBuilderOptions) => {\n const { position, order, isEditing } = options;\n // const isEditing = !!order;\n if (isEditing && !order) {\n throw new SDKError(\"order is required when isEditing is true\");\n }\n const symbol = isEditing ? order!.symbol : position.symbol;\n const symbolInfo = useSymbolsInfo();\n const prevTPSLType = useRef<AlgoOrderRootType>(AlgoOrderRootType.TP_SL);\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const [\n tpslOrder,\n {\n submit,\n deleteOrder,\n setValue,\n validate,\n errors,\n isCreateMutating,\n isUpdateMutating,\n },\n ] = useTPSLOrder(\n {\n symbol,\n position_qty: position.position_qty,\n average_open_price: position.average_open_price,\n },\n {\n defaultOrder: order,\n isEditing,\n },\n );\n\n const setQuantity = (value: number | string) => {\n setValue(\"quantity\", value);\n };\n\n const setOrderPrice = (\n name: \"tp_trigger_price\" | \"sl_trigger_price\",\n value: number | string,\n ) => {\n setValue(name, value);\n };\n\n const setPnL = (type: string, value: number | string) => {\n setValue(type, value);\n };\n\n const maxQty = useMemo(\n () => Math.abs(Number(position.position_qty)),\n [position.position_qty],\n );\n\n const dirty = useMemo(() => {\n const quantity =\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n ? maxQty\n : order?.quantity;\n\n let diff: number = 0;\n\n if (Number(tpslOrder.quantity) !== quantity) {\n diff = 1;\n } else if (!isEditing && !!tpslOrder.quantity) {\n diff = 1;\n }\n\n if (order && isEditing) {\n const tp = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.TAKE_PROFIT,\n );\n const sl = order.child_orders.find(\n (o) => o.algo_type === AlgoOrderType.STOP_LOSS,\n );\n\n if (\n tp?.trigger_price !== Number(tpslOrder.tp_trigger_price) &&\n typeof typeof tpslOrder.tp_trigger_price !== \"undefined\"\n ) {\n // return true;\n diff = 2;\n }\n\n if (\n sl?.trigger_price !== Number(tpslOrder.sl_trigger_price) &&\n typeof tpslOrder.sl_trigger_price !== \"undefined\"\n ) {\n diff = 3;\n }\n }\n\n if (\n diff === 1 &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n diff = -1;\n }\n\n return diff;\n }, [\n tpslOrder.tp_trigger_price,\n tpslOrder.sl_trigger_price,\n tpslOrder.quantity,\n order,\n isEditing,\n ]);\n\n const valid = useMemo(() => {\n /**\n * if the order is a POSITIONAL_TP_SL and the quantity is less than the maxQty,\n * and the tp/sl trigger price is not set, then the order is not valid\n */\n if (\n order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n Number(tpslOrder.quantity) < maxQty &&\n !tpslOrder.tp_trigger_price &&\n !tpslOrder.sl_trigger_price\n ) {\n return false;\n }\n\n return dirty > 0 && !!tpslOrder.quantity && !errors;\n }, [tpslOrder.quantity, maxQty, dirty, errors]);\n\n const isPositionTPSL = useMemo(() => {\n if (!isEditing) return Number(tpslOrder.quantity) >= maxQty;\n /**\n * if current order is not a POSITIONAL_TP_SL, then it's always a general TP/SL\n */\n if (!!order && order.algo_type !== AlgoOrderRootType.POSITIONAL_TP_SL) {\n return false;\n }\n if (tpslOrder.algo_order_id && tpslOrder.quantity == 0) return true;\n return Number(tpslOrder.quantity) >= maxQty;\n }, [tpslOrder.quantity, maxQty, order?.algo_type, isEditing]);\n\n useEffect(() => {\n if (!isEditing && isPositionTPSL) {\n const trigger_prices = utils.findTPSLFromOrder(order!);\n if (!tpslOrder.tp_trigger_price && trigger_prices.tp_trigger_price) {\n setOrderPrice(\"tp_trigger_price\", trigger_prices.tp_trigger_price);\n }\n if (!tpslOrder.sl_trigger_price && trigger_prices.sl_trigger_price) {\n setOrderPrice(\"sl_trigger_price\", trigger_prices.sl_trigger_price);\n }\n }\n }, [isEditing, isPositionTPSL, tpslOrder]);\n\n useEffect(() => {\n const type =\n Number(tpslOrder.quantity) < maxQty\n ? AlgoOrderRootType.TP_SL\n : AlgoOrderRootType.POSITIONAL_TP_SL;\n if (\n typeof options.onTPSLTypeChange === \"function\" &&\n prevTPSLType.current !== type\n ) {\n options.onTPSLTypeChange(type);\n }\n\n prevTPSLType.current = type;\n }, [tpslOrder.quantity, maxQty]);\n\n const cancel = (): Promise<void> => {\n if (order?.algo_order_id && order?.symbol) {\n return deleteOrder(order?.algo_order_id, order?.symbol);\n }\n return Promise.reject(\"order id or symbol is invalid\");\n };\n\n const onSubmit = async () => {\n if (typeof options.onConfirm !== \"function\" || !needConfirm) {\n return submit({ accountId: position.account_id })\n .then(() => true)\n .catch((err) => {\n if (err?.message) {\n toast.error(err.message);\n }\n throw false;\n });\n }\n\n return options.onConfirm(tpslOrder, {\n position,\n submit,\n cancel,\n });\n };\n\n return {\n isEditing,\n symbolInfo: symbolInfo[symbol],\n maxQty,\n setQuantity,\n orderQuantity: tpslOrder.quantity,\n isPosition: isPositionTPSL,\n\n TPSL_OrderEntity: tpslOrder,\n setOrderValue: setValue,\n setPnL,\n setOrderPrice,\n // needConfirm,\n onSubmit,\n valid,\n errors,\n status: {\n isCreateMutating,\n isUpdateMutating,\n },\n } as const;\n};\n\nexport type TPSLBuilderState = ReturnType<typeof useTPSLBuilder>;\n","import { type AlgoOrderRootType } from \"@orderly.network/types\";\nimport { TPSL, TPSLProps } from \"./tpsl.ui\";\nimport { TPSLBuilderOptions, useTPSLBuilder } from \"./useTPSL.script\";\n\nexport type TPSLWidgetProps = {\n onTPSLTypeChange?: (type: AlgoOrderRootType) => void;\n} & TPSLBuilderOptions &\n TPSLProps;\n\nexport const TPSLWidget = (props: TPSLWidgetProps) => {\n const { onCancel, onComplete, ...rest } = props;\n const state = useTPSLBuilder(rest);\n\n return <TPSL {...state} onCancel={onCancel} onComplete={onComplete} />;\n};\n","import { ReactNode, useState } from \"react\";\nimport { useLocalStorage } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n toast,\n} from \"@orderly.network/ui\";\nimport { ButtonProps } from \"@orderly.network/ui\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { TPSLWidget } from \"./tpsl.widget\";\n\nexport const PositionTPSLPopover = (props: {\n position: API.Position;\n order?: API.AlgoOrder;\n label?: string;\n baseDP?: number;\n quoteDP?: number;\n /**\n * Button props\n */\n buttonProps?: ButtonProps;\n isEditing?: boolean;\n children?: ReactNode;\n}) => {\n const { position, order, baseDP, quoteDP, buttonProps, isEditing } = props;\n const [open, setOpen] = useState(false);\n const [visible, setVisible] = useState(true);\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n return (\n <PopoverRoot\n onOpenChange={(isOpen) => {\n // console.log(\"isOpen\", isOpen);\n if (visible) {\n setOpen(isOpen);\n }\n }}\n open={open}\n >\n <PopoverTrigger\n asChild\n onClick={() => {\n setOpen(true);\n }}\n >\n {props.children || (\n <Button\n variant=\"outlined\"\n size=\"sm\"\n color=\"secondary\"\n {...buttonProps}\n // onClick={() => {\n // setOpen(true);\n // }}\n >\n {props.label}\n </Button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"oui-w-[360px]\",\n visible ? \"oui-visible\" : \"oui-invisible\",\n )}\n align=\"end\"\n side={\"top\"}\n >\n <TPSLWidget\n position={position}\n order={order}\n isEditing={isEditing}\n onComplete={() => {\n // console.log(\"tpsl order completed\");\n setOpen(false);\n }}\n onCancel={() => {\n setOpen(false);\n }}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n setVisible(false);\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n // console.log(\n // \"order\",\n // order,\n // isEditing ||\n // (!!order &&\n // order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n // order.quantity === maxQty)\n // );\n\n if (\n `${order.tp_trigger_price ?? \"\"}`.length === 0 &&\n `${order.sl_trigger_price ?? \"\"}`.length === 0\n ) {\n return modal\n .confirm({\n title: t(\"orders.cancelOrder\"),\n content: t(\"tpsl.cancelOrder.description\"),\n onOk: () => {\n return options.cancel();\n },\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n },\n );\n }\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n // bodyClassName: \"lg:oui-py-0\",\n onOk: async () => {\n try {\n const res = await options.submit({\n accountId: position.account_id,\n });\n\n if (res.success) {\n return res;\n }\n\n if (res.message) {\n toast.error(res.message);\n }\n\n return false;\n } catch (err: any) {\n if (err?.message) {\n toast.error(err.message);\n }\n return false;\n }\n },\n classNames: {\n body: \"!oui-pb-0\",\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={finalIsEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quoteDP ?? 2}\n baseDP={baseDP ?? 2}\n />\n ),\n })\n .then(\n () => {\n setOpen(false);\n setVisible(true);\n return true;\n },\n () => {\n setVisible(true);\n return Promise.reject(false);\n },\n );\n }}\n />\n </PopoverContent>\n </PopoverRoot>\n );\n};\n","import { useMemo } from \"react\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n Flex,\n modal,\n useModal,\n Text,\n Box,\n Badge,\n Divider,\n toast,\n} from \"@orderly.network/ui\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { TPSLWidget, TPSLWidgetProps } from \"./tpsl.widget\";\n\ntype TPSLSheetProps = {\n position: API.Position;\n order?: API.AlgoOrder;\n // label: string;\n // baseDP?: number;\n // quoteDP?: number;\n symbolInfo: API.SymbolExt;\n isEditing?: boolean;\n};\n\nexport const PositionTPSLSheet = (props: TPSLWidgetProps & TPSLSheetProps) => {\n const { position, order, symbolInfo, isEditing } = props;\n const { resolve, hide, updateArgs } = useModal();\n\n const [needConfirm] = useLocalStorage(\"orderly_order_confirm\", true);\n const { t } = useTranslation();\n\n const isPositionTPSL = isEditing\n ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL\n : undefined;\n\n const updateSheetTitle = (title: string) => {\n if (isEditing) return;\n updateArgs({ title });\n };\n\n const onCompleted = () => {\n resolve();\n hide();\n };\n\n const { quote_dp, base_dp } = symbolInfo;\n\n return (\n <>\n <PositionInfo position={position} symbolInfo={symbolInfo} />\n\n <TPSLWidget\n {...props}\n onTPSLTypeChange={(type) => {\n updateSheetTitle(\n type === AlgoOrderRootType.TP_SL\n ? t(\"common.tpsl\")\n : t(\"tpsl.positionTpsl\"),\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n const maxQty = Math.abs(Number(position.position_qty));\n\n const finalIsEditing =\n isEditing ||\n (!!order &&\n order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL &&\n order.quantity === maxQty);\n\n return modal\n .confirm({\n title: finalIsEditing\n ? t(\"orders.editOrder\")\n : t(\"tpsl.confirmOrder\"),\n bodyClassName: \"oui-pb-0 lg:oui-pb-0\",\n onOk: async () => {\n try {\n const res = await options.submit({\n accountId: position.account_id,\n });\n\n if (res.success) {\n return res;\n }\n\n if (res.message) {\n toast.error(res.message);\n }\n\n return false;\n } catch (err: any) {\n if (err?.message) {\n toast.error(err.message);\n }\n return false;\n }\n },\n content: (\n <PositionTPSLConfirm\n isPositionTPSL={isPositionTPSL}\n isEditing={isEditing}\n symbol={order.symbol!}\n qty={Number(order.quantity)}\n maxQty={maxQty}\n tpPrice={Number(order.tp_trigger_price)}\n slPrice={Number(order.sl_trigger_price)}\n side={order.side!}\n quoteDP={quote_dp ?? 2}\n baseDP={base_dp ?? 2}\n />\n ),\n })\n .then(\n () => {\n // setOpen(false);\n // setVisible(true);\n return true;\n },\n (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n\n // setVisible(true);\n return Promise.reject(false);\n },\n );\n }}\n onCancel={() => {\n hide();\n }}\n />\n </>\n );\n};\n\nexport const TPSLSheetTitle = () => {\n const modal = useModal();\n const { t } = useTranslation();\n\n const title = useMemo<string>(() => {\n return (modal.args?.title || t(\"common.tpsl\")) as string;\n }, [modal.args?.title, t]);\n\n return <span>{title}</span>;\n};\n\nexport const PositionInfo = (props: {\n position: API.Position;\n symbolInfo: API.SymbolExt;\n}) => {\n const { position, symbolInfo } = props;\n const { data: markPrice } = useMarkPrice(position.symbol);\n const modal = useModal();\n const { t } = useTranslation();\n\n const isPositionTPSL = useMemo(() => {\n return modal.args?.title === t(\"tpsl.positionTpsl\");\n }, [modal.args?.title, t]);\n return (\n <>\n <Flex justify={\"between\"} pb={3} itemAlign={\"center\"}>\n <Text.formatted rule=\"symbol\" className=\"oui-text-xs\" showIcon>\n {position.symbol}\n </Text.formatted>\n <Flex gapX={1}>\n {isPositionTPSL && (\n <Badge size=\"xs\" color=\"primary\">\n {t(\"common.position\")}\n </Badge>\n )}\n <Badge size=\"xs\" color=\"neutral\">\n {t(\"common.tpsl\")}\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n {t(\"common.buy\")}\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n {t(\"common.sell\")}\n </Badge>\n )}\n </Flex>\n </Flex>\n <Divider intensity={8} />\n <Box py={3} className=\"oui-space-y-1\">\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.avgOpen\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {position.average_open_price}\n </Text.numeral>\n </Flex>\n <Flex justify={\"between\"}>\n <Text size=\"sm\" intensity={54}>\n {t(\"common.markPrice\")}\n </Text>\n <Text.numeral\n className=\"oui-text-xs\"\n unit={symbolInfo.quote}\n dp={symbolInfo.quote_dp}\n unitClassName=\"oui-ml-1 oui-text-base-contrast-36\"\n >\n {markPrice}\n </Text.numeral>\n </Flex>\n </Box>\n </>\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orderly.network/ui-tpsl",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@orderly.network/
|
|
21
|
-
"@orderly.network/
|
|
22
|
-
"@orderly.network/hooks": "2.
|
|
23
|
-
"@orderly.network/
|
|
24
|
-
"@orderly.network/
|
|
25
|
-
"@orderly.network/react-app": "2.
|
|
20
|
+
"@orderly.network/ui": "2.3.0",
|
|
21
|
+
"@orderly.network/i18n": "2.3.0",
|
|
22
|
+
"@orderly.network/hooks": "2.3.0",
|
|
23
|
+
"@orderly.network/utils": "2.3.0",
|
|
24
|
+
"@orderly.network/types": "2.3.0",
|
|
25
|
+
"@orderly.network/react-app": "2.3.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/react": "^18.3.2",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"tailwindcss": "^3.4.4",
|
|
33
33
|
"tsup": "^7.1.0",
|
|
34
34
|
"typescript": "^5.1.6",
|
|
35
|
-
"tsconfig": "0.
|
|
35
|
+
"tsconfig": "0.6.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsup && pnpm run build:css",
|