@orderly.network/ui-tpsl 2.0.1-alpha.1
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 +66 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +0 -0
- package/package.json +40 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { API, AlgoOrderRootType, OrderSide } from '@orderly.network/types';
|
|
3
|
+
import { ComputedAlgoOrder } from '@orderly.network/hooks';
|
|
4
|
+
import { ButtonProps } from '@orderly.network/ui';
|
|
5
|
+
|
|
6
|
+
type TPSLBuilderOptions = {
|
|
7
|
+
position: API.Position;
|
|
8
|
+
order?: API.AlgoOrder;
|
|
9
|
+
onTPSLTypeChange?: (type: AlgoOrderRootType) => void;
|
|
10
|
+
isEditing?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* either show the confirm dialog or not,
|
|
13
|
+
* if the Promise reject or return false, cancel the submit action
|
|
14
|
+
*/
|
|
15
|
+
onConfirm?: (order: ComputedAlgoOrder, options: {
|
|
16
|
+
position: API.Position;
|
|
17
|
+
submit: () => Promise<any>;
|
|
18
|
+
cancel: () => Promise<any>;
|
|
19
|
+
}) => Promise<boolean>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type TPSLProps = {
|
|
23
|
+
onCancel?: () => void;
|
|
24
|
+
onComplete?: () => void;
|
|
25
|
+
};
|
|
26
|
+
type PositionTPSLConfirmProps = {
|
|
27
|
+
symbol: string;
|
|
28
|
+
qty: number;
|
|
29
|
+
tpPrice?: number;
|
|
30
|
+
slPrice?: number;
|
|
31
|
+
maxQty: number;
|
|
32
|
+
side: OrderSide;
|
|
33
|
+
baseDP: number;
|
|
34
|
+
quoteDP: number;
|
|
35
|
+
isEditing?: boolean;
|
|
36
|
+
isPositionTPSL?: boolean;
|
|
37
|
+
};
|
|
38
|
+
declare const PositionTPSLConfirm: (props: PositionTPSLConfirmProps) => react_jsx_runtime.JSX.Element;
|
|
39
|
+
|
|
40
|
+
type TPSLWidgetProps = {
|
|
41
|
+
onTPSLTypeChange?: (type: AlgoOrderRootType) => void;
|
|
42
|
+
} & TPSLBuilderOptions & TPSLProps;
|
|
43
|
+
declare const TPSLWidget: (props: TPSLWidgetProps) => react_jsx_runtime.JSX.Element;
|
|
44
|
+
|
|
45
|
+
declare const PositionTPSLPopover: (props: {
|
|
46
|
+
position: API.Position;
|
|
47
|
+
order?: API.AlgoOrder;
|
|
48
|
+
label: string;
|
|
49
|
+
baseDP?: number;
|
|
50
|
+
quoteDP?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Button props
|
|
53
|
+
*/
|
|
54
|
+
buttonProps?: ButtonProps;
|
|
55
|
+
isEditing?: boolean;
|
|
56
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
type TPSLSheetProps = {
|
|
59
|
+
position: API.Position;
|
|
60
|
+
order?: API.AlgoOrder;
|
|
61
|
+
symbolInfo: API.SymbolExt;
|
|
62
|
+
isEditing?: boolean;
|
|
63
|
+
};
|
|
64
|
+
declare const PositionTPSLSheet: (props: TPSLWidgetProps & TPSLSheetProps) => react_jsx_runtime.JSX.Element;
|
|
65
|
+
|
|
66
|
+
export { PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSLWidget, type TPSLWidgetProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { API, AlgoOrderRootType, OrderSide } from '@orderly.network/types';
|
|
3
|
+
import { ComputedAlgoOrder } from '@orderly.network/hooks';
|
|
4
|
+
import { ButtonProps } from '@orderly.network/ui';
|
|
5
|
+
|
|
6
|
+
type TPSLBuilderOptions = {
|
|
7
|
+
position: API.Position;
|
|
8
|
+
order?: API.AlgoOrder;
|
|
9
|
+
onTPSLTypeChange?: (type: AlgoOrderRootType) => void;
|
|
10
|
+
isEditing?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* either show the confirm dialog or not,
|
|
13
|
+
* if the Promise reject or return false, cancel the submit action
|
|
14
|
+
*/
|
|
15
|
+
onConfirm?: (order: ComputedAlgoOrder, options: {
|
|
16
|
+
position: API.Position;
|
|
17
|
+
submit: () => Promise<any>;
|
|
18
|
+
cancel: () => Promise<any>;
|
|
19
|
+
}) => Promise<boolean>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type TPSLProps = {
|
|
23
|
+
onCancel?: () => void;
|
|
24
|
+
onComplete?: () => void;
|
|
25
|
+
};
|
|
26
|
+
type PositionTPSLConfirmProps = {
|
|
27
|
+
symbol: string;
|
|
28
|
+
qty: number;
|
|
29
|
+
tpPrice?: number;
|
|
30
|
+
slPrice?: number;
|
|
31
|
+
maxQty: number;
|
|
32
|
+
side: OrderSide;
|
|
33
|
+
baseDP: number;
|
|
34
|
+
quoteDP: number;
|
|
35
|
+
isEditing?: boolean;
|
|
36
|
+
isPositionTPSL?: boolean;
|
|
37
|
+
};
|
|
38
|
+
declare const PositionTPSLConfirm: (props: PositionTPSLConfirmProps) => react_jsx_runtime.JSX.Element;
|
|
39
|
+
|
|
40
|
+
type TPSLWidgetProps = {
|
|
41
|
+
onTPSLTypeChange?: (type: AlgoOrderRootType) => void;
|
|
42
|
+
} & TPSLBuilderOptions & TPSLProps;
|
|
43
|
+
declare const TPSLWidget: (props: TPSLWidgetProps) => react_jsx_runtime.JSX.Element;
|
|
44
|
+
|
|
45
|
+
declare const PositionTPSLPopover: (props: {
|
|
46
|
+
position: API.Position;
|
|
47
|
+
order?: API.AlgoOrder;
|
|
48
|
+
label: string;
|
|
49
|
+
baseDP?: number;
|
|
50
|
+
quoteDP?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Button props
|
|
53
|
+
*/
|
|
54
|
+
buttonProps?: ButtonProps;
|
|
55
|
+
isEditing?: boolean;
|
|
56
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
type TPSLSheetProps = {
|
|
59
|
+
position: API.Position;
|
|
60
|
+
order?: API.AlgoOrder;
|
|
61
|
+
symbolInfo: API.SymbolExt;
|
|
62
|
+
isEditing?: boolean;
|
|
63
|
+
};
|
|
64
|
+
declare const PositionTPSLSheet: (props: TPSLWidgetProps & TPSLSheetProps) => react_jsx_runtime.JSX.Element;
|
|
65
|
+
|
|
66
|
+
export { PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSLWidget, type TPSLWidgetProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var ui = require('@orderly.network/ui');
|
|
5
|
+
var hooks = require('@orderly.network/hooks');
|
|
6
|
+
var utils = require('@orderly.network/utils');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
var types = require('@orderly.network/types');
|
|
9
|
+
|
|
10
|
+
var j=e=>{let{type:t,values:o}=e,[s,u]=hooks.useLocalStorage("TP/SL_Mode","Offset%"),c=react.useMemo(()=>{switch(s){case"Offset":return `${t.toLowerCase()}_offset`;case"Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[s]),d=react.useMemo(()=>o[s],[o]),a=react.useMemo(()=>[{label:"PnL",value:"PnL",testId:"PnL_menu_item"},{label:"Offset",value:"Offset",testId:"Offset_mneu_item"},{label:"Offset%",value:"Offset%",testId:"Offset%_menu_item"}],[]),i=react.useRef(""),y=g=>{e.onChange(c,g);},P=g=>{let{dp:_=2}=g;return {onRenderBefore:(n,l)=>(n=`${n}`,n===""||n==="-"?"":s==="Offset%"?`${new utils.Decimal(n.replace(new RegExp(i.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${i.current}`:(s==="Offset"&&(n=utils.todpIfNeed(n,_)),`${n}`)),onSendBefore:n=>{if(/^\-?0{2,}$/.test(n))return "0";if(s==="Offset%"){if(n!==""){n=utils.todpIfNeed(n,2);let l=n.match(/\.0{0,2}$/);l?i.current=l[0]:i.current="",n=new utils.Decimal(n).div(100).toString(),n=`${n}${i.current}`;}}else n=utils.todpIfNeed(n,_);return n===""||n==="-"?"":n}}};return {mode:s,modes:a,type:e.type,formatter:P,onModeChange:g=>{u(g);},value:d,pnl:o.PnL,onValueChange:y,quote_dp:e.quote_dp}};var K=e=>{let{mode:t,modes:o,onModeChange:s,onValueChange:u,quote:c,quote_dp:d,value:a,pnl:i}=e,[y,P]=react.useState(t),[g,_]=react.useState(t==="Offset%"?"%":c),n=react.useMemo(()=>{let l=Number(i);if(isNaN(l)||l===0)return "";if(l>0)return "oui-text-trade-profit";if(l<0)return "oui-text-trade-loss"},[i]);return react.useEffect(()=>{P(t),_(t==="Offset%"?"%":c);},[t]),jsxRuntime.jsx(ui.Input,{prefix:t,size:{initial:"lg",lg:"md"},placeholder:g,align:"right",value:a,"data-testid":e.testId,autoComplete:"off",onValueChange:u,formatters:[e.formatter({dp:d,mode:t}),ui.inputFormatter.currencyFormatter],classNames:{input:n,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{_("");},onBlur:()=>{_(t==="Offset%"?"%":c);},suffix:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t==="Offset%"&&!!a&&jsxRuntime.jsx(ui.Text,{size:"2xs",color:"inherit",className:ui.cn("oui-ml-[2px]",n),children:"%"}),jsxRuntime.jsx(Ie,{mode:t,modes:o,onModeChange:l=>s(l.value)})]})})},Ie=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 V=e=>{let{testId:t,quote:o,...s}=e,u=j(s);return jsxRuntime.jsx(K,{...u,testId:t,quote:o})};var te=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:s,onComplete:u,status:c,errors:d,isPosition:a}=e;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(Ve,{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:a,errorMsg:e.errors?.quantity?.message}),jsxRuntime.jsx(ui.Divider,{my:4,intensity:8})]}),jsxRuntime.jsx(De,{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:d,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:()=>{s?.();},children:"Cancel"}),jsxRuntime.jsx(ui.ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||c.isCreateMutating,loading:c.isCreateMutating||c.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{u?.();},()=>{});},children:"Confirm"})]})]})},Ve=e=>{let{isPosition:t}=e,o=react.useRef(null),s=ui.convertValueToPercentage(e.quantity,0,e.maxQty)/100,u=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},c=a=>{if(e.baseTick>0){e.onQuantityChange?.(hooks.utils.formatNumber(a,e.baseTick)??a);}},d=(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,{ref:o,prefix:"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",d&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:d,color:d?"danger":void 0,formatters:[ui.inputFormatter.dpFormatter(e.dp),ui.inputFormatter.numberFormatter,ui.inputFormatter.currencyFormatter],onValueChange:a=>{e.onQuantityChange?.(a);let i=Number(a);if(i&&i>e.maxQty){let y=t?0:e.maxQty;e.onQuantityChange?.(y),o.current?.blur();}},onBlur:a=>c(a.target.value),suffix:t?jsxRuntime.jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{u();},children:"Entire position"}):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 a=t?0:e.maxQty;e.onQuantityChange?.(a),a===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:"Position"})]}),jsxRuntime.jsx(ui.Flex,{mt:2,itemAlign:"center",height:"15px",children:jsxRuntime.jsx(ui.Slider.single,{markCount:5,color:"primaryLight",max:e.maxQty,min:0,showTip:!0,step:e.baseTick,value:e.quantity,onValueCommit:a=>{c(`${a}`);},onValueChange:a=>{e.onQuantityChange?.(a);}})}),jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text.numeral,{rule:"percentages",color:"primaryLight",size:"2xs",children:s}),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:"primaryLight",size:"2xs",children:"Max"})}),jsxRuntime.jsx(ui.Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},De=e=>{let t=(o,s)=>{e.onPnLChange(o,s);};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:80,children:"Task profit"}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:"Est. PNL:"}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:!0,showIdentifier:!0,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(X,{type:"TP",value:e.tp_trigger_price,error:e.errors?.tp_trigger_price?.message,onValueChange:o=>{e.onPriceChange("tp_trigger_price",o);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(V,{type:"TP",onChange:t,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs(ui.Flex,{justify:"between",children:[jsxRuntime.jsx(ui.Text,{size:"sm",intensity:80,children:"Stop loss"}),jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Text,{size:"2xs",intensity:36,children:"Est. PNL:"}),jsxRuntime.jsx(ui.Text.numeral,{size:"2xs",coloring:!0,showIdentifier:!0,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxRuntime.jsxs(ui.Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsxRuntime.jsx(X,{type:"SL",value:e.sl_trigger_price,error:e.errors?.sl_trigger_price?.message,onValueChange:o=>{e.onPriceChange("sl_trigger_price",o);},quote_dp:e.quote_dp??2}),jsxRuntime.jsx(V,{type:"SL",onChange:t,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},X=e=>{let[t,o]=react.useState("USDC");return jsxRuntime.jsx(ui.Input.tooltip,{prefix:`${e.type} price`,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]})},v=e=>{let{symbol:t,tpPrice:o,slPrice:s,qty:u,maxQty:c,side:d,quoteDP:a,baseDP:i,isEditing:y,isPositionTPSL:P}=e,[g,_]=hooks.useLocalStorage("orderly_order_confirm",!0),n=ui.textVariants({size:"xs",intensity:54}),l=P??u>=c;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[y&&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:!0,children:jsxRuntime.jsx(ui.Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:!0,as:"div",intensity:80,children:t})}),jsxRuntime.jsxs(ui.Flex,{gap:1,children:[l&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primaryLight",children:"Position"}),jsxRuntime.jsx(Ge,{tpPrice:o,slPrice:s}),d===types.OrderSide.SELL?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"success",children:"Buy"}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"danger",children:"Sell"})]})]}),jsxRuntime.jsx(ui.Divider,{}),jsxRuntime.jsxs(ui.Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:ui.cn(n,"oui-pb-4 xl:oui-pb-5"),children:[jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:!0,children:"Qty."}),jsxRuntime.jsx("div",{children:l?jsxRuntime.jsx("span",{className:"oui-text-base-contrast",children:"Entire position"}):jsxRuntime.jsx(ui.Text.numeral,{intensity:98,dp:i,padding:!1,children:u})})]}),typeof o=="number"&&o>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:!0,children:"TP Price"}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:!0,unit:"USDC",size:"sm",dp:a,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof s=="number"&&s>0?jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:!0,children:"SL Price"}),jsxRuntime.jsx(ui.Text.numeral,{as:"div",coloring:!0,unit:"USDC",size:"sm",dp:a,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:s})]}):null,jsxRuntime.jsxs(ui.Flex,{children:[jsxRuntime.jsx(ui.Box,{grow:!0,children:"Price"}),jsxRuntime.jsx("div",{className:"oui-text-base-contrast",children:"Market"})]})]}),jsxRuntime.jsx(ui.Box,{pt:2,children:jsxRuntime.jsxs(ui.Flex,{gap:1,children:[jsxRuntime.jsx(ui.Checkbox,{id:"disabledConfirm",color:"white",checked:!g,onCheckedChange:S=>{_(!S);}}),jsxRuntime.jsx("label",{htmlFor:"disabledConfirm",className:ui.textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:"Disable order confirmation"})]})})]})},Ge=e=>{let{tpPrice:t,slPrice:o}=e;return t&&o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:"TP/SL"}):t?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:"TP"}):o?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:"SL"}):null};var re=e=>{let{position:t,order:o,isEditing:s}=e;if(s&&!o)throw new types.SDKError("order is required when isEditing is true");let u=s?o.symbol:t.symbol,c=hooks.useSymbolsInfo(),d=react.useRef(types.AlgoOrderRootType.TP_SL),[a]=hooks.useLocalStorage("orderly_order_confirm",!0),[i,{submit:y,deleteOrder:P,setValue:g,validate:_,errors:n,isCreateMutating:l,isUpdateMutating:S}]=hooks.useTPSLOrder({symbol:u,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:s}),C=f=>{g("quantity",f);},me=(f,T)=>{g(f,T);},ce=(f,T)=>{g(f,T);},L=react.useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),W=react.useMemo(()=>{let f=o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL?L:o?.quantity,T=0;if((Number(i.quantity)!==f||!s&&i.quantity)&&(T=1),o&&s){let fe=o.child_orders.find(k=>k.algo_type===types.AlgoOrderType.TAKE_PROFIT),ye=o.child_orders.find(k=>k.algo_type===types.AlgoOrderType.STOP_LOSS);fe?.trigger_price!==Number(i.tp_trigger_price)&&typeof typeof i.tp_trigger_price<"u"&&(T=2),ye?.trigger_price!==Number(i.sl_trigger_price)&&typeof i.sl_trigger_price<"u"&&(T=3);}return T===1&&!i.tp_trigger_price&&!i.sl_trigger_price&&(T=-1),T},[i.tp_trigger_price,i.sl_trigger_price,i.quantity,o,s]),de=react.useMemo(()=>o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&Number(i.quantity)<L&&!i.tp_trigger_price&&!i.sl_trigger_price?!1:W>0&&!!i.quantity&&!n,[i.quantity,L,W,n]),ge=react.useMemo(()=>s?o&&o.algo_type!==types.AlgoOrderRootType.POSITIONAL_TP_SL?!1:i.algo_order_id&&i.quantity==0?!0:Number(i.quantity)>=L:Number(i.quantity)>=L,[i.quantity,L,o?.algo_type,s]);react.useEffect(()=>{let f=Number(i.quantity)<L?types.AlgoOrderRootType.TP_SL:types.AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&d.current!==f&&e.onTPSLTypeChange(f),d.current=f;},[i.quantity,L]);let pe=()=>o?.algo_order_id&&o?.symbol?P(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),Pe=async()=>Promise.resolve().then(()=>typeof e.onConfirm!="function"||!a?y().then(()=>!0,f=>(f?.message&&ui.toast.error(f.message),Promise.reject(!1))):e.onConfirm(i,{position:t,submit:y,cancel:pe})).then(f=>{});return {isEditing:s,symbolInfo:c[u],maxQty:L,setQuantity:C,orderQuantity:i.quantity,isPosition:ge,TPSL_OrderEntity:i,setOrderValue:g,setPnL:ce,setOrderPrice:me,onSubmit:Pe,valid:de,errors:n,status:{isCreateMutating:l,isUpdateMutating:S}}};var B=e=>{let{onCancel:t,onComplete:o,...s}=e,u=re(s);return jsxRuntime.jsx(te,{...u,onCancel:t,onComplete:o})};var nt=e=>{let{position:t,order:o,baseDP:s,quoteDP:u,buttonProps:c,isEditing:d}=e,[a,i]=react.useState(!1),[y,P]=react.useState(!0),[g]=hooks.useLocalStorage("orderly_order_confirm",!0),_=d?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxRuntime.jsxs(ui.PopoverRoot,{onOpenChange:n=>{y&&i(n);},open:a,children:[jsxRuntime.jsx(ui.PopoverTrigger,{asChild:!0,children:jsxRuntime.jsx(ui.Button,{variant:"outlined",size:"sm",color:"secondary",...c,onClick:()=>{i(!0);},children:e.label})}),jsxRuntime.jsx(ui.PopoverContent,{className:ui.cn("oui-w-[360px]",y?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsxRuntime.jsx(B,{position:t,order:o,isEditing:d,onComplete:()=>{i(!1);},onCancel:()=>{i(!1);},onConfirm:(n,l)=>{if(!g)return Promise.resolve(!0);P(!1);let S=Math.abs(Number(t.position_qty));if(`${n.tp_trigger_price??""}`.length===0&&`${n.sl_trigger_price??""}`.length===0)return ui.modal.confirm({title:"Cancel Order",content:"Are you sure you want to cancel this TP/SL order?",onOk:()=>l.cancel()}).then(()=>(i(!1),P(!0),!0),()=>(P(!0),Promise.reject(!1)));let C=d||!!n&&n.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL&&n.quantity===S;return ui.modal.confirm({title:C?"Edit Order":"Confirm Order",onOk:()=>l.submit(),classNames:{body:"!oui-pb-0"},content:jsxRuntime.jsx(v,{isPositionTPSL:_,isEditing:C,symbol:n.symbol,qty:Number(n.quantity),maxQty:S,tpPrice:Number(n.tp_trigger_price),slPrice:Number(n.sl_trigger_price),side:n.side,quoteDP:u??2,baseDP:s??2})}).then(()=>(i(!1),P(!0),!0),()=>(P(!0),Promise.reject(!1)))}})})]})};var pt=e=>{let{position:t,order:o,symbolInfo:s,isEditing:u}=e,{resolve:c,hide:d,updateArgs:a}=ui.useModal(),[i]=hooks.useLocalStorage("orderly_order_confirm",!0),y=u?o?.algo_type===types.AlgoOrderRootType.POSITIONAL_TP_SL:void 0,P=l=>{u||a({title:l});},g=()=>{c(),d();},{quote_dp:_,base_dp:n}=s;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Pt,{position:t,symbolInfo:s}),jsxRuntime.jsx(B,{...e,onTPSLTypeChange:l=>{P(l===types.AlgoOrderRootType.TP_SL?"TP/SL":"Position TP/SL");},onComplete:g,onConfirm:(l,S)=>i?ui.modal.confirm({title:u?"Edit Order":"Confirm Order",bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:()=>S.submit(),content:jsxRuntime.jsx(v,{isPositionTPSL:y,isEditing:u,symbol:l.symbol,qty:Number(l.quantity),maxQty:Math.abs(Number(t.position_qty)),tpPrice:Number(l.tp_trigger_price),slPrice:Number(l.sl_trigger_price),side:l.side,quoteDP:_??2,baseDP:n??2})}).then(()=>!0,C=>(C?.message&&ui.toast.error(C.message),Promise.reject(!1))):Promise.resolve(!0),onCancel:()=>{d();}})]})};var Pt=e=>{let{position:t,symbolInfo:o}=e,{data:s}=hooks.useMarkPrice(t.symbol),u=ui.useModal(),c=react.useMemo(()=>u.args?.title==="Position TP/SL",[u.args?.title]);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:!0,children:t.symbol}),jsxRuntime.jsxs(ui.Flex,{gapX:1,children:[c&&jsxRuntime.jsx(ui.Badge,{size:"xs",color:"primaryLight",children:"Position"}),jsxRuntime.jsx(ui.Badge,{size:"xs",color:"neutral",children:"TP/SL"}),t.position_qty<0?jsxRuntime.jsx(ui.Badge,{size:"xs",color:"buy",children:"Buy"}):jsxRuntime.jsx(ui.Badge,{size:"xs",color:"sell",children:"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:"Avg. open"}),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:"Mark price"}),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:s})]})]})]})};
|
|
11
|
+
|
|
12
|
+
exports.PositionTPSLConfirm = v;
|
|
13
|
+
exports.PositionTPSLPopover = nt;
|
|
14
|
+
exports.PositionTPSLSheet = pt;
|
|
15
|
+
exports.TPSLWidget = B;
|
|
16
|
+
//# sourceMappingURL=out.js.map
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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","usePNLInputBuilder","props","type","values","mode","setMode","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","PNLMenus","item","PnlInputWidget","testId","rest","state","utils","OrderSide","transSymbolformString","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","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","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\";\n\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\";\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\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={props.errors?.quantity?.message}\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 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 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\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 = (isPosition ? \"\" : props.quantity).toString().length > 0 ? props.errorMsg : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n ref={inputRef}\n prefix={\"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(\"oui-bg-base-5 oui-outline-line-12\", errorMsg && \"oui-outline-danger\"),\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 ]}\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 Entire position\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 Position\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primaryLight\"\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={\"primaryLight\"} 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={\"primaryLight\"} size={\"2xs\"}>\n Max\n </Text>\n </button>\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: Record<string, { message: string }> | null;\n}) => {\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Text size={\"sm\"} intensity={80}>\n Task profit\n </Text>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n Est. PNL:\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={props.errors?.tp_trigger_price?.message}\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 <Text size={\"sm\"} intensity={80}>\n Stop loss\n </Text>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n Est. PNL:\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={props.errors?.sl_trigger_price?.message}\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 return (\n <Input.tooltip\n prefix={`${props.type} price`}\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 ]}\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 [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={\"primaryLight\"}>\n 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 Buy\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n 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>Qty.</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">Entire position</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>TP Price</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>SL Price</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>Price</Box>\n <div className=\"oui-text-base-contrast\">Market</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 Disable order confirmation\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 if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n TP\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n SL\n </Badge>\n );\n }\n\n return null;\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\";\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\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 setPrefix(mode);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode]);\n\n \n\n return (\n <Input\n prefix={mode}\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 ]}\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 }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text size={\"2xs\"} color=\"inherit\" className={cn(\"oui-ml-[2px]\", color)}>\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 } 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\";\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\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]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n { label: \"PnL\", value: PnLMode.PnL, testId: `${PnLMode.PnL}_menu_item` },\n {\n label: \"Offset\",\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: \"Offset%\",\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, []);\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 (type === \"SL\" && mode === PnLMode.PnL) {\n // value = value.startsWith(\"-\") ? value : \"-\" + value;\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 {\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 };\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} 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 { submit, deleteOrder, setValue, validate, errors, isCreateMutating, isUpdateMutating },\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 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(() => true, (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n return Promise.reject(false);\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 { useLocalStorage } from \"@orderly.network/hooks\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n} from \"@orderly.network/ui\";\nimport { useState } from \"react\";\nimport { TPSLWidget } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport { ButtonProps } from \"@orderly.network/ui\";\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}) => {\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 isPositionTPSL = isEditing ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL : 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 asChild>\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 </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: \"Cancel Order\",\n content:\n \"Are you sure you want to cancel this TP/SL order?\",\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 ? \"Edit Order\" : \"Confirm Order\",\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 { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n cn,\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 { useMemo, useState } from \"react\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\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\n const isPositionTPSL = isEditing ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL : undefined;\n\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 ? \"TP/SL\" : \"Position TP/SL\"\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n return modal\n .confirm({\n title: isEditing ? \"Edit Order\" : \"Confirm Order\",\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={Math.abs(Number(position.position_qty))}\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\n const title = useMemo<string>(() => {\n return (modal.args?.title || \"TP/SL\") as string;\n }, [modal.args?.title]);\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 isPositionTPSL = useMemo(() => {\n return modal.args?.title === \"Position TP/SL\";\n }, [modal.args?.title]);\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 && <Badge size=\"xs\" color=\"primaryLight\">Position</Badge>}\n <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n Buy\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n 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 Avg. open\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 Mark price\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
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
import { useLocalStorage, useMarkPrice, useSymbolsInfo, useTPSLOrder, utils } from '@orderly.network/hooks';
|
|
4
|
+
import { transSymbolformString, Decimal, todpIfNeed } from '@orderly.network/utils';
|
|
5
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
|
+
import { OrderSide, AlgoOrderRootType, SDKError, AlgoOrderType } from '@orderly.network/types';
|
|
7
|
+
|
|
8
|
+
var j=e=>{let{type:t,values:o}=e,[s,u]=useLocalStorage("TP/SL_Mode","Offset%"),c=useMemo(()=>{switch(s){case"Offset":return `${t.toLowerCase()}_offset`;case"Offset%":return `${t.toLowerCase()}_offset_percentage`;default:return `${t.toLowerCase()}_pnl`}},[s]),d=useMemo(()=>o[s],[o]),a=useMemo(()=>[{label:"PnL",value:"PnL",testId:"PnL_menu_item"},{label:"Offset",value:"Offset",testId:"Offset_mneu_item"},{label:"Offset%",value:"Offset%",testId:"Offset%_menu_item"}],[]),i=useRef(""),y=g=>{e.onChange(c,g);},P=g=>{let{dp:_=2}=g;return {onRenderBefore:(n,l)=>(n=`${n}`,n===""||n==="-"?"":s==="Offset%"?`${new Decimal(n.replace(new RegExp(i.current.replace(".","\\.")+"$"),"")).mul(100).todp(2,4).toString()}${i.current}`:(s==="Offset"&&(n=todpIfNeed(n,_)),`${n}`)),onSendBefore:n=>{if(/^\-?0{2,}$/.test(n))return "0";if(s==="Offset%"){if(n!==""){n=todpIfNeed(n,2);let l=n.match(/\.0{0,2}$/);l?i.current=l[0]:i.current="",n=new Decimal(n).div(100).toString(),n=`${n}${i.current}`;}}else n=todpIfNeed(n,_);return n===""||n==="-"?"":n}}};return {mode:s,modes:a,type:e.type,formatter:P,onModeChange:g=>{u(g);},value:d,pnl:o.PnL,onValueChange:y,quote_dp:e.quote_dp}};var K=e=>{let{mode:t,modes:o,onModeChange:s,onValueChange:u,quote:c,quote_dp:d,value:a,pnl:i}=e,[y,P]=useState(t),[g,_]=useState(t==="Offset%"?"%":c),n=useMemo(()=>{let l=Number(i);if(isNaN(l)||l===0)return "";if(l>0)return "oui-text-trade-profit";if(l<0)return "oui-text-trade-loss"},[i]);return useEffect(()=>{P(t),_(t==="Offset%"?"%":c);},[t]),jsx(Input,{prefix:t,size:{initial:"lg",lg:"md"},placeholder:g,align:"right",value:a,"data-testid":e.testId,autoComplete:"off",onValueChange:u,formatters:[e.formatter({dp:d,mode:t}),inputFormatter.currencyFormatter],classNames:{input:n,prefix:"oui-text-base-contrast-54",root:"oui-outline-line-12 focus-within:oui-outline-primary-light"},onFocus:()=>{_("");},onBlur:()=>{_(t==="Offset%"?"%":c);},suffix:jsxs(Fragment,{children:[t==="Offset%"&&!!a&&jsx(Text,{size:"2xs",color:"inherit",className:cn("oui-ml-[2px]",n),children:"%"}),jsx(Ie,{mode:t,modes:o,onModeChange:l=>s(l.value)})]})})},Ie=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 V=e=>{let{testId:t,quote:o,...s}=e,u=j(s);return jsx(K,{...u,testId:t,quote:o})};var te=e=>{let{TPSL_OrderEntity:t,symbolInfo:o,onCancel:s,onComplete:u,status:c,errors:d,isPosition:a}=e;return jsxs("div",{id:"orderly-tp_sl-order-edit-content",children:[(!e.isEditing||e.isEditing&&!e.isPosition)&&jsxs(Fragment,{children:[jsx(Ve,{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:a,errorMsg:e.errors?.quantity?.message}),jsx(Divider,{my:4,intensity:8})]}),jsx(De,{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:d,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:()=>{s?.();},children:"Cancel"}),jsx(ThrottledButton,{size:"md","data-testid":"tpsl-confirm",disabled:!e.valid||c.isCreateMutating,loading:c.isCreateMutating||c.isUpdateMutating,onClick:()=>{e.onSubmit().then(()=>{u?.();},()=>{});},children:"Confirm"})]})]})},Ve=e=>{let{isPosition:t}=e,o=useRef(null),s=convertValueToPercentage(e.quantity,0,e.maxQty)/100,u=()=>{e.onQuantityChange?.(0),o.current?.focus(),setTimeout(()=>{o.current?.setSelectionRange(0,1);},0);},c=a=>{if(e.baseTick>0){e.onQuantityChange?.(utils.formatNumber(a,e.baseTick)??a);}},d=(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,{ref:o,prefix:"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",d&&"oui-outline-danger")},tooltipProps:{content:{className:"oui-bg-base-6 oui-text-base-contrast-80"},arrow:{className:"oui-fill-base-6"}},tooltip:d,color:d?"danger":void 0,formatters:[inputFormatter.dpFormatter(e.dp),inputFormatter.numberFormatter,inputFormatter.currencyFormatter],onValueChange:a=>{e.onQuantityChange?.(a);let i=Number(a);if(i&&i>e.maxQty){let y=t?0:e.maxQty;e.onQuantityChange?.(y),o.current?.blur();}},onBlur:a=>c(a.target.value),suffix:t?jsx("button",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",onClick:()=>{u();},children:"Entire position"}):jsx("span",{className:"oui-text-2xs oui-text-base-contrast-54 oui-px-3",children:e.quote})})}),!e.isEditing&&jsx(Button,{onClick:()=>{let a=t?0:e.maxQty;e.onQuantityChange?.(a),a===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:"Position"})]}),jsx(Flex,{mt:2,itemAlign:"center",height:"15px",children:jsx(Slider.single,{markCount:5,color:"primaryLight",max:e.maxQty,min:0,showTip:!0,step:e.baseTick,value:e.quantity,onValueCommit:a=>{c(`${a}`);},onValueChange:a=>{e.onQuantityChange?.(a);}})}),jsxs(Flex,{justify:"between",children:[jsx(Text.numeral,{rule:"percentages",color:"primaryLight",size:"2xs",children:s}),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:"primaryLight",size:"2xs",children:"Max"})}),jsx(Text.numeral,{rule:"price",size:"2xs",intensity:54,tick:e.baseTick,children:e.maxQty})]})]})]})},De=e=>{let t=(o,s)=>{e.onPnLChange(o,s);};return jsxs(Fragment,{children:[jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:80,children:"Task profit"}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:"Est. PNL:"}),jsx(Text.numeral,{size:"2xs",coloring:!0,showIdentifier:!0,className:"oui-ml-1",children:e.tp_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(X,{type:"TP",value:e.tp_trigger_price,error:e.errors?.tp_trigger_price?.message,onValueChange:o=>{e.onPriceChange("tp_trigger_price",o);},quote_dp:e.quote_dp??2}),jsx(V,{type:"TP",onChange:t,quote:e.quote,quote_dp:e.quote_dp,values:e.tp_values})]})]}),jsxs("div",{children:[jsxs(Flex,{justify:"between",children:[jsx(Text,{size:"sm",intensity:80,children:"Stop loss"}),jsxs(Flex,{children:[jsx(Text,{size:"2xs",intensity:36,children:"Est. PNL:"}),jsx(Text.numeral,{size:"2xs",coloring:!0,showIdentifier:!0,className:"oui-ml-1",children:e.sl_pnl??"-"})]})]}),jsxs(Grid,{cols:2,gap:2,pt:2,pb:4,children:[jsx(X,{type:"SL",value:e.sl_trigger_price,error:e.errors?.sl_trigger_price?.message,onValueChange:o=>{e.onPriceChange("sl_trigger_price",o);},quote_dp:e.quote_dp??2}),jsx(V,{type:"SL",onChange:t,quote:e.quote,quote_dp:e.quote_dp,values:e.sl_values})]})]})]})},X=e=>{let[t,o]=useState("USDC");return jsx(Input.tooltip,{prefix:`${e.type} price`,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]})},v=e=>{let{symbol:t,tpPrice:o,slPrice:s,qty:u,maxQty:c,side:d,quoteDP:a,baseDP:i,isEditing:y,isPositionTPSL:P}=e,[g,_]=useLocalStorage("orderly_order_confirm",!0),n=textVariants({size:"xs",intensity:54}),l=P??u>=c;return jsxs(Fragment,{children:[y&&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:!0,children:jsx(Text.formatted,{rule:"symbol",formatString:"base-type",size:"base",showIcon:!0,as:"div",intensity:80,children:t})}),jsxs(Flex,{gap:1,children:[l&&jsx(Badge,{size:"xs",color:"primaryLight",children:"Position"}),jsx(Ge,{tpPrice:o,slPrice:s}),d===OrderSide.SELL?jsx(Badge,{size:"xs",color:"success",children:"Buy"}):jsx(Badge,{size:"xs",color:"danger",children:"Sell"})]})]}),jsx(Divider,{}),jsxs(Flex,{direction:"column",itemAlign:"stretch",gapY:1,pt:4,className:cn(n,"oui-pb-4 xl:oui-pb-5"),children:[jsxs(Flex,{children:[jsx(Box,{grow:!0,children:"Qty."}),jsx("div",{children:l?jsx("span",{className:"oui-text-base-contrast",children:"Entire position"}):jsx(Text.numeral,{intensity:98,dp:i,padding:!1,children:u})})]}),typeof o=="number"&&o>0?jsxs(Flex,{children:[jsx(Box,{grow:!0,children:"TP Price"}),jsx(Text.numeral,{as:"div",coloring:!0,unit:"USDC",size:"sm",dp:a,unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:o})]}):null,typeof s=="number"&&s>0?jsxs(Flex,{children:[jsx(Box,{grow:!0,children:"SL Price"}),jsx(Text.numeral,{as:"div",coloring:!0,unit:"USDC",size:"sm",dp:a,className:"oui-text-trade-loss",unitClassName:"oui-text-base-contrast-54 oui-ml-1",children:s})]}):null,jsxs(Flex,{children:[jsx(Box,{grow:!0,children:"Price"}),jsx("div",{className:"oui-text-base-contrast",children:"Market"})]})]}),jsx(Box,{pt:2,children:jsxs(Flex,{gap:1,children:[jsx(Checkbox,{id:"disabledConfirm",color:"white",checked:!g,onCheckedChange:S=>{_(!S);}}),jsx("label",{htmlFor:"disabledConfirm",className:textVariants({size:"xs",intensity:54,className:"oui-ml-1"}),children:"Disable order confirmation"})]})})]})},Ge=e=>{let{tpPrice:t,slPrice:o}=e;return t&&o?jsx(Badge,{size:"xs",color:"neutral",children:"TP/SL"}):t?jsx(Badge,{size:"xs",color:"neutral",children:"TP"}):o?jsx(Badge,{size:"xs",color:"neutral",children:"SL"}):null};var re=e=>{let{position:t,order:o,isEditing:s}=e;if(s&&!o)throw new SDKError("order is required when isEditing is true");let u=s?o.symbol:t.symbol,c=useSymbolsInfo(),d=useRef(AlgoOrderRootType.TP_SL),[a]=useLocalStorage("orderly_order_confirm",!0),[i,{submit:y,deleteOrder:P,setValue:g,validate:_,errors:n,isCreateMutating:l,isUpdateMutating:S}]=useTPSLOrder({symbol:u,position_qty:t.position_qty,average_open_price:t.average_open_price},{defaultOrder:o,isEditing:s}),C=f=>{g("quantity",f);},me=(f,T)=>{g(f,T);},ce=(f,T)=>{g(f,T);},L=useMemo(()=>Math.abs(Number(t.position_qty)),[t.position_qty]),W=useMemo(()=>{let f=o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL?L:o?.quantity,T=0;if((Number(i.quantity)!==f||!s&&i.quantity)&&(T=1),o&&s){let fe=o.child_orders.find(k=>k.algo_type===AlgoOrderType.TAKE_PROFIT),ye=o.child_orders.find(k=>k.algo_type===AlgoOrderType.STOP_LOSS);fe?.trigger_price!==Number(i.tp_trigger_price)&&typeof typeof i.tp_trigger_price<"u"&&(T=2),ye?.trigger_price!==Number(i.sl_trigger_price)&&typeof i.sl_trigger_price<"u"&&(T=3);}return T===1&&!i.tp_trigger_price&&!i.sl_trigger_price&&(T=-1),T},[i.tp_trigger_price,i.sl_trigger_price,i.quantity,o,s]),de=useMemo(()=>o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&Number(i.quantity)<L&&!i.tp_trigger_price&&!i.sl_trigger_price?!1:W>0&&!!i.quantity&&!n,[i.quantity,L,W,n]),ge=useMemo(()=>s?o&&o.algo_type!==AlgoOrderRootType.POSITIONAL_TP_SL?!1:i.algo_order_id&&i.quantity==0?!0:Number(i.quantity)>=L:Number(i.quantity)>=L,[i.quantity,L,o?.algo_type,s]);useEffect(()=>{let f=Number(i.quantity)<L?AlgoOrderRootType.TP_SL:AlgoOrderRootType.POSITIONAL_TP_SL;typeof e.onTPSLTypeChange=="function"&&d.current!==f&&e.onTPSLTypeChange(f),d.current=f;},[i.quantity,L]);let pe=()=>o?.algo_order_id&&o?.symbol?P(o?.algo_order_id,o?.symbol):Promise.reject("order id or symbol is invalid"),Pe=async()=>Promise.resolve().then(()=>typeof e.onConfirm!="function"||!a?y().then(()=>!0,f=>(f?.message&&toast.error(f.message),Promise.reject(!1))):e.onConfirm(i,{position:t,submit:y,cancel:pe})).then(f=>{});return {isEditing:s,symbolInfo:c[u],maxQty:L,setQuantity:C,orderQuantity:i.quantity,isPosition:ge,TPSL_OrderEntity:i,setOrderValue:g,setPnL:ce,setOrderPrice:me,onSubmit:Pe,valid:de,errors:n,status:{isCreateMutating:l,isUpdateMutating:S}}};var B=e=>{let{onCancel:t,onComplete:o,...s}=e,u=re(s);return jsx(te,{...u,onCancel:t,onComplete:o})};var nt=e=>{let{position:t,order:o,baseDP:s,quoteDP:u,buttonProps:c,isEditing:d}=e,[a,i]=useState(!1),[y,P]=useState(!0),[g]=useLocalStorage("orderly_order_confirm",!0),_=d?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0;return jsxs(PopoverRoot,{onOpenChange:n=>{y&&i(n);},open:a,children:[jsx(PopoverTrigger,{asChild:!0,children:jsx(Button,{variant:"outlined",size:"sm",color:"secondary",...c,onClick:()=>{i(!0);},children:e.label})}),jsx(PopoverContent,{className:cn("oui-w-[360px]",y?"oui-visible":"oui-invisible"),align:"end",side:"top",children:jsx(B,{position:t,order:o,isEditing:d,onComplete:()=>{i(!1);},onCancel:()=>{i(!1);},onConfirm:(n,l)=>{if(!g)return Promise.resolve(!0);P(!1);let S=Math.abs(Number(t.position_qty));if(`${n.tp_trigger_price??""}`.length===0&&`${n.sl_trigger_price??""}`.length===0)return modal.confirm({title:"Cancel Order",content:"Are you sure you want to cancel this TP/SL order?",onOk:()=>l.cancel()}).then(()=>(i(!1),P(!0),!0),()=>(P(!0),Promise.reject(!1)));let C=d||!!n&&n.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL&&n.quantity===S;return modal.confirm({title:C?"Edit Order":"Confirm Order",onOk:()=>l.submit(),classNames:{body:"!oui-pb-0"},content:jsx(v,{isPositionTPSL:_,isEditing:C,symbol:n.symbol,qty:Number(n.quantity),maxQty:S,tpPrice:Number(n.tp_trigger_price),slPrice:Number(n.sl_trigger_price),side:n.side,quoteDP:u??2,baseDP:s??2})}).then(()=>(i(!1),P(!0),!0),()=>(P(!0),Promise.reject(!1)))}})})]})};var pt=e=>{let{position:t,order:o,symbolInfo:s,isEditing:u}=e,{resolve:c,hide:d,updateArgs:a}=useModal(),[i]=useLocalStorage("orderly_order_confirm",!0),y=u?o?.algo_type===AlgoOrderRootType.POSITIONAL_TP_SL:void 0,P=l=>{u||a({title:l});},g=()=>{c(),d();},{quote_dp:_,base_dp:n}=s;return jsxs(Fragment,{children:[jsx(Pt,{position:t,symbolInfo:s}),jsx(B,{...e,onTPSLTypeChange:l=>{P(l===AlgoOrderRootType.TP_SL?"TP/SL":"Position TP/SL");},onComplete:g,onConfirm:(l,S)=>i?modal.confirm({title:u?"Edit Order":"Confirm Order",bodyClassName:"oui-pb-0 lg:oui-pb-0",onOk:()=>S.submit(),content:jsx(v,{isPositionTPSL:y,isEditing:u,symbol:l.symbol,qty:Number(l.quantity),maxQty:Math.abs(Number(t.position_qty)),tpPrice:Number(l.tp_trigger_price),slPrice:Number(l.sl_trigger_price),side:l.side,quoteDP:_??2,baseDP:n??2})}).then(()=>!0,C=>(C?.message&&toast.error(C.message),Promise.reject(!1))):Promise.resolve(!0),onCancel:()=>{d();}})]})};var Pt=e=>{let{position:t,symbolInfo:o}=e,{data:s}=useMarkPrice(t.symbol),u=useModal(),c=useMemo(()=>u.args?.title==="Position TP/SL",[u.args?.title]);return jsxs(Fragment,{children:[jsxs(Flex,{justify:"between",pb:3,itemAlign:"center",children:[jsx(Text.formatted,{rule:"symbol",className:"oui-text-xs",showIcon:!0,children:t.symbol}),jsxs(Flex,{gapX:1,children:[c&&jsx(Badge,{size:"xs",color:"primaryLight",children:"Position"}),jsx(Badge,{size:"xs",color:"neutral",children:"TP/SL"}),t.position_qty<0?jsx(Badge,{size:"xs",color:"buy",children:"Buy"}):jsx(Badge,{size:"xs",color:"sell",children:"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:"Avg. open"}),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:"Mark price"}),jsx(Text.numeral,{className:"oui-text-xs",unit:o.quote,dp:o.quote_dp,unitClassName:"oui-ml-1 oui-text-base-contrast-36",children:s})]})]})]})};
|
|
9
|
+
|
|
10
|
+
export { v as PositionTPSLConfirm, nt as PositionTPSLPopover, pt as PositionTPSLSheet, B as TPSLWidget };
|
|
11
|
+
//# sourceMappingURL=out.js.map
|
|
12
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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","usePNLInputBuilder","props","type","values","mode","setMode","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","PNLMenus","item","PnlInputWidget","testId","rest","state","utils","OrderSide","transSymbolformString","TPSL","TPSL_OrderEntity","symbolInfo","onCancel","onComplete","status","errors","isPosition","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","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\";\n\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\";\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\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={props.errors?.quantity?.message}\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 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 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\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 = (isPosition ? \"\" : props.quantity).toString().length > 0 ? props.errorMsg : undefined;\n\n return (\n <>\n <Flex gap={2}>\n <div className={\"oui-flex-1\"}>\n <Input.tooltip\n ref={inputRef}\n prefix={\"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(\"oui-bg-base-5 oui-outline-line-12\", errorMsg && \"oui-outline-danger\"),\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 ]}\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 Entire position\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 Position\n </Button>\n )}\n </Flex>\n <Flex mt={2} itemAlign={\"center\"} height={\"15px\"}>\n <Slider.single\n markCount={5}\n color=\"primaryLight\"\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={\"primaryLight\"} 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={\"primaryLight\"} size={\"2xs\"}>\n Max\n </Text>\n </button>\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: Record<string, { message: string }> | null;\n}) => {\n const onPnLChange = (key: string, value: number | string) => {\n // console.log(key, value);\n props.onPnLChange(key, value);\n };\n return (\n <>\n <div>\n <Flex justify={\"between\"}>\n <Text size={\"sm\"} intensity={80}>\n Task profit\n </Text>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n Est. PNL:\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={props.errors?.tp_trigger_price?.message}\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 <Text size={\"sm\"} intensity={80}>\n Stop loss\n </Text>\n <Flex>\n <Text size={\"2xs\"} intensity={36}>\n Est. PNL:\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={props.errors?.sl_trigger_price?.message}\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 return (\n <Input.tooltip\n prefix={`${props.type} price`}\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 ]}\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 [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={\"primaryLight\"}>\n 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 Buy\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"danger\">\n 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>Qty.</Box>\n\n <div>\n {isPositionTPSL ? (\n <span className=\"oui-text-base-contrast\">Entire position</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>TP Price</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>SL Price</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>Price</Box>\n <div className=\"oui-text-base-contrast\">Market</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 Disable order confirmation\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 if (!!tpPrice && !!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge>\n );\n }\n\n if (!!tpPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n TP\n </Badge>\n );\n }\n\n if (!!slPrice) {\n return (\n <Badge size=\"xs\" color=\"neutral\">\n SL\n </Badge>\n );\n }\n\n return null;\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\";\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\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 setPrefix(mode);\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }, [mode]);\n\n \n\n return (\n <Input\n prefix={mode}\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 ]}\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 }}\n onBlur={() => {\n setPlaceholder(mode === PnLMode.PERCENTAGE ? \"%\" : quote);\n }}\n // value={props.value}\n suffix={\n <>\n {mode === PnLMode.PERCENTAGE && !!value && (\n <Text size={\"2xs\"} color=\"inherit\" className={cn(\"oui-ml-[2px]\", color)}>\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 } 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\";\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\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]);\n\n const modes = useMemo<MenuItem[]>(() => {\n return [\n { label: \"PnL\", value: PnLMode.PnL, testId: `${PnLMode.PnL}_menu_item` },\n {\n label: \"Offset\",\n value: PnLMode.OFFSET,\n testId: `${PnLMode.OFFSET}_mneu_item`,\n },\n {\n label: \"Offset%\",\n value: PnLMode.PERCENTAGE,\n testId: `${PnLMode.PERCENTAGE}_menu_item`,\n },\n ];\n }, []);\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 (type === \"SL\" && mode === PnLMode.PnL) {\n // value = value.startsWith(\"-\") ? value : \"-\" + value;\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 {\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 };\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} 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 { submit, deleteOrder, setValue, validate, errors, isCreateMutating, isUpdateMutating },\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 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(() => true, (reject) => {\n if (reject?.message) {\n toast.error(reject.message);\n }\n return Promise.reject(false);\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 { useLocalStorage } from \"@orderly.network/hooks\";\nimport {\n Button,\n cn,\n modal,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n} from \"@orderly.network/ui\";\nimport { useState } from \"react\";\nimport { TPSLWidget } from \"./tpsl.widget\";\nimport { PositionTPSLConfirm } from \"./tpsl.ui\";\nimport { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport { ButtonProps } from \"@orderly.network/ui\";\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}) => {\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 isPositionTPSL = isEditing ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL : 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 asChild>\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 </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: \"Cancel Order\",\n content:\n \"Are you sure you want to cancel this TP/SL order?\",\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 ? \"Edit Order\" : \"Confirm Order\",\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 { AlgoOrderRootType, API } from \"@orderly.network/types\";\nimport {\n cn,\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 { useMemo, useState } from \"react\";\nimport { useLocalStorage, useMarkPrice } from \"@orderly.network/hooks\";\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\n const isPositionTPSL = isEditing ? order?.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL : undefined;\n\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 ? \"TP/SL\" : \"Position TP/SL\"\n );\n }}\n onComplete={onCompleted}\n onConfirm={(order, options) => {\n if (!needConfirm) {\n return Promise.resolve(true);\n }\n\n return modal\n .confirm({\n title: isEditing ? \"Edit Order\" : \"Confirm Order\",\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={Math.abs(Number(position.position_qty))}\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\n const title = useMemo<string>(() => {\n return (modal.args?.title || \"TP/SL\") as string;\n }, [modal.args?.title]);\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 isPositionTPSL = useMemo(() => {\n return modal.args?.title === \"Position TP/SL\";\n }, [modal.args?.title]);\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 && <Badge size=\"xs\" color=\"primaryLight\">Position</Badge>}\n <Badge size=\"xs\" color=\"neutral\">\n TP/SL\n </Badge>\n {position.position_qty < 0 ? (\n <Badge size=\"xs\" color=\"buy\">\n Buy\n </Badge>\n ) : (\n <Badge size=\"xs\" color=\"sell\">\n 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 Avg. open\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 Mark price\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/styles.css
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orderly.network/ui-tpsl",
|
|
3
|
+
"version": "2.0.1-alpha.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"Orderly",
|
|
10
|
+
"UI",
|
|
11
|
+
"TPSL"
|
|
12
|
+
],
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@orderly.network/ui": "2.0.1-alpha.1",
|
|
21
|
+
"@orderly.network/types": "2.0.1-alpha.1",
|
|
22
|
+
"@orderly.network/utils": "2.0.1-alpha.1",
|
|
23
|
+
"@orderly.network/hooks": "2.0.1-alpha.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/react": "^18.3.2",
|
|
27
|
+
"@types/react-dom": "^18.3.0",
|
|
28
|
+
"react": "^18.3.1",
|
|
29
|
+
"react-dom": "^18.2.0",
|
|
30
|
+
"tailwindcss": "^3.4.4",
|
|
31
|
+
"tsup": "^7.1.0",
|
|
32
|
+
"typescript": "^5.1.6",
|
|
33
|
+
"tsconfig": "0.3.16"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup && pnpm run build:css",
|
|
37
|
+
"build:css": "tailwindcss build -i src/tailwind.css -o dist/styles.css --minify",
|
|
38
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
39
|
+
}
|
|
40
|
+
}
|