@orderly.network/ui-tpsl 2.8.5-alpha.0 → 2.8.6-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -64,6 +64,8 @@ declare const useTPSLBuilder: (options: TPSLBuilderOptions$1 & PropsWithTriggerP
64
64
  readonly setPnL: (type: string, value: number | string) => void;
65
65
  readonly setOrderPrice: (name: "tp_trigger_price" | "sl_trigger_price", value: number | string) => void;
66
66
  readonly onSubmit: () => Promise<boolean | undefined>;
67
+ readonly slPriceError: _orderly_network_hooks.OrderValidationResult | null;
68
+ readonly estLiqPrice: number | undefined;
67
69
  readonly metaState: {
68
70
  dirty: { [K in keyof _orderly_network_types.OrderlyOrder]?: boolean; };
69
71
  submitted: boolean;
@@ -231,6 +233,8 @@ declare const useTPSLAdvanced: (props: Props$3) => {
231
233
  order: OrderlyOrder;
232
234
  formattedOrder: Partial<OrderlyOrder>;
233
235
  symbolInfo: _orderly_network_types.API.SymbolExt;
236
+ slPriceError: OrderValidationResult | null;
237
+ estLiqPrice: number | null;
234
238
  setValue: (key: "symbol" | "type" | "order_type" | "order_type_ext" | "order_price" | "order_quantity" | "order_amount" | "visible_quantity" | "side" | "reduce_only" | "slippage" | "order_tag" | "level" | "post_only_adjust" | "client_order_id" | "total" | "start_price" | "end_price" | "total_orders" | "distribution_type" | "skew" | "activated_price" | "callback_value" | "callback_rate" | "quantity" | "price" | "algo_type" | "trigger_price_type" | "trigger_price" | "child_orders" | "position_type" | "tp_pnl" | "tp_offset" | "tp_offset_percentage" | "tp_ROI" | "tp_trigger_price" | "tp_order_price" | "tp_order_type" | "sl_pnl" | "sl_offset" | "sl_offset_percentage" | "sl_ROI" | "sl_trigger_price" | "sl_order_price" | "sl_order_type", value: any, options?: {
235
239
  shouldUpdateLastChangedField?: boolean;
236
240
  }) => void;
@@ -379,4 +383,12 @@ declare const EditBracketOrderWidget: (props: {
379
383
  declare const EditBracketOrderSheetId = "EditBracketOrderSheetId";
380
384
  declare const EditBracketOrderDialogId = "EditBracketOrderDialogId";
381
385
 
382
- export { ArrowRightIcon, EditBracketOrderDialogId, EditBracketOrderSheetId, EditBracketOrderWidget, PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSL, TPSLAdvancedDialogId, TPSLAdvancedSheetId, TPSLAdvancedUI, TPSLAdvancedWidget, type TPSLBuilderOptions$1 as TPSLBuilderOptions, type TPSLBuilderState, TPSLDetailDialogId, type TPSLDetailProps, TPSLDetailSheetId, TPSLDetailWidget, TPSLDialogId, TPSLPositionTypeWidget, type TPSLProps, TPSLSheetId, TPSLSimpleDialogId, TPSLSimpleDialogUI, TPSLSimpleDialogWidget, TPSLSimpleSheetId, TPSLWidget, type TPSLWidgetProps, useTPSLAdvanced, useTPSLBuilder, useTPSLSimpleDialog };
386
+ declare const CloseToLiqPriceIcon: {
387
+ ({ slPriceError, className, }: {
388
+ slPriceError: OrderValidationResult | null;
389
+ className?: string;
390
+ }): react_jsx_runtime.JSX.Element | null;
391
+ displayName: string;
392
+ };
393
+
394
+ export { ArrowRightIcon, CloseToLiqPriceIcon, EditBracketOrderDialogId, EditBracketOrderSheetId, EditBracketOrderWidget, PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSL, TPSLAdvancedDialogId, TPSLAdvancedSheetId, TPSLAdvancedUI, TPSLAdvancedWidget, type TPSLBuilderOptions$1 as TPSLBuilderOptions, type TPSLBuilderState, TPSLDetailDialogId, type TPSLDetailProps, TPSLDetailSheetId, TPSLDetailWidget, TPSLDialogId, TPSLPositionTypeWidget, type TPSLProps, TPSLSheetId, TPSLSimpleDialogId, TPSLSimpleDialogUI, TPSLSimpleDialogWidget, TPSLSimpleSheetId, TPSLWidget, type TPSLWidgetProps, useTPSLAdvanced, useTPSLBuilder, useTPSLSimpleDialog };
package/dist/index.d.ts CHANGED
@@ -64,6 +64,8 @@ declare const useTPSLBuilder: (options: TPSLBuilderOptions$1 & PropsWithTriggerP
64
64
  readonly setPnL: (type: string, value: number | string) => void;
65
65
  readonly setOrderPrice: (name: "tp_trigger_price" | "sl_trigger_price", value: number | string) => void;
66
66
  readonly onSubmit: () => Promise<boolean | undefined>;
67
+ readonly slPriceError: _orderly_network_hooks.OrderValidationResult | null;
68
+ readonly estLiqPrice: number | undefined;
67
69
  readonly metaState: {
68
70
  dirty: { [K in keyof _orderly_network_types.OrderlyOrder]?: boolean; };
69
71
  submitted: boolean;
@@ -231,6 +233,8 @@ declare const useTPSLAdvanced: (props: Props$3) => {
231
233
  order: OrderlyOrder;
232
234
  formattedOrder: Partial<OrderlyOrder>;
233
235
  symbolInfo: _orderly_network_types.API.SymbolExt;
236
+ slPriceError: OrderValidationResult | null;
237
+ estLiqPrice: number | null;
234
238
  setValue: (key: "symbol" | "type" | "order_type" | "order_type_ext" | "order_price" | "order_quantity" | "order_amount" | "visible_quantity" | "side" | "reduce_only" | "slippage" | "order_tag" | "level" | "post_only_adjust" | "client_order_id" | "total" | "start_price" | "end_price" | "total_orders" | "distribution_type" | "skew" | "activated_price" | "callback_value" | "callback_rate" | "quantity" | "price" | "algo_type" | "trigger_price_type" | "trigger_price" | "child_orders" | "position_type" | "tp_pnl" | "tp_offset" | "tp_offset_percentage" | "tp_ROI" | "tp_trigger_price" | "tp_order_price" | "tp_order_type" | "sl_pnl" | "sl_offset" | "sl_offset_percentage" | "sl_ROI" | "sl_trigger_price" | "sl_order_price" | "sl_order_type", value: any, options?: {
235
239
  shouldUpdateLastChangedField?: boolean;
236
240
  }) => void;
@@ -379,4 +383,12 @@ declare const EditBracketOrderWidget: (props: {
379
383
  declare const EditBracketOrderSheetId = "EditBracketOrderSheetId";
380
384
  declare const EditBracketOrderDialogId = "EditBracketOrderDialogId";
381
385
 
382
- export { ArrowRightIcon, EditBracketOrderDialogId, EditBracketOrderSheetId, EditBracketOrderWidget, PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSL, TPSLAdvancedDialogId, TPSLAdvancedSheetId, TPSLAdvancedUI, TPSLAdvancedWidget, type TPSLBuilderOptions$1 as TPSLBuilderOptions, type TPSLBuilderState, TPSLDetailDialogId, type TPSLDetailProps, TPSLDetailSheetId, TPSLDetailWidget, TPSLDialogId, TPSLPositionTypeWidget, type TPSLProps, TPSLSheetId, TPSLSimpleDialogId, TPSLSimpleDialogUI, TPSLSimpleDialogWidget, TPSLSimpleSheetId, TPSLWidget, type TPSLWidgetProps, useTPSLAdvanced, useTPSLBuilder, useTPSLSimpleDialog };
386
+ declare const CloseToLiqPriceIcon: {
387
+ ({ slPriceError, className, }: {
388
+ slPriceError: OrderValidationResult | null;
389
+ className?: string;
390
+ }): react_jsx_runtime.JSX.Element | null;
391
+ displayName: string;
392
+ };
393
+
394
+ export { ArrowRightIcon, CloseToLiqPriceIcon, EditBracketOrderDialogId, EditBracketOrderSheetId, EditBracketOrderWidget, PositionTPSLConfirm, PositionTPSLPopover, PositionTPSLSheet, TPSL, TPSLAdvancedDialogId, TPSLAdvancedSheetId, TPSLAdvancedUI, TPSLAdvancedWidget, type TPSLBuilderOptions$1 as TPSLBuilderOptions, type TPSLBuilderState, TPSLDetailDialogId, type TPSLDetailProps, TPSLDetailSheetId, TPSLDetailWidget, TPSLDialogId, TPSLPositionTypeWidget, type TPSLProps, TPSLSheetId, TPSLSimpleDialogId, TPSLSimpleDialogUI, TPSLSimpleDialogWidget, TPSLSimpleSheetId, TPSLWidget, type TPSLWidgetProps, useTPSLAdvanced, useTPSLBuilder, useTPSLSimpleDialog };
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ var hooks = require('@orderly.network/hooks');
4
4
  var i18n = require('@orderly.network/i18n');
5
5
  var types = require('@orderly.network/types');
6
6
  var ui = require('@orderly.network/ui');
7
+ var react = require('react');
7
8
  var reactApp = require('@orderly.network/react-app');
8
9
  var jsxRuntime = require('react/jsx-runtime');
9
- var react = require('react');
10
10
  var utils = require('@orderly.network/utils');
11
11
  var perp = require('@orderly.network/perp');
12
12
  var uiConnector = require('@orderly.network/ui-connector');
@@ -124,6 +124,19 @@ var OrderInfo = (props) => {
124
124
  children: markPrice?.data
125
125
  }
126
126
  )
127
+ ] }),
128
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-text-base-contrast-36", children: [
129
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: t("positions.column.liqPrice") }),
130
+ /* @__PURE__ */ jsxRuntime.jsx(
131
+ ui.Text.numeral,
132
+ {
133
+ rule: "price",
134
+ className: "oui-text-warning",
135
+ size: "2xs",
136
+ dp: props.quoteDP ?? 2,
137
+ children: props.estLiqPrice ?? "--"
138
+ }
139
+ )
127
140
  ] })
128
141
  ]
129
142
  }
@@ -491,10 +504,15 @@ var PriceInput = (props) => {
491
504
  value: props.value,
492
505
  color: props.error ? "danger" : void 0,
493
506
  classNames: {
494
- input: "oui-text-2xs placeholder:oui-text-2xs",
495
- prefix: "oui-text-base-contrast-54 oui-text-2xs",
496
- root: "oui-w-full"
497
- // root: "oui-outline-line-12 focus-within:oui-outline-primary-light",
507
+ input: ui.cn(
508
+ "oui-text-2xs placeholder:oui-text-2xs",
509
+ props.classNames?.input
510
+ ),
511
+ prefix: ui.cn(
512
+ "oui-text-base-contrast-54 oui-text-2xs",
513
+ props.classNames?.prefix
514
+ ),
515
+ root: ui.cn("oui-w-full", props.classNames?.root)
498
516
  },
499
517
  onValueChange: props.onValueChange,
500
518
  onFocus: () => {
@@ -551,7 +569,10 @@ var TPSLInputRowUI = (props) => {
551
569
  onValueChange: (value) => {
552
570
  props.onChange(`${props.type}_trigger_price`, value);
553
571
  },
554
- quote_dp: props.quote_dp
572
+ quote_dp: props.quote_dp,
573
+ classNames: {
574
+ root: props.inputWarnNode ? "oui-outline-warning-darken focus-within:oui-outline-warning-darken" : void 0
575
+ }
555
576
  }
556
577
  ),
557
578
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -570,6 +591,7 @@ var TPSLInputRowUI = (props) => {
570
591
  ]
571
592
  }
572
593
  ),
594
+ props.inputWarnNode,
573
595
  /* @__PURE__ */ jsxRuntime.jsxs(
574
596
  ui.Flex,
575
597
  {
@@ -868,7 +890,23 @@ var TPSL = (props) => {
868
890
  const { errors, validated } = props.metaState;
869
891
  const { t } = i18n.useTranslation();
870
892
  const { isMobile } = ui.useScreen();
893
+ const tpErrors = react.useMemo(() => {
894
+ if (!errors)
895
+ return null;
896
+ const { sl_trigger_price, ...rest } = errors;
897
+ return rest;
898
+ }, [errors]);
899
+ const slErrors = react.useMemo(() => {
900
+ if (!errors)
901
+ return null;
902
+ const { tp_trigger_price, ...rest } = errors;
903
+ return rest;
904
+ }, [errors]);
871
905
  const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(errors);
906
+ const { getErrorMsg: getSlPriceErrorMsg } = reactApp.useOrderEntryFormErrorMsg(
907
+ props.slPriceError
908
+ );
909
+ const isSlPriceWarning = props.slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
872
910
  if (!position) {
873
911
  return null;
874
912
  }
@@ -898,6 +936,7 @@ var TPSL = (props) => {
898
936
  {
899
937
  baseDP: symbolInfo("base_dp"),
900
938
  quoteDP: symbolInfo("quote_dp"),
939
+ estLiqPrice: props.estLiqPrice,
901
940
  classNames: {
902
941
  root: "oui-mb-3",
903
942
  container: "oui-gap-x-[30px]"
@@ -929,7 +968,14 @@ var TPSL = (props) => {
929
968
  }
930
969
  }
931
970
  ),
932
- TPSL_OrderEntity.position_type === types.PositionType.FULL && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-2xs oui-text-warning", children: t("tpsl.positionType.full.tips.market") })
971
+ TPSL_OrderEntity.position_type === types.PositionType.FULL && /* @__PURE__ */ jsxRuntime.jsx(
972
+ ui.DotStatus,
973
+ {
974
+ color: "warning",
975
+ size: "xs",
976
+ label: t("tpsl.positionType.full.tips.market")
977
+ }
978
+ )
933
979
  ]
934
980
  }
935
981
  ),
@@ -960,7 +1006,7 @@ var TPSL = (props) => {
960
1006
  order_type: TPSL_OrderEntity.tp_order_type ?? types.OrderType.MARKET
961
1007
  },
962
1008
  hideOrderPrice: TPSL_OrderEntity.position_type === types.PositionType.FULL,
963
- errors: validated ? errors : null,
1009
+ errors: validated ? tpErrors : null,
964
1010
  disableOrderTypeSelector: isEditing,
965
1011
  quote_dp: symbolInfo("quote_dp"),
966
1012
  positionType: TPSL_OrderEntity.position_type ?? types.PositionType.PARTIAL,
@@ -973,6 +1019,16 @@ var TPSL = (props) => {
973
1019
  /* @__PURE__ */ jsxRuntime.jsx(
974
1020
  TPSLInputRowWidget,
975
1021
  {
1022
+ inputWarnNode: isSlPriceWarning && /* @__PURE__ */ jsxRuntime.jsx(
1023
+ ui.DotStatus,
1024
+ {
1025
+ color: "warning",
1026
+ label: getSlPriceErrorMsg("sl_trigger_price"),
1027
+ classNames: {
1028
+ root: "oui-mt-1"
1029
+ }
1030
+ }
1031
+ ),
976
1032
  symbol: position.symbol,
977
1033
  rootOrderPrice: position.average_open_price.toString(),
978
1034
  type: "sl",
@@ -987,7 +1043,7 @@ var TPSL = (props) => {
987
1043
  order_type: TPSL_OrderEntity.sl_order_type ?? types.OrderType.MARKET
988
1044
  },
989
1045
  hideOrderPrice: TPSL_OrderEntity.position_type === types.PositionType.FULL,
990
- errors: validated ? errors : null,
1046
+ errors: validated ? slErrors : null,
991
1047
  quote_dp: symbolInfo("quote_dp"),
992
1048
  positionType: TPSL_OrderEntity.position_type ?? types.PositionType.PARTIAL,
993
1049
  disableOrderTypeSelector: isEditing,
@@ -1271,6 +1327,7 @@ var useTPSLBuilder = (options) => {
1271
1327
  const [{ rows: positions }] = hooks.usePositionStream();
1272
1328
  const [needConfirm] = hooks.useLocalStorage("orderly_order_confirm", true);
1273
1329
  const position = positions.find((item) => item.symbol === symbol);
1330
+ const estLiqPrice = hooks.useEstLiqPriceBySymbol(symbol);
1274
1331
  react.useEffect(() => {
1275
1332
  if (!position) {
1276
1333
  options.close?.();
@@ -1305,6 +1362,12 @@ var useTPSLBuilder = (options) => {
1305
1362
  isEditing
1306
1363
  }
1307
1364
  );
1365
+ const slPriceError = hooks.useTpslPriceChecker({
1366
+ slPrice: tpslOrder.sl_trigger_price?.toString() ?? void 0,
1367
+ liqPrice: estLiqPrice ?? null,
1368
+ side: tpslOrder.side
1369
+ });
1370
+ const isSlPriceWarning = slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
1308
1371
  const setQuantity = (value) => {
1309
1372
  setValue("quantity", value);
1310
1373
  };
@@ -1450,7 +1513,9 @@ var useTPSLBuilder = (options) => {
1450
1513
  };
1451
1514
  const onSubmit = async () => {
1452
1515
  try {
1453
- const validOrder = await validate();
1516
+ const validOrder = await validate(
1517
+ isSlPriceWarning ? void 0 : slPriceError
1518
+ );
1454
1519
  if (validOrder) {
1455
1520
  if (!needConfirm) {
1456
1521
  return submit({ accountId: position?.account_id }).then(() => true).catch((err) => {
@@ -1483,6 +1548,8 @@ var useTPSLBuilder = (options) => {
1483
1548
  setOrderPrice,
1484
1549
  // needConfirm,
1485
1550
  onSubmit,
1551
+ slPriceError,
1552
+ estLiqPrice,
1486
1553
  metaState,
1487
1554
  errors,
1488
1555
  status: {
@@ -1556,6 +1623,8 @@ var PositionTPSLSheet = (props) => {
1556
1623
  var TPSLAdvancedUI = (props) => {
1557
1624
  const { t } = i18n.useTranslation();
1558
1625
  const { errors, validated } = props.metaState;
1626
+ const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(props.slPriceError);
1627
+ const isSlPriceWarning = props.slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
1559
1628
  const {
1560
1629
  formattedOrder,
1561
1630
  setValue: setOrderValue,
@@ -1630,6 +1699,7 @@ var TPSLAdvancedUI = (props) => {
1630
1699
  order: formattedOrder,
1631
1700
  baseDP: symbolInfo.base_dp,
1632
1701
  quoteDP: symbolInfo.quote_dp,
1702
+ estLiqPrice: props.estLiqPrice ?? void 0,
1633
1703
  symbolLeverage: props.symbolLeverage
1634
1704
  }
1635
1705
  ) }),
@@ -1732,6 +1802,14 @@ var TPSLAdvancedUI = (props) => {
1732
1802
  values: slValues,
1733
1803
  hideOrderPrice: formattedOrder.position_type === types.PositionType.FULL,
1734
1804
  errors: validated ? errors : null,
1805
+ inputWarnNode: isSlPriceWarning && /* @__PURE__ */ jsxRuntime.jsx(
1806
+ ui.DotStatus,
1807
+ {
1808
+ color: "warning",
1809
+ size: "xs",
1810
+ label: getErrorMsg("sl_trigger_price")
1811
+ }
1812
+ ),
1735
1813
  quote_dp: symbolInfo.quote_dp,
1736
1814
  positionType: formattedOrder.position_type ?? types.PositionType.PARTIAL,
1737
1815
  onChange: (key, value) => {
@@ -1831,8 +1909,14 @@ var useTPSLAdvanced = (props) => {
1831
1909
  tp_offset_percentage: order2.tp_offset_percentage
1832
1910
  }
1833
1911
  });
1912
+ const slPriceError = hooks.useTpslPriceChecker({
1913
+ slPrice: formattedOrder.sl_trigger_price,
1914
+ liqPrice: state.estLiqPrice,
1915
+ side: formattedOrder.side
1916
+ });
1834
1917
  const onSubmit = () => {
1835
- helper.validate().then(() => {
1918
+ const isSlPriceError = slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_ERROR;
1919
+ helper.validate(isSlPriceError ? slPriceError : void 0).then(() => {
1836
1920
  props.onSubmit(formattedOrder);
1837
1921
  }).catch((err) => {
1838
1922
  });
@@ -1841,6 +1925,8 @@ var useTPSLAdvanced = (props) => {
1841
1925
  order: order2,
1842
1926
  formattedOrder,
1843
1927
  symbolInfo,
1928
+ slPriceError,
1929
+ estLiqPrice: state.estLiqPrice,
1844
1930
  setValue,
1845
1931
  setValues,
1846
1932
  onSubmit,
@@ -1936,13 +2022,16 @@ var useTPSLDetail = (props) => {
1936
2022
  var TPSLDetailContext = react.createContext({});
1937
2023
  var TPSLDetailProvider = (props) => {
1938
2024
  const symbolInfo = hooks.useSymbolsInfo()[props.symbol];
2025
+ const estLiqPrice = hooks.useEstLiqPriceBySymbol(props.symbol);
1939
2026
  return /* @__PURE__ */ jsxRuntime.jsx(
1940
2027
  TPSLDetailContext.Provider,
1941
2028
  {
1942
2029
  value: {
1943
2030
  base_dp: symbolInfo("base_dp"),
1944
2031
  quote_dp: symbolInfo("quote_dp"),
1945
- position: props.position
2032
+ side: props.position.position_qty > 0 ? types.OrderSide.BUY : types.OrderSide.SELL,
2033
+ position: props.position,
2034
+ estLiqPrice
1946
2035
  },
1947
2036
  children: props.children
1948
2037
  }
@@ -1958,7 +2047,7 @@ var FlexCell = (props) => {
1958
2047
  direction: "column",
1959
2048
  justify: "center",
1960
2049
  itemAlign: "start",
1961
- className: "oui-text-2xs oui-h-[36px]",
2050
+ className: ui.cn("oui-text-2xs oui-h-[36px]", props.className),
1962
2051
  children: props.children
1963
2052
  }
1964
2053
  );
@@ -2085,9 +2174,65 @@ var TriggerPrice = ({ order: order2 }) => {
2085
2174
  }
2086
2175
  );
2087
2176
  };
2177
+ var CloseToLiqPriceIcon = ({
2178
+ slPriceError,
2179
+ className
2180
+ }) => {
2181
+ const { t } = i18n.useTranslation();
2182
+ const { isMobile } = ui.useScreen();
2183
+ const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(slPriceError);
2184
+ const isSlPriceWarning = slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
2185
+ const icon = /* @__PURE__ */ jsxRuntime.jsx(
2186
+ ui.ExclamationFillIcon,
2187
+ {
2188
+ onMouseEnter: (e) => e.stopPropagation(),
2189
+ onMouseLeave: (e) => e.stopPropagation(),
2190
+ onPointerEnter: (e) => e.stopPropagation(),
2191
+ onPointerLeave: (e) => e.stopPropagation(),
2192
+ size: 14,
2193
+ className: ui.cn(
2194
+ "oui-text-warning-darken hover:oui-cursor-pointer",
2195
+ className
2196
+ )
2197
+ }
2198
+ );
2199
+ if (!isSlPriceWarning || !slPriceError)
2200
+ return null;
2201
+ if (isMobile) {
2202
+ return /* @__PURE__ */ jsxRuntime.jsx(
2203
+ "button",
2204
+ {
2205
+ onClick: (e) => {
2206
+ ui.modal.alert({
2207
+ title: t("common.tips"),
2208
+ message: getErrorMsg("sl_trigger_price")
2209
+ });
2210
+ },
2211
+ className: "oui-px-1",
2212
+ children: icon
2213
+ }
2214
+ );
2215
+ }
2216
+ return /* @__PURE__ */ jsxRuntime.jsx(
2217
+ ui.Tooltip,
2218
+ {
2219
+ content: getErrorMsg("sl_trigger_price"),
2220
+ className: "oui-max-w-[240px] oui-text-base-contrast-80",
2221
+ children: icon
2222
+ }
2223
+ );
2224
+ };
2225
+ CloseToLiqPriceIcon.displayName = "CloseToLiqPriceIcon";
2088
2226
  var TypeRender = ({ order: order2 }) => {
2227
+ const { side, estLiqPrice } = useTPSLDetailContext();
2089
2228
  const { tp_trigger_price, sl_trigger_price } = hooks.findTPSLFromOrder(order2);
2090
2229
  const { t } = i18n.useTranslation();
2230
+ const slPriceError = hooks.useTpslPriceChecker({
2231
+ slPrice: sl_trigger_price?.toString() ?? void 0,
2232
+ liqPrice: estLiqPrice ?? null,
2233
+ side
2234
+ });
2235
+ const isSlPriceWarning = slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
2091
2236
  return /* @__PURE__ */ jsxRuntime.jsxs(
2092
2237
  ui.Flex,
2093
2238
  {
@@ -2097,7 +2242,10 @@ var TypeRender = ({ order: order2 }) => {
2097
2242
  className: "oui-text-2xs",
2098
2243
  children: [
2099
2244
  tp_trigger_price && /* @__PURE__ */ jsxRuntime.jsx(FlexCell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-trade-profit", children: t("tpsl.tp") }) }),
2100
- sl_trigger_price && /* @__PURE__ */ jsxRuntime.jsx(FlexCell, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-trade-loss", children: t("tpsl.sl") }) })
2245
+ sl_trigger_price && /* @__PURE__ */ jsxRuntime.jsxs(FlexCell, { className: "oui-flex-row oui-items-center oui-gap-1", children: [
2246
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-trade-loss", children: t("tpsl.sl") }),
2247
+ isSlPriceWarning && /* @__PURE__ */ jsxRuntime.jsx(CloseToLiqPriceIcon, { slPriceError })
2248
+ ] })
2101
2249
  ]
2102
2250
  }
2103
2251
  );
@@ -2389,6 +2537,7 @@ var TPSLDetailUI = (props) => {
2389
2537
  addTPSLOrder,
2390
2538
  symbolInfo
2391
2539
  } = props;
2540
+ const { estLiqPrice } = useTPSLDetailContext();
2392
2541
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.ScrollArea, { className: ui.cn(isMobile && "oui-h-[calc(100vh-100px)]"), children: [
2393
2542
  /* @__PURE__ */ jsxRuntime.jsx(
2394
2543
  OrderInfo,
@@ -2398,6 +2547,7 @@ var TPSLDetailUI = (props) => {
2398
2547
  order_quantity: position.position_qty.toString(),
2399
2548
  order_price: position.average_open_price.toString()
2400
2549
  },
2550
+ estLiqPrice,
2401
2551
  symbolLeverage: position.leverage,
2402
2552
  baseDP: symbolInfo("base_dp"),
2403
2553
  quoteDP: symbolInfo("quote_dp"),
@@ -3073,8 +3223,19 @@ var useEditBracketOrder = (props) => {
3073
3223
  props.order
3074
3224
  );
3075
3225
  const [doUpdateOrder, { isMutating }] = hooks.useMutation("/v1/algo/order", "PUT");
3076
- const { formattedOrder, setValue, setValues, metaState, symbolInfo, helper } = hooks.useOrderEntry(props.order.symbol, {
3077
- initialOrder: baseInfo
3226
+ const maxQty = useEditOrderMaxQty(props.order, props.order.quantity);
3227
+ const {
3228
+ formattedOrder,
3229
+ setValue,
3230
+ setValues,
3231
+ estLiqPrice,
3232
+ metaState,
3233
+ symbolInfo,
3234
+ helper,
3235
+ ...state
3236
+ } = hooks.useOrderEntry(props.order.symbol, {
3237
+ initialOrder: baseInfo,
3238
+ maxQty
3078
3239
  });
3079
3240
  const symbol = props.order.symbol;
3080
3241
  const isPriceChanged = react.useMemo(() => {
@@ -3116,8 +3277,14 @@ var useEditBracketOrder = (props) => {
3116
3277
  ...tpslPriceInfo
3117
3278
  });
3118
3279
  }, [props.order, setValues]);
3280
+ const slPriceError = hooks.useTpslPriceChecker({
3281
+ slPrice: formattedOrder.sl_trigger_price,
3282
+ liqPrice: estLiqPrice,
3283
+ side: formattedOrder.side
3284
+ });
3285
+ const isSlPriceError = slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_ERROR;
3119
3286
  const onSubmit = async () => {
3120
- return helper.validate().then(() => {
3287
+ return helper.validate(isSlPriceError ? slPriceError : void 0).then(() => {
3121
3288
  const tpOrder = {
3122
3289
  order_id: tpInfo.orderId,
3123
3290
  algo_type: types.AlgoOrderType.TAKE_PROFIT,
@@ -3157,6 +3324,9 @@ var useEditBracketOrder = (props) => {
3157
3324
  return {
3158
3325
  symbol,
3159
3326
  symbolInfo,
3327
+ slPriceError,
3328
+ estLiqPrice,
3329
+ side: formattedOrder.side,
3160
3330
  formattedOrder,
3161
3331
  setValue,
3162
3332
  setValues,
@@ -3166,10 +3336,22 @@ var useEditBracketOrder = (props) => {
3166
3336
  isPriceChanged
3167
3337
  };
3168
3338
  };
3339
+ function useEditOrderMaxQty(order2, positionQty) {
3340
+ const { reduce_only } = order2;
3341
+ const maxQty = hooks.useMaxQty(order2.symbol, order2.side, reduce_only);
3342
+ return react.useMemo(() => {
3343
+ if (reduce_only) {
3344
+ return Math.abs(positionQty ?? 0);
3345
+ }
3346
+ return order2.quantity + Math.abs(maxQty);
3347
+ }, [order2.quantity, maxQty, reduce_only, positionQty]);
3348
+ }
3169
3349
  var EditBracketOrderUI = (props) => {
3170
3350
  const { t } = i18n.useTranslation();
3171
3351
  const { errors, validated } = props.metaState;
3172
3352
  const { isMobile } = ui.useScreen();
3353
+ const isSlPriceWarning = props.slPriceError?.sl_trigger_price?.type === hooks.ERROR_MSG_CODES.SL_PRICE_WARNING;
3354
+ const { getErrorMsg } = reactApp.useOrderEntryFormErrorMsg(props.slPriceError);
3173
3355
  const {
3174
3356
  formattedOrder,
3175
3357
  setValue: setOrderValue,
@@ -3237,6 +3419,7 @@ var EditBracketOrderUI = (props) => {
3237
3419
  order_quantity: formattedOrder.order_quantity,
3238
3420
  order_price: formattedOrder.order_price
3239
3421
  },
3422
+ estLiqPrice: props.estLiqPrice ?? void 0,
3240
3423
  baseDP: symbolInfo.base_dp,
3241
3424
  quoteDP: symbolInfo.quote_dp
3242
3425
  }
@@ -3310,6 +3493,14 @@ var EditBracketOrderUI = (props) => {
3310
3493
  side: formattedOrder.side,
3311
3494
  values: slValues,
3312
3495
  hideOrderPrice: formattedOrder.position_type === types.PositionType.FULL,
3496
+ inputWarnNode: isSlPriceWarning && /* @__PURE__ */ jsxRuntime.jsx(
3497
+ ui.DotStatus,
3498
+ {
3499
+ color: "warning",
3500
+ size: "xs",
3501
+ label: getErrorMsg("sl_trigger_price")
3502
+ }
3503
+ ),
3313
3504
  errors: validated ? errors : null,
3314
3505
  quote_dp: symbolInfo.quote_dp,
3315
3506
  positionType: formattedOrder.position_type ?? types.PositionType.PARTIAL,
@@ -3373,6 +3564,7 @@ ui.registerSimpleDialog(EditBracketOrderDialogId, EditBracketOrderWidget, {
3373
3564
  });
3374
3565
 
3375
3566
  exports.ArrowRightIcon = ArrowRightIcon;
3567
+ exports.CloseToLiqPriceIcon = CloseToLiqPriceIcon;
3376
3568
  exports.EditBracketOrderDialogId = EditBracketOrderDialogId;
3377
3569
  exports.EditBracketOrderSheetId = EditBracketOrderSheetId;
3378
3570
  exports.EditBracketOrderWidget = EditBracketOrderWidget;