@orderly.network/ui-positions 2.10.2 → 3.0.0-beta.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.js CHANGED
@@ -598,7 +598,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
598
598
  return positions2.map((item) => {
599
599
  const info = symbolsInfo[item.symbol];
600
600
  const notional = perp.positions.notional(item.position_qty, item.mark_price);
601
- const account2 = accountInfo.find(
601
+ const account3 = accountInfo.find(
602
602
  (acc) => acc.account_id === item.account_id
603
603
  );
604
604
  const baseMMR = info?.("base_mmr");
@@ -609,7 +609,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
609
609
  const MMR = perp.positions.MMR({
610
610
  baseMMR,
611
611
  baseIMR,
612
- IMRFactor: account2?.imr_factor[item.symbol] ?? 0,
612
+ IMRFactor: account3?.imr_factor[item.symbol] ?? 0,
613
613
  positionNotional: notional,
614
614
  IMR_factor_power: 4 / 5
615
615
  });
@@ -627,7 +627,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
627
627
  const imr = perp.account.IMR({
628
628
  maxLeverage,
629
629
  baseIMR,
630
- IMR_Factor: account2?.imr_factor[item.symbol] ?? 0,
630
+ IMR_Factor: account3?.imr_factor[item.symbol] ?? 0,
631
631
  positionNotional: notional,
632
632
  ordersNotional: 0,
633
633
  IMR_factor_power: 4 / 5
@@ -656,7 +656,7 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
656
656
  const filteredTPSLOrders = tpslOrders.filter(
657
657
  (tpslOrder) => tpslOrder.account_id === item.account_id
658
658
  );
659
- const tpsl = formatTPSL(filteredTPSLOrders, item.symbol);
659
+ const tpsl = formatTPSL(filteredTPSLOrders, item.symbol, item.margin_mode);
660
660
  return {
661
661
  ...item,
662
662
  ...tpsl,
@@ -669,9 +669,9 @@ var calculatePositions = (positions2, symbolsInfo, accountInfo, tpslOrders) => {
669
669
  };
670
670
  });
671
671
  };
672
- function formatTPSL(tpslOrders, symbol) {
672
+ function formatTPSL(tpslOrders, symbol, marginMode) {
673
673
  if (Array.isArray(tpslOrders) && tpslOrders.length) {
674
- const { fullPositionOrder, partialPositionOrders } = hooks.findPositionTPSLFromOrders(tpslOrders, symbol);
674
+ const { fullPositionOrder, partialPositionOrders } = hooks.findPositionTPSLFromOrders(tpslOrders, symbol, marginMode);
675
675
  const full_tp_sl = fullPositionOrder ? hooks.findTPSLFromOrder(fullPositionOrder) : void 0;
676
676
  const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
677
677
  const partial_tp_sl = partialPossitionOrder ? hooks.findTPSLFromOrder(partialPossitionOrder) : void 0;
@@ -690,7 +690,7 @@ function formatTPSL(tpslOrders, symbol) {
690
690
  };
691
691
  }
692
692
  }
693
- var signatureMiddleware = (account2, accountId) => {
693
+ var signatureMiddleware = (account3, accountId) => {
694
694
  const apiBaseUrl = hooks.useConfig("apiBaseUrl");
695
695
  return (useSWRNext) => {
696
696
  return (key, fetcher2, config) => {
@@ -698,7 +698,7 @@ var signatureMiddleware = (account2, accountId) => {
698
698
  const extendedFetcher = async (args) => {
699
699
  const url = Array.isArray(args) ? args[0] : args;
700
700
  const fullUrl = `${apiBaseUrl}${url}`;
701
- const signer = account2.signer;
701
+ const signer = account3.signer;
702
702
  const payload = { method: "GET", url };
703
703
  const signature = await signer.sign(payload, utils.getTimestamp());
704
704
  const ids = Array.isArray(accountId) ? accountId : [accountId];
@@ -722,7 +722,7 @@ var signatureMiddleware = (account2, accountId) => {
722
722
  };
723
723
  var useSubAccountQuery = (query, options) => {
724
724
  const { formatter, accountId, ...swrOptions } = options || {};
725
- const { state, account: account2 } = hooks.useAccount();
725
+ const { state, account: account3 } = hooks.useAccount();
726
726
  const middleware = Array.isArray(options?.use) ? options?.use ?? [] : [];
727
727
  const ids = Array.isArray(accountId) ? accountId : [accountId];
728
728
  const shouldFetch = ids.filter(Boolean).length && (state.status >= types.AccountStatusEnum.EnableTrading || state.status === types.AccountStatusEnum.EnableTradingWithoutConnected);
@@ -733,7 +733,7 @@ var useSubAccountQuery = (query, options) => {
733
733
  },
734
734
  {
735
735
  ...swrOptions,
736
- use: [...middleware, signatureMiddleware(account2, ids)],
736
+ use: [...middleware, signatureMiddleware(account3, ids)],
737
737
  onError: () => {
738
738
  }
739
739
  }
@@ -1268,7 +1268,9 @@ var useReversePositionScript = (options) => {
1268
1268
  order_type: types.OrderType.MARKET,
1269
1269
  side,
1270
1270
  order_quantity: new utils.Decimal(qty).todp(baseDp).toString(),
1271
- reduce_only: reduceOnly
1271
+ reduce_only: reduceOnly,
1272
+ // Use position's margin_mode or default to CROSS for backward compatibility
1273
+ margin_mode: position.margin_mode || types.MarginMode.CROSS
1272
1274
  };
1273
1275
  };
1274
1276
  const closeSide = isLong ? types.OrderSide.SELL : types.OrderSide.BUY;
@@ -1604,6 +1606,619 @@ var RwaStatusTag = ({ symbol }) => {
1604
1606
  }
1605
1607
  );
1606
1608
  };
1609
+ var usePositionMargin = (symbol, isAdd, isolatedMargin, finalMargin) => {
1610
+ const { freeCollateral, freeCollateralUSDCOnly, usdcHolding } = hooks.useCollateral(
1611
+ {
1612
+ dp: 2
1613
+ }
1614
+ );
1615
+ const positions2 = hooks.usePositions();
1616
+ const total_cross_unsettled_pnl = React2.useMemo(() => {
1617
+ return positions2?.filter((item) => (item.margin_mode ?? "CROSS") === "CROSS").reduce((acc, item) => acc.add(item.unsettled_pnl), new utils.Decimal(0));
1618
+ }, [positions2]);
1619
+ const fundingRates = hooks.useAppStore((state) => state.fundingRates);
1620
+ const symbolsInfo = hooks.useAppStore((state) => state.symbolsInfo);
1621
+ const accountInfo = hooks.useAppStore((state) => state.accountInfo);
1622
+ const { data: markPrice } = hooks.useMarkPrice(symbol);
1623
+ const totalUnsettlementPnl = React2.useMemo(() => {
1624
+ if (!positions2?.length) {
1625
+ return null;
1626
+ }
1627
+ return positions2.reduce((acc, item) => {
1628
+ const itemAny = item;
1629
+ const positionUnsettlementPnl = itemAny["unsettlement_pnl"] ?? item.unsettled_pnl ?? 0;
1630
+ return acc.add(positionUnsettlementPnl);
1631
+ }, new utils.Decimal(0));
1632
+ }, [positions2]);
1633
+ const currentPosition = React2.useMemo(() => {
1634
+ return positions2?.find(
1635
+ (item) => item.symbol === symbol && item.margin_mode === types.MarginMode.ISOLATED
1636
+ );
1637
+ }, [positions2]);
1638
+ const notional = React2.useMemo(() => {
1639
+ if (!currentPosition) return null;
1640
+ return new utils.Decimal(currentPosition.notional);
1641
+ }, [currentPosition]);
1642
+ const unSettledPnl = React2.useMemo(() => {
1643
+ if (!currentPosition || !notional || !fundingRates) return null;
1644
+ const fundingRate = fundingRates[currentPosition.symbol];
1645
+ return notional.sub(new utils.Decimal(currentPosition.cost_position)).sub(
1646
+ new utils.Decimal(currentPosition.position_qty).mul(
1647
+ new utils.Decimal(fundingRate.sum_unitary_funding ?? 0).sub(
1648
+ new utils.Decimal(currentPosition.last_sum_unitary_funding)
1649
+ )
1650
+ )
1651
+ );
1652
+ }, [notional, currentPosition, fundingRates]);
1653
+ const imr = React2.useMemo(() => {
1654
+ if (!currentPosition || !symbolsInfo?.[symbol] || !notional) {
1655
+ return null;
1656
+ }
1657
+ const currentSymbolInfo = symbolsInfo[symbol];
1658
+ const maxLeverage = Math.max(currentPosition.leverage ?? 1, 1);
1659
+ const IMR_Factor = accountInfo?.imr_factor?.[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
1660
+ return new utils.Decimal(
1661
+ perp.account.IMR({
1662
+ maxLeverage,
1663
+ baseIMR: currentSymbolInfo.base_imr ?? 0,
1664
+ IMR_Factor,
1665
+ positionNotional: notional.toNumber(),
1666
+ ordersNotional: 0
1667
+ })
1668
+ );
1669
+ }, [currentPosition, symbolsInfo, symbol, notional, accountInfo]);
1670
+ const maxAmount = React2.useMemo(() => {
1671
+ if (isAdd) {
1672
+ if (!freeCollateralUSDCOnly) return null;
1673
+ return Math.max(0, freeCollateralUSDCOnly);
1674
+ }
1675
+ if (!imr || !notional || isolatedMargin === void 0 || isolatedMargin === null || !currentPosition) {
1676
+ return null;
1677
+ }
1678
+ const positionNotional = notional;
1679
+ const imrValue = imr;
1680
+ const unsettledPnlValue = unSettledPnl ?? new utils.Decimal(0);
1681
+ return perp.account.maxReduce({
1682
+ isolatedPositionMargin: isolatedMargin,
1683
+ positionNotional: positionNotional.toNumber(),
1684
+ imr: imrValue.toNumber(),
1685
+ positionUnsettledPnL: unsettledPnlValue.toNumber()
1686
+ });
1687
+ }, [
1688
+ total_cross_unsettled_pnl,
1689
+ usdcHolding,
1690
+ isAdd,
1691
+ freeCollateral,
1692
+ unSettledPnl,
1693
+ isolatedMargin
1694
+ ]);
1695
+ const liquidationPrice = React2.useMemo(() => {
1696
+ if (!totalUnsettlementPnl || !currentPosition || !symbolsInfo?.[symbol] || !accountInfo?.imr_factor) {
1697
+ return null;
1698
+ }
1699
+ const currentSymbolInfo = symbolsInfo[symbol];
1700
+ const currentPositionNotional = notional?.toNumber() ?? 0;
1701
+ const currentPositionIMRFactor = accountInfo.imr_factor[symbol] ?? currentSymbolInfo.imr_factor ?? 0;
1702
+ const currentPositionMMR = perp.positions.MMR({
1703
+ baseMMR: currentSymbolInfo.base_mmr ?? 0,
1704
+ baseIMR: currentSymbolInfo.base_imr ?? 0,
1705
+ IMRFactor: currentPositionIMRFactor,
1706
+ positionNotional: currentPositionNotional,
1707
+ IMR_factor_power: 4 / 5
1708
+ });
1709
+ const otherPositions = positions2?.filter((item) => item.symbol !== symbol).map((item) => {
1710
+ const itemSymbolInfo = symbolsInfo[item.symbol];
1711
+ const itemIMRFactor = accountInfo.imr_factor[item.symbol] ?? itemSymbolInfo?.imr_factor ?? 0;
1712
+ const itemNotional = item.notional ?? new utils.Decimal(item.position_qty).mul(item.mark_price).abs().toNumber();
1713
+ const itemMMR = item.mmr ?? perp.positions.MMR({
1714
+ baseMMR: itemSymbolInfo?.base_mmr ?? 0,
1715
+ baseIMR: itemSymbolInfo?.base_imr ?? 0,
1716
+ IMRFactor: itemIMRFactor,
1717
+ positionNotional: itemNotional,
1718
+ IMR_factor_power: 4 / 5
1719
+ });
1720
+ return {
1721
+ symbol: item.symbol,
1722
+ position_qty: item.position_qty,
1723
+ mark_price: item.mark_price,
1724
+ mmr: itemMMR
1725
+ };
1726
+ }) ?? [];
1727
+ const totalCollateral = new utils.Decimal(finalMargin).add(currentPosition.unsettled_pnl ?? 0).toNumber();
1728
+ const liqPrice = perp.positions.liqPrice({
1729
+ markPrice,
1730
+ symbol,
1731
+ totalCollateral,
1732
+ positionQty: currentPosition.position_qty,
1733
+ positions: otherPositions,
1734
+ MMR: currentPositionMMR,
1735
+ baseMMR: currentSymbolInfo.base_mmr ?? 0,
1736
+ baseIMR: currentSymbolInfo.base_imr ?? 0,
1737
+ IMRFactor: currentPositionIMRFactor,
1738
+ costPosition: currentPosition.cost_position ?? 0
1739
+ });
1740
+ return liqPrice;
1741
+ }, [
1742
+ totalUnsettlementPnl,
1743
+ currentPosition,
1744
+ symbolsInfo,
1745
+ symbol,
1746
+ accountInfo,
1747
+ notional,
1748
+ positions2,
1749
+ finalMargin,
1750
+ markPrice
1751
+ ]);
1752
+ const total_collateral_value = React2.useMemo(() => {
1753
+ if (!unSettledPnl) return null;
1754
+ return new utils.Decimal(finalMargin).add(unSettledPnl).toNumber();
1755
+ }, [unSettledPnl, finalMargin]);
1756
+ const effectiveLeverage = React2.useMemo(() => {
1757
+ if (!notional || !total_collateral_value) return null;
1758
+ return notional.div(total_collateral_value).toNumber();
1759
+ }, [notional, total_collateral_value]);
1760
+ return {
1761
+ maxAmount,
1762
+ liquidationPrice,
1763
+ effectiveLeverage
1764
+ };
1765
+ };
1766
+ var usePositionMargin_default = usePositionMargin;
1767
+
1768
+ // src/components/positions/adjustMargin/adjustMargin.script.tsx
1769
+ var useAdjustMarginScript = (props) => {
1770
+ const { position, symbol, close } = props;
1771
+ const { t } = i18n.useTranslation();
1772
+ const [tab, setTab] = React2.useState("add");
1773
+ const [inputValue, setInputValue] = React2.useState("");
1774
+ const [sliderValue, setSliderValue] = React2.useState(0);
1775
+ const [updateMargin, { isMutating: isLoading }] = hooks.useMutation(
1776
+ "/v1/position_margin",
1777
+ "POST"
1778
+ );
1779
+ const isAdd = React2.useMemo(() => {
1780
+ return tab === "add";
1781
+ }, [tab]);
1782
+ const currentMargin = position.margin ?? 0;
1783
+ const finalMargin = React2.useMemo(() => {
1784
+ const delta = new utils.Decimal(inputValue || 0);
1785
+ if (tab === "add") return currentMargin + delta.toNumber();
1786
+ return currentMargin - delta.toNumber();
1787
+ }, [currentMargin, inputValue, tab]);
1788
+ const { maxAmount, liquidationPrice, effectiveLeverage } = usePositionMargin_default(
1789
+ symbol,
1790
+ isAdd,
1791
+ currentMargin,
1792
+ finalMargin
1793
+ );
1794
+ const syncSliderFromInput = React2.useCallback(
1795
+ (value) => {
1796
+ if (!value) {
1797
+ setSliderValue(0);
1798
+ return;
1799
+ }
1800
+ if (!maxAmount) return;
1801
+ const val = new utils.Decimal(value);
1802
+ if (maxAmount === 0) {
1803
+ setSliderValue(0);
1804
+ return;
1805
+ }
1806
+ const percent = val.div(maxAmount).mul(100).toNumber();
1807
+ setSliderValue(Math.min(100, Math.max(0, percent)));
1808
+ },
1809
+ [maxAmount]
1810
+ );
1811
+ const syncInputFromSlider = React2.useCallback(
1812
+ (value) => {
1813
+ if (!maxAmount) return;
1814
+ const val = new utils.Decimal(maxAmount).mul(value).div(100);
1815
+ setInputValue(val.toFixed(2, utils.Decimal.ROUND_DOWN));
1816
+ },
1817
+ [maxAmount]
1818
+ );
1819
+ const onInputChange = React2.useCallback(
1820
+ (value) => {
1821
+ let finalValue = value;
1822
+ if (maxAmount && value) {
1823
+ const inputDecimal = new utils.Decimal(value);
1824
+ if (inputDecimal.gt(maxAmount)) {
1825
+ finalValue = new utils.Decimal(maxAmount).toFixed(2, utils.Decimal.ROUND_DOWN);
1826
+ }
1827
+ }
1828
+ setInputValue(finalValue);
1829
+ syncSliderFromInput(finalValue);
1830
+ },
1831
+ [syncSliderFromInput, maxAmount]
1832
+ );
1833
+ const onSliderChange = React2.useCallback(
1834
+ (value) => {
1835
+ setSliderValue(value);
1836
+ syncInputFromSlider(value);
1837
+ },
1838
+ [syncInputFromSlider]
1839
+ );
1840
+ const onTabChange = React2.useCallback((nextTab) => {
1841
+ setTab(nextTab);
1842
+ setInputValue("");
1843
+ setSliderValue(0);
1844
+ }, []);
1845
+ const canConfirm = React2.useMemo(() => {
1846
+ if (!inputValue) return false;
1847
+ const value = new utils.Decimal(inputValue);
1848
+ return !value.isZero() && value.isPositive();
1849
+ }, [inputValue]);
1850
+ const onConfirm = React2.useCallback(async () => {
1851
+ if (!inputValue || new utils.Decimal(inputValue).isZero()) return;
1852
+ if (maxAmount) {
1853
+ const inputDecimal = new utils.Decimal(inputValue);
1854
+ if (inputDecimal.gt(maxAmount)) {
1855
+ ui.toast.error(t("positions.adjustMargin.marginCannotMoreThanMax"));
1856
+ return;
1857
+ }
1858
+ }
1859
+ try {
1860
+ const payload = {
1861
+ symbol,
1862
+ amount: new utils.Decimal(inputValue).toString(),
1863
+ type: tab === "add" ? "ADD" : "REDUCE"
1864
+ };
1865
+ const response = await updateMargin(payload);
1866
+ if (!response?.success) {
1867
+ ui.toast.error(response?.message || t("positions.adjustMargin.failed"));
1868
+ return;
1869
+ }
1870
+ ui.toast.success(t("positions.adjustMargin.success"));
1871
+ close();
1872
+ } catch (error) {
1873
+ const message = error instanceof Error ? error.message : void 0;
1874
+ ui.toast.error(message || t("positions.adjustMargin.failed"));
1875
+ }
1876
+ }, [close, inputValue, symbol, t, tab, updateMargin, maxAmount]);
1877
+ return {
1878
+ symbol,
1879
+ tab,
1880
+ inputValue,
1881
+ sliderValue,
1882
+ maxAmount: maxAmount ?? 0,
1883
+ currentMargin,
1884
+ liquidationPrice: liquidationPrice ?? 0,
1885
+ effectiveLeverage: effectiveLeverage ?? 0,
1886
+ isLoading,
1887
+ isAdd,
1888
+ canConfirm,
1889
+ onTabChange,
1890
+ onInputChange,
1891
+ onSliderChange,
1892
+ onConfirm,
1893
+ close
1894
+ };
1895
+ };
1896
+ var Footer = (props) => {
1897
+ const { t } = i18n.useTranslation();
1898
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 3, className: "oui-w-full oui-pt-5", children: [
1899
+ /* @__PURE__ */ jsxRuntime.jsx(
1900
+ ui.Button,
1901
+ {
1902
+ variant: "contained",
1903
+ fullWidth: true,
1904
+ size: "lg",
1905
+ color: "secondary",
1906
+ className: "oui-h-10",
1907
+ onClick: props.close,
1908
+ children: t("common.cancel")
1909
+ }
1910
+ ),
1911
+ /* @__PURE__ */ jsxRuntime.jsx(
1912
+ ui.Button,
1913
+ {
1914
+ variant: "contained",
1915
+ color: "primary",
1916
+ fullWidth: true,
1917
+ size: "lg",
1918
+ className: "oui-h-10",
1919
+ loading: props.isLoading,
1920
+ disabled: !props.canConfirm,
1921
+ onClick: props.onConfirm,
1922
+ children: t("common.confirm")
1923
+ }
1924
+ )
1925
+ ] });
1926
+ };
1927
+ var fotter_default = Footer;
1928
+ var Infos = ({
1929
+ currentMargin,
1930
+ liquidationPrice,
1931
+ effectiveLeverage
1932
+ }) => {
1933
+ const { t } = i18n.useTranslation();
1934
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1935
+ ui.Flex,
1936
+ {
1937
+ direction: "column",
1938
+ gap: 1,
1939
+ className: "oui-w-full oui-rounded-[6px] oui-bg-base-6 oui-p-3 oui-text-2xs oui-font-semibold",
1940
+ children: [
1941
+ /* @__PURE__ */ jsxRuntime.jsx(
1942
+ ui.Statistic,
1943
+ {
1944
+ label: t("positions.adjustMargin.currentMargin"),
1945
+ valueProps: { dp: 2, unit: " USDC", padding: false },
1946
+ classNames: {
1947
+ root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
1948
+ label: "oui-text-2xs"
1949
+ },
1950
+ children: currentMargin
1951
+ }
1952
+ ),
1953
+ /* @__PURE__ */ jsxRuntime.jsx(
1954
+ ui.Statistic,
1955
+ {
1956
+ label: t("positions.adjustMargin.liqPriceAfter"),
1957
+ valueProps: { dp: 2, unit: " USDC", padding: false },
1958
+ classNames: {
1959
+ root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
1960
+ label: "oui-text-2xs"
1961
+ },
1962
+ children: liquidationPrice ?? "--"
1963
+ }
1964
+ ),
1965
+ /* @__PURE__ */ jsxRuntime.jsx(
1966
+ ui.Statistic,
1967
+ {
1968
+ label: t("positions.adjustMargin.leverageAfter"),
1969
+ valueProps: { dp: 2, unit: " x" },
1970
+ classNames: {
1971
+ root: "oui-flex-row oui-justify-between oui-items-center oui-w-full oui-text-2xs oui-h-5",
1972
+ label: "oui-text-2xs"
1973
+ },
1974
+ children: effectiveLeverage ?? "--"
1975
+ }
1976
+ )
1977
+ ]
1978
+ }
1979
+ );
1980
+ };
1981
+ var MarginActions = ({
1982
+ isAdd,
1983
+ onTabChange
1984
+ }) => {
1985
+ const { t } = i18n.useTranslation();
1986
+ const tabBase = "oui-h-7 oui-rounded-[4px] oui-text-xs oui-font-semibold oui-transition-colors";
1987
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-w-full oui-gap-[6px]", children: [
1988
+ /* @__PURE__ */ jsxRuntime.jsx(
1989
+ ui.Button,
1990
+ {
1991
+ size: "md",
1992
+ fullWidth: true,
1993
+ variant: "contained",
1994
+ color: "secondary",
1995
+ className: ui.cn(
1996
+ tabBase,
1997
+ isAdd && "oui-bg-base-5 oui-text-base-contrast-98",
1998
+ !isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
1999
+ ),
2000
+ onClick: () => onTabChange("add"),
2001
+ children: t("positions.adjustMargin.add")
2002
+ }
2003
+ ),
2004
+ /* @__PURE__ */ jsxRuntime.jsx(
2005
+ ui.Button,
2006
+ {
2007
+ size: "sm",
2008
+ fullWidth: true,
2009
+ variant: "contained",
2010
+ color: "secondary",
2011
+ className: ui.cn(
2012
+ tabBase,
2013
+ !isAdd && "oui-bg-base-5 oui-text-base-contrast-98 hover:oui-text-base-contrast-80",
2014
+ isAdd && "oui-bg-base-7 oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
2015
+ ),
2016
+ onClick: () => onTabChange("reduce"),
2017
+ children: t("positions.adjustMargin.reduce")
2018
+ }
2019
+ )
2020
+ ] });
2021
+ };
2022
+ var Quantity = ({
2023
+ inputValue,
2024
+ sliderValue,
2025
+ maxAmount,
2026
+ onInputChange,
2027
+ onSliderChange
2028
+ }) => {
2029
+ const { t } = i18n.useTranslation();
2030
+ const percentMarks = React2.useMemo(
2031
+ () => [0, 25, 50, 75, 100].map((m) => ({ value: m, label: `${m}%` })),
2032
+ []
2033
+ );
2034
+ const isMaxClickable = maxAmount > 0;
2035
+ const handleSetToMax = React2.useCallback(() => {
2036
+ if (!isMaxClickable) return;
2037
+ onSliderChange(100);
2038
+ }, [isMaxClickable, onSliderChange]);
2039
+ const handleKeyDown = React2.useCallback(
2040
+ (e) => {
2041
+ if (e.key === "Enter" || e.key === " ") {
2042
+ e.preventDefault();
2043
+ handleSetToMax();
2044
+ }
2045
+ },
2046
+ [handleSetToMax]
2047
+ );
2048
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 3, className: "oui-w-full", children: [
2049
+ /* @__PURE__ */ jsxRuntime.jsx(
2050
+ ui.Input,
2051
+ {
2052
+ value: inputValue,
2053
+ onValueChange: onInputChange,
2054
+ type: "text",
2055
+ fullWidth: true,
2056
+ size: "lg",
2057
+ align: "right",
2058
+ prefix: t("positions.adjustMargin.quantity"),
2059
+ suffix: "USDC",
2060
+ formatters: [
2061
+ ui.inputFormatter.numberFormatter,
2062
+ ui.inputFormatter.dpFormatter(2)
2063
+ ],
2064
+ disabled: maxAmount === null || maxAmount <= 0,
2065
+ autoComplete: "off",
2066
+ classNames: {
2067
+ // Keep border color stable and remove focus ring (Input has focus-within:outline-primary-light by default)
2068
+ root: "oui-rounded-[6px] oui-bg-base-6 oui-border oui-border-solid oui-border-white/[0.12] oui-outline oui-outline-1 oui-outline-offset-0 oui-outline-transparent focus-within:oui-outline-transparent",
2069
+ // keep value aligned to suffix side and match design emphasis
2070
+ input: "oui-text-sm oui-font-semibold oui-text-base-contrast-98",
2071
+ // override default additional padding so value can sit closer to suffix
2072
+ additional: "oui-px-0",
2073
+ prefix: "oui-pl-3 oui-pr-2 oui-text-sm oui-text-base-contrast-54",
2074
+ suffix: "oui-pl-2 oui-pr-3 oui-text-sm oui-text-base-contrast-54"
2075
+ }
2076
+ }
2077
+ ),
2078
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 2, className: "oui-w-full", children: [
2079
+ /* @__PURE__ */ jsxRuntime.jsx(
2080
+ ui.Slider,
2081
+ {
2082
+ value: [sliderValue],
2083
+ onValueChange: (val) => onSliderChange(val[0]),
2084
+ max: 100,
2085
+ min: 0,
2086
+ step: 1,
2087
+ color: "primary",
2088
+ showTip: true,
2089
+ tipFormatter: (v, _min, _max, percent) => `${percent.toFixed(0)}%`,
2090
+ marks: percentMarks,
2091
+ markLabelVisible: false,
2092
+ disabled: maxAmount === null || maxAmount <= 0
2093
+ }
2094
+ ),
2095
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
2096
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: `${sliderValue.toFixed(0)}%` }),
2097
+ /* @__PURE__ */ jsxRuntime.jsxs(
2098
+ ui.Flex,
2099
+ {
2100
+ gap: 1,
2101
+ itemAlign: "baseline",
2102
+ role: isMaxClickable ? "button" : void 0,
2103
+ tabIndex: isMaxClickable ? 0 : void 0,
2104
+ onClick: isMaxClickable ? handleSetToMax : void 0,
2105
+ onKeyDown: isMaxClickable ? handleKeyDown : void 0,
2106
+ className: isMaxClickable ? "oui-cursor-pointer oui-opacity-90 hover:oui-opacity-100" : void 0,
2107
+ children: [
2108
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: t("positions.adjustMargin.max") }),
2109
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { size: "2xs", intensity: 54, dp: 2, children: maxAmount })
2110
+ ]
2111
+ }
2112
+ )
2113
+ ] })
2114
+ ] })
2115
+ ] });
2116
+ };
2117
+ var SymbolInfo = ({ symbol }) => {
2118
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-2", children: [
2119
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol, className: "oui-size-5" }),
2120
+ /* @__PURE__ */ jsxRuntime.jsx(
2121
+ ui.Text.formatted,
2122
+ {
2123
+ rule: "symbol",
2124
+ formatString: "base-type",
2125
+ size: "base",
2126
+ weight: "semibold",
2127
+ intensity: 98,
2128
+ children: symbol
2129
+ }
2130
+ )
2131
+ ] });
2132
+ };
2133
+ var Title = ({ close }) => {
2134
+ const { t } = i18n.useTranslation();
2135
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full", children: [
2136
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", itemAlign: "center", children: [
2137
+ /* @__PURE__ */ jsxRuntime.jsx(
2138
+ ui.Text,
2139
+ {
2140
+ className: "oui-text-base oui-leading-6 oui-font-semibold oui-tracking-[0.48px]",
2141
+ intensity: 98,
2142
+ children: t("positions.adjustMargin.title")
2143
+ }
2144
+ ),
2145
+ /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: close, color: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: 18, color: "white", opacity: 0.98 }) })
2146
+ ] }),
2147
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-mt-[9px] oui-w-full" })
2148
+ ] });
2149
+ };
2150
+ var title_default = Title;
2151
+ var AdjustMargin = (props) => {
2152
+ const {
2153
+ symbol,
2154
+ inputValue,
2155
+ sliderValue,
2156
+ maxAmount,
2157
+ currentMargin,
2158
+ liquidationPrice,
2159
+ effectiveLeverage,
2160
+ onTabChange,
2161
+ onInputChange,
2162
+ onSliderChange,
2163
+ close,
2164
+ isAdd
2165
+ } = props;
2166
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2167
+ ui.Flex,
2168
+ {
2169
+ direction: "column",
2170
+ className: "oui-w-full oui-rounded-[12px] oui-bg-base-8 oui-font-semibold",
2171
+ children: [
2172
+ /* @__PURE__ */ jsxRuntime.jsx(title_default, { close }),
2173
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-w-full oui-pt-5", children: [
2174
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolInfo, { symbol }),
2175
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 4, className: "oui-mt-4 oui-w-full", children: [
2176
+ /* @__PURE__ */ jsxRuntime.jsx(MarginActions, { isAdd, onTabChange }),
2177
+ /* @__PURE__ */ jsxRuntime.jsx(
2178
+ Quantity,
2179
+ {
2180
+ inputValue,
2181
+ sliderValue,
2182
+ maxAmount,
2183
+ onInputChange,
2184
+ onSliderChange
2185
+ }
2186
+ ),
2187
+ /* @__PURE__ */ jsxRuntime.jsx(
2188
+ Infos,
2189
+ {
2190
+ currentMargin,
2191
+ liquidationPrice,
2192
+ effectiveLeverage
2193
+ }
2194
+ )
2195
+ ] })
2196
+ ] }),
2197
+ /* @__PURE__ */ jsxRuntime.jsx(fotter_default, { ...props })
2198
+ ]
2199
+ }
2200
+ );
2201
+ };
2202
+ var AdjustMarginDialogId = "AdjustMarginDialog";
2203
+ var AdjustMarginSheetId = "AdjustMarginSheet";
2204
+ var AdjustMarginWidget = (props) => {
2205
+ const { isMobile } = ui.useScreen();
2206
+ const state = useAdjustMarginScript({
2207
+ position: props.position,
2208
+ symbol: props.symbol,
2209
+ close: () => ui.modal.hide(isMobile ? AdjustMarginSheetId : AdjustMarginDialogId)
2210
+ });
2211
+ return /* @__PURE__ */ jsxRuntime.jsx(AdjustMargin, { ...state });
2212
+ };
2213
+ ui.registerSimpleDialog(AdjustMarginDialogId, AdjustMarginWidget, {
2214
+ title: void 0,
2215
+ closable: false,
2216
+ size: "sm"
2217
+ });
2218
+ ui.registerSimpleSheet(AdjustMarginSheetId, AdjustMarginWidget, {
2219
+ title: void 0,
2220
+ closable: false
2221
+ });
1607
2222
  var QuantitySlider = (props) => {
1608
2223
  const { t } = i18n.useTranslation();
1609
2224
  const [sliderValue, setSliderValue] = React2.useState(props.value);
@@ -2260,29 +2875,59 @@ var AddIcon = (props) => {
2260
2875
  );
2261
2876
  };
2262
2877
  var LeverageBadge = (props) => {
2263
- const { symbol, leverage } = props;
2878
+ const { symbol, leverage, marginMode } = props;
2879
+ const { t } = i18n.useTranslation();
2880
+ const resolvedMarginMode = marginMode;
2264
2881
  const showModal = () => {
2265
2882
  ui.modal.show(props.modalId, {
2266
2883
  symbol,
2267
- curLeverage: Number(leverage)
2884
+ curLeverage: leverage,
2885
+ marginMode: resolvedMarginMode
2268
2886
  });
2269
2887
  };
2270
- return /* @__PURE__ */ jsxRuntime.jsx(
2271
- "div",
2272
- {
2273
- className: ui.cn(
2274
- "oui-flex oui-h-[18px] oui-items-center oui-gap-1",
2275
- "oui-cursor-pointer oui-rounded oui-bg-line-6 oui-px-2",
2276
- "oui-text-2xs oui-font-semibold oui-text-base-contrast-36"
2277
- ),
2278
- onClick: showModal,
2279
- children: leverage ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage }) : /* @__PURE__ */ jsxRuntime.jsx(LeverageDisplay, { symbol })
2280
- }
2281
- );
2888
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-gap-1", children: [
2889
+ /* @__PURE__ */ jsxRuntime.jsx(
2890
+ "div",
2891
+ {
2892
+ className: ui.cn(
2893
+ "oui-flex oui-h-[18px] oui-items-center",
2894
+ "oui-rounded oui-bg-line-6 oui-px-2",
2895
+ "oui-text-2xs oui-font-semibold oui-text-base-contrast-36"
2896
+ ),
2897
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: resolvedMarginMode === void 0 ? "--" : resolvedMarginMode === types.MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross") })
2898
+ }
2899
+ ),
2900
+ /* @__PURE__ */ jsxRuntime.jsxs(
2901
+ "div",
2902
+ {
2903
+ className: ui.cn(
2904
+ "oui-flex oui-h-[18px] oui-items-center oui-gap-1",
2905
+ "oui-rounded oui-bg-line-6 oui-px-2",
2906
+ "oui-text-2xs oui-font-semibold oui-text-base-contrast-36",
2907
+ "oui-cursor-pointer"
2908
+ ),
2909
+ onClick: showModal,
2910
+ children: [
2911
+ leverage === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(LeverageDisplay, { symbol, marginMode }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage }),
2912
+ /* @__PURE__ */ jsxRuntime.jsx(
2913
+ ui.ChevronRightIcon,
2914
+ {
2915
+ size: 12,
2916
+ className: "oui-text-base-contrast-36",
2917
+ opacity: 1
2918
+ }
2919
+ )
2920
+ ]
2921
+ }
2922
+ )
2923
+ ] });
2282
2924
  };
2283
- var LeverageDisplay = ({ symbol }) => {
2284
- const leverage = hooks.useLeverageBySymbol(symbol);
2285
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage || 1 });
2925
+ var LeverageDisplay = ({
2926
+ symbol,
2927
+ marginMode
2928
+ }) => {
2929
+ const leverage = hooks.useLeverageBySymbol(symbol, marginMode);
2930
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: leverage === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: "--" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 0, rm: utils.Decimal.ROUND_DOWN, size: "2xs", unit: "X", children: leverage }) });
2286
2931
  };
2287
2932
  var renderQuantity = (value) => {
2288
2933
  const symbolInfo = useSymbolContext();
@@ -2436,11 +3081,13 @@ var useShareButtonScript = (props) => {
2436
3081
  const { position, sharePnLConfig, iconSize } = props;
2437
3082
  const { getFirstRefCode } = hooks.useReferralInfo();
2438
3083
  const symbolsInfo = hooks.useSymbolsInfo();
2439
- const { data: accountInfo } = hooks.useAccountInfo();
2440
3084
  const refCode = React2.useMemo(() => {
2441
3085
  return getFirstRefCode()?.code;
2442
3086
  }, [getFirstRefCode]);
2443
- const symbolLeverage = hooks.useLeverageBySymbol(position.symbol);
3087
+ const symbolLeverage = hooks.useLeverageBySymbol(
3088
+ position.symbol,
3089
+ position.margin_mode ?? types.MarginMode.CROSS
3090
+ );
2444
3091
  const getHistoryEntity = () => {
2445
3092
  const netPnL = position.netPnL || 0;
2446
3093
  const openPrice = Math.abs(position.avg_open_price);
@@ -2449,10 +3096,22 @@ var useShareButtonScript = (props) => {
2449
3096
  const symbolInfo = symbolsInfo[position.symbol];
2450
3097
  const baseIMR = symbolInfo("base_imr");
2451
3098
  const IMR_Factor = symbolInfo("imr_factor");
2452
- if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 && accountInfo?.max_leverage && baseIMR && // IMR_Factor is possible to be 0
3099
+ if (netPnL !== 0 && quantity !== 0 && openPrice !== 0 && baseIMR && // IMR_Factor is possible to be 0
2453
3100
  typeof IMR_Factor !== "undefined") {
2454
3101
  const notional = perp.positions.notional(quantity, openPrice);
2455
- const maxLeverage = position.leverage ? position.leverage : accountInfo.max_leverage;
3102
+ const maxLeverage = position.leverage || symbolLeverage;
3103
+ if (!maxLeverage) {
3104
+ return {
3105
+ side: position.side,
3106
+ pnl: netPnL,
3107
+ roi,
3108
+ openPrice,
3109
+ closePrice: Math.abs(position.avg_close_price),
3110
+ openTime: position.open_timestamp,
3111
+ closeTime: position.close_timestamp,
3112
+ quantity: position.closed_position_qty
3113
+ };
3114
+ }
2456
3115
  const imr = perp.account.IMR({
2457
3116
  maxLeverage,
2458
3117
  baseIMR,
@@ -2496,7 +3155,8 @@ var useShareButtonScript = (props) => {
2496
3155
  symbol: position.symbol,
2497
3156
  // when position.leverage is empty, use leverage from useSymbolLeverage
2498
3157
  leverage: position.leverage || symbolLeverage,
2499
- ...entity
3158
+ ...entity,
3159
+ marginMode: position.margin_mode
2500
3160
  },
2501
3161
  refCode,
2502
3162
  ...sharePnLConfig
@@ -2811,7 +3471,7 @@ var useColumn = (config) => {
2811
3471
  positionReverse
2812
3472
  } = config;
2813
3473
  const { t } = i18n.useTranslation();
2814
- React2.useRef(Date.now().toString());
3474
+ const { isMobile } = ui.useScreen();
2815
3475
  const column = React2.useMemo(
2816
3476
  () => [
2817
3477
  {
@@ -2854,7 +3514,8 @@ var useColumn = (config) => {
2854
3514
  {
2855
3515
  symbol: value,
2856
3516
  leverage: record.leverage,
2857
- modalId: uiLeverage.SymbolLeverageDialogId
3517
+ modalId: uiLeverage.SymbolLeverageDialogId,
3518
+ marginMode: record.margin_mode
2858
3519
  }
2859
3520
  ),
2860
3521
  /* @__PURE__ */ jsxRuntime.jsx(RwaStatusTag, { symbol: value })
@@ -3043,17 +3704,13 @@ var useColumn = (config) => {
3043
3704
  ui.Tooltip,
3044
3705
  {
3045
3706
  className: "oui-max-w-[280px] oui-bg-base-8 oui-p-3 oui-text-2xs oui-text-base-contrast-54",
3046
- content: /* @__PURE__ */ jsxRuntime.jsxs(
3707
+ content: /* @__PURE__ */ jsxRuntime.jsx(
3047
3708
  ui.Flex,
3048
3709
  {
3049
3710
  direction: "column",
3050
3711
  gap: 3,
3051
3712
  className: "oui-rounded-sm oui-bg-base-8 oui-text-base-contrast-54",
3052
- children: [
3053
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.tooltip") }),
3054
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
3055
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.formula") })
3056
- ]
3713
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("positions.column.margin.tooltip") })
3057
3714
  }
3058
3715
  ),
3059
3716
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") })
@@ -3063,7 +3720,26 @@ var useColumn = (config) => {
3063
3720
  onSort: true,
3064
3721
  width: 140,
3065
3722
  rule: "price",
3066
- render: (value) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { children: value })
3723
+ render: (value, record) => {
3724
+ const isIsolated = record.margin_mode === "ISOLATED";
3725
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, itemAlign: "center", children: [
3726
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { children: isIsolated ? record.margin ?? "--" : "--" }),
3727
+ isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
3728
+ ui.IconButton,
3729
+ {
3730
+ color: "secondary",
3731
+ onClick: (e) => {
3732
+ e.stopPropagation();
3733
+ ui.modal.show(AdjustMarginDialogId, {
3734
+ position: record,
3735
+ symbol: record.symbol
3736
+ });
3737
+ },
3738
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
3739
+ }
3740
+ )
3741
+ ] });
3742
+ }
3067
3743
  },
3068
3744
  // {
3069
3745
  // title: t("funding.fundingFee"),
@@ -3128,7 +3804,8 @@ var SymbolToken = (props) => {
3128
3804
  {
3129
3805
  symbol: item.symbol,
3130
3806
  leverage: item.leverage,
3131
- modalId: uiLeverage.SymbolLeverageSheetId
3807
+ modalId: uiLeverage.SymbolLeverageSheetId,
3808
+ marginMode: item.margin_mode
3132
3809
  }
3133
3810
  )
3134
3811
  ] }),
@@ -3211,11 +3888,8 @@ var Qty = (props) => {
3211
3888
  var Margin = (props) => {
3212
3889
  const { item } = props;
3213
3890
  const { t } = i18n.useTranslation();
3214
- const marginTipsContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-text-2xs oui-text-base-contrast-80", children: [
3215
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("positions.column.margin.tooltip") }),
3216
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-my-2 oui-h-px oui-w-full oui-bg-base-8" }),
3217
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("positions.column.margin.formula") })
3218
- ] });
3891
+ const isIsolated = item.margin_mode === "ISOLATED";
3892
+ const marginTipsContent = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-text-2xs oui-text-base-contrast-80", children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("positions.column.margin.tooltip") }) });
3219
3893
  const marginLabel = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-underline oui-decoration-dotted", children: t("positions.column.margin") });
3220
3894
  return /* @__PURE__ */ jsxRuntime.jsx(
3221
3895
  ui.Statistic,
@@ -3232,7 +3906,23 @@ var Margin = (props) => {
3232
3906
  root: "oui-text-xs",
3233
3907
  label: "oui-text-2xs"
3234
3908
  },
3235
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 2, intensity: 80, children: item.mm })
3909
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
3910
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { dp: 2, intensity: 80, children: isIsolated ? item.margin ?? "--" : "--" }),
3911
+ isIsolated && /* @__PURE__ */ jsxRuntime.jsx(
3912
+ ui.IconButton,
3913
+ {
3914
+ color: "secondary",
3915
+ onClick: (e) => {
3916
+ e.stopPropagation();
3917
+ ui.modal.show(AdjustMarginSheetId, {
3918
+ position: item,
3919
+ symbol: item.symbol
3920
+ });
3921
+ },
3922
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { size: 16, fill: "currentColor", opacity: 1 })
3923
+ }
3924
+ )
3925
+ ] })
3236
3926
  }
3237
3927
  );
3238
3928
  };
@@ -3637,7 +4327,7 @@ var Positions = (props) => {
3637
4327
  columns,
3638
4328
  bordered: true,
3639
4329
  dataSource,
3640
- generatedRowKey: (record) => record.symbol,
4330
+ generatedRowKey: (record, index) => `${record.symbol}-${index}`,
3641
4331
  renderRowContainer: (record, index, children) => {
3642
4332
  return /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children: /* @__PURE__ */ jsxRuntime.jsx(PositionsRowProvider, { position: record, children }) });
3643
4333
  },
@@ -3709,7 +4399,7 @@ var CombinePositions = (props) => {
3709
4399
  dataSource,
3710
4400
  expanded: true,
3711
4401
  getSubRows: (row) => row.children,
3712
- generatedRowKey: (record) => `${record.account_id}${record.symbol || ""}`,
4402
+ generatedRowKey: (record, index) => `${record.account_id}${record.symbol || ""}-${index}`,
3713
4403
  onCell: (column, record) => {
3714
4404
  const isGroup = (record.children ?? []).length > 0;
3715
4405
  if (isGroup) {
@@ -3768,14 +4458,14 @@ var usePositionHistoryColumn = (props) => {
3768
4458
  onSort: (r1, r2) => {
3769
4459
  return r1.symbol?.localeCompare(r2.symbol || "");
3770
4460
  },
3771
- render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(SymbolInfo, { record, onSymbolChange })
4461
+ render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(SymbolInfo2, { record, onSymbolChange })
3772
4462
  },
3773
4463
  // quantity
3774
4464
  {
3775
4465
  title: t("positions.history.column.closed&maxClosed"),
3776
4466
  dataIndex: "close_maxClose",
3777
4467
  width: 200,
3778
- render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(Quantity, { record })
4468
+ render: (value, record) => /* @__PURE__ */ jsxRuntime.jsx(Quantity2, { record })
3779
4469
  },
3780
4470
  // net pnl
3781
4471
  {
@@ -3883,7 +4573,7 @@ var usePositionHistoryColumn = (props) => {
3883
4573
  );
3884
4574
  return column;
3885
4575
  };
3886
- var SymbolInfo = (props) => {
4576
+ var SymbolInfo2 = (props) => {
3887
4577
  const { record, onSymbolChange } = props;
3888
4578
  const { t } = i18n.useTranslation();
3889
4579
  const tags = React2.useMemo(() => {
@@ -3997,7 +4687,7 @@ var SymbolInfo = (props) => {
3997
4687
  ] })
3998
4688
  ] });
3999
4689
  };
4000
- var Quantity = (props) => {
4690
+ var Quantity2 = (props) => {
4001
4691
  const { record } = props;
4002
4692
  const { base_dp } = useSymbolContext();
4003
4693
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4130,6 +4820,8 @@ var usePositionHistoryScript = (props) => {
4130
4820
  const netPnL = item.realized_pnl - item.accumulated_funding_fee - item.trading_fee;
4131
4821
  return {
4132
4822
  ...item,
4823
+ // convert margin_mode to MarginMode
4824
+ margin_mode: item.margin_mode === 1 || item.margin_mode === types.MarginMode.ISOLATED ? types.MarginMode.ISOLATED : types.MarginMode.CROSS,
4133
4825
  netPnL
4134
4826
  };
4135
4827
  }
@@ -4743,7 +5435,7 @@ var PositionHistory = (props) => {
4743
5435
  columns: column,
4744
5436
  bordered: true,
4745
5437
  dataSource: props.dataSource,
4746
- generatedRowKey: (record) => `${record.symbol}_${record.position_id}`,
5438
+ generatedRowKey: (record, index) => `${record.symbol}_${record.position_id}_${index}`,
4747
5439
  renderRowContainer: (record, index, children) => /* @__PURE__ */ jsxRuntime.jsx(SymbolProvider, { symbol: record.symbol, children }),
4748
5440
  manualPagination: false,
4749
5441
  pagination,
@@ -5536,7 +6228,8 @@ var useCloseAllPositionsScript = (options) => {
5536
6228
  order_type: types.OrderType.MARKET,
5537
6229
  side,
5538
6230
  order_quantity: quantity,
5539
- reduce_only: true
6231
+ reduce_only: true,
6232
+ margin_mode: position.margin_mode
5540
6233
  };
5541
6234
  }),
5542
6235
  []