@orderly.network/ui-order-entry 3.0.0-beta.1 → 3.0.0-beta.2

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
@@ -547,1225 +547,799 @@ var EditIcon = (props) => {
547
547
  }
548
548
  );
549
549
  };
550
- var RegularFeesUI = (props) => {
551
- const { t } = i18n.useTranslation();
552
- const { taker, maker } = props;
553
- const originalTrailingFees = /* @__PURE__ */ jsxRuntime.jsx(
554
- ui.Flex,
555
- {
556
- itemAlign: "center",
557
- justify: "between",
558
- width: "100%",
559
- gap: 1,
560
- className: "oui-orderEntry-fees",
561
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", itemAlign: "center", justify: "between", children: [
562
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-fees-label oui-truncate", size: "2xs", children: t("common.fees") }),
563
- /* @__PURE__ */ jsxRuntime.jsx(
564
- uiConnector.AuthGuard,
565
- {
566
- fallback: () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
567
- t("dmm.taker"),
568
- ": --% / ",
569
- t("dmm.maker"),
570
- ": --%"
571
- ] }),
572
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, className: "oui-fees-value-container", children: [
573
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
574
- t("dmm.taker"),
575
- ":"
576
- ] }),
577
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-base-contrast-80", children: taker }),
578
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: "/" }),
579
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
580
- t("dmm.maker"),
581
- ":"
582
- ] }),
583
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-base-contrast-80", children: maker })
584
- ] })
585
- }
586
- )
587
- ] })
550
+ function isBBOOrder(options2) {
551
+ const { order_type, order_type_ext } = options2;
552
+ const isBBO = [types.OrderType.ASK, types.OrderType.BID].includes(order_type_ext);
553
+ if (order_type) {
554
+ return order_type === types.OrderType.LIMIT && isBBO;
555
+ }
556
+ return isBBO;
557
+ }
558
+ function getOrderTypeByBBO(value, size) {
559
+ if ([types.BBOOrderType.COUNTERPARTY1, types.BBOOrderType.COUNTERPARTY5].includes(value)) {
560
+ return size === types.OrderSide.BUY ? types.OrderType.ASK : types.OrderType.BID;
561
+ }
562
+ if ([types.BBOOrderType.QUEUE1, types.BBOOrderType.QUEUE5].includes(value)) {
563
+ return size === types.OrderSide.BUY ? types.OrderType.BID : types.OrderType.ASK;
564
+ }
565
+ }
566
+ function getOrderLevelByBBO(value) {
567
+ if ([types.BBOOrderType.COUNTERPARTY1, types.BBOOrderType.QUEUE1].includes(value)) {
568
+ return types.OrderLevel.ONE;
569
+ }
570
+ if ([types.BBOOrderType.COUNTERPARTY5, types.BBOOrderType.QUEUE5].includes(value)) {
571
+ return types.OrderLevel.FIVE;
572
+ }
573
+ }
574
+ function getScaledPlaceOrderMessage(result) {
575
+ const rows = result?.data?.rows || [];
576
+ if (rows.length > 0) {
577
+ const totalCount = rows.length;
578
+ const successCount = rows.filter((row) => row.success).length;
579
+ if (successCount === totalCount) {
580
+ return i18n.i18n.t("orderEntry.scaledOrder.fullySuccessful", {
581
+ total: totalCount
582
+ });
588
583
  }
589
- );
590
- return originalTrailingFees;
591
- };
592
- var RegularFeesWidget = (props) => {
593
- return /* @__PURE__ */ jsxRuntime.jsx(RegularFeesUI, { ...props });
594
- };
595
- var FeesWidget = ({ symbol }) => {
596
- const { takerFee, makerFee, rwaTakerFee, rwaMakerFee } = hooks.useFeeState();
597
- const info = hooks.useRwaSymbolsInfoStore();
598
- const isRwa = info?.[symbol] !== void 0;
599
- return /* @__PURE__ */ jsxRuntime.jsx(
600
- RegularFeesWidget,
601
- {
602
- taker: isRwa ? rwaTakerFee : takerFee,
603
- maker: isRwa ? rwaMakerFee : makerFee
584
+ if (successCount === 0) {
585
+ return i18n.i18n.t("orderEntry.scaledOrder.allFailed");
604
586
  }
587
+ return i18n.i18n.t("orderEntry.scaledOrder.partiallySuccessful", {
588
+ successCount,
589
+ total: totalCount
590
+ });
591
+ }
592
+ }
593
+ var safeNumber = (val) => {
594
+ return Number.isNaN(Number(val)) ? 0 : Number(val);
595
+ };
596
+ var SymbolBadge = (props) => {
597
+ const { brokerId, brokerName, brokerNameRaw } = hooks.useBadgeBySymbol(
598
+ props.symbol
605
599
  );
600
+ const badge = brokerName ?? brokerId ?? void 0;
601
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.SymbolBadge, { badge, fullName: brokerNameRaw });
606
602
  };
607
- var options = [0.01, 0.05, 0.1];
608
- var SlippageEditor = React3.forwardRef((props, ref) => {
603
+ var OrderConfirmDialog = (props) => {
604
+ const { symbolInfo, order, onConfirm, onCancel } = props;
605
+ const { quote, quote_dp, base_dp } = symbolInfo;
606
+ const { side, order_type, order_type_ext, level, symbol } = order;
607
+ const orderMarginMode = order.margin_mode;
609
608
  const { t } = i18n.useTranslation();
610
- const [value, setValue] = React3.useState();
611
- const [customValue, setCustomValue] = React3.useState("");
612
- const [error, setError] = React3.useState(void 0);
613
- React3.useImperativeHandle(ref, () => ({
614
- getValue: () => customValue ? new utils.Decimal(customValue)?.toNumber() : value
615
- }));
616
- React3.useEffect(() => {
617
- if (props.initialValue && !options.includes(props.initialValue)) {
618
- setCustomValue(props.initialValue.toString());
619
- } else {
620
- setValue(props.initialValue);
609
+ const [{ rows: positions }] = hooks.usePositionStream(symbol);
610
+ const position = React3.useMemo(
611
+ () => orderMarginMode != null ? positions?.find(
612
+ (row) => row.symbol === symbol && row.margin_mode === orderMarginMode
613
+ ) : positions?.[0],
614
+ [positions, symbol, orderMarginMode]
615
+ );
616
+ const positionQty = position?.position_qty;
617
+ const [_, setNeedConfirm] = hooks.useLocalStorage("orderly_order_confirm", true);
618
+ const renderPositionType = () => {
619
+ if (order.position_type === types.PositionType.FULL) {
620
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.full") });
621
621
  }
622
- }, [props.initialValue, open]);
623
- const onClick = (val) => {
624
- setValue(val);
625
- setCustomValue("");
626
- setError(void 0);
622
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.partial") });
627
623
  };
628
- const onValueChange = (val) => {
629
- if (!val) {
630
- setCustomValue(val);
631
- return;
624
+ const renderPrice = () => {
625
+ if (order_type === types.OrderType.MARKET || order_type === types.OrderType.STOP_MARKET) {
626
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: t("common.marketPrice") });
632
627
  }
633
- const d = new utils.Decimal(val);
634
- setValue(void 0);
635
- if (d.gt(3)) {
636
- setCustomValue("3");
637
- setError(t("orderEntry.slippage.error.exceed"));
638
- } else {
639
- setCustomValue(val);
640
- setError(void 0);
628
+ if (isBBOOrder({ order_type, order_type_ext })) {
629
+ const bboType = utils.getBBOType({
630
+ type: order_type_ext,
631
+ side,
632
+ level
633
+ });
634
+ const label = {
635
+ [types.BBOOrderType.COUNTERPARTY1]: t("orderEntry.bbo.counterparty1"),
636
+ [types.BBOOrderType.COUNTERPARTY5]: t("orderEntry.bbo.counterparty5"),
637
+ [types.BBOOrderType.QUEUE1]: t("orderEntry.bbo.queue1"),
638
+ [types.BBOOrderType.QUEUE5]: t("orderEntry.bbo.queue5")
639
+ }[bboType];
640
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: label });
641
641
  }
642
+ return /* @__PURE__ */ jsxRuntime.jsx(
643
+ ui.Text.numeral,
644
+ {
645
+ unit: quote,
646
+ rule: "price",
647
+ className: "oui-text-base-contrast",
648
+ unitClassName: "oui-text-base-contrast-36 oui-ml-1",
649
+ dp: quote_dp,
650
+ padding: false,
651
+ children: order.order_price
652
+ }
653
+ );
642
654
  };
643
- const toolTipButton = props.isMobile ? /* @__PURE__ */ jsxRuntime.jsx(
644
- "button",
645
- {
646
- onClick: () => {
647
- ui.modal.alert({
648
- title: t("common.tips"),
649
- message: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: t("orderEntry.slippage.tips") })
650
- });
651
- },
652
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.ExclamationFillIcon, { className: "oui-text-base-contrast-54", size: 16 })
655
+ const renderTPSLPrice = ({
656
+ price,
657
+ isOrderPrice,
658
+ isEnable,
659
+ colorType
660
+ }) => {
661
+ if (!isEnable) {
662
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: "-- USDC" });
653
663
  }
654
- ) : /* @__PURE__ */ jsxRuntime.jsx(
655
- ui.Tooltip,
656
- {
657
- content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, size: "2xs", children: t("orderEntry.slippage.tips") }),
658
- className: "oui-w-[260px] oui-bg-base-6",
659
- arrow: { className: "oui-fill-base-6" },
660
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.ExclamationFillIcon, { className: "oui-text-base-contrast-54", size: 16 }) })
664
+ if (!price) {
665
+ if (isOrderPrice) {
666
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: t("common.marketPrice") });
667
+ }
661
668
  }
662
- );
663
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-slippageEditor oui-text-2xs", children: [
664
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { mb: 2, gapX: 1, children: [
665
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.slippage") }),
666
- toolTipButton
667
- ] }),
668
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 2, children: [
669
- options.map((item) => {
670
- const isActive = value === item;
671
- return /* @__PURE__ */ jsxRuntime.jsx(
672
- SlippageItem,
673
- {
674
- value: item,
675
- isActive,
676
- onClick: () => {
677
- onClick(item);
678
- }
679
- },
680
- item
681
- );
682
- }),
669
+ return /* @__PURE__ */ jsxRuntime.jsx(
670
+ ui.Text.numeral,
671
+ {
672
+ unit: "USDC",
673
+ rule: "price",
674
+ className: ui.cn(
675
+ "oui-text-base-contrast",
676
+ colorType === "TP" ? "oui-text-trade-profit" : "oui-text-trade-loss"
677
+ ),
678
+ unitClassName: "oui-text-base-contrast-36 oui-ml-1",
679
+ dp: quote_dp,
680
+ padding: false,
681
+ children: price
682
+ }
683
+ );
684
+ };
685
+ const renderTPSLQty = () => {
686
+ if (!positionQty || !order.order_quantity) {
687
+ return null;
688
+ }
689
+ let qty = new utils.Decimal(order.order_quantity);
690
+ if (order.position_type === types.PositionType.FULL) {
691
+ qty = qty.plus(new utils.Decimal(positionQty ?? 0));
692
+ }
693
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
694
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: order.position_type === types.PositionType.FULL ? t("common.positionQty") : t("common.orderQty") }),
683
695
  /* @__PURE__ */ jsxRuntime.jsx(
684
- ui.Input,
696
+ ui.Text.numeral,
685
697
  {
686
- suffix: "%",
687
- formatters: [
688
- ui.inputFormatter.numberFormatter,
689
- ui.inputFormatter.dpFormatter(2)
690
- ],
691
- value: customValue,
692
- onValueChange,
693
- classNames: {
694
- root: ui.cn(
695
- "oui-slippageEditor-customInput",
696
- "oui-rounded-md oui-bg-base-6",
697
- "oui-h-[40px] oui-w-[74px]"
698
- ),
699
- input: "oui-text-base-contrast",
700
- additional: "oui-pl-1"
701
- }
698
+ rule: "price",
699
+ dp: base_dp,
700
+ padding: false,
701
+ className: "oui-text-base-contrast",
702
+ children: qty.toNumber()
702
703
  }
703
704
  )
704
- ] }),
705
- !!error && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { mt: 5, className: "-oui-mb-5", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", color: "danger", children: error }) })
706
- ] });
707
- });
708
- var SlippageItem = ({ value, isActive, onClick }) => {
709
- return /* @__PURE__ */ jsxRuntime.jsx(
710
- ui.Flex,
711
- {
712
- intensity: 600,
713
- justify: "center",
714
- itemAlign: "center",
715
- r: "md",
716
- width: 74,
717
- height: 40,
718
- className: ui.cn(
719
- "oui-slippageEditor-option",
720
- "oui-cursor-pointer oui-select-none",
721
- isActive ? "oui-bg-primary-light oui-text-primary-contrast/80" : "oui-text-base-contrast-80"
722
- ),
723
- onClick,
724
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "sm", children: [
725
- value,
726
- "%"
727
- ] })
728
- }
729
- );
730
- };
731
- var SlippageCell = (props) => {
732
- const { t } = i18n.useTranslation();
733
- const [open2, { setTrue: setOpen, setFalse: setClose, toggle }] = hooks.useBoolean(false);
734
- const { isMobile } = ui.useScreen();
735
- const slippageRef = React3.useRef(null);
736
- const onConfirm = () => {
737
- const val = slippageRef.current?.getValue();
738
- props.setSlippage(!val ? "1" : val.toString());
739
- setClose();
740
- return Promise.resolve(true);
705
+ ] });
741
706
  };
742
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
743
- /* @__PURE__ */ jsxRuntime.jsx(
744
- ui.SimpleDialog,
745
- {
746
- open: open2,
747
- onOpenChange: toggle,
748
- title: t("common.settings"),
749
- contentProps: { size: isMobile ? "xs" : "sm" },
750
- classNames: {
751
- footer: "oui-orderEntry-slippage-footer",
752
- body: "oui-orderEntry-slippage-body"
753
- },
754
- actions: {
755
- primary: {
756
- disabled: false,
757
- label: t("common.save"),
758
- onClick: onConfirm,
759
- className: "oui-slippage-save-btn"
760
- },
761
- secondary: {
762
- label: t("common.cancel"),
763
- onClick: () => setClose(),
764
- className: "oui-slippage-cancel-btn"
765
- }
766
- },
767
- children: /* @__PURE__ */ jsxRuntime.jsx(
768
- SlippageEditor,
707
+ const renderPriceAndTotal = () => {
708
+ if (order_type === types.OrderType.TRAILING_STOP) {
709
+ const { activated_price, callback_value, callback_rate } = order;
710
+ const callbackView = callback_rate ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
711
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.trailingRate") }),
712
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-text-base-contrast", children: [
713
+ callback_rate,
714
+ "%"
715
+ ] })
716
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
717
+ OrderItem,
718
+ {
719
+ title: t("orderEntry.trailingValue"),
720
+ value: callback_value,
721
+ unit: quote,
722
+ dp: quote_dp
723
+ }
724
+ );
725
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
726
+ activated_price && /* @__PURE__ */ jsxRuntime.jsx(
727
+ OrderItem,
769
728
  {
770
- ref: slippageRef,
771
- isMobile,
772
- initialValue: props.slippage ? Number(props.slippage) : void 0
729
+ title: t("common.triggerPrice"),
730
+ value: activated_price,
731
+ unit: quote,
732
+ dp: quote_dp
773
733
  }
774
- )
775
- }
776
- ),
777
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-orderEntry-slippage", children: [
778
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-slippage-label", size: "2xs", children: t("orderEntry.slippage") }),
734
+ ),
735
+ callbackView
736
+ ] });
737
+ }
738
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
739
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
740
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.price") }),
741
+ renderPrice()
742
+ ] }),
779
743
  /* @__PURE__ */ jsxRuntime.jsx(
780
- uiConnector.AuthGuard,
744
+ OrderItem,
781
745
  {
782
- fallback: () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "2xs", children: [
783
- t("orderEntry.slippage.est"),
784
- ": -% / ",
785
- t("common.max"),
786
- ": --%"
787
- ] }),
788
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, className: "oui-slippage-value-container", children: [
789
- /* @__PURE__ */ jsxRuntime.jsx(
790
- ui.Text.numeral,
791
- {
792
- size: "2xs",
793
- rule: "percentages",
794
- prefix: `${t("orderEntry.slippage.est")}: `,
795
- suffix: ` / ${t("common.max")}: `,
796
- children: props.estSlippage ?? 0
797
- }
798
- ),
799
- /* @__PURE__ */ jsxRuntime.jsx(
800
- "button",
801
- {
802
- className: "oui-slippage-edit-btn oui-text-2xs",
803
- onClick: () => setOpen(),
804
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-gap-0.5", as: "span", children: [
805
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: `${props.slippage || "-"}%` }),
806
- /* @__PURE__ */ jsxRuntime.jsx(
807
- ui.EditIcon,
808
- {
809
- className: "oui-slippage-edit-icon oui-text-primary oui-hidden md:oui-block",
810
- size: 12,
811
- opacity: 1
812
- }
813
- )
814
- ] })
815
- }
816
- )
817
- ] })
746
+ title: t("common.estTotal"),
747
+ value: order.total,
748
+ unit: quote,
749
+ dp: quote_dp
818
750
  }
819
751
  )
820
- ] })
821
- ] });
822
- };
823
- var SlippageUI = (props) => {
824
- return /* @__PURE__ */ jsxRuntime.jsx(SlippageCell, { ...props });
825
- };
826
- function AssetInfo(props) {
827
- const { canTrade, disableFeatures, orderType, symbol } = props;
828
- const { t } = i18n.useTranslation();
829
- const { isMobile } = ui.useScreen();
830
- const displayEstLiqPrice = hooks.useGetEstLiqPrice({
831
- estLiqPrice: props.estLiqPrice,
832
- symbol,
833
- side: props.side
834
- });
835
- return /* @__PURE__ */ jsxRuntime.jsxs(
836
- "div",
752
+ ] });
753
+ };
754
+ const header = /* @__PURE__ */ jsxRuntime.jsxs(
755
+ ui.Flex,
837
756
  {
838
- className: "oui-orderEntry-assetInfo oui-space-y-[2px] xl:oui-space-y-1",
757
+ justify: "between",
758
+ className: "oui-orderEntry-orderConfirmDialog-header",
839
759
  children: [
840
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-orderEntry-estLiqPrice", children: [
841
- isMobile ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: t("orderEntry.estLiqPrice") }) : /* @__PURE__ */ jsxRuntime.jsx(
842
- ui.Tooltip,
843
- {
844
- content: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-min-w-[204px] oui-max-w-[280px] oui-text-2xs oui-leading-normal oui-text-base-contrast-80", children: [
845
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-text-pretty", children: t("common.liquidationPrice.tooltip") }),
846
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
847
- "a",
848
- {
849
- href: "https://orderly.network/docs/introduction/trade-on-orderly/perpetual-futures/liquidations",
850
- target: "_blank",
851
- rel: "noopener noreferrer",
852
- className: "oui-text-primary oui-underline",
853
- children: t("common.liquidationPrice.tooltip.learnMore")
854
- }
855
- ) })
856
- ] }),
857
- children: /* @__PURE__ */ jsxRuntime.jsx(
858
- ui.Text,
859
- {
860
- size: "2xs",
861
- className: "oui-estLiqPrice-label oui-cursor-pointer oui-border-b oui-border-dashed oui-border-line-12",
862
- children: t("orderEntry.estLiqPrice")
863
- }
864
- )
865
- }
866
- ),
760
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, direction: "column", itemAlign: "start", children: [
867
761
  /* @__PURE__ */ jsxRuntime.jsx(
868
- ui.Text.numeral,
762
+ ui.Text.formatted,
869
763
  {
870
- unit: props.quote,
871
- size: "2xs",
872
- dp: props.dp,
873
- className: "oui-estLiqPrice-value oui-text-base-contrast-80",
874
- unitClassName: "oui-ml-1 oui-text-base-contrast-36",
875
- children: canTrade ? displayEstLiqPrice ?? "--" : "--"
764
+ rule: "symbol",
765
+ formatString: "base",
766
+ showIcon: true,
767
+ className: "oui-orderConfirmDialog-symbol",
768
+ children: order.symbol
876
769
  }
877
- )
770
+ ),
771
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol: order.symbol })
878
772
  ] }),
879
- orderType === types.OrderType.MARKET && !disableFeatures?.includes("slippageSetting") && /* @__PURE__ */ jsxRuntime.jsx(
880
- SlippageUI,
773
+ /* @__PURE__ */ jsxRuntime.jsxs(
774
+ ui.Flex,
881
775
  {
882
- slippage: props.slippage,
883
- setSlippage: props.setSlippage,
884
- estSlippage: props.estSlippage
776
+ justify: "end",
777
+ gapX: 1,
778
+ className: "oui-orderConfirmDialog-header-tags",
779
+ children: [
780
+ /* @__PURE__ */ jsxRuntime.jsx(OrderTypeTag, { type: order_type }),
781
+ side === types.OrderSide.BUY ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "buy", size: "sm", children: t("common.buy") }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "sell", size: "sm", children: t("common.sell") })
782
+ ]
885
783
  }
886
- ),
887
- !disableFeatures?.includes("feesInfo") && /* @__PURE__ */ jsxRuntime.jsx(FeesWidget, { symbol: props.symbol })
784
+ )
888
785
  ]
889
786
  }
890
787
  );
891
- }
892
- var calculateLTVColor = (val) => {
893
- if (val >= 0 && val < 50) {
894
- return "oui-text-success";
895
- } else if (val >= 50 && val < 80) {
896
- return "oui-text-warning";
897
- } else if (val >= 80) {
898
- return "oui-text-danger";
899
- } else {
900
- return "";
901
- }
902
- };
903
- var LTVRiskTooltipUI = (props) => {
904
- const { t } = i18n.useTranslation();
905
- const {
906
- ltv_threshold,
907
- negative_usdc_threshold,
908
- isThresholdLoading,
909
- holdingData = [],
910
- currentLtv,
911
- onConvert,
912
- marginMode
913
- } = props;
914
- return /* @__PURE__ */ jsxRuntime.jsxs(
915
- ui.Flex,
788
+ const quantityItem = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
789
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.orderQty") }),
790
+ /* @__PURE__ */ jsxRuntime.jsx(
791
+ ui.Text.numeral,
792
+ {
793
+ rule: "price",
794
+ dp: base_dp,
795
+ padding: false,
796
+ className: "oui-text-base-contrast",
797
+ children: order.order_quantity
798
+ }
799
+ )
800
+ ] });
801
+ const triggerPriceItem = (order_type === types.OrderType.STOP_LIMIT || order_type === types.OrderType.STOP_MARKET && order.trigger_price) && /* @__PURE__ */ jsxRuntime.jsx(
802
+ OrderItem,
916
803
  {
917
- gap: 1,
918
- className: "oui-orderEntry-ltvRiskTooltip oui-w-72 oui-max-w-72",
919
- direction: "column",
920
- itemAlign: "start",
921
- children: [
922
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", justify: "between", itemAlign: "center", children: [
923
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("common.assets") }),
924
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("transfer.deposit.collateralContribution") })
925
- ] }),
926
- holdingData.map((asset, index) => {
927
- return /* @__PURE__ */ jsxRuntime.jsxs(
804
+ title: t("common.trigger"),
805
+ value: order.trigger_price,
806
+ unit: quote,
807
+ dp: quote_dp
808
+ }
809
+ );
810
+ const tpslTriggerPrice = (order.tp_trigger_price || order.sl_trigger_price) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
811
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
812
+ /* @__PURE__ */ jsxRuntime.jsxs(
813
+ "div",
814
+ {
815
+ className: ui.textVariants({
816
+ size: "sm",
817
+ intensity: 54,
818
+ className: "oui-space-y-1 oui-w-full oui-flex oui-flex-col oui-gap-3"
819
+ }),
820
+ children: [
821
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast", children: renderPositionType() }),
822
+ renderTPSLQty(),
823
+ /* @__PURE__ */ jsxRuntime.jsxs(
928
824
  ui.Flex,
929
825
  {
930
- width: "100%",
826
+ direction: "column",
931
827
  justify: "between",
932
- itemAlign: "center",
828
+ itemAlign: "start",
829
+ gap: 1,
830
+ className: "oui-w-full",
933
831
  children: [
934
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, size: "xs", children: asset.token }),
935
- /* @__PURE__ */ jsxRuntime.jsx(
936
- ui.Text,
937
- {
938
- size: "xs",
939
- intensity: 80,
940
- className: ui.cn(
941
- Number(asset.collateralContribution) < 0 && "oui-text-warning"
942
- ),
943
- children: utils.removeTrailingZeros(asset.collateralContribution)
944
- }
945
- )
832
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
833
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpTriggerPrice") }),
834
+ renderTPSLPrice({
835
+ price: order.tp_trigger_price ?? "",
836
+ isOrderPrice: false,
837
+ isEnable: !!order.tp_trigger_price,
838
+ colorType: "TP"
839
+ })
840
+ ] }),
841
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
842
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpOrderPrice") }),
843
+ renderTPSLPrice({
844
+ price: order.tp_order_price ?? "",
845
+ isOrderPrice: true,
846
+ isEnable: !!order.tp_trigger_price,
847
+ colorType: "TP"
848
+ })
849
+ ] })
946
850
  ]
947
- },
948
- `item-${index}`
949
- );
950
- }),
951
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
952
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", justify: "between", itemAlign: "center", children: [
953
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("transfer.LTV.currentLTV") }),
851
+ }
852
+ ),
954
853
  /* @__PURE__ */ jsxRuntime.jsxs(
955
- ui.Text,
854
+ ui.Flex,
956
855
  {
957
- size: "xs",
958
- intensity: 36,
959
- className: ui.cn("oui-select-none", calculateLTVColor(currentLtv)),
856
+ direction: "column",
857
+ justify: "between",
858
+ itemAlign: "start",
859
+ gap: 1,
860
+ className: "oui-w-full",
960
861
  children: [
961
- currentLtv,
962
- "%"
862
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
863
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slTriggerPrice") }),
864
+ renderTPSLPrice({
865
+ price: order.sl_trigger_price ?? "",
866
+ isOrderPrice: false,
867
+ isEnable: !!order.sl_trigger_price,
868
+ colorType: "SL"
869
+ })
870
+ ] }),
871
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
872
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slOrderPrice") }),
873
+ renderTPSLPrice({
874
+ price: order.sl_order_price ?? "",
875
+ isOrderPrice: true,
876
+ isEnable: !!order.sl_trigger_price,
877
+ colorType: "SL"
878
+ })
879
+ ] })
963
880
  ]
964
881
  }
965
882
  )
966
- ] }),
967
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-py-2", intensity: 54, size: "2xs", children: t("transfer.LTV.tooltip", {
968
- threshold: isThresholdLoading ? "-" : ltv_threshold,
969
- usdcThreshold: isThresholdLoading ? "-" : negative_usdc_threshold
970
- }) }),
883
+ ]
884
+ }
885
+ )
886
+ ] });
887
+ const orderConfirmCheckbox = /* @__PURE__ */ jsxRuntime.jsxs(
888
+ ui.Flex,
889
+ {
890
+ gapX: 1,
891
+ pt: 4,
892
+ pb: 5,
893
+ className: "oui-orderEntry-orderConfirmDialog-disableConfirm",
894
+ children: [
895
+ /* @__PURE__ */ jsxRuntime.jsx(
896
+ ui.Checkbox,
897
+ {
898
+ id: "orderConfirm",
899
+ color: "white",
900
+ className: "oui-orderConfirmDialog-disableConfirm-checkbox",
901
+ onCheckedChange: (checked) => {
902
+ setNeedConfirm(!!!checked);
903
+ }
904
+ }
905
+ ),
906
+ /* @__PURE__ */ jsxRuntime.jsx(
907
+ "label",
908
+ {
909
+ htmlFor: "orderConfirm",
910
+ className: ui.textVariants({
911
+ size: "xs",
912
+ intensity: 54
913
+ }),
914
+ children: t("orderEntry.disableOrderConfirm")
915
+ }
916
+ )
917
+ ]
918
+ }
919
+ );
920
+ const buttons = /* @__PURE__ */ jsxRuntime.jsxs(
921
+ ui.Grid,
922
+ {
923
+ cols: 2,
924
+ gapX: 3,
925
+ className: "oui-orderEntry-orderConfirmDialog-actions",
926
+ children: [
971
927
  /* @__PURE__ */ jsxRuntime.jsx(
972
928
  ui.Button,
973
929
  {
974
- fullWidth: true,
975
- size: "md",
976
- variant: "outlined",
977
930
  color: "secondary",
978
- className: "oui-ltvRiskTooltip-convert-btn",
979
- onClick: onConvert,
980
- children: t("transfer.convert.convertAssets")
931
+ size: "md",
932
+ className: "oui-cancel-btn",
933
+ onClick: () => onCancel(),
934
+ children: t("common.cancel")
935
+ }
936
+ ),
937
+ /* @__PURE__ */ jsxRuntime.jsx(
938
+ ui.Button,
939
+ {
940
+ size: "md",
941
+ className: "oui-confirm-btn",
942
+ onClick: () => onConfirm(),
943
+ children: t("common.confirm")
981
944
  }
982
945
  )
983
946
  ]
984
947
  }
985
948
  );
949
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
950
+ header,
951
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
952
+ /* @__PURE__ */ jsxRuntime.jsxs(
953
+ "div",
954
+ {
955
+ className: ui.textVariants({
956
+ size: "sm",
957
+ intensity: 54,
958
+ className: "oui-orderEntry-orderConfirmDialog-content oui-space-y-1"
959
+ }),
960
+ children: [
961
+ quantityItem,
962
+ triggerPriceItem,
963
+ renderPriceAndTotal()
964
+ ]
965
+ }
966
+ ),
967
+ tpslTriggerPrice,
968
+ orderConfirmCheckbox,
969
+ buttons
970
+ ] });
986
971
  };
987
- var useConvertThreshold = () => {
988
- const { data, error, isLoading } = hooks.useQuery(
989
- "/v1/public/auto_convert_threshold",
990
- { errorRetryCount: 3 }
991
- );
992
- return {
993
- ltv_threshold: new utils.Decimal(data?.ltv_threshold ?? 0).mul(100).toNumber(),
994
- negative_usdc_threshold: data?.negative_usdc_threshold,
995
- isLoading,
996
- error
997
- };
972
+ var OrderItem = (props) => {
973
+ const { title, value, unit, dp } = props;
974
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
975
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: title }),
976
+ /* @__PURE__ */ jsxRuntime.jsx(
977
+ ui.Text.numeral,
978
+ {
979
+ unit,
980
+ rule: "price",
981
+ dp,
982
+ padding: false,
983
+ className: "oui-text-base-contrast",
984
+ unitClassName: "oui-text-base-contrast-36 oui-ml-1",
985
+ children: value
986
+ }
987
+ )
988
+ ] });
998
989
  };
999
- var useLTVTooltipScript = (marginMode) => {
1000
- const { data: holdingList = [], isLoading: isHoldingLoading } = hooks.useHoldingStream();
1001
- const {
1002
- ltv_threshold,
1003
- negative_usdc_threshold,
1004
- isLoading: isThresholdLoading
1005
- } = useConvertThreshold();
1006
- const tokensInfo = hooks.useAppStore((state) => state.tokensInfo);
1007
- const { getIndexPrice } = hooks.useIndexPricesStream();
1008
- const holdingData = holdingList.map((item) => {
1009
- const tokenInfo = tokensInfo?.find(({ token }) => token === item.token);
1010
- const indexPrice = getIndexPrice(item.token);
1011
- const collateralRatio = tokenInfo ? perp.account.collateralRatio({
1012
- baseWeight: tokenInfo.base_weight ?? 0,
1013
- discountFactor: tokenInfo.discount_factor ?? 0,
1014
- collateralQty: item.holding,
1015
- collateralCap: tokenInfo?.user_max_qty ?? item.holding,
1016
- indexPrice
1017
- }) : utils.zero;
1018
- const collateralContribution = perp.account.collateralContribution({
1019
- collateralQty: item.holding,
1020
- collateralCap: tokenInfo?.user_max_qty ?? item.holding,
1021
- collateralRatio: collateralRatio.toNumber(),
1022
- indexPrice
1023
- });
1024
- return {
1025
- ...item,
1026
- collateralContribution
1027
- };
1028
- });
1029
- const currentLtv = hooks.useComputedLTV();
1030
- const onConvert = React3.useCallback(async () => {
1031
- return ui.modal.show("ConvertDialogId");
1032
- }, []);
1033
- return {
1034
- holdingData,
1035
- isHoldingLoading,
1036
- ltv_threshold,
1037
- negative_usdc_threshold,
1038
- isThresholdLoading,
1039
- currentLtv,
1040
- onConvert,
1041
- marginMode
1042
- };
990
+ OrderConfirmDialog.displayName = "OrderConfirmDialog";
991
+ var OrderTypeTag = (props) => {
992
+ const { t } = i18n.useTranslation();
993
+ const typeStr = React3.useMemo(() => {
994
+ switch (props.type) {
995
+ case types.OrderType.LIMIT:
996
+ return t("orderEntry.orderType.limit");
997
+ case types.OrderType.MARKET:
998
+ return t("common.marketPrice");
999
+ case types.OrderType.STOP_LIMIT:
1000
+ return t("orderEntry.orderType.stopLimit");
1001
+ case types.OrderType.STOP_MARKET:
1002
+ return t("orderEntry.orderType.stopMarket");
1003
+ case types.OrderType.TRAILING_STOP:
1004
+ return t("orderEntry.orderType.trailingStop");
1005
+ default:
1006
+ return "";
1007
+ }
1008
+ }, [props.type]);
1009
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "sm", children: typeStr });
1043
1010
  };
1044
- var LTVRiskTooltipWidget = ({
1045
- marginMode
1046
- }) => {
1047
- const state = useLTVTooltipScript(marginMode);
1048
- return /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipUI, { ...state });
1011
+ var Dialog = (props) => {
1012
+ const { close, resolve, reject, ...rest } = props;
1013
+ return /* @__PURE__ */ jsxRuntime.jsx(
1014
+ OrderConfirmDialog,
1015
+ {
1016
+ ...rest,
1017
+ onCancel: () => {
1018
+ reject();
1019
+ close();
1020
+ },
1021
+ onConfirm: () => {
1022
+ resolve();
1023
+ close();
1024
+ }
1025
+ }
1026
+ );
1049
1027
  };
1050
- var Available = (props) => {
1051
- const { canTrade, currentLtv, quote, freeCollateral, marginMode } = props;
1028
+ var orderConfirmDialogId = "orderConfirm";
1029
+ ui.registerSimpleDialog(orderConfirmDialogId, Dialog, {
1030
+ size: "sm",
1031
+ title: () => i18n.i18n.t("orderEntry.orderConfirm")
1032
+ });
1033
+ var MaxQtyConfirm = React3.memo((props) => {
1052
1034
  const { t } = i18n.useTranslation();
1053
- const { isMobile } = ui.useScreen();
1054
- const showLTV = React3.useMemo(() => {
1055
- return typeof currentLtv === "number" && !Number.isNaN(currentLtv) && currentLtv > 0;
1056
- }, [currentLtv]);
1057
- return /* @__PURE__ */ jsxRuntime.jsxs(
1035
+ return /* @__PURE__ */ jsxRuntime.jsx(
1036
+ ui.SimpleDialog,
1037
+ {
1038
+ open: props.open,
1039
+ title: t("orderEntry.orderConfirm"),
1040
+ closable: true,
1041
+ onOpenChange: props.onOpenChange,
1042
+ size: "sm",
1043
+ classNames: {
1044
+ footer: "oui-maxQtyConfirm-footer",
1045
+ body: "oui-maxQtyConfirm-body"
1046
+ },
1047
+ actions: {
1048
+ primary: {
1049
+ label: t("orderEntry.placeOrderNow"),
1050
+ className: "oui-primary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1051
+ onClick: () => {
1052
+ props.onConfirm();
1053
+ return Promise.resolve();
1054
+ }
1055
+ },
1056
+ secondary: {
1057
+ label: t("common.cancel"),
1058
+ className: "oui-secondary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1059
+ onClick: () => {
1060
+ props.onOpenChange(false);
1061
+ return Promise.resolve();
1062
+ }
1063
+ }
1064
+ },
1065
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-maxQtyConfirm-content oui-text-2xs lg:oui-text-sm", children: t("orderEntry.maxQty.reminder.content", {
1066
+ maxQty: `${props.maxQty} ${props.base}`
1067
+ }) })
1068
+ }
1069
+ );
1070
+ });
1071
+ var PermissionlessMarketNoticeDialog = (props) => {
1072
+ const { onConfirm, onCancel } = props;
1073
+ const { t } = i18n.useTranslation();
1074
+ const [checked, setChecked] = React3.useState(false);
1075
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(
1058
1076
  ui.Flex,
1059
1077
  {
1060
- itemAlign: "center",
1061
- justify: "between",
1062
- className: "oui-orderEntry-available",
1078
+ direction: "column",
1079
+ gap: 3,
1080
+ itemAlign: "start",
1081
+ className: "oui-permissionlessNotice-content",
1063
1082
  children: [
1064
- marginMode === types.MarginMode.ISOLATED ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("transfer.LTV.isolatedModeUsdcOnly"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label oui-cursor-pointer", size: "2xs", children: t("common.available") }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label", size: "2xs", children: t("common.available") }),
1065
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { itemAlign: "center", justify: "center", gap: 1, children: [
1066
- showLTV && /* @__PURE__ */ jsxRuntime.jsx(
1067
- ui.Tooltip,
1068
- {
1069
- className: "oui-available-ltvRisk-tooltip oui-bg-base-6 oui-p-2",
1070
- content: /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipWidget, { marginMode }),
1071
- children: /* @__PURE__ */ jsxRuntime.jsx(
1072
- ui.InfoCircleIcon,
1073
- {
1074
- className: "oui-cursor-pointer oui-text-warning oui-opacity-80"
1075
- }
1076
- )
1077
- }
1078
- ),
1079
- /* @__PURE__ */ jsxRuntime.jsx(
1080
- ui.Text.numeral,
1081
- {
1082
- unit: quote,
1083
- size: "2xs",
1084
- className: "oui-available-value oui-text-base-contrast-80",
1085
- unitClassName: "oui-ml-1 oui-text-base-contrast-54",
1086
- dp: 2,
1087
- padding: false,
1088
- children: canTrade ? freeCollateral : 0
1089
- }
1090
- ),
1091
- /* @__PURE__ */ jsxRuntime.jsx(
1092
- ui.Button,
1093
- {
1094
- variant: "text",
1083
+ /* @__PURE__ */ jsxRuntime.jsx(
1084
+ ui.Text,
1085
+ {
1086
+ className: ui.textVariants({
1087
+ size: "sm",
1088
+ intensity: 54
1089
+ }),
1090
+ children: t("orderEntry.permissionlessNotice.content1")
1091
+ }
1092
+ ),
1093
+ /* @__PURE__ */ jsxRuntime.jsx(
1094
+ ui.Text,
1095
+ {
1096
+ className: ui.textVariants({
1097
+ size: "sm",
1098
+ intensity: 54
1099
+ }),
1100
+ children: t("orderEntry.permissionlessNotice.content2")
1101
+ }
1102
+ ),
1103
+ /* @__PURE__ */ jsxRuntime.jsx(
1104
+ ui.Text,
1105
+ {
1106
+ className: ui.textVariants({
1107
+ size: "sm",
1108
+ intensity: 54
1109
+ }),
1110
+ children: t("orderEntry.permissionlessNotice.content3")
1111
+ }
1112
+ )
1113
+ ]
1114
+ }
1115
+ );
1116
+ const checkboxSection = /* @__PURE__ */ jsxRuntime.jsxs(
1117
+ ui.Flex,
1118
+ {
1119
+ gapX: 1,
1120
+ pt: 4,
1121
+ pb: 5,
1122
+ itemAlign: "start",
1123
+ className: "oui-permissionlessNotice-checkbox oui-orderEntry-orderConfirmDialog-disableConfirm oui-cursor-pointer",
1124
+ children: [
1125
+ /* @__PURE__ */ jsxRuntime.jsx(
1126
+ ui.Checkbox,
1127
+ {
1128
+ id: "permissionlessNotice",
1129
+ color: "white",
1130
+ className: "oui-permissionlessNotice-checkbox-input oui-mt-1",
1131
+ checked,
1132
+ onCheckedChange: (value) => setChecked(!!value)
1133
+ }
1134
+ ),
1135
+ /* @__PURE__ */ jsxRuntime.jsx(
1136
+ "label",
1137
+ {
1138
+ htmlFor: "permissionlessNotice",
1139
+ className: ui.textVariants({
1095
1140
  size: "xs",
1096
- color: "secondary",
1097
- className: "oui-available-deposit-icon oui-p-0 hover:oui-text-base-contrast-80",
1098
- onClick: () => {
1099
- const handleDomId = isMobile ? "DepositAndWithdrawWithSheetId" : "DepositAndWithdrawWithDialogId";
1100
- ui.modal.show(handleDomId, {
1101
- activeTab: "deposit"
1102
- });
1103
- },
1104
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { opacity: 1 })
1105
- }
1106
- )
1107
- ] })
1141
+ intensity: 54,
1142
+ className: "oui-cursor-pointer"
1143
+ }),
1144
+ children: t("orderEntry.permissionlessNotice.checkbox")
1145
+ }
1146
+ )
1108
1147
  ]
1109
1148
  }
1110
1149
  );
1150
+ const confirmButton = /* @__PURE__ */ jsxRuntime.jsx(
1151
+ ui.Flex,
1152
+ {
1153
+ className: "oui-permissionlessNotice-confirm-button oui-w-full",
1154
+ justify: "center",
1155
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1156
+ ui.Button,
1157
+ {
1158
+ fullWidth: true,
1159
+ size: "md",
1160
+ className: "oui-permissionlessNotice-confirm oui-confirm-btn oui-max-w-[244px]",
1161
+ disabled: !checked,
1162
+ onClick: () => onConfirm(),
1163
+ children: t("common.confirm")
1164
+ }
1165
+ )
1166
+ }
1167
+ );
1168
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1169
+ content,
1170
+ checkboxSection,
1171
+ confirmButton
1172
+ ] });
1111
1173
  };
1112
- function isBBOOrder(options2) {
1113
- const { order_type, order_type_ext } = options2;
1114
- const isBBO = [types.OrderType.ASK, types.OrderType.BID].includes(order_type_ext);
1115
- if (order_type) {
1116
- return order_type === types.OrderType.LIMIT && isBBO;
1117
- }
1118
- return isBBO;
1119
- }
1120
- function getOrderTypeByBBO(value, size) {
1121
- if ([types.BBOOrderType.COUNTERPARTY1, types.BBOOrderType.COUNTERPARTY5].includes(value)) {
1122
- return size === types.OrderSide.BUY ? types.OrderType.ASK : types.OrderType.BID;
1123
- }
1124
- if ([types.BBOOrderType.QUEUE1, types.BBOOrderType.QUEUE5].includes(value)) {
1125
- return size === types.OrderSide.BUY ? types.OrderType.BID : types.OrderType.ASK;
1126
- }
1127
- }
1128
- function getOrderLevelByBBO(value) {
1129
- if ([types.BBOOrderType.COUNTERPARTY1, types.BBOOrderType.QUEUE1].includes(value)) {
1130
- return types.OrderLevel.ONE;
1131
- }
1132
- if ([types.BBOOrderType.COUNTERPARTY5, types.BBOOrderType.QUEUE5].includes(value)) {
1133
- return types.OrderLevel.FIVE;
1134
- }
1135
- }
1136
- function getScaledPlaceOrderMessage(result) {
1137
- const rows = result?.data?.rows || [];
1138
- if (rows.length > 0) {
1139
- const totalCount = rows.length;
1140
- const successCount = rows.filter((row) => row.success).length;
1141
- if (successCount === totalCount) {
1142
- return i18n.i18n.t("orderEntry.scaledOrder.fullySuccessful", {
1143
- total: totalCount
1144
- });
1145
- }
1146
- if (successCount === 0) {
1147
- return i18n.i18n.t("orderEntry.scaledOrder.allFailed");
1174
+ PermissionlessMarketNoticeDialog.displayName = "PermissionlessMarketNoticeDialog";
1175
+ var Dialog2 = (props) => {
1176
+ const { close, resolve, reject } = props;
1177
+ return /* @__PURE__ */ jsxRuntime.jsx(
1178
+ PermissionlessMarketNoticeDialog,
1179
+ {
1180
+ onCancel: () => {
1181
+ reject();
1182
+ close();
1183
+ },
1184
+ onConfirm: () => {
1185
+ resolve();
1186
+ close();
1187
+ }
1148
1188
  }
1149
- return i18n.i18n.t("orderEntry.scaledOrder.partiallySuccessful", {
1150
- successCount,
1151
- total: totalCount
1152
- });
1153
- }
1154
- }
1155
- var safeNumber = (val) => {
1156
- return Number.isNaN(Number(val)) ? 0 : Number(val);
1189
+ );
1157
1190
  };
1158
- var OrderConfirmDialog = (props) => {
1159
- const { symbolInfo, order, onConfirm, onCancel } = props;
1160
- const { quote, quote_dp, base_dp } = symbolInfo;
1161
- const { side, order_type, order_type_ext, level, symbol } = order;
1162
- const orderMarginMode = order.margin_mode;
1191
+ var permissionlessMarketNoticeDialogId = "permissionlessMarketNotice";
1192
+ var permissionlessMarketNoticeDesktopDialogId = "permissionlessMarketNoticeDesktop";
1193
+ ui.registerSimpleDialog(permissionlessMarketNoticeDialogId, Dialog2, {
1194
+ size: "sm",
1195
+ title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1196
+ });
1197
+ ui.registerSimpleDialog(permissionlessMarketNoticeDesktopDialogId, Dialog2, {
1198
+ size: "xl",
1199
+ title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1200
+ });
1201
+ var ScaledOrderConfirm = (props) => {
1202
+ const { order, symbolInfo, dataSource, national, askAndBid, totalQuantity } = props;
1203
+ const { base, quote, base_dp, quote_dp } = symbolInfo;
1163
1204
  const { t } = i18n.useTranslation();
1164
- const [{ rows: positions }] = hooks.usePositionStream(symbol);
1165
- const position = React3.useMemo(
1166
- () => orderMarginMode != null ? positions?.find(
1167
- (row) => row.symbol === symbol && row.margin_mode === orderMarginMode
1168
- ) : positions?.[0],
1169
- [positions, symbol, orderMarginMode]
1170
- );
1171
- const positionQty = position?.position_qty;
1172
- const [_, setNeedConfirm] = hooks.useLocalStorage("orderly_order_confirm", true);
1173
- const renderPositionType = () => {
1174
- if (order.position_type === types.PositionType.FULL) {
1175
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.full") });
1176
- }
1177
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.partial") });
1205
+ const onCancel = () => {
1206
+ props.reject();
1207
+ props.close?.();
1178
1208
  };
1179
- const renderPrice = () => {
1180
- if (order_type === types.OrderType.MARKET || order_type === types.OrderType.STOP_MARKET) {
1181
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: t("common.marketPrice") });
1182
- }
1183
- if (isBBOOrder({ order_type, order_type_ext })) {
1184
- const bboType = utils.getBBOType({
1185
- type: order_type_ext,
1186
- side,
1187
- level
1188
- });
1189
- const label = {
1190
- [types.BBOOrderType.COUNTERPARTY1]: t("orderEntry.bbo.counterparty1"),
1191
- [types.BBOOrderType.COUNTERPARTY5]: t("orderEntry.bbo.counterparty5"),
1192
- [types.BBOOrderType.QUEUE1]: t("orderEntry.bbo.queue1"),
1193
- [types.BBOOrderType.QUEUE5]: t("orderEntry.bbo.queue5")
1194
- }[bboType];
1195
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: label });
1196
- }
1197
- return /* @__PURE__ */ jsxRuntime.jsx(
1198
- ui.Text.numeral,
1199
- {
1200
- unit: quote,
1201
- rule: "price",
1202
- className: "oui-text-base-contrast",
1203
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1204
- dp: quote_dp,
1205
- padding: false,
1206
- children: order.order_price
1207
- }
1208
- );
1209
+ const onConfirm = () => {
1210
+ props.resolve();
1211
+ props.close?.();
1209
1212
  };
1210
- const renderTPSLPrice = ({
1211
- price,
1212
- isOrderPrice,
1213
- isEnable,
1214
- colorType
1215
- }) => {
1216
- if (!isEnable) {
1217
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: "-- USDC" });
1218
- }
1219
- if (!price) {
1220
- if (isOrderPrice) {
1221
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: t("common.marketPrice") });
1222
- }
1223
- }
1224
- return /* @__PURE__ */ jsxRuntime.jsx(
1225
- ui.Text.numeral,
1213
+ const columns = React3.useMemo(() => {
1214
+ return [
1226
1215
  {
1227
- unit: "USDC",
1228
- rule: "price",
1229
- className: ui.cn(
1230
- "oui-text-base-contrast",
1231
- colorType === "TP" ? "oui-text-trade-profit" : "oui-text-trade-loss"
1232
- ),
1233
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1234
- dp: quote_dp,
1235
- padding: false,
1236
- children: price
1237
- }
1238
- );
1239
- };
1240
- const renderTPSLQty = () => {
1241
- if (!positionQty || !order.order_quantity) {
1242
- return null;
1243
- }
1244
- let qty = new utils.Decimal(order.order_quantity);
1245
- if (order.position_type === types.PositionType.FULL) {
1246
- qty = qty.plus(new utils.Decimal(positionQty ?? 0));
1247
- }
1248
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1249
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: order.position_type === types.PositionType.FULL ? t("common.positionQty") : t("common.orderQty") }),
1250
- /* @__PURE__ */ jsxRuntime.jsx(
1251
- ui.Text.numeral,
1252
- {
1253
- rule: "price",
1254
- dp: base_dp,
1255
- padding: false,
1256
- className: "oui-text-base-contrast",
1257
- children: qty.toNumber()
1216
+ title: t("common.symbol"),
1217
+ dataIndex: "symbol",
1218
+ width: 125,
1219
+ render: (value, record) => {
1220
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, children: [
1221
+ /* @__PURE__ */ jsxRuntime.jsx(
1222
+ "div",
1223
+ {
1224
+ className: ui.cn(
1225
+ "oui-h-[42px] oui-w-1 oui-shrink-0 oui-rounded-[1px]",
1226
+ record.side === types.OrderSide.BUY ? "oui-bg-trade-profit" : "oui-bg-trade-loss"
1227
+ )
1228
+ }
1229
+ ),
1230
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", children: [
1231
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1232
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: value, className: "oui-size-3" }),
1233
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.formatted, { rule: "symbol", size: "xs", formatString: "base", children: value })
1234
+ ] }),
1235
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
1236
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol: value }),
1237
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "xs", children: t("orderEntry.orderType.limit") })
1238
+ ] })
1239
+ ] })
1240
+ ] });
1258
1241
  }
1259
- )
1260
- ] });
1261
- };
1262
- const renderPriceAndTotal = () => {
1263
- if (order_type === types.OrderType.TRAILING_STOP) {
1264
- const { activated_price, callback_value, callback_rate } = order;
1265
- const callbackView = callback_rate ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1266
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.trailingRate") }),
1267
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-text-base-contrast", children: [
1268
- callback_rate,
1269
- "%"
1270
- ] })
1271
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
1272
- OrderItem,
1273
- {
1274
- title: t("orderEntry.trailingValue"),
1275
- value: callback_value,
1276
- unit: quote,
1277
- dp: quote_dp
1242
+ },
1243
+ {
1244
+ title: t("common.quantity"),
1245
+ dataIndex: "order_quantity",
1246
+ width: 100,
1247
+ render: (value, record) => {
1248
+ return /* @__PURE__ */ jsxRuntime.jsx(
1249
+ ui.Text.numeral,
1250
+ {
1251
+ rule: "price",
1252
+ dp: base_dp,
1253
+ padding: false,
1254
+ color: record.side === types.OrderSide.BUY ? "buy" : "sell",
1255
+ children: value
1256
+ }
1257
+ );
1278
1258
  }
1279
- );
1280
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1281
- activated_price && /* @__PURE__ */ jsxRuntime.jsx(
1282
- OrderItem,
1283
- {
1284
- title: t("common.triggerPrice"),
1285
- value: activated_price,
1286
- unit: quote,
1287
- dp: quote_dp
1288
- }
1289
- ),
1290
- callbackView
1291
- ] });
1292
- }
1293
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1294
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1295
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.price") }),
1296
- renderPrice()
1297
- ] }),
1298
- /* @__PURE__ */ jsxRuntime.jsx(
1299
- OrderItem,
1300
- {
1301
- title: t("common.estTotal"),
1302
- value: order.total,
1303
- unit: quote,
1304
- dp: quote_dp
1259
+ },
1260
+ {
1261
+ title: t("common.orderPrice"),
1262
+ dataIndex: "order_price",
1263
+ width: 100,
1264
+ render: (value, record) => {
1265
+ const showWarning = !!(record.side === types.OrderSide.BUY ? askAndBid?.[0] && Number(value) >= askAndBid?.[0] : askAndBid?.[1] && Number(value) <= askAndBid?.[1]);
1266
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1267
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "price", dp: quote_dp, children: value }),
1268
+ showWarning && /* @__PURE__ */ jsxRuntime.jsx(
1269
+ ui.Tooltip,
1270
+ {
1271
+ content: t(
1272
+ "orderEntry.confirmScaledOrder.orderPrice.warning"
1273
+ ),
1274
+ className: "oui-w-[240px] oui-text-2xs oui-font-semibold oui-text-base-contrast-80",
1275
+ children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIcon, { className: "oui-text-warning-darken" })
1276
+ }
1277
+ )
1278
+ ] });
1305
1279
  }
1306
- )
1307
- ] });
1308
- };
1309
- const header = /* @__PURE__ */ jsxRuntime.jsxs(
1310
- ui.Flex,
1311
- {
1312
- justify: "between",
1313
- className: "oui-orderEntry-orderConfirmDialog-header",
1314
- children: [
1315
- /* @__PURE__ */ jsxRuntime.jsx(
1316
- ui.Text.formatted,
1317
- {
1318
- rule: "symbol",
1319
- showIcon: true,
1320
- className: "oui-orderConfirmDialog-symbol",
1321
- children: order.symbol
1322
- }
1323
- ),
1324
- /* @__PURE__ */ jsxRuntime.jsxs(
1325
- ui.Flex,
1326
- {
1327
- justify: "end",
1328
- gapX: 1,
1329
- className: "oui-orderConfirmDialog-header-tags",
1330
- children: [
1331
- /* @__PURE__ */ jsxRuntime.jsx(OrderTypeTag, { type: order_type }),
1332
- side === types.OrderSide.BUY ? /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "buy", size: "sm", children: t("common.buy") }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "sell", size: "sm", children: t("common.sell") })
1333
- ]
1334
- }
1335
- )
1336
- ]
1337
- }
1338
- );
1339
- const quantityItem = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1340
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.orderQty") }),
1341
- /* @__PURE__ */ jsxRuntime.jsx(
1342
- ui.Text.numeral,
1343
- {
1344
- rule: "price",
1345
- dp: base_dp,
1346
- padding: false,
1347
- className: "oui-text-base-contrast",
1348
- children: order.order_quantity
1349
1280
  }
1350
- )
1351
- ] });
1352
- const triggerPriceItem = (order_type === types.OrderType.STOP_LIMIT || order_type === types.OrderType.STOP_MARKET && order.trigger_price) && /* @__PURE__ */ jsxRuntime.jsx(
1353
- OrderItem,
1354
- {
1355
- title: t("common.trigger"),
1356
- value: order.trigger_price,
1357
- unit: quote,
1358
- dp: quote_dp
1359
- }
1360
- );
1361
- const tpslTriggerPrice = (order.tp_trigger_price || order.sl_trigger_price) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1362
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
1363
- /* @__PURE__ */ jsxRuntime.jsxs(
1364
- "div",
1281
+ ];
1282
+ }, [t, symbolInfo, askAndBid, base_dp, quote_dp]);
1283
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-scaledOrderConfirm oui-font-semibold", children: [
1284
+ /* @__PURE__ */ jsxRuntime.jsx(
1285
+ ui.DataTable,
1365
1286
  {
1366
- className: ui.textVariants({
1367
- size: "sm",
1368
- intensity: 54,
1369
- className: "oui-space-y-1 oui-w-full oui-flex oui-flex-col oui-gap-3"
1370
- }),
1371
- children: [
1372
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast", children: renderPositionType() }),
1373
- renderTPSLQty(),
1374
- /* @__PURE__ */ jsxRuntime.jsxs(
1375
- ui.Flex,
1376
- {
1377
- direction: "column",
1378
- justify: "between",
1379
- itemAlign: "start",
1380
- gap: 1,
1381
- className: "oui-w-full",
1382
- children: [
1383
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1384
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpTriggerPrice") }),
1385
- renderTPSLPrice({
1386
- price: order.tp_trigger_price ?? "",
1387
- isOrderPrice: false,
1388
- isEnable: !!order.tp_trigger_price,
1389
- colorType: "TP"
1390
- })
1391
- ] }),
1392
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1393
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpOrderPrice") }),
1394
- renderTPSLPrice({
1395
- price: order.tp_order_price ?? "",
1396
- isOrderPrice: true,
1397
- isEnable: !!order.tp_trigger_price,
1398
- colorType: "TP"
1399
- })
1400
- ] })
1401
- ]
1402
- }
1287
+ classNames: {
1288
+ root: ui.cn(
1289
+ "oui-scaledOrderConfirm-table",
1290
+ "oui-bg-base-7",
1291
+ "oui-rounded-lg",
1292
+ // need to set overflow hidden because table header will avoid the border radius
1293
+ "oui-overflow-hidden",
1294
+ // "oui-text-2xs lg:oui-text-xs",
1295
+ // if orders is greater than 6, set the height to 320px to show scroll bar
1296
+ order.orders?.length >= 6 && "oui-h-[320px]"
1403
1297
  ),
1404
- /* @__PURE__ */ jsxRuntime.jsxs(
1405
- ui.Flex,
1406
- {
1407
- direction: "column",
1408
- justify: "between",
1409
- itemAlign: "start",
1410
- gap: 1,
1411
- className: "oui-w-full",
1412
- children: [
1413
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1414
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slTriggerPrice") }),
1415
- renderTPSLPrice({
1416
- price: order.sl_trigger_price ?? "",
1417
- isOrderPrice: false,
1418
- isEnable: !!order.sl_trigger_price,
1419
- colorType: "SL"
1420
- })
1421
- ] }),
1422
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1423
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slOrderPrice") }),
1424
- renderTPSLPrice({
1425
- price: order.sl_order_price ?? "",
1426
- isOrderPrice: true,
1427
- isEnable: !!order.sl_trigger_price,
1428
- colorType: "SL"
1429
- })
1430
- ] })
1431
- ]
1432
- }
1433
- )
1434
- ]
1298
+ // set the min height of the table to show 2 rows
1299
+ scroll: "!oui-min-h-[130px]"
1300
+ },
1301
+ dataSource,
1302
+ columns,
1303
+ bordered: true,
1304
+ onRow: () => {
1305
+ return {
1306
+ className: ui.cn("oui-h-[50px]")
1307
+ };
1308
+ }
1435
1309
  }
1436
- )
1437
- ] });
1438
- const orderConfirmCheckbox = /* @__PURE__ */ jsxRuntime.jsxs(
1439
- ui.Flex,
1440
- {
1441
- gapX: 1,
1442
- pt: 4,
1443
- pb: 5,
1444
- className: "oui-orderEntry-orderConfirmDialog-disableConfirm",
1445
- children: [
1446
- /* @__PURE__ */ jsxRuntime.jsx(
1447
- ui.Checkbox,
1448
- {
1449
- id: "orderConfirm",
1450
- color: "white",
1451
- className: "oui-orderConfirmDialog-disableConfirm-checkbox",
1452
- onCheckedChange: (checked) => {
1453
- setNeedConfirm(!!!checked);
1454
- }
1455
- }
1456
- ),
1310
+ ),
1311
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-scaledOrderConfirm-content oui-mb-5 oui-mt-4 oui-text-2xs", children: [
1312
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1313
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.totalOrders") }),
1314
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: order.orders?.length })
1315
+ ] }),
1316
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", mt: 2, children: [
1317
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.totalQuantity") }),
1457
1318
  /* @__PURE__ */ jsxRuntime.jsx(
1458
- "label",
1319
+ ui.Text.numeral,
1459
1320
  {
1460
- htmlFor: "orderConfirm",
1461
- className: ui.textVariants({
1462
- size: "xs",
1463
- intensity: 54
1464
- }),
1465
- children: t("orderEntry.disableOrderConfirm")
1321
+ rule: "price",
1322
+ unit: base,
1323
+ dp: base_dp,
1324
+ padding: false,
1325
+ intensity: 80,
1326
+ unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1327
+ children: totalQuantity
1466
1328
  }
1467
1329
  )
1468
- ]
1469
- }
1470
- );
1471
- const buttons = /* @__PURE__ */ jsxRuntime.jsxs(
1472
- ui.Grid,
1473
- {
1474
- cols: 2,
1475
- gapX: 3,
1476
- className: "oui-orderEntry-orderConfirmDialog-actions",
1477
- children: [
1478
- /* @__PURE__ */ jsxRuntime.jsx(
1479
- ui.Button,
1480
- {
1481
- color: "secondary",
1482
- size: "md",
1483
- className: "oui-cancel-btn",
1484
- onClick: () => onCancel(),
1485
- children: t("common.cancel")
1486
- }
1487
- ),
1330
+ ] }),
1331
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", mt: 2, children: [
1332
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.notional") }),
1488
1333
  /* @__PURE__ */ jsxRuntime.jsx(
1489
- ui.Button,
1334
+ ui.Text.numeral,
1490
1335
  {
1491
- size: "md",
1492
- className: "oui-confirm-btn",
1493
- onClick: () => onConfirm(),
1494
- children: t("common.confirm")
1495
- }
1496
- )
1497
- ]
1498
- }
1499
- );
1500
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1501
- header,
1502
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
1503
- /* @__PURE__ */ jsxRuntime.jsxs(
1504
- "div",
1505
- {
1506
- className: ui.textVariants({
1507
- size: "sm",
1508
- intensity: 54,
1509
- className: "oui-orderEntry-orderConfirmDialog-content oui-space-y-1"
1510
- }),
1511
- children: [
1512
- quantityItem,
1513
- triggerPriceItem,
1514
- renderPriceAndTotal()
1515
- ]
1516
- }
1517
- ),
1518
- tpslTriggerPrice,
1519
- orderConfirmCheckbox,
1520
- buttons
1521
- ] });
1522
- };
1523
- var OrderItem = (props) => {
1524
- const { title, value, unit, dp } = props;
1525
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1526
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: title }),
1527
- /* @__PURE__ */ jsxRuntime.jsx(
1528
- ui.Text.numeral,
1529
- {
1530
- unit,
1531
- rule: "price",
1532
- dp,
1533
- padding: false,
1534
- className: "oui-text-base-contrast",
1535
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1536
- children: value
1537
- }
1538
- )
1539
- ] });
1540
- };
1541
- OrderConfirmDialog.displayName = "OrderConfirmDialog";
1542
- var OrderTypeTag = (props) => {
1543
- const { t } = i18n.useTranslation();
1544
- const typeStr = React3.useMemo(() => {
1545
- switch (props.type) {
1546
- case types.OrderType.LIMIT:
1547
- return t("orderEntry.orderType.limit");
1548
- case types.OrderType.MARKET:
1549
- return t("common.marketPrice");
1550
- case types.OrderType.STOP_LIMIT:
1551
- return t("orderEntry.orderType.stopLimit");
1552
- case types.OrderType.STOP_MARKET:
1553
- return t("orderEntry.orderType.stopMarket");
1554
- case types.OrderType.TRAILING_STOP:
1555
- return t("orderEntry.orderType.trailingStop");
1556
- default:
1557
- return "";
1558
- }
1559
- }, [props.type]);
1560
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "sm", children: typeStr });
1561
- };
1562
- var Dialog = (props) => {
1563
- const { close, resolve, reject, ...rest } = props;
1564
- return /* @__PURE__ */ jsxRuntime.jsx(
1565
- OrderConfirmDialog,
1566
- {
1567
- ...rest,
1568
- onCancel: () => {
1569
- reject();
1570
- close();
1571
- },
1572
- onConfirm: () => {
1573
- resolve();
1574
- close();
1575
- }
1576
- }
1577
- );
1578
- };
1579
- var orderConfirmDialogId = "orderConfirm";
1580
- ui.registerSimpleDialog(orderConfirmDialogId, Dialog, {
1581
- size: "sm",
1582
- title: () => i18n.i18n.t("orderEntry.orderConfirm")
1583
- });
1584
- var MaxQtyConfirm = React3.memo((props) => {
1585
- const { t } = i18n.useTranslation();
1586
- return /* @__PURE__ */ jsxRuntime.jsx(
1587
- ui.SimpleDialog,
1588
- {
1589
- open: props.open,
1590
- title: t("orderEntry.orderConfirm"),
1591
- closable: true,
1592
- onOpenChange: props.onOpenChange,
1593
- size: "sm",
1594
- classNames: {
1595
- footer: "oui-maxQtyConfirm-footer",
1596
- body: "oui-maxQtyConfirm-body"
1597
- },
1598
- actions: {
1599
- primary: {
1600
- label: t("orderEntry.placeOrderNow"),
1601
- className: "oui-primary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1602
- onClick: () => {
1603
- props.onConfirm();
1604
- return Promise.resolve();
1605
- }
1606
- },
1607
- secondary: {
1608
- label: t("common.cancel"),
1609
- className: "oui-secondary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1610
- onClick: () => {
1611
- props.onOpenChange(false);
1612
- return Promise.resolve();
1613
- }
1614
- }
1615
- },
1616
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-maxQtyConfirm-content oui-text-2xs lg:oui-text-sm", children: t("orderEntry.maxQty.reminder.content", {
1617
- maxQty: `${props.maxQty} ${props.base}`
1618
- }) })
1619
- }
1620
- );
1621
- });
1622
- var ScaledOrderConfirm = (props) => {
1623
- const { order, symbolInfo, dataSource, national, askAndBid, totalQuantity } = props;
1624
- const { base, quote, base_dp, quote_dp } = symbolInfo;
1625
- const { t } = i18n.useTranslation();
1626
- const onCancel = () => {
1627
- props.reject();
1628
- props.close?.();
1629
- };
1630
- const onConfirm = () => {
1631
- props.resolve();
1632
- props.close?.();
1633
- };
1634
- const columns = React3.useMemo(() => {
1635
- return [
1636
- {
1637
- title: t("common.symbol"),
1638
- dataIndex: "symbol",
1639
- width: 125,
1640
- render: (value, record) => {
1641
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, children: [
1642
- /* @__PURE__ */ jsxRuntime.jsx(
1643
- "div",
1644
- {
1645
- className: ui.cn(
1646
- "oui-h-[38px] oui-w-1 oui-shrink-0 oui-rounded-[1px]",
1647
- record.side === types.OrderSide.BUY ? "oui-bg-trade-profit" : "oui-bg-trade-loss"
1648
- )
1649
- }
1650
- ),
1651
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", itemAlign: "start", children: [
1652
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1653
- /* @__PURE__ */ jsxRuntime.jsx(ui.TokenIcon, { symbol: value, className: "oui-size-3" }),
1654
- /* @__PURE__ */ jsxRuntime.jsx(
1655
- ui.Text.formatted,
1656
- {
1657
- rule: "symbol",
1658
- size: "xs",
1659
- formatString: "base-type",
1660
- children: value
1661
- }
1662
- )
1663
- ] }),
1664
- /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "xs", children: t("orderEntry.orderType.limit") })
1665
- ] })
1666
- ] });
1667
- }
1668
- },
1669
- {
1670
- title: t("common.quantity"),
1671
- dataIndex: "order_quantity",
1672
- width: 100,
1673
- render: (value, record) => {
1674
- return /* @__PURE__ */ jsxRuntime.jsx(
1675
- ui.Text.numeral,
1676
- {
1677
- rule: "price",
1678
- dp: base_dp,
1679
- padding: false,
1680
- color: record.side === types.OrderSide.BUY ? "buy" : "sell",
1681
- children: value
1682
- }
1683
- );
1684
- }
1685
- },
1686
- {
1687
- title: t("common.orderPrice"),
1688
- dataIndex: "order_price",
1689
- width: 100,
1690
- render: (value, record) => {
1691
- const showWarning = !!(record.side === types.OrderSide.BUY ? askAndBid?.[0] && Number(value) >= askAndBid?.[0] : askAndBid?.[1] && Number(value) <= askAndBid?.[1]);
1692
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 1, children: [
1693
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text.numeral, { rule: "price", dp: quote_dp, children: value }),
1694
- showWarning && /* @__PURE__ */ jsxRuntime.jsx(
1695
- ui.Tooltip,
1696
- {
1697
- content: t(
1698
- "orderEntry.confirmScaledOrder.orderPrice.warning"
1699
- ),
1700
- className: "oui-w-[240px] oui-text-2xs oui-font-semibold oui-text-base-contrast-80",
1701
- children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIcon, { className: "oui-text-warning-darken" })
1702
- }
1703
- )
1704
- ] });
1705
- }
1706
- }
1707
- ];
1708
- }, [t, symbolInfo, askAndBid, base_dp, quote_dp]);
1709
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-scaledOrderConfirm oui-font-semibold", children: [
1710
- /* @__PURE__ */ jsxRuntime.jsx(
1711
- ui.DataTable,
1712
- {
1713
- classNames: {
1714
- root: ui.cn(
1715
- "oui-scaledOrderConfirm-table",
1716
- "oui-bg-base-7",
1717
- "oui-rounded-lg",
1718
- // need to set overflow hidden because table header will avoid the border radius
1719
- "oui-overflow-hidden",
1720
- // "oui-text-2xs lg:oui-text-xs",
1721
- // if orders is greater than 6, set the height to 320px to show scroll bar
1722
- order.orders?.length >= 6 && "oui-h-[320px]"
1723
- ),
1724
- // set the min height of the table to show 2 rows
1725
- scroll: "!oui-min-h-[130px]"
1726
- },
1727
- dataSource,
1728
- columns,
1729
- bordered: true,
1730
- onRow: () => {
1731
- return {
1732
- className: ui.cn("oui-h-[50px]")
1733
- };
1734
- }
1735
- }
1736
- ),
1737
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-scaledOrderConfirm-content oui-mb-5 oui-mt-4 oui-text-2xs", children: [
1738
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1739
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.totalOrders") }),
1740
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: order.orders?.length })
1741
- ] }),
1742
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", mt: 2, children: [
1743
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.totalQuantity") }),
1744
- /* @__PURE__ */ jsxRuntime.jsx(
1745
- ui.Text.numeral,
1746
- {
1747
- rule: "price",
1748
- unit: base,
1749
- dp: base_dp,
1750
- padding: false,
1751
- intensity: 80,
1752
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1753
- children: totalQuantity
1754
- }
1755
- )
1756
- ] }),
1757
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", mt: 2, children: [
1758
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.notional") }),
1759
- /* @__PURE__ */ jsxRuntime.jsx(
1760
- ui.Text.numeral,
1761
- {
1762
- rule: "price",
1763
- unit: quote,
1764
- dp: quote_dp,
1765
- padding: false,
1766
- intensity: 80,
1767
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1768
- children: national
1336
+ rule: "price",
1337
+ unit: quote,
1338
+ dp: quote_dp,
1339
+ padding: false,
1340
+ intensity: 80,
1341
+ unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1342
+ children: national
1769
1343
  }
1770
1344
  )
1771
1345
  ] })
@@ -1851,17 +1425,580 @@ var ScaledOrderConfirmWidget = (props) => {
1851
1425
  const state = useScaledOrderConfirmScript(props);
1852
1426
  return /* @__PURE__ */ jsxRuntime.jsx(ScaledOrderConfirm, { ...props, ...state });
1853
1427
  };
1854
- var scaledOrderConfirmDialogId = "scaledOrderConfirm";
1855
- ui.registerSimpleDialog(scaledOrderConfirmDialogId, ScaledOrderConfirmWidget, {
1856
- size: "md",
1857
- title: () => i18n.i18n.t("orderEntry.confirmScaledOrder"),
1858
- contentProps: {
1859
- // className: "oui-p-0",
1860
- }
1861
- });
1428
+ var scaledOrderConfirmDialogId = "scaledOrderConfirm";
1429
+ ui.registerSimpleDialog(scaledOrderConfirmDialogId, ScaledOrderConfirmWidget, {
1430
+ size: "md",
1431
+ title: () => i18n.i18n.t("orderEntry.confirmScaledOrder"),
1432
+ contentProps: {
1433
+ // className: "oui-p-0",
1434
+ }
1435
+ });
1436
+ var RegularFeesUI = (props) => {
1437
+ const { t } = i18n.useTranslation();
1438
+ const { taker, maker } = props;
1439
+ const originalTrailingFees = /* @__PURE__ */ jsxRuntime.jsx(
1440
+ ui.Flex,
1441
+ {
1442
+ itemAlign: "center",
1443
+ justify: "between",
1444
+ width: "100%",
1445
+ gap: 1,
1446
+ className: "oui-orderEntry-fees",
1447
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", itemAlign: "center", justify: "between", children: [
1448
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-fees-label oui-truncate", size: "2xs", children: t("common.fees") }),
1449
+ /* @__PURE__ */ jsxRuntime.jsx(
1450
+ uiConnector.AuthGuard,
1451
+ {
1452
+ fallback: () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
1453
+ t("dmm.taker"),
1454
+ ": --% / ",
1455
+ t("dmm.maker"),
1456
+ ": --%"
1457
+ ] }),
1458
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, className: "oui-fees-value-container", children: [
1459
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
1460
+ t("dmm.taker"),
1461
+ ":"
1462
+ ] }),
1463
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-base-contrast-80", children: taker }),
1464
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: "/" }),
1465
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-truncate", size: "2xs", children: [
1466
+ t("dmm.maker"),
1467
+ ":"
1468
+ ] }),
1469
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-base-contrast-80", children: maker })
1470
+ ] })
1471
+ }
1472
+ )
1473
+ ] })
1474
+ }
1475
+ );
1476
+ return originalTrailingFees;
1477
+ };
1478
+ var RegularFeesWidget = (props) => {
1479
+ return /* @__PURE__ */ jsxRuntime.jsx(RegularFeesUI, { ...props });
1480
+ };
1481
+ var FeesWidget = ({ symbol }) => {
1482
+ const { takerFee, makerFee, rwaTakerFee, rwaMakerFee } = hooks.useFeeState();
1483
+ const info = hooks.useRwaSymbolsInfoStore();
1484
+ const isRwa = info?.[symbol] !== void 0;
1485
+ return /* @__PURE__ */ jsxRuntime.jsx(
1486
+ RegularFeesWidget,
1487
+ {
1488
+ taker: isRwa ? rwaTakerFee : takerFee,
1489
+ maker: isRwa ? rwaMakerFee : makerFee
1490
+ }
1491
+ );
1492
+ };
1493
+ var options = [0.01, 0.05, 0.1];
1494
+ var SlippageEditor = React3.forwardRef((props, ref) => {
1495
+ const { t } = i18n.useTranslation();
1496
+ const [value, setValue] = React3.useState();
1497
+ const [customValue, setCustomValue] = React3.useState("");
1498
+ const [error, setError] = React3.useState(void 0);
1499
+ React3.useImperativeHandle(ref, () => ({
1500
+ getValue: () => customValue ? new utils.Decimal(customValue)?.toNumber() : value
1501
+ }));
1502
+ React3.useEffect(() => {
1503
+ if (props.initialValue && !options.includes(props.initialValue)) {
1504
+ setCustomValue(props.initialValue.toString());
1505
+ } else {
1506
+ setValue(props.initialValue);
1507
+ }
1508
+ }, [props.initialValue, open]);
1509
+ const onClick = (val) => {
1510
+ setValue(val);
1511
+ setCustomValue("");
1512
+ setError(void 0);
1513
+ };
1514
+ const onValueChange = (val) => {
1515
+ if (!val) {
1516
+ setCustomValue(val);
1517
+ return;
1518
+ }
1519
+ const d = new utils.Decimal(val);
1520
+ setValue(void 0);
1521
+ if (d.gt(3)) {
1522
+ setCustomValue("3");
1523
+ setError(t("orderEntry.slippage.error.exceed"));
1524
+ } else {
1525
+ setCustomValue(val);
1526
+ setError(void 0);
1527
+ }
1528
+ };
1529
+ const toolTipButton = props.isMobile ? /* @__PURE__ */ jsxRuntime.jsx(
1530
+ "button",
1531
+ {
1532
+ onClick: () => {
1533
+ ui.modal.alert({
1534
+ title: t("common.tips"),
1535
+ message: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: t("orderEntry.slippage.tips") })
1536
+ });
1537
+ },
1538
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.ExclamationFillIcon, { className: "oui-text-base-contrast-54", size: 16 })
1539
+ }
1540
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1541
+ ui.Tooltip,
1542
+ {
1543
+ content: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, size: "2xs", children: t("orderEntry.slippage.tips") }),
1544
+ className: "oui-w-[260px] oui-bg-base-6",
1545
+ arrow: { className: "oui-fill-base-6" },
1546
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.ExclamationFillIcon, { className: "oui-text-base-contrast-54", size: 16 }) })
1547
+ }
1548
+ );
1549
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-slippageEditor oui-text-2xs", children: [
1550
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { mb: 2, gapX: 1, children: [
1551
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.slippage") }),
1552
+ toolTipButton
1553
+ ] }),
1554
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gapX: 2, children: [
1555
+ options.map((item) => {
1556
+ const isActive = value === item;
1557
+ return /* @__PURE__ */ jsxRuntime.jsx(
1558
+ SlippageItem,
1559
+ {
1560
+ value: item,
1561
+ isActive,
1562
+ onClick: () => {
1563
+ onClick(item);
1564
+ }
1565
+ },
1566
+ item
1567
+ );
1568
+ }),
1569
+ /* @__PURE__ */ jsxRuntime.jsx(
1570
+ ui.Input,
1571
+ {
1572
+ suffix: "%",
1573
+ formatters: [
1574
+ ui.inputFormatter.numberFormatter,
1575
+ ui.inputFormatter.dpFormatter(2)
1576
+ ],
1577
+ value: customValue,
1578
+ onValueChange,
1579
+ classNames: {
1580
+ root: ui.cn(
1581
+ "oui-slippageEditor-customInput",
1582
+ "oui-rounded-md oui-bg-base-6",
1583
+ "oui-h-[40px] oui-w-[74px]"
1584
+ ),
1585
+ input: "oui-text-base-contrast",
1586
+ additional: "oui-pl-1"
1587
+ }
1588
+ }
1589
+ )
1590
+ ] }),
1591
+ !!error && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { mt: 5, className: "-oui-mb-5", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", color: "danger", children: error }) })
1592
+ ] });
1593
+ });
1594
+ var SlippageItem = ({ value, isActive, onClick }) => {
1595
+ return /* @__PURE__ */ jsxRuntime.jsx(
1596
+ ui.Flex,
1597
+ {
1598
+ intensity: 600,
1599
+ justify: "center",
1600
+ itemAlign: "center",
1601
+ r: "md",
1602
+ width: 74,
1603
+ height: 40,
1604
+ className: ui.cn(
1605
+ "oui-slippageEditor-option",
1606
+ "oui-cursor-pointer oui-select-none",
1607
+ isActive ? "oui-bg-primary-light oui-text-primary-contrast/80" : "oui-text-base-contrast-80"
1608
+ ),
1609
+ onClick,
1610
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "sm", children: [
1611
+ value,
1612
+ "%"
1613
+ ] })
1614
+ }
1615
+ );
1616
+ };
1617
+ var SlippageCell = (props) => {
1618
+ const { t } = i18n.useTranslation();
1619
+ const [open2, { setTrue: setOpen, setFalse: setClose, toggle }] = hooks.useBoolean(false);
1620
+ const { isMobile } = ui.useScreen();
1621
+ const slippageRef = React3.useRef(null);
1622
+ const onConfirm = () => {
1623
+ const val = slippageRef.current?.getValue();
1624
+ props.setSlippage(!val ? "1" : val.toString());
1625
+ setClose();
1626
+ return Promise.resolve(true);
1627
+ };
1628
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1629
+ /* @__PURE__ */ jsxRuntime.jsx(
1630
+ ui.SimpleDialog,
1631
+ {
1632
+ open: open2,
1633
+ onOpenChange: toggle,
1634
+ title: t("common.settings"),
1635
+ contentProps: { size: isMobile ? "xs" : "sm" },
1636
+ classNames: {
1637
+ footer: "oui-orderEntry-slippage-footer",
1638
+ body: "oui-orderEntry-slippage-body"
1639
+ },
1640
+ actions: {
1641
+ primary: {
1642
+ disabled: false,
1643
+ label: t("common.save"),
1644
+ onClick: onConfirm,
1645
+ className: "oui-slippage-save-btn"
1646
+ },
1647
+ secondary: {
1648
+ label: t("common.cancel"),
1649
+ onClick: () => setClose(),
1650
+ className: "oui-slippage-cancel-btn"
1651
+ }
1652
+ },
1653
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1654
+ SlippageEditor,
1655
+ {
1656
+ ref: slippageRef,
1657
+ isMobile,
1658
+ initialValue: props.slippage ? Number(props.slippage) : void 0
1659
+ }
1660
+ )
1661
+ }
1662
+ ),
1663
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-orderEntry-slippage", children: [
1664
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-slippage-label", size: "2xs", children: t("orderEntry.slippage") }),
1665
+ /* @__PURE__ */ jsxRuntime.jsx(
1666
+ uiConnector.AuthGuard,
1667
+ {
1668
+ fallback: () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "2xs", children: [
1669
+ t("orderEntry.slippage.est"),
1670
+ ": -% / ",
1671
+ t("common.max"),
1672
+ ": --%"
1673
+ ] }),
1674
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, className: "oui-slippage-value-container", children: [
1675
+ /* @__PURE__ */ jsxRuntime.jsx(
1676
+ ui.Text.numeral,
1677
+ {
1678
+ size: "2xs",
1679
+ rule: "percentages",
1680
+ prefix: `${t("orderEntry.slippage.est")}: `,
1681
+ suffix: ` / ${t("common.max")}: `,
1682
+ children: props.estSlippage ?? 0
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsxRuntime.jsx(
1686
+ "button",
1687
+ {
1688
+ className: "oui-slippage-edit-btn oui-text-2xs",
1689
+ onClick: () => setOpen(),
1690
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { className: "oui-gap-0.5", as: "span", children: [
1691
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", className: "oui-text-primary", children: `${props.slippage || "-"}%` }),
1692
+ /* @__PURE__ */ jsxRuntime.jsx(
1693
+ ui.EditIcon,
1694
+ {
1695
+ className: "oui-slippage-edit-icon oui-text-primary oui-hidden md:oui-block",
1696
+ size: 12,
1697
+ opacity: 1
1698
+ }
1699
+ )
1700
+ ] })
1701
+ }
1702
+ )
1703
+ ] })
1704
+ }
1705
+ )
1706
+ ] })
1707
+ ] });
1708
+ };
1709
+ var SlippageUI = (props) => {
1710
+ return /* @__PURE__ */ jsxRuntime.jsx(SlippageCell, { ...props });
1711
+ };
1712
+ function AssetInfo(props) {
1713
+ const { canTrade, disableFeatures, orderType, symbol } = props;
1714
+ const { t } = i18n.useTranslation();
1715
+ const { isMobile } = ui.useScreen();
1716
+ const displayEstLiqPrice = hooks.useGetEstLiqPrice({
1717
+ estLiqPrice: props.estLiqPrice,
1718
+ symbol,
1719
+ side: props.side
1720
+ });
1721
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1722
+ "div",
1723
+ {
1724
+ className: "oui-orderEntry-assetInfo oui-space-y-[2px] xl:oui-space-y-1",
1725
+ children: [
1726
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-orderEntry-estLiqPrice", children: [
1727
+ isMobile ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "2xs", children: t("orderEntry.estLiqPrice") }) : /* @__PURE__ */ jsxRuntime.jsx(
1728
+ ui.Tooltip,
1729
+ {
1730
+ content: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-min-w-[204px] oui-max-w-[280px] oui-text-2xs oui-leading-normal oui-text-base-contrast-80", children: [
1731
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-text-pretty", children: t("common.liquidationPrice.tooltip") }),
1732
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
1733
+ "a",
1734
+ {
1735
+ href: "https://orderly.network/docs/introduction/trade-on-orderly/perpetual-futures/liquidations",
1736
+ target: "_blank",
1737
+ rel: "noopener noreferrer",
1738
+ className: "oui-text-primary oui-underline",
1739
+ children: t("common.liquidationPrice.tooltip.learnMore")
1740
+ }
1741
+ ) })
1742
+ ] }),
1743
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1744
+ ui.Text,
1745
+ {
1746
+ size: "2xs",
1747
+ className: "oui-estLiqPrice-label oui-cursor-pointer oui-border-b oui-border-dashed oui-border-line-12",
1748
+ children: t("orderEntry.estLiqPrice")
1749
+ }
1750
+ )
1751
+ }
1752
+ ),
1753
+ /* @__PURE__ */ jsxRuntime.jsx(
1754
+ ui.Text.numeral,
1755
+ {
1756
+ unit: props.quote,
1757
+ size: "2xs",
1758
+ dp: props.dp,
1759
+ className: "oui-estLiqPrice-value oui-text-base-contrast-80",
1760
+ unitClassName: "oui-ml-1 oui-text-base-contrast-36",
1761
+ children: canTrade ? displayEstLiqPrice ?? "--" : "--"
1762
+ }
1763
+ )
1764
+ ] }),
1765
+ orderType === types.OrderType.MARKET && !disableFeatures?.includes("slippageSetting") && /* @__PURE__ */ jsxRuntime.jsx(
1766
+ SlippageUI,
1767
+ {
1768
+ slippage: props.slippage,
1769
+ setSlippage: props.setSlippage,
1770
+ estSlippage: props.estSlippage
1771
+ }
1772
+ ),
1773
+ !disableFeatures?.includes("feesInfo") && /* @__PURE__ */ jsxRuntime.jsx(FeesWidget, { symbol: props.symbol })
1774
+ ]
1775
+ }
1776
+ );
1777
+ }
1778
+ var calculateLTVColor = (val) => {
1779
+ if (val >= 0 && val < 50) {
1780
+ return "oui-text-success";
1781
+ } else if (val >= 50 && val < 80) {
1782
+ return "oui-text-warning";
1783
+ } else if (val >= 80) {
1784
+ return "oui-text-danger";
1785
+ } else {
1786
+ return "";
1787
+ }
1788
+ };
1789
+ var LTVRiskTooltipUI = (props) => {
1790
+ const { t } = i18n.useTranslation();
1791
+ const {
1792
+ ltv_threshold,
1793
+ negative_usdc_threshold,
1794
+ isThresholdLoading,
1795
+ holdingData = [],
1796
+ currentLtv,
1797
+ onConvert,
1798
+ marginMode
1799
+ } = props;
1800
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1801
+ ui.Flex,
1802
+ {
1803
+ gap: 1,
1804
+ className: "oui-orderEntry-ltvRiskTooltip oui-w-72 oui-max-w-72",
1805
+ direction: "column",
1806
+ itemAlign: "start",
1807
+ children: [
1808
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", justify: "between", itemAlign: "center", children: [
1809
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("common.assets") }),
1810
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("transfer.deposit.collateralContribution") })
1811
+ ] }),
1812
+ holdingData.map((asset, index) => {
1813
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1814
+ ui.Flex,
1815
+ {
1816
+ width: "100%",
1817
+ justify: "between",
1818
+ itemAlign: "center",
1819
+ children: [
1820
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, size: "xs", children: asset.token }),
1821
+ /* @__PURE__ */ jsxRuntime.jsx(
1822
+ ui.Text,
1823
+ {
1824
+ size: "xs",
1825
+ intensity: 80,
1826
+ className: ui.cn(
1827
+ Number(asset.collateralContribution) < 0 && "oui-text-warning"
1828
+ ),
1829
+ children: utils.removeTrailingZeros(asset.collateralContribution)
1830
+ }
1831
+ )
1832
+ ]
1833
+ },
1834
+ `item-${index}`
1835
+ );
1836
+ }),
1837
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
1838
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { width: "100%", justify: "between", itemAlign: "center", children: [
1839
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 36, size: "xs", children: t("transfer.LTV.currentLTV") }),
1840
+ /* @__PURE__ */ jsxRuntime.jsxs(
1841
+ ui.Text,
1842
+ {
1843
+ size: "xs",
1844
+ intensity: 36,
1845
+ className: ui.cn("oui-select-none", calculateLTVColor(currentLtv)),
1846
+ children: [
1847
+ currentLtv,
1848
+ "%"
1849
+ ]
1850
+ }
1851
+ )
1852
+ ] }),
1853
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-py-2", intensity: 54, size: "2xs", children: t("transfer.LTV.tooltip", {
1854
+ threshold: isThresholdLoading ? "-" : ltv_threshold,
1855
+ usdcThreshold: isThresholdLoading ? "-" : negative_usdc_threshold
1856
+ }) }),
1857
+ /* @__PURE__ */ jsxRuntime.jsx(
1858
+ ui.Button,
1859
+ {
1860
+ fullWidth: true,
1861
+ size: "md",
1862
+ variant: "outlined",
1863
+ color: "secondary",
1864
+ className: "oui-ltvRiskTooltip-convert-btn",
1865
+ onClick: onConvert,
1866
+ children: t("transfer.convert.convertAssets")
1867
+ }
1868
+ )
1869
+ ]
1870
+ }
1871
+ );
1872
+ };
1873
+ var useConvertThreshold = () => {
1874
+ const { data, error, isLoading } = hooks.useQuery(
1875
+ "/v1/public/auto_convert_threshold",
1876
+ { errorRetryCount: 3 }
1877
+ );
1878
+ return {
1879
+ ltv_threshold: new utils.Decimal(data?.ltv_threshold ?? 0).mul(100).toNumber(),
1880
+ negative_usdc_threshold: data?.negative_usdc_threshold,
1881
+ isLoading,
1882
+ error
1883
+ };
1884
+ };
1885
+ var useLTVTooltipScript = (marginMode) => {
1886
+ const { data: holdingList = [], isLoading: isHoldingLoading } = hooks.useHoldingStream();
1887
+ const {
1888
+ ltv_threshold,
1889
+ negative_usdc_threshold,
1890
+ isLoading: isThresholdLoading
1891
+ } = useConvertThreshold();
1892
+ const tokensInfo = hooks.useAppStore((state) => state.tokensInfo);
1893
+ const { getIndexPrice } = hooks.useIndexPricesStream();
1894
+ const holdingData = holdingList.map((item) => {
1895
+ const tokenInfo = tokensInfo?.find(({ token }) => token === item.token);
1896
+ const indexPrice = getIndexPrice(item.token);
1897
+ const collateralRatio = tokenInfo ? perp.account.collateralRatio({
1898
+ baseWeight: tokenInfo.base_weight ?? 0,
1899
+ discountFactor: tokenInfo.discount_factor ?? 0,
1900
+ collateralQty: item.holding,
1901
+ collateralCap: tokenInfo?.user_max_qty ?? item.holding,
1902
+ indexPrice
1903
+ }) : utils.zero;
1904
+ const collateralContribution = perp.account.collateralContribution({
1905
+ collateralQty: item.holding,
1906
+ collateralCap: tokenInfo?.user_max_qty ?? item.holding,
1907
+ collateralRatio: collateralRatio.toNumber(),
1908
+ indexPrice
1909
+ });
1910
+ return {
1911
+ ...item,
1912
+ collateralContribution
1913
+ };
1914
+ });
1915
+ const currentLtv = hooks.useComputedLTV();
1916
+ const onConvert = React3.useCallback(async () => {
1917
+ return ui.modal.show("ConvertDialogId");
1918
+ }, []);
1919
+ return {
1920
+ holdingData,
1921
+ isHoldingLoading,
1922
+ ltv_threshold,
1923
+ negative_usdc_threshold,
1924
+ isThresholdLoading,
1925
+ currentLtv,
1926
+ onConvert,
1927
+ marginMode
1928
+ };
1929
+ };
1930
+ var LTVRiskTooltipWidget = ({
1931
+ marginMode
1932
+ }) => {
1933
+ const state = useLTVTooltipScript(marginMode);
1934
+ return /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipUI, { ...state });
1935
+ };
1936
+ var Available = (props) => {
1937
+ const { canTrade, currentLtv, quote, freeCollateral, marginMode } = props;
1938
+ const { t } = i18n.useTranslation();
1939
+ const { isMobile } = ui.useScreen();
1940
+ const showLTV = React3.useMemo(() => {
1941
+ return typeof currentLtv === "number" && !Number.isNaN(currentLtv) && currentLtv > 0;
1942
+ }, [currentLtv]);
1943
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1944
+ ui.Flex,
1945
+ {
1946
+ itemAlign: "center",
1947
+ justify: "between",
1948
+ className: "oui-orderEntry-available",
1949
+ children: [
1950
+ marginMode === types.MarginMode.ISOLATED ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: t("transfer.LTV.isolatedModeUsdcOnly"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label oui-cursor-pointer", size: "2xs", children: t("common.available") }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-available-label", size: "2xs", children: t("common.available") }),
1951
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { itemAlign: "center", justify: "center", gap: 1, children: [
1952
+ showLTV && /* @__PURE__ */ jsxRuntime.jsx(
1953
+ ui.Tooltip,
1954
+ {
1955
+ className: "oui-available-ltvRisk-tooltip oui-bg-base-6 oui-p-2",
1956
+ content: /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipWidget, { marginMode }),
1957
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1958
+ ui.InfoCircleIcon,
1959
+ {
1960
+ className: "oui-cursor-pointer oui-text-warning oui-opacity-80"
1961
+ }
1962
+ )
1963
+ }
1964
+ ),
1965
+ /* @__PURE__ */ jsxRuntime.jsx(
1966
+ ui.Text.numeral,
1967
+ {
1968
+ unit: quote,
1969
+ size: "2xs",
1970
+ className: "oui-available-value oui-text-base-contrast-80",
1971
+ unitClassName: "oui-ml-1 oui-text-base-contrast-54",
1972
+ dp: 2,
1973
+ padding: false,
1974
+ children: canTrade ? freeCollateral : 0
1975
+ }
1976
+ ),
1977
+ /* @__PURE__ */ jsxRuntime.jsx(
1978
+ ui.Button,
1979
+ {
1980
+ variant: "text",
1981
+ size: "xs",
1982
+ color: "secondary",
1983
+ className: "oui-available-deposit-icon oui-p-0 hover:oui-text-base-contrast-80",
1984
+ onClick: () => {
1985
+ const handleDomId = isMobile ? "DepositAndWithdrawWithSheetId" : "DepositAndWithdrawWithDialogId";
1986
+ ui.modal.show(handleDomId, {
1987
+ activeTab: "deposit"
1988
+ });
1989
+ },
1990
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddCircleIcon, { opacity: 1 })
1991
+ }
1992
+ )
1993
+ ] })
1994
+ ]
1995
+ }
1996
+ );
1997
+ };
1862
1998
  var OrderTypeSelect = (props) => {
1863
1999
  const { t } = i18n.useTranslation();
1864
2000
  const { isMobile } = ui.useScreen();
2001
+ const { marketOrderDisabled = false, marketOrderDisabledTooltip } = props;
1865
2002
  const allOptions = React3.useMemo(() => {
1866
2003
  return [
1867
2004
  { label: t("orderEntry.orderType.limitOrder"), value: types.OrderType.LIMIT },
@@ -1942,7 +2079,24 @@ var OrderTypeSelect = (props) => {
1942
2079
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.orderType.limit") })
1943
2080
  }
1944
2081
  ),
1945
- /* @__PURE__ */ jsxRuntime.jsx(
2082
+ marketOrderDisabled && marketOrderDisabledTooltip ? /* @__PURE__ */ jsxRuntime.jsx(
2083
+ ui.Tooltip,
2084
+ {
2085
+ content: marketOrderDisabledTooltip,
2086
+ className: "oui-max-w-[275px]",
2087
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-inline-flex oui-flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2088
+ "button",
2089
+ {
2090
+ type: "button",
2091
+ className: unselectedButtonClassName,
2092
+ "aria-pressed": false,
2093
+ disabled: true,
2094
+ "data-testid": "oui-testid-orderEntry-orderType-market",
2095
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: t("orderEntry.orderType.market") })
2096
+ }
2097
+ ) })
2098
+ }
2099
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1946
2100
  "button",
1947
2101
  {
1948
2102
  type: "button",
@@ -1992,14 +2146,25 @@ var OrderTypeSelect = (props) => {
1992
2146
  }
1993
2147
  );
1994
2148
  }
2149
+ const mobileOptions = React3.useMemo(() => allOptions, [allOptions]);
2150
+ const handleMobileValueChange = (value) => {
2151
+ if (marketOrderDisabled && value === types.OrderType.MARKET && marketOrderDisabledTooltip) {
2152
+ ui.modal.alert({
2153
+ title: t("common.tips"),
2154
+ message: marketOrderDisabledTooltip
2155
+ });
2156
+ return;
2157
+ }
2158
+ props.onChange(value);
2159
+ };
1995
2160
  return /* @__PURE__ */ jsxRuntime.jsx(
1996
2161
  ui.Select.options,
1997
2162
  {
1998
2163
  testid: "oui-testid-orderEntry-orderType-button",
1999
2164
  currentValue: props.type,
2000
2165
  value: props.type,
2001
- options: allOptions,
2002
- onValueChange: props.onChange,
2166
+ options: mobileOptions,
2167
+ onValueChange: handleMobileValueChange,
2003
2168
  contentProps: {
2004
2169
  className: ui.cn(
2005
2170
  "oui-orderEntry-orderTypeSelect-content",
@@ -2017,13 +2182,281 @@ var OrderTypeSelect = (props) => {
2017
2182
  if (!item) {
2018
2183
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: option.placeholder });
2019
2184
  }
2020
- const label = displayLabelMap[value];
2021
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", className: "oui-text-base-contrast-80", children: label });
2022
- },
2023
- size: "md"
2024
- }
2025
- );
2026
- };
2185
+ const label = displayLabelMap[value];
2186
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", className: "oui-text-base-contrast-80", children: label });
2187
+ },
2188
+ size: "md"
2189
+ }
2190
+ );
2191
+ };
2192
+ var OrderEntryContext = React3.createContext(
2193
+ {}
2194
+ );
2195
+ var useOrderEntryContext = () => {
2196
+ return React3.useContext(OrderEntryContext);
2197
+ };
2198
+ var SLIDER_MIN = 0;
2199
+ var SLIDER_MAX = 100;
2200
+ var QuantitySlider = React3.memo((props) => {
2201
+ const { canTrade, side, order_quantity, maxQty } = props;
2202
+ const [sliderValue, setSliderValue] = React3.useState(0);
2203
+ const {
2204
+ setOrderValue,
2205
+ manualSetOrderValue,
2206
+ symbolInfo,
2207
+ lastQuantityInputType
2208
+ } = useOrderEntryContext();
2209
+ const { base_dp, base_tick } = symbolInfo;
2210
+ const { t } = i18n.useTranslation();
2211
+ const color = React3.useMemo(
2212
+ () => canTrade ? side === types.OrderSide.BUY ? "buy" : "sell" : void 0,
2213
+ [side, canTrade]
2214
+ );
2215
+ const maxLabel = React3.useMemo(() => {
2216
+ return side === types.OrderSide.BUY ? t("orderEntry.maxBuy") : t("orderEntry.maxSell");
2217
+ }, [side, t]);
2218
+ const onSliderValueChange = (value) => {
2219
+ lastQuantityInputType.current = 4 /* QUANTITY_SLIDER */;
2220
+ setSliderValue(value);
2221
+ sliderToQuantity(value, true);
2222
+ };
2223
+ const sliderToQuantity = (value, isManual = false) => {
2224
+ const newQty = new utils.Decimal(value).div(SLIDER_MAX).mul(maxQty).toFixed(base_dp, utils.Decimal.ROUND_DOWN);
2225
+ if (isManual) {
2226
+ manualSetOrderValue?.(
2227
+ "order_quantity",
2228
+ hooks.utils.formatNumber(newQty, base_tick)
2229
+ );
2230
+ } else {
2231
+ setOrderValue("order_quantity", hooks.utils.formatNumber(newQty, base_tick));
2232
+ }
2233
+ };
2234
+ const onMax = () => {
2235
+ onSliderValueChange(SLIDER_MAX);
2236
+ if (sliderValue === SLIDER_MAX) {
2237
+ sliderToQuantity(SLIDER_MAX, true);
2238
+ }
2239
+ };
2240
+ React3.useEffect(() => {
2241
+ if (lastQuantityInputType.current === 4 /* QUANTITY_SLIDER */) {
2242
+ sliderToQuantity(sliderValue);
2243
+ }
2244
+ }, [maxQty]);
2245
+ React3.useEffect(() => {
2246
+ const quantityToSlider = () => {
2247
+ if (order_quantity && Number(order_quantity) !== 0 && maxQty !== 0) {
2248
+ return new utils.Decimal(Math.min(Number(order_quantity), maxQty)).div(maxQty).mul(SLIDER_MAX).todp(2, utils.Decimal.ROUND_DOWN).toNumber();
2249
+ }
2250
+ return 0;
2251
+ };
2252
+ if (lastQuantityInputType.current !== 4 /* QUANTITY_SLIDER */) {
2253
+ setSliderValue(quantityToSlider());
2254
+ }
2255
+ }, [order_quantity, maxQty]);
2256
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-quantitySlider", children: [
2257
+ /* @__PURE__ */ jsxRuntime.jsx(
2258
+ ui.Slider,
2259
+ {
2260
+ disabled: maxQty === 0 || !canTrade,
2261
+ value: [sliderValue],
2262
+ color,
2263
+ markCount: 4,
2264
+ showTip: true,
2265
+ onValueChange: (e) => {
2266
+ onSliderValueChange(e[0]);
2267
+ },
2268
+ min: SLIDER_MIN,
2269
+ max: SLIDER_MAX
2270
+ }
2271
+ ),
2272
+ /* @__PURE__ */ jsxRuntime.jsxs(
2273
+ ui.Flex,
2274
+ {
2275
+ justify: "between",
2276
+ className: "oui-quantitySlider-footer oui-pt-1 xl:oui-pt-2",
2277
+ children: [
2278
+ /* @__PURE__ */ jsxRuntime.jsx(
2279
+ ui.Text.numeral,
2280
+ {
2281
+ size: "2xs",
2282
+ color,
2283
+ dp: 2,
2284
+ padding: false,
2285
+ suffix: "%",
2286
+ children: canTrade ? sliderValue : 0
2287
+ }
2288
+ ),
2289
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
2290
+ /* @__PURE__ */ jsxRuntime.jsx(
2291
+ "button",
2292
+ {
2293
+ className: ui.textVariants({
2294
+ size: "2xs",
2295
+ className: "oui-quantitySlider-maxQty-btn oui-mr-1"
2296
+ }),
2297
+ onClick: onMax,
2298
+ "data-testid": "oui-testid-orderEntry-maxQty-value-button",
2299
+ children: maxLabel
2300
+ }
2301
+ ),
2302
+ /* @__PURE__ */ jsxRuntime.jsx(
2303
+ ui.Text.numeral,
2304
+ {
2305
+ size: "2xs",
2306
+ color,
2307
+ dp: base_dp,
2308
+ padding: false,
2309
+ className: "oui-quantitySlider-maxQty-value",
2310
+ "data-testid": "oui-testid-orderEntry-maxQty-value",
2311
+ children: canTrade ? maxQty : 0
2312
+ }
2313
+ )
2314
+ ] })
2315
+ ]
2316
+ }
2317
+ )
2318
+ ] });
2319
+ });
2320
+ QuantitySlider.displayName = "QuantitySlider";
2321
+ var OrderEntryTypeTabsInjectabled = ui.injectable(
2322
+ (props) => {
2323
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
2324
+ OrderTypeSelect,
2325
+ {
2326
+ type: props.type,
2327
+ side: props.side,
2328
+ canTrade: props.canTrade,
2329
+ onChange: props.onChange,
2330
+ marketOrderDisabled: props.marketOrderDisabled,
2331
+ marketOrderDisabledTooltip: props.marketOrderDisabledTooltip
2332
+ }
2333
+ ) });
2334
+ },
2335
+ "Trading.OrderEntry.TypeTabs"
2336
+ );
2337
+ var OrderEntryBuySellSwitchInjectabled = ui.injectable(
2338
+ (props) => {
2339
+ const { t } = i18n.useTranslation();
2340
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2341
+ "div",
2342
+ {
2343
+ className: ui.cn(
2344
+ "oui-orderEntry-side",
2345
+ "oui-grid oui-w-full oui-flex-1 oui-gap-x-2 lg:oui-flex lg:oui-gap-x-[6px]",
2346
+ "oui-grid-cols-2"
2347
+ ),
2348
+ children: [
2349
+ /* @__PURE__ */ jsxRuntime.jsx(
2350
+ ui.Button,
2351
+ {
2352
+ onClick: () => {
2353
+ props.onSideChange(types.OrderSide.BUY);
2354
+ },
2355
+ size: "md",
2356
+ fullWidth: true,
2357
+ "data-type": types.OrderSide.BUY,
2358
+ className: ui.cn(
2359
+ "oui-orderEntry-side-buy-btn",
2360
+ props.side === types.OrderSide.BUY && props.canTrade ? "oui-bg-success-darken hover:oui-bg-success-darken/80 active:oui-bg-success-darken/80" : "oui-bg-base-7 oui-text-base-contrast-36 hover:oui-bg-base-6 active:oui-bg-base-6"
2361
+ ),
2362
+ "data-testid": "oui-testid-orderEntry-side-buy-button",
2363
+ children: t("common.buy")
2364
+ }
2365
+ ),
2366
+ /* @__PURE__ */ jsxRuntime.jsx(
2367
+ ui.Button,
2368
+ {
2369
+ onClick: () => {
2370
+ props.onSideChange(types.OrderSide.SELL);
2371
+ },
2372
+ "data-type": types.OrderSide.SELL,
2373
+ fullWidth: true,
2374
+ size: "md",
2375
+ className: ui.cn(
2376
+ "oui-orderEntry-side-sell-btn",
2377
+ props.side === types.OrderSide.SELL && props.canTrade ? "oui-bg-danger-darken hover:oui-bg-danger-darken/80 active:oui-bg-danger-darken/80" : "oui-bg-base-7 oui-text-base-contrast-36 hover:oui-bg-base-6 active:oui-bg-base-6"
2378
+ ),
2379
+ "data-testid": "oui-testid-orderEntry-side-sell-button",
2380
+ children: t("common.sell")
2381
+ }
2382
+ )
2383
+ ]
2384
+ }
2385
+ );
2386
+ },
2387
+ "Trading.OrderEntry.BuySellSwitch"
2388
+ );
2389
+ var OrderEntryAvailableInjectabled = ui.injectable(
2390
+ (props) => {
2391
+ return /* @__PURE__ */ jsxRuntime.jsx(
2392
+ Available,
2393
+ {
2394
+ currentLtv: props.currentLtv,
2395
+ canTrade: props.canTrade,
2396
+ quote: props.quote,
2397
+ freeCollateral: props.freeCollateral,
2398
+ marginMode: props.marginMode
2399
+ }
2400
+ );
2401
+ },
2402
+ "Trading.OrderEntry.Available"
2403
+ );
2404
+ var OrderEntryQuantitySliderInjectabled = ui.injectable(
2405
+ (props) => {
2406
+ return /* @__PURE__ */ jsxRuntime.jsx(
2407
+ QuantitySlider,
2408
+ {
2409
+ canTrade: props.canTrade,
2410
+ side: props.side,
2411
+ order_quantity: props.order_quantity,
2412
+ maxQty: props.maxQty
2413
+ }
2414
+ );
2415
+ },
2416
+ "Trading.OrderEntry.QuantitySlider"
2417
+ );
2418
+ var OrderEntrySubmitSectionInjectabled = ui.injectable(
2419
+ (props) => {
2420
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2421
+ /* @__PURE__ */ jsxRuntime.jsx(
2422
+ ui.ThrottledButton,
2423
+ {
2424
+ fullWidth: true,
2425
+ id: "order-entry-submit-button",
2426
+ "data-type": types.OrderSide.BUY,
2427
+ className: ui.cn(
2428
+ "oui-orderEntry-submit-btn",
2429
+ props.side === types.OrderSide.BUY ? "orderly-order-entry-submit-button-buy oui-bg-success-darken hover:oui-bg-success-darken/80 active:oui-bg-success-darken/80" : "orderly-order-entry-submit-button-sell oui-bg-danger-darken hover:oui-bg-danger-darken/80 active:oui-bg-danger-darken/80"
2430
+ ),
2431
+ onClick: props.onSubmit,
2432
+ loading: props.isMutating,
2433
+ disabled: !props.canTrade,
2434
+ children: props.buttonLabel
2435
+ }
2436
+ ),
2437
+ /* @__PURE__ */ jsxRuntime.jsx(
2438
+ AssetInfo,
2439
+ {
2440
+ canTrade: props.assetInfo.canTrade,
2441
+ quote: props.assetInfo.quote,
2442
+ estLiqPrice: props.assetInfo.estLiqPrice,
2443
+ estLiqPriceDistance: props.assetInfo.estLiqPriceDistance,
2444
+ estLeverage: props.assetInfo.estLeverage,
2445
+ currentLeverage: props.assetInfo.currentLeverage,
2446
+ slippage: props.assetInfo.slippage,
2447
+ dp: props.assetInfo.dp,
2448
+ setSlippage: props.assetInfo.setSlippage,
2449
+ estSlippage: props.assetInfo.estSlippage,
2450
+ orderType: props.assetInfo.orderType,
2451
+ disableFeatures: props.assetInfo.disableFeatures,
2452
+ symbol: props.assetInfo.symbol,
2453
+ side: props.assetInfo.side
2454
+ }
2455
+ )
2456
+ ] });
2457
+ },
2458
+ "Trading.OrderEntry.SubmitSection"
2459
+ );
2027
2460
  var MarginModeSwitch = (props) => {
2028
2461
  const { t } = i18n.useTranslation();
2029
2462
  const handleSelect = (mode) => {
@@ -2102,10 +2535,11 @@ var MarginModeSwitch = (props) => {
2102
2535
  {
2103
2536
  className: "oui-tracking-[0.03em]",
2104
2537
  rule: "symbol",
2105
- formatString: "base-type",
2538
+ formatString: "base",
2106
2539
  size: "base",
2107
2540
  weight: "semibold",
2108
2541
  intensity: 98,
2542
+ suffix: /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol: props.symbol }),
2109
2543
  children: props.symbol
2110
2544
  }
2111
2545
  )
@@ -2117,7 +2551,8 @@ var MarginModeSwitch = (props) => {
2117
2551
  mode: types.MarginMode.CROSS,
2118
2552
  selected: props.selectedMarginMode === types.MarginMode.CROSS,
2119
2553
  isCurrent: props.currentMarginMode === types.MarginMode.CROSS,
2120
- onClick: () => handleSelect(types.MarginMode.CROSS)
2554
+ onClick: () => handleSelect(types.MarginMode.CROSS),
2555
+ disabled: props.isPermissionlessListing
2121
2556
  }
2122
2557
  ),
2123
2558
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2180,9 +2615,11 @@ var OptionCard = (props) => {
2180
2615
  "oui-relative oui-w-full oui-rounded-md oui-p-2",
2181
2616
  "oui-bg-base-6",
2182
2617
  "oui-text-left",
2183
- props.selected ? "oui-border oui-border-[#38e2fe]" : "oui-border oui-border-transparent hover:oui-border-line-12"
2618
+ props.disabled ? "oui-cursor-not-allowed oui-opacity-50 oui-border oui-border-transparent" : props.selected ? "oui-border oui-border-[#38e2fe]" : "oui-border oui-border-transparent hover:oui-border-line-12"
2184
2619
  ),
2185
- onClick: props.onClick,
2620
+ onClick: props.disabled ? void 0 : props.onClick,
2621
+ disabled: props.disabled,
2622
+ "aria-disabled": props.disabled,
2186
2623
  "data-testid": `oui-testid-marginModeSwitch-option-${props.mode}`,
2187
2624
  children: [
2188
2625
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", gap: 2, itemAlign: "start", className: "oui-w-full", children: [
@@ -2215,7 +2652,11 @@ var useMarginModeSwitchScript = (options2) => {
2215
2652
  const { symbol, close } = options2;
2216
2653
  const { isMobile } = ui.useScreen();
2217
2654
  const { t } = i18n.useTranslation();
2218
- const { marginMode: currentMarginMode, update } = hooks.useMarginModeBySymbol(symbol);
2655
+ const {
2656
+ marginMode: currentMarginMode,
2657
+ update,
2658
+ isPermissionlessListing
2659
+ } = hooks.useMarginModeBySymbol(symbol);
2219
2660
  const [selectedMarginMode, setSelectedMarginMode] = React3.useState(currentMarginMode);
2220
2661
  React3.useEffect(() => {
2221
2662
  setSelectedMarginMode(currentMarginMode);
@@ -2253,11 +2694,13 @@ var useMarginModeSwitchScript = (options2) => {
2253
2694
  setSelectedMarginMode,
2254
2695
  applyMarginMode,
2255
2696
  close,
2256
- onSelect
2697
+ onSelect,
2698
+ isPermissionlessListing
2257
2699
  };
2258
2700
  };
2259
2701
  var useMarginModeSettingsScript = (options2) => {
2260
2702
  const { isMobile } = ui.useScreen();
2703
+ const { t } = i18n.useTranslation();
2261
2704
  const [markets] = hooks.useMarkets(hooks.MarketsType.ALL);
2262
2705
  const items = React3.useMemo(() => {
2263
2706
  if (!markets || markets.length === 0) {
@@ -2266,10 +2709,20 @@ var useMarginModeSettingsScript = (options2) => {
2266
2709
  return markets.map((market) => ({
2267
2710
  key: market.symbol,
2268
2711
  // Original symbol: "PERP_BTC_USDC"
2269
- symbol: utils.formatSymbol(market.symbol, "base-type")
2712
+ symbol: utils.formatSymbol(market.symbol, "base"),
2270
2713
  // Formatted: "BTC-PERP"
2714
+ brokerId: market.broker_id
2271
2715
  }));
2272
2716
  }, [markets]);
2717
+ const brokerLockedKeys = React3.useMemo(() => {
2718
+ const locked = /* @__PURE__ */ new Set();
2719
+ for (const item of items) {
2720
+ if (item.brokerId) {
2721
+ locked.add(item.key);
2722
+ }
2723
+ }
2724
+ return locked;
2725
+ }, [items]);
2273
2726
  const [searchKeyword, setSearchKeyword] = React3.useState("");
2274
2727
  const [selectedKeys, setSelectedKeys] = React3.useState(
2275
2728
  () => /* @__PURE__ */ new Set()
@@ -2290,11 +2743,15 @@ var useMarginModeSettingsScript = (options2) => {
2290
2743
  const itemMarginModes = React3.useMemo(() => {
2291
2744
  const result = {};
2292
2745
  for (const item of items) {
2746
+ if (brokerLockedKeys.has(item.key)) {
2747
+ result[item.key] = types.MarginMode.ISOLATED;
2748
+ continue;
2749
+ }
2293
2750
  const marginMode = marginModes[item.key];
2294
2751
  result[item.key] = marginMode ?? types.MarginMode.CROSS;
2295
2752
  }
2296
2753
  return result;
2297
- }, [items, marginModes]);
2754
+ }, [brokerLockedKeys, items, marginModes]);
2298
2755
  const filteredItems = React3.useMemo(() => {
2299
2756
  const keyword = searchKeyword.trim().toLowerCase();
2300
2757
  if (!keyword) return items;
@@ -2330,17 +2787,21 @@ var useMarginModeSettingsScript = (options2) => {
2330
2787
  const onSearchChange = React3.useCallback((keyword) => {
2331
2788
  setSearchKeyword(keyword);
2332
2789
  }, []);
2333
- const onToggleItem = React3.useCallback((key) => {
2334
- setSelectedKeys((prev) => {
2335
- const next = new Set(prev);
2336
- if (next.has(key)) {
2337
- next.delete(key);
2338
- } else {
2339
- next.add(key);
2340
- }
2341
- return next;
2342
- });
2343
- }, []);
2790
+ const onToggleItem = React3.useCallback(
2791
+ (key) => {
2792
+ if (brokerLockedKeys.has(key)) return;
2793
+ setSelectedKeys((prev) => {
2794
+ const next = new Set(prev);
2795
+ if (next.has(key)) {
2796
+ next.delete(key);
2797
+ } else {
2798
+ next.add(key);
2799
+ }
2800
+ return next;
2801
+ });
2802
+ },
2803
+ [brokerLockedKeys]
2804
+ );
2344
2805
  const onToggleSelectAll = React3.useCallback(() => {
2345
2806
  setSelectedKeys((prev) => {
2346
2807
  const next = new Set(prev);
@@ -2351,31 +2812,39 @@ var useMarginModeSettingsScript = (options2) => {
2351
2812
  return next;
2352
2813
  }
2353
2814
  for (const item of filteredItems) {
2815
+ if (brokerLockedKeys.has(item.key)) continue;
2354
2816
  next.add(item.key);
2355
2817
  }
2356
2818
  return next;
2357
2819
  });
2358
- }, [filteredItems, isSelectAll]);
2820
+ }, [brokerLockedKeys, filteredItems, isSelectAll]);
2359
2821
  const onSetMarginMode = React3.useCallback(
2360
2822
  async (mode) => {
2361
2823
  if (selectedKeys.size === 0) return;
2824
+ const editableSymbolList = Array.from(selectedKeys).filter(
2825
+ (key) => !brokerLockedKeys.has(key)
2826
+ );
2827
+ if (editableSymbolList.length === 0) {
2828
+ ui.toast.error(t("marginMode.noEditableSymbolsSelected"));
2829
+ return;
2830
+ }
2362
2831
  setIsOperationLoading(true);
2363
2832
  try {
2364
2833
  const payload = {
2365
- symbol_list: Array.from(selectedKeys),
2834
+ symbol_list: editableSymbolList,
2366
2835
  default_margin_mode: mode
2367
2836
  };
2368
2837
  await updateMarginMode(payload);
2369
- ui.toast.success("Updated successfully");
2838
+ ui.toast.success(t("marginMode.updatedSuccessfully"));
2370
2839
  } catch (error) {
2371
2840
  ui.toast.error(
2372
- error instanceof Error ? error.message : "Failed to update margin mode"
2841
+ error instanceof Error ? error.message : t("marginMode.failedToUpdateMarginMode")
2373
2842
  );
2374
2843
  } finally {
2375
2844
  setIsOperationLoading(false);
2376
2845
  }
2377
2846
  },
2378
- [selectedKeys, updateMarginMode]
2847
+ [brokerLockedKeys, selectedKeys, updateMarginMode]
2379
2848
  );
2380
2849
  const isLoading = isDataLoading || isMarginModesLoading || isOperationLoading || isSettingMarginMode;
2381
2850
  return {
@@ -2523,7 +2992,8 @@ var MarginModeSettings = (props) => {
2523
2992
  item,
2524
2993
  checked: props.selectedKeys.has(item.key),
2525
2994
  marginMode: props.itemMarginModes[item.key] ?? types.MarginMode.CROSS,
2526
- onToggle: props.onToggleItem
2995
+ onToggle: props.onToggleItem,
2996
+ disabled: !!item.brokerId
2527
2997
  },
2528
2998
  item.key
2529
2999
  ))
@@ -2626,13 +3096,15 @@ var MarginModeSettings = (props) => {
2626
3096
  var SymbolRow = (props) => {
2627
3097
  const { t } = i18n.useTranslation();
2628
3098
  const handleCheckedChange = React3.useCallback(() => {
3099
+ if (props.disabled) return;
2629
3100
  props.onToggle(props.item.key);
2630
3101
  }, [props]);
2631
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { itemAlign: "center", className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
3102
+ const row = /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { itemAlign: "center", className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
2632
3103
  "label",
2633
3104
  {
2634
3105
  className: ui.cn(
2635
- "oui-flex oui-items-center oui-gap-2 oui-flex-1 oui-cursor-pointer oui-select-none oui-w-full"
3106
+ "oui-flex oui-items-center oui-gap-2 oui-flex-1 oui-cursor-pointer oui-select-none oui-w-full",
3107
+ props.disabled ? "oui-cursor-not-allowed oui-opacity-50" : ""
2636
3108
  ),
2637
3109
  "data-testid": `oui-testid-marginModeSettings-item-${props.item.key}`,
2638
3110
  children: [
@@ -2642,10 +3114,12 @@ var SymbolRow = (props) => {
2642
3114
  color: "white",
2643
3115
  checked: props.checked,
2644
3116
  onCheckedChange: handleCheckedChange,
2645
- "aria-label": props.item.symbol
3117
+ "aria-label": props.item.symbol,
3118
+ disabled: props.disabled
2646
3119
  }
2647
3120
  ),
2648
3121
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-sm oui-font-semibold oui-text-base-contrast-80", children: props.item.symbol }),
3122
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol: props.item.key }),
2649
3123
  /* @__PURE__ */ jsxRuntime.jsx(
2650
3124
  "span",
2651
3125
  {
@@ -2661,6 +3135,17 @@ var SymbolRow = (props) => {
2661
3135
  ]
2662
3136
  }
2663
3137
  ) });
3138
+ if (props.disabled) {
3139
+ return /* @__PURE__ */ jsxRuntime.jsx(
3140
+ ui.Tooltip,
3141
+ {
3142
+ content: t("marginMode.disabledSymbolTooltip"),
3143
+ className: "oui-max-w-[280px] oui-text-2xs oui-text-base-contrast-80",
3144
+ children: row
3145
+ }
3146
+ );
3147
+ }
3148
+ return row;
2664
3149
  };
2665
3150
  var SearchGlyph = (props) => {
2666
3151
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2832,7 +3317,6 @@ var LeverageBadge = (props) => {
2832
3317
  };
2833
3318
  function OrderEntryHeader(props) {
2834
3319
  const { canTrade, side, order_type, setOrderValue } = props;
2835
- const { t } = i18n.useTranslation();
2836
3320
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2837
3321
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
2838
3322
  LeverageBadge,
@@ -2844,71 +3328,31 @@ function OrderEntryHeader(props) {
2844
3328
  disabled: !props.canTrade
2845
3329
  }
2846
3330
  ) }),
2847
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
2848
- OrderTypeSelect,
3331
+ /* @__PURE__ */ jsxRuntime.jsx(
3332
+ OrderEntryTypeTabsInjectabled,
2849
3333
  {
2850
3334
  type: order_type,
2851
3335
  side,
2852
3336
  canTrade,
2853
3337
  onChange: (type) => {
2854
3338
  setOrderValue("order_type", type);
2855
- }
3339
+ },
3340
+ marketOrderDisabled: props.marketOrderDisabled,
3341
+ marketOrderDisabledTooltip: props.marketOrderDisabledTooltip
2856
3342
  }
2857
- ) }),
2858
- /* @__PURE__ */ jsxRuntime.jsxs(
2859
- "div",
3343
+ ),
3344
+ /* @__PURE__ */ jsxRuntime.jsx(
3345
+ OrderEntryBuySellSwitchInjectabled,
2860
3346
  {
2861
- className: ui.cn(
2862
- "oui-orderEntry-side",
2863
- "oui-grid oui-w-full oui-flex-1 oui-gap-x-2 lg:oui-flex lg:oui-gap-x-[6px]",
2864
- "oui-grid-cols-2"
2865
- ),
2866
- children: [
2867
- /* @__PURE__ */ jsxRuntime.jsx(
2868
- ui.Button,
2869
- {
2870
- onClick: () => {
2871
- props.setOrderValue("side", types.OrderSide.BUY);
2872
- },
2873
- size: "md",
2874
- fullWidth: true,
2875
- "data-type": types.OrderSide.BUY,
2876
- className: ui.cn(
2877
- "oui-orderEntry-side-buy-btn",
2878
- side === types.OrderSide.BUY && canTrade ? "oui-bg-success-darken hover:oui-bg-success-darken/80 active:oui-bg-success-darken/80" : "oui-bg-base-7 oui-text-base-contrast-36 hover:oui-bg-base-6 active:oui-bg-base-6"
2879
- ),
2880
- "data-testid": "oui-testid-orderEntry-side-buy-button",
2881
- children: t("common.buy")
2882
- }
2883
- ),
2884
- /* @__PURE__ */ jsxRuntime.jsx(
2885
- ui.Button,
2886
- {
2887
- onClick: () => {
2888
- props.setOrderValue("side", types.OrderSide.SELL);
2889
- },
2890
- "data-type": types.OrderSide.SELL,
2891
- fullWidth: true,
2892
- size: "md",
2893
- className: ui.cn(
2894
- "oui-orderEntry-side-sell-btn",
2895
- side === types.OrderSide.SELL && props.canTrade ? "oui-bg-danger-darken hover:oui-bg-danger-darken/80 active:oui-bg-danger-darken/80" : "oui-bg-base-7 oui-text-base-contrast-36 hover:oui-bg-base-6 active:oui-bg-base-6"
2896
- ),
2897
- "data-testid": "oui-testid-orderEntry-side-sell-button",
2898
- children: t("common.sell")
2899
- }
2900
- )
2901
- ]
3347
+ side,
3348
+ canTrade,
3349
+ onSideChange: (nextSide) => {
3350
+ props.setOrderValue("side", nextSide);
3351
+ }
2902
3352
  }
2903
3353
  )
2904
3354
  ] });
2905
3355
  }
2906
- var OrderEntryContext = React3.createContext(
2907
- {}
2908
- );
2909
- var useOrderEntryContext = () => {
2910
- return React3.useContext(OrderEntryContext);
2911
- };
2912
3356
  var OrderEntryProvider = (props) => {
2913
3357
  const {
2914
3358
  errorMsgVisible,
@@ -2917,6 +3361,7 @@ var OrderEntryProvider = (props) => {
2917
3361
  onBlur,
2918
3362
  getErrorMsg,
2919
3363
  setOrderValue,
3364
+ manualSetOrderValue,
2920
3365
  setOrderValues,
2921
3366
  currentFocusInput,
2922
3367
  errors,
@@ -2935,6 +3380,7 @@ var OrderEntryProvider = (props) => {
2935
3380
  onBlur,
2936
3381
  getErrorMsg,
2937
3382
  setOrderValue,
3383
+ manualSetOrderValue,
2938
3384
  setOrderValues,
2939
3385
  currentFocusInput,
2940
3386
  errors,
@@ -2953,6 +3399,7 @@ var OrderEntryProvider = (props) => {
2953
3399
  onBlur,
2954
3400
  getErrorMsg,
2955
3401
  setOrderValue,
3402
+ manualSetOrderValue,
2956
3403
  setOrderValues,
2957
3404
  currentFocusInput,
2958
3405
  errors,
@@ -4376,116 +4823,6 @@ function OrderInput(props) {
4376
4823
  )
4377
4824
  ] });
4378
4825
  }
4379
- var SLIDER_MIN = 0;
4380
- var SLIDER_MAX = 100;
4381
- var QuantitySlider = React3.memo((props) => {
4382
- const { canTrade, side, order_quantity, maxQty } = props;
4383
- const [sliderValue, setSliderValue] = React3.useState(0);
4384
- const { setOrderValue, symbolInfo, lastQuantityInputType } = useOrderEntryContext();
4385
- const { base_dp, base_tick } = symbolInfo;
4386
- const { t } = i18n.useTranslation();
4387
- const color = React3.useMemo(
4388
- () => canTrade ? side === types.OrderSide.BUY ? "buy" : "sell" : void 0,
4389
- [side, canTrade]
4390
- );
4391
- const maxLabel = React3.useMemo(() => {
4392
- return side === types.OrderSide.BUY ? t("orderEntry.maxBuy") : t("orderEntry.maxSell");
4393
- }, [side, t]);
4394
- const onSliderValueChange = (value) => {
4395
- lastQuantityInputType.current = 4 /* QUANTITY_SLIDER */;
4396
- setSliderValue(value);
4397
- };
4398
- const sliderToQuantity = (value) => {
4399
- const newQty = new utils.Decimal(value).div(SLIDER_MAX).mul(maxQty).toFixed(base_dp, utils.Decimal.ROUND_DOWN);
4400
- setOrderValue("order_quantity", hooks.utils.formatNumber(newQty, base_tick));
4401
- };
4402
- const onMax = () => {
4403
- onSliderValueChange(SLIDER_MAX);
4404
- if (sliderValue === SLIDER_MAX) {
4405
- sliderToQuantity(SLIDER_MAX);
4406
- }
4407
- };
4408
- React3.useEffect(() => {
4409
- if (lastQuantityInputType.current === 4 /* QUANTITY_SLIDER */) {
4410
- sliderToQuantity(sliderValue);
4411
- }
4412
- }, [sliderValue, maxQty]);
4413
- React3.useEffect(() => {
4414
- const quantityToSlider = () => {
4415
- if (order_quantity && Number(order_quantity) !== 0 && maxQty !== 0) {
4416
- return new utils.Decimal(Math.min(Number(order_quantity), maxQty)).div(maxQty).mul(SLIDER_MAX).todp(2, utils.Decimal.ROUND_DOWN).toNumber();
4417
- }
4418
- return 0;
4419
- };
4420
- if (lastQuantityInputType.current !== 4 /* QUANTITY_SLIDER */) {
4421
- setSliderValue(quantityToSlider());
4422
- }
4423
- }, [order_quantity, maxQty]);
4424
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-quantitySlider", children: [
4425
- /* @__PURE__ */ jsxRuntime.jsx(
4426
- ui.Slider,
4427
- {
4428
- disabled: maxQty === 0 || !canTrade,
4429
- value: [sliderValue],
4430
- color,
4431
- markCount: 4,
4432
- showTip: true,
4433
- onValueChange: (e) => {
4434
- onSliderValueChange(e[0]);
4435
- },
4436
- min: SLIDER_MIN,
4437
- max: SLIDER_MAX
4438
- }
4439
- ),
4440
- /* @__PURE__ */ jsxRuntime.jsxs(
4441
- ui.Flex,
4442
- {
4443
- justify: "between",
4444
- className: "oui-quantitySlider-footer oui-pt-1 xl:oui-pt-2",
4445
- children: [
4446
- /* @__PURE__ */ jsxRuntime.jsx(
4447
- ui.Text.numeral,
4448
- {
4449
- size: "2xs",
4450
- color,
4451
- dp: 2,
4452
- padding: false,
4453
- suffix: "%",
4454
- children: canTrade ? sliderValue : 0
4455
- }
4456
- ),
4457
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
4458
- /* @__PURE__ */ jsxRuntime.jsx(
4459
- "button",
4460
- {
4461
- className: ui.textVariants({
4462
- size: "2xs",
4463
- className: "oui-quantitySlider-maxQty-btn oui-mr-1"
4464
- }),
4465
- onClick: onMax,
4466
- "data-testid": "oui-testid-orderEntry-maxQty-value-button",
4467
- children: maxLabel
4468
- }
4469
- ),
4470
- /* @__PURE__ */ jsxRuntime.jsx(
4471
- ui.Text.numeral,
4472
- {
4473
- size: "2xs",
4474
- color,
4475
- dp: base_dp,
4476
- padding: false,
4477
- className: "oui-quantitySlider-maxQty-value",
4478
- "data-testid": "oui-testid-orderEntry-maxQty-value",
4479
- children: canTrade ? maxQty : 0
4480
- }
4481
- )
4482
- ] })
4483
- ]
4484
- }
4485
- )
4486
- ] });
4487
- });
4488
- QuantitySlider.displayName = "QuantitySlider";
4489
4826
  var ReduceOnlySwitch = ({
4490
4827
  checked,
4491
4828
  onCheckedChange,
@@ -4607,12 +4944,15 @@ var usePNLInputBuilder = (props) => {
4607
4944
  }
4608
4945
  if (value === "" || value === "-") return "";
4609
4946
  if (mode === "Offset%" /* PERCENTAGE */) {
4610
- return `${new utils.Decimal(
4611
- value.replace(
4612
- new RegExp(percentageSuffix.current.replace(".", "\\.") + "$"),
4613
- ""
4614
- )
4615
- ).mul(100).todp(2, 4).toString()}${percentageSuffix.current}`;
4947
+ let normalized = value.replace(
4948
+ new RegExp(percentageSuffix.current.replace(".", "\\.") + "$"),
4949
+ ""
4950
+ ).replace(/,/g, "");
4951
+ normalized = normalized.replace(/\.$/, "");
4952
+ if (isNaN(Number(normalized)) || normalized === "" || normalized === "-") {
4953
+ return value;
4954
+ }
4955
+ return `${new utils.Decimal(normalized).mul(100).todp(2, 4).toString()}${percentageSuffix.current}`;
4616
4956
  } else if (mode === "Offset" /* OFFSET */) {
4617
4957
  value = utils.todpIfNeed(value, dp);
4618
4958
  } else ;
@@ -4631,6 +4971,9 @@ var usePNLInputBuilder = (props) => {
4631
4971
  } else {
4632
4972
  percentageSuffix.current = "";
4633
4973
  }
4974
+ if (isNaN(Number(value))) {
4975
+ return value;
4976
+ }
4634
4977
  value = new utils.Decimal(value).div(100).toString();
4635
4978
  value = `${value}${percentageSuffix.current}`;
4636
4979
  }
@@ -4878,8 +5221,8 @@ var OrderTPSL = (props) => {
4878
5221
  {
4879
5222
  className: ui.cn(
4880
5223
  "oui-orderEntry-tpsl-body",
4881
- "oui-max-h-0 oui-overflow-hidden oui-transition-all",
4882
- props.switchState && "oui-max-h-[120px]"
5224
+ "oui-overflow-hidden oui-transition-all",
5225
+ props.switchState ? "oui-max-h-[120px]" : "oui-max-h-0"
4883
5226
  ),
4884
5227
  onTransitionEnd: () => {
4885
5228
  tpslFormRef.current?.style.setProperty(
@@ -5164,7 +5507,9 @@ var OrderEntry = (props) => {
5164
5507
  side,
5165
5508
  formattedOrder,
5166
5509
  setOrderValue,
5510
+ manualSetOrderValue,
5167
5511
  setOrderValues,
5512
+ setOrderValuesRaw,
5168
5513
  symbolInfo,
5169
5514
  maxQty,
5170
5515
  freeCollateral,
@@ -5180,9 +5525,13 @@ var OrderEntry = (props) => {
5180
5525
  fillMiddleValue,
5181
5526
  soundAlert,
5182
5527
  setSoundAlert,
5183
- currentFocusInput
5528
+ currentFocusInput,
5529
+ walletAddress,
5530
+ isPermissionlessListing,
5531
+ symbol
5184
5532
  } = props;
5185
5533
  const [maxQtyConfirmOpen, setMaxQtyConfirmOpen] = React3.useState(false);
5534
+ const [permissionlessAcknowledgedKeys, setPermissionlessAcknowledgedKeys] = hooks.useLocalStorage("orderly-permissionless-market-notice", []);
5186
5535
  const { t } = i18n.useTranslation();
5187
5536
  const { isMobile } = ui.useScreen();
5188
5537
  const [hasAdvancedTPSLResult, setHasAdvancedTPSLResult] = React3.useState(false);
@@ -5219,11 +5568,11 @@ var OrderEntry = (props) => {
5219
5568
  return;
5220
5569
  }
5221
5570
  if (slippage) {
5222
- setOrderValue("slippage", Number(slippage));
5571
+ manualSetOrderValue("slippage", Number(slippage));
5223
5572
  } else {
5224
- setOrderValue("slippage", void 0);
5573
+ manualSetOrderValue("slippage", void 0);
5225
5574
  }
5226
- }, [slippage, disableFeatures]);
5575
+ }, [slippage, disableFeatures, manualSetOrderValue]);
5227
5576
  React3.useEffect(() => {
5228
5577
  const clickHandler = (event) => {
5229
5578
  const target = event.target;
@@ -5252,22 +5601,7 @@ var OrderEntry = (props) => {
5252
5601
  helper.validate(isSlPriceError ? props.slPriceError : void 0).then(
5253
5602
  // validate success, it return the order
5254
5603
  // TODO: get order from other function
5255
- (order) => {
5256
- if (isScaledOrder) {
5257
- return ui.modal.show(scaledOrderConfirmDialogId, {
5258
- order,
5259
- symbolInfo,
5260
- size: isMobile ? "sm" : "md"
5261
- });
5262
- }
5263
- if (needConfirm) {
5264
- return ui.modal.show(orderConfirmDialogId, {
5265
- order: formattedOrder,
5266
- symbolInfo
5267
- });
5268
- }
5269
- return true;
5270
- },
5604
+ (order) => order,
5271
5605
  // should catch validate error first, then submit
5272
5606
  (errors2) => {
5273
5607
  if (errors2.slippage) {
@@ -5276,7 +5610,38 @@ var OrderEntry = (props) => {
5276
5610
  setErrorMsgVisible(true);
5277
5611
  return Promise.reject();
5278
5612
  }
5279
- ).then(() => {
5613
+ ).then((order) => {
5614
+ const shouldShowPermissionlessNotice = isPermissionlessListing && walletAddress && !(permissionlessAcknowledgedKeys ?? []).includes(
5615
+ `${walletAddress}_${symbol}`
5616
+ );
5617
+ if (shouldShowPermissionlessNotice) {
5618
+ return ui.modal.show(
5619
+ isMobile ? permissionlessMarketNoticeDialogId : permissionlessMarketNoticeDesktopDialogId
5620
+ ).then(() => {
5621
+ setPermissionlessAcknowledgedKeys([
5622
+ ...Array.isArray(permissionlessAcknowledgedKeys) ? permissionlessAcknowledgedKeys : [],
5623
+ `${walletAddress}_${symbol}`
5624
+ ]);
5625
+ return order;
5626
+ });
5627
+ }
5628
+ return Promise.resolve(order);
5629
+ }).then((order) => {
5630
+ if (isScaledOrder) {
5631
+ return ui.modal.show(scaledOrderConfirmDialogId, {
5632
+ order,
5633
+ symbolInfo,
5634
+ size: isMobile ? "sm" : "md"
5635
+ });
5636
+ }
5637
+ if (needConfirm) {
5638
+ return ui.modal.show(orderConfirmDialogId, {
5639
+ order: formattedOrder,
5640
+ symbolInfo
5641
+ });
5642
+ }
5643
+ return true;
5644
+ }).then(() => {
5280
5645
  return submit({ resetOnSuccess: false }).then((result) => {
5281
5646
  if (!result.success && result.message) {
5282
5647
  ui.toast.error(result.message);
@@ -5297,12 +5662,12 @@ var OrderEntry = (props) => {
5297
5662
  return new utils.Decimal(maxQty).todp(symbolInfo.base_dp, utils.Decimal.ROUND_DOWN).toString();
5298
5663
  }, [maxQty, symbolInfo.base_dp]);
5299
5664
  const onMaxQtyConfirm = React3.useCallback(() => {
5300
- setOrderValue("order_quantity", formattedMaxQty);
5665
+ manualSetOrderValue("order_quantity", formattedMaxQty);
5301
5666
  requestAnimationFrame(() => {
5302
5667
  onSubmit();
5303
5668
  });
5304
5669
  setMaxQtyConfirmOpen(false);
5305
- }, [setOrderValue, formattedMaxQty]);
5670
+ }, [manualSetOrderValue, formattedMaxQty, onSubmit]);
5306
5671
  const validateSubmit = async () => {
5307
5672
  if (formattedOrder.reduce_only && maxQty === 0) {
5308
5673
  return ui.modal.confirm({
@@ -5310,7 +5675,7 @@ var OrderEntry = (props) => {
5310
5675
  content: t("orderEntry.reduceOnly.reminder.content"),
5311
5676
  okLabel: t("orderEntry.placeOrderNow"),
5312
5677
  onOk: async () => {
5313
- setOrderValue("reduce_only", false);
5678
+ manualSetOrderValue("reduce_only", false);
5314
5679
  requestAnimationFrame(() => {
5315
5680
  props.resetMetaState();
5316
5681
  onSubmit();
@@ -5342,9 +5707,9 @@ var OrderEntry = (props) => {
5342
5707
  };
5343
5708
  const onSubmitAdvancedTPSL = (order) => {
5344
5709
  if (order.side !== formattedOrder.side) {
5345
- setOrderValue("side", order.side);
5710
+ manualSetOrderValue("side", order.side);
5346
5711
  }
5347
- setOrderValues({
5712
+ setOrderValuesRaw({
5348
5713
  position_type: order.position_type,
5349
5714
  tp_order_type: order.tp_order_type,
5350
5715
  tp_pnl: order.tp_pnl,
@@ -5390,7 +5755,7 @@ var OrderEntry = (props) => {
5390
5755
  setNeedConfirm,
5391
5756
  hidden,
5392
5757
  setHidden,
5393
- onValueChange: setOrderValue,
5758
+ onValueChange: manualSetOrderValue,
5394
5759
  orderTypeExtra: formattedOrder["order_type_ext"],
5395
5760
  showExtra: formattedOrder["order_type"] === types.OrderType.LIMIT && !props.tpslSwitch
5396
5761
  };
@@ -5405,6 +5770,7 @@ var OrderEntry = (props) => {
5405
5770
  onBlur: props.onBlur,
5406
5771
  getErrorMsg,
5407
5772
  setOrderValue,
5773
+ manualSetOrderValue,
5408
5774
  setOrderValues,
5409
5775
  currentFocusInput: currentFocusInput.current,
5410
5776
  priceInputRef: props.priceInputRef,
@@ -5440,13 +5806,17 @@ var OrderEntry = (props) => {
5440
5806
  canTrade: props.canTrade,
5441
5807
  side,
5442
5808
  order_type: formattedOrder.order_type,
5443
- setOrderValue,
5809
+ setOrderValue: manualSetOrderValue,
5444
5810
  symbolLeverage: props.symbolLeverage,
5445
- marginMode: props.marginMode
5811
+ marginMode: props.marginMode,
5812
+ marketOrderDisabled: props.isSymbolPostOnly,
5813
+ marketOrderDisabledTooltip: t(
5814
+ "orderEntry.orderType.symbolPostOnly.tooltip"
5815
+ )
5446
5816
  }
5447
5817
  ),
5448
5818
  /* @__PURE__ */ jsxRuntime.jsx(
5449
- Available,
5819
+ OrderEntryAvailableInjectabled,
5450
5820
  {
5451
5821
  currentLtv,
5452
5822
  canTrade: props.canTrade,
@@ -5470,7 +5840,7 @@ var OrderEntry = (props) => {
5470
5840
  }
5471
5841
  ),
5472
5842
  /* @__PURE__ */ jsxRuntime.jsx(
5473
- QuantitySlider,
5843
+ OrderEntryQuantitySliderInjectabled,
5474
5844
  {
5475
5845
  canTrade: props.canTrade,
5476
5846
  side: props.side,
@@ -5479,38 +5849,29 @@ var OrderEntry = (props) => {
5479
5849
  }
5480
5850
  ),
5481
5851
  /* @__PURE__ */ jsxRuntime.jsx(
5482
- ui.ThrottledButton,
5483
- {
5484
- fullWidth: true,
5485
- id: "order-entry-submit-button",
5486
- "data-type": types.OrderSide.BUY,
5487
- className: ui.cn(
5488
- "oui-orderEntry-submit-btn",
5489
- side === types.OrderSide.BUY ? "orderly-order-entry-submit-button-buy oui-bg-success-darken hover:oui-bg-success-darken/80 active:oui-bg-success-darken/80" : "orderly-order-entry-submit-button-sell oui-bg-danger-darken hover:oui-bg-danger-darken/80 active:oui-bg-danger-darken/80"
5490
- ),
5491
- onClick: validateSubmit,
5492
- loading: props.isMutating,
5493
- disabled: !props.canTrade,
5494
- children: buttonLabel
5495
- }
5496
- ),
5497
- /* @__PURE__ */ jsxRuntime.jsx(
5498
- AssetInfo,
5852
+ OrderEntrySubmitSectionInjectabled,
5499
5853
  {
5854
+ buttonLabel,
5855
+ side,
5500
5856
  canTrade: props.canTrade,
5501
- quote: symbolInfo.quote,
5502
- estLiqPrice: props.estLiqPrice,
5503
- estLiqPriceDistance: props.estLiqPriceDistance,
5504
- estLeverage: props.estLeverage,
5505
- currentLeverage: props.currentLeverage,
5506
- slippage,
5507
- dp: symbolInfo.quote_dp,
5508
- setSlippage,
5509
- estSlippage: props.estSlippage,
5510
- orderType: formattedOrder.order_type,
5511
- disableFeatures,
5512
- symbol: props.symbol,
5513
- side
5857
+ isMutating: props.isMutating,
5858
+ onSubmit: validateSubmit,
5859
+ assetInfo: {
5860
+ canTrade: props.canTrade,
5861
+ quote: symbolInfo.quote,
5862
+ estLiqPrice: props.estLiqPrice,
5863
+ estLiqPriceDistance: props.estLiqPriceDistance,
5864
+ estLeverage: props.estLeverage,
5865
+ currentLeverage: props.currentLeverage,
5866
+ slippage,
5867
+ dp: symbolInfo.quote_dp,
5868
+ setSlippage,
5869
+ estSlippage: props.estSlippage,
5870
+ orderType: formattedOrder.order_type,
5871
+ disableFeatures,
5872
+ symbol: props.symbol,
5873
+ side
5874
+ }
5514
5875
  }
5515
5876
  ),
5516
5877
  /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
@@ -5535,10 +5896,10 @@ var OrderEntry = (props) => {
5535
5896
  onSwitchChanged: props.setTpslSwitch,
5536
5897
  orderType: formattedOrder.order_type,
5537
5898
  errors: validated || props.slPriceError !== void 0 ? { ...errors, ...props.slPriceError } : null,
5538
- setOrderValue,
5899
+ setOrderValue: manualSetOrderValue,
5539
5900
  reduceOnlyChecked: formattedOrder.reduce_only ?? false,
5540
5901
  onReduceOnlyChange: (checked) => {
5541
- setOrderValue("reduce_only", checked);
5902
+ manualSetOrderValue("reduce_only", checked);
5542
5903
  },
5543
5904
  values: {
5544
5905
  position_type: formattedOrder.position_type ?? types.PositionType.PARTIAL,
@@ -5575,7 +5936,7 @@ var OrderEntry = (props) => {
5575
5936
  {
5576
5937
  checked: formattedOrder.reduce_only ?? false,
5577
5938
  onCheckedChange: (checked) => {
5578
- setOrderValue("reduce_only", checked);
5939
+ manualSetOrderValue("reduce_only", checked);
5579
5940
  }
5580
5941
  }
5581
5942
  ),
@@ -5664,7 +6025,7 @@ var OrderEntry = (props) => {
5664
6025
  children: showTPSLAdvanced && /* @__PURE__ */ jsxRuntime.jsx(
5665
6026
  uiTpsl.TPSLAdvancedWidget,
5666
6027
  {
5667
- setOrderValue,
6028
+ setOrderValue: manualSetOrderValue,
5668
6029
  order: formattedOrder,
5669
6030
  onSubmit: onSubmitAdvancedTPSL,
5670
6031
  onClose: () => {
@@ -5840,11 +6201,14 @@ var useOrderEntryScript = (inputs) => {
5840
6201
  defaultSoundValue ?? null
5841
6202
  );
5842
6203
  const canTrade = reactApp.useCanTrade();
5843
- const { marginMode } = hooks.useMarginModeBySymbol(symbol);
6204
+ const { state: accountState } = hooks.useAccount();
6205
+ const { marginMode, isPermissionlessListing } = hooks.useMarginModeBySymbol(symbol);
6206
+ const walletAddress = accountState?.address;
5844
6207
  const {
5845
6208
  formattedOrder,
5846
6209
  setValue,
5847
6210
  setValues: setOrderValues,
6211
+ setValuesRaw: setOrderValuesRaw,
5848
6212
  symbolInfo,
5849
6213
  symbolLeverage,
5850
6214
  ...state
@@ -5943,6 +6307,12 @@ var useOrderEntryScript = (inputs) => {
5943
6307
  );
5944
6308
  }
5945
6309
  );
6310
+ const manualSetOrderValue = hooks.useMemoizedFn(
6311
+ (key, value, options2) => {
6312
+ lastUserActiveTimeRef.current = Date.now();
6313
+ setOrderValue(key, value, options2);
6314
+ }
6315
+ );
5946
6316
  const onTPSLSwitchChanged = (state2) => {
5947
6317
  setTpslSwitch(state2);
5948
6318
  if (state2) {
@@ -6034,6 +6404,16 @@ var useOrderEntryScript = (inputs) => {
6034
6404
  setValue("distribution_type", types.DistributionType.FLAT);
6035
6405
  }
6036
6406
  }, [formattedOrder.order_type, formattedOrder.distribution_type]);
6407
+ const isSymbolPostOnly = symbolInfo?.status === "POST_ONLY";
6408
+ React3.useEffect(() => {
6409
+ if (isSymbolPostOnly && (formattedOrder.order_type === types.OrderType.MARKET || formattedOrder.order_type === types.OrderType.STOP_MARKET)) {
6410
+ setLocalOrderType(types.OrderType.LIMIT);
6411
+ setOrderValues({
6412
+ order_type: types.OrderType.LIMIT,
6413
+ order_type_ext: void 0
6414
+ });
6415
+ }
6416
+ }, [isSymbolPostOnly, formattedOrder.order_type, setOrderValues]);
6037
6417
  const currentLtv = hooks.useComputedLTV();
6038
6418
  const askAndBid = useAskAndBid();
6039
6419
  const fillMiddleValue = () => {
@@ -6069,22 +6449,21 @@ var useOrderEntryScript = (inputs) => {
6069
6449
  }
6070
6450
  }, [tpslSwitch]);
6071
6451
  React3.useEffect(() => {
6072
- lastUserActiveTimeRef.current = Date.now();
6073
- }, [
6074
- formattedOrder.order_price,
6075
- formattedOrder.order_quantity,
6076
- formattedOrder.side
6077
- ]);
6078
- React3.useEffect(() => {
6452
+ let estLiqPrice = state.estLiqPrice;
6453
+ if (estLiqPrice == null || formattedOrder.side == null || state.markPrice == null) {
6454
+ estLiqPrice = null;
6455
+ } else if (formattedOrder.side === types.OrderSide.BUY && estLiqPrice > state.markPrice || formattedOrder.side === types.OrderSide.SELL && estLiqPrice < state.markPrice) {
6456
+ estLiqPrice = null;
6457
+ }
6079
6458
  const lastActive = lastUserActiveTimeRef.current;
6080
6459
  const now = Date.now();
6081
6460
  const isUserActive = now - lastActive <= ORDER_ENTRY_EST_LIQ_ACTIVE_WINDOW_MS;
6082
6461
  ee.emit(types.ORDER_ENTRY_EST_LIQ_PRICE_CHANGE, {
6083
6462
  symbol,
6084
- estLiqPrice: state.estLiqPrice ?? null,
6463
+ estLiqPrice,
6085
6464
  isUserActive
6086
6465
  });
6087
- }, [ee, symbol, state.estLiqPrice]);
6466
+ }, [ee, symbol, state.estLiqPrice, state.markPrice, formattedOrder.side]);
6088
6467
  React3.useEffect(() => {
6089
6468
  setOrderValue("margin_mode", marginMode);
6090
6469
  }, [marginMode]);
@@ -6096,7 +6475,9 @@ var useOrderEntryScript = (inputs) => {
6096
6475
  level: formattedOrder.level,
6097
6476
  formattedOrder,
6098
6477
  setOrderValue,
6478
+ manualSetOrderValue,
6099
6479
  setOrderValues,
6480
+ setOrderValuesRaw,
6100
6481
  // account-level leverage (for other consumers)
6101
6482
  currentLeverage,
6102
6483
  // symbol-level leverage & margin mode for this order entry
@@ -6125,7 +6506,10 @@ var useOrderEntryScript = (inputs) => {
6125
6506
  symbol,
6126
6507
  soundAlert,
6127
6508
  setSoundAlert,
6128
- currentFocusInput
6509
+ currentFocusInput,
6510
+ walletAddress,
6511
+ isPermissionlessListing,
6512
+ isSymbolPostOnly
6129
6513
  };
6130
6514
  };
6131
6515
  var InjectableOrderEntry = ui.injectable(
@@ -6150,6 +6534,7 @@ exports.LTVRiskTooltipWidget = LTVRiskTooltipWidget;
6150
6534
  exports.OrderConfirmDialog = OrderConfirmDialog;
6151
6535
  exports.OrderEntry = OrderEntry;
6152
6536
  exports.OrderEntryWidget = OrderEntryWidget;
6537
+ exports.SymbolBadge = SymbolBadge;
6153
6538
  exports.useOrderEntryScript = useOrderEntryScript;
6154
6539
  //# sourceMappingURL=index.js.map
6155
6540
  //# sourceMappingURL=index.js.map