@orderly.network/ui-order-entry 2.12.4-alpha.0 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -547,1035 +547,636 @@ 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
- };
998
- };
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
- };
1043
- };
1044
- var LTVRiskTooltipWidget = ({
1045
- marginMode
1046
- }) => {
1047
- const state = useLTVTooltipScript(marginMode);
1048
- return /* @__PURE__ */ jsxRuntime.jsx(LTVRiskTooltipUI, { ...state });
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
+ ] });
1049
989
  };
1050
- var Available = (props) => {
1051
- const { canTrade, currentLtv, quote, freeCollateral, marginMode } = props;
990
+ OrderConfirmDialog.displayName = "OrderConfirmDialog";
991
+ var OrderTypeTag = (props) => {
1052
992
  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(
1058
- ui.Flex,
1059
- {
1060
- itemAlign: "center",
1061
- justify: "between",
1062
- className: "oui-orderEntry-available",
1063
- 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",
1095
- 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
- ] })
1108
- ]
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 "";
1109
1007
  }
1110
- );
1008
+ }, [props.type]);
1009
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "sm", children: typeStr });
1111
1010
  };
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");
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
+ }
1148
1025
  }
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);
1157
- };
1158
- var SymbolBadge = (props) => {
1159
- const { brokerId, brokerName, brokerNameRaw } = hooks.useBadgeBySymbol(
1160
- props.symbol
1161
1026
  );
1162
- const badge = brokerName ?? brokerId ?? void 0;
1163
- return /* @__PURE__ */ jsxRuntime.jsx(ui.SymbolBadge, { badge, fullName: brokerNameRaw });
1164
1027
  };
1165
- var OrderConfirmDialog = (props) => {
1166
- const { symbolInfo, order, onConfirm, onCancel } = props;
1167
- const { quote, quote_dp, base_dp } = symbolInfo;
1168
- const { side, order_type, order_type_ext, level, symbol } = order;
1169
- const orderMarginMode = order.margin_mode;
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) => {
1170
1034
  const { t } = i18n.useTranslation();
1171
- const [{ rows: positions }] = hooks.usePositionStream(symbol);
1172
- const position = React3.useMemo(
1173
- () => orderMarginMode != null ? positions?.find(
1174
- (row) => row.symbol === symbol && row.margin_mode === orderMarginMode
1175
- ) : positions?.[0],
1176
- [positions, symbol, orderMarginMode]
1177
- );
1178
- const positionQty = position?.position_qty;
1179
- const [_, setNeedConfirm] = hooks.useLocalStorage("orderly_order_confirm", true);
1180
- const renderPositionType = () => {
1181
- if (order.position_type === types.PositionType.FULL) {
1182
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.full") });
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
+ }) })
1183
1068
  }
1184
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.positionType.partial") });
1185
- };
1186
- const renderPrice = () => {
1187
- if (order_type === types.OrderType.MARKET || order_type === types.OrderType.STOP_MARKET) {
1188
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: t("common.marketPrice") });
1189
- }
1190
- if (isBBOOrder({ order_type, order_type_ext })) {
1191
- const bboType = utils.getBBOType({
1192
- type: order_type_ext,
1193
- side,
1194
- level
1195
- });
1196
- const label = {
1197
- [types.BBOOrderType.COUNTERPARTY1]: t("orderEntry.bbo.counterparty1"),
1198
- [types.BBOOrderType.COUNTERPARTY5]: t("orderEntry.bbo.counterparty5"),
1199
- [types.BBOOrderType.QUEUE1]: t("orderEntry.bbo.queue1"),
1200
- [types.BBOOrderType.QUEUE5]: t("orderEntry.bbo.queue5")
1201
- }[bboType];
1202
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { intensity: 80, children: label });
1203
- }
1204
- return /* @__PURE__ */ jsxRuntime.jsx(
1205
- ui.Text.numeral,
1206
- {
1207
- unit: quote,
1208
- rule: "price",
1209
- className: "oui-text-base-contrast",
1210
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1211
- dp: quote_dp,
1212
- padding: false,
1213
- children: order.order_price
1214
- }
1215
- );
1216
- };
1217
- const renderTPSLPrice = ({
1218
- price,
1219
- isOrderPrice,
1220
- isEnable,
1221
- colorType
1222
- }) => {
1223
- if (!isEnable) {
1224
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: "-- USDC" });
1225
- }
1226
- if (!price) {
1227
- if (isOrderPrice) {
1228
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast-36", children: t("common.marketPrice") });
1229
- }
1230
- }
1231
- return /* @__PURE__ */ jsxRuntime.jsx(
1232
- ui.Text.numeral,
1233
- {
1234
- unit: "USDC",
1235
- rule: "price",
1236
- className: ui.cn(
1237
- "oui-text-base-contrast",
1238
- colorType === "TP" ? "oui-text-trade-profit" : "oui-text-trade-loss"
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(
1076
+ ui.Flex,
1077
+ {
1078
+ direction: "column",
1079
+ gap: 3,
1080
+ itemAlign: "start",
1081
+ className: "oui-permissionlessNotice-content",
1082
+ children: [
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
+ }
1239
1092
  ),
1240
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1241
- dp: quote_dp,
1242
- padding: false,
1243
- children: price
1244
- }
1245
- );
1246
- };
1247
- const renderTPSLQty = () => {
1248
- if (!positionQty || !order.order_quantity) {
1249
- return null;
1250
- }
1251
- let qty = new utils.Decimal(order.order_quantity);
1252
- if (order.position_type === types.PositionType.FULL) {
1253
- qty = qty.plus(new utils.Decimal(positionQty ?? 0));
1254
- }
1255
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1256
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: order.position_type === types.PositionType.FULL ? t("common.positionQty") : t("common.orderQty") }),
1257
- /* @__PURE__ */ jsxRuntime.jsx(
1258
- ui.Text.numeral,
1259
- {
1260
- rule: "price",
1261
- dp: base_dp,
1262
- padding: false,
1263
- className: "oui-text-base-contrast",
1264
- children: qty.toNumber()
1265
- }
1266
- )
1267
- ] });
1268
- };
1269
- const renderPriceAndTotal = () => {
1270
- if (order_type === types.OrderType.TRAILING_STOP) {
1271
- const { activated_price, callback_value, callback_rate } = order;
1272
- const callbackView = callback_rate ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1273
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("orderEntry.trailingRate") }),
1274
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "oui-text-base-contrast", children: [
1275
- callback_rate,
1276
- "%"
1277
- ] })
1278
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
1279
- OrderItem,
1280
- {
1281
- title: t("orderEntry.trailingValue"),
1282
- value: callback_value,
1283
- unit: quote,
1284
- dp: quote_dp
1285
- }
1286
- );
1287
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1288
- activated_price && /* @__PURE__ */ jsxRuntime.jsx(
1289
- OrderItem,
1093
+ /* @__PURE__ */ jsxRuntime.jsx(
1094
+ ui.Text,
1290
1095
  {
1291
- title: t("common.triggerPrice"),
1292
- value: activated_price,
1293
- unit: quote,
1294
- dp: quote_dp
1096
+ className: ui.textVariants({
1097
+ size: "sm",
1098
+ intensity: 54
1099
+ }),
1100
+ children: t("orderEntry.permissionlessNotice.content2")
1295
1101
  }
1296
1102
  ),
1297
- callbackView
1298
- ] });
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
+ ]
1299
1114
  }
1300
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1301
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1302
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.price") }),
1303
- renderPrice()
1304
- ] }),
1305
- /* @__PURE__ */ jsxRuntime.jsx(
1306
- OrderItem,
1307
- {
1308
- title: t("common.estTotal"),
1309
- value: order.total,
1310
- unit: quote,
1311
- dp: quote_dp
1312
- }
1313
- )
1314
- ] });
1315
- };
1316
- const header = /* @__PURE__ */ jsxRuntime.jsxs(
1115
+ );
1116
+ const checkboxSection = /* @__PURE__ */ jsxRuntime.jsxs(
1317
1117
  ui.Flex,
1318
1118
  {
1319
- justify: "between",
1320
- className: "oui-orderEntry-orderConfirmDialog-header",
1119
+ gapX: 1,
1120
+ pt: 4,
1121
+ pb: 5,
1122
+ itemAlign: "start",
1123
+ className: "oui-permissionlessNotice-checkbox oui-orderEntry-orderConfirmDialog-disableConfirm oui-cursor-pointer",
1321
1124
  children: [
1322
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, direction: "column", itemAlign: "start", children: [
1323
- /* @__PURE__ */ jsxRuntime.jsx(
1324
- ui.Text.formatted,
1325
- {
1326
- rule: "symbol",
1327
- formatString: "base",
1328
- showIcon: true,
1329
- className: "oui-orderConfirmDialog-symbol",
1330
- children: order.symbol
1331
- }
1332
- ),
1333
- /* @__PURE__ */ jsxRuntime.jsx(SymbolBadge, { symbol: order.symbol })
1334
- ] }),
1335
- /* @__PURE__ */ jsxRuntime.jsxs(
1336
- ui.Flex,
1125
+ /* @__PURE__ */ jsxRuntime.jsx(
1126
+ ui.Checkbox,
1337
1127
  {
1338
- justify: "end",
1339
- gapX: 1,
1340
- className: "oui-orderConfirmDialog-header-tags",
1341
- children: [
1342
- /* @__PURE__ */ jsxRuntime.jsx(OrderTypeTag, { type: order_type }),
1343
- 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") })
1344
- ]
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({
1140
+ size: "xs",
1141
+ intensity: 54,
1142
+ className: "oui-cursor-pointer"
1143
+ }),
1144
+ children: t("orderEntry.permissionlessNotice.checkbox")
1345
1145
  }
1346
1146
  )
1347
1147
  ]
1348
1148
  }
1349
1149
  );
1350
- const quantityItem = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1351
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("common.orderQty") }),
1352
- /* @__PURE__ */ jsxRuntime.jsx(
1353
- ui.Text.numeral,
1354
- {
1355
- rule: "price",
1356
- dp: base_dp,
1357
- padding: false,
1358
- className: "oui-text-base-contrast",
1359
- children: order.order_quantity
1360
- }
1361
- )
1362
- ] });
1363
- const triggerPriceItem = (order_type === types.OrderType.STOP_LIMIT || order_type === types.OrderType.STOP_MARKET && order.trigger_price) && /* @__PURE__ */ jsxRuntime.jsx(
1364
- OrderItem,
1150
+ const confirmButton = /* @__PURE__ */ jsxRuntime.jsx(
1151
+ ui.Flex,
1365
1152
  {
1366
- title: t("common.trigger"),
1367
- value: order.trigger_price,
1368
- unit: quote,
1369
- dp: quote_dp
1370
- }
1371
- );
1372
- const tpslTriggerPrice = (order.tp_trigger_price || order.sl_trigger_price) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1373
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
1374
- /* @__PURE__ */ jsxRuntime.jsxs(
1375
- "div",
1376
- {
1377
- className: ui.textVariants({
1378
- size: "sm",
1379
- intensity: 54,
1380
- className: "oui-space-y-1 oui-w-full oui-flex oui-flex-col oui-gap-3"
1381
- }),
1382
- children: [
1383
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "oui-text-base-contrast", children: renderPositionType() }),
1384
- renderTPSLQty(),
1385
- /* @__PURE__ */ jsxRuntime.jsxs(
1386
- ui.Flex,
1387
- {
1388
- direction: "column",
1389
- justify: "between",
1390
- itemAlign: "start",
1391
- gap: 1,
1392
- className: "oui-w-full",
1393
- children: [
1394
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1395
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpTriggerPrice") }),
1396
- renderTPSLPrice({
1397
- price: order.tp_trigger_price ?? "",
1398
- isOrderPrice: false,
1399
- isEnable: !!order.tp_trigger_price,
1400
- colorType: "TP"
1401
- })
1402
- ] }),
1403
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1404
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.tpOrderPrice") }),
1405
- renderTPSLPrice({
1406
- price: order.tp_order_price ?? "",
1407
- isOrderPrice: true,
1408
- isEnable: !!order.tp_trigger_price,
1409
- colorType: "TP"
1410
- })
1411
- ] })
1412
- ]
1413
- }
1414
- ),
1415
- /* @__PURE__ */ jsxRuntime.jsxs(
1416
- ui.Flex,
1417
- {
1418
- direction: "column",
1419
- justify: "between",
1420
- itemAlign: "start",
1421
- gap: 1,
1422
- className: "oui-w-full",
1423
- children: [
1424
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1425
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slTriggerPrice") }),
1426
- renderTPSLPrice({
1427
- price: order.sl_trigger_price ?? "",
1428
- isOrderPrice: false,
1429
- isEnable: !!order.sl_trigger_price,
1430
- colorType: "SL"
1431
- })
1432
- ] }),
1433
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", className: "oui-w-full", children: [
1434
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: t("tpsl.slOrderPrice") }),
1435
- renderTPSLPrice({
1436
- price: order.sl_order_price ?? "",
1437
- isOrderPrice: true,
1438
- isEnable: !!order.sl_trigger_price,
1439
- colorType: "SL"
1440
- })
1441
- ] })
1442
- ]
1443
- }
1444
- )
1445
- ]
1446
- }
1447
- )
1448
- ] });
1449
- const orderConfirmCheckbox = /* @__PURE__ */ jsxRuntime.jsxs(
1450
- ui.Flex,
1451
- {
1452
- gapX: 1,
1453
- pt: 4,
1454
- pb: 5,
1455
- className: "oui-orderEntry-orderConfirmDialog-disableConfirm",
1456
- children: [
1457
- /* @__PURE__ */ jsxRuntime.jsx(
1458
- ui.Checkbox,
1459
- {
1460
- id: "orderConfirm",
1461
- color: "white",
1462
- className: "oui-orderConfirmDialog-disableConfirm-checkbox",
1463
- onCheckedChange: (checked) => {
1464
- setNeedConfirm(!!!checked);
1465
- }
1466
- }
1467
- ),
1468
- /* @__PURE__ */ jsxRuntime.jsx(
1469
- "label",
1470
- {
1471
- htmlFor: "orderConfirm",
1472
- className: ui.textVariants({
1473
- size: "xs",
1474
- intensity: 54
1475
- }),
1476
- children: t("orderEntry.disableOrderConfirm")
1477
- }
1478
- )
1479
- ]
1480
- }
1481
- );
1482
- const buttons = /* @__PURE__ */ jsxRuntime.jsxs(
1483
- ui.Grid,
1484
- {
1485
- cols: 2,
1486
- gapX: 3,
1487
- className: "oui-orderEntry-orderConfirmDialog-actions",
1488
- children: [
1489
- /* @__PURE__ */ jsxRuntime.jsx(
1490
- ui.Button,
1491
- {
1492
- color: "secondary",
1493
- size: "md",
1494
- className: "oui-cancel-btn",
1495
- onClick: () => onCancel(),
1496
- children: t("common.cancel")
1497
- }
1498
- ),
1499
- /* @__PURE__ */ jsxRuntime.jsx(
1500
- ui.Button,
1501
- {
1502
- size: "md",
1503
- className: "oui-confirm-btn",
1504
- onClick: () => onConfirm(),
1505
- children: t("common.confirm")
1506
- }
1507
- )
1508
- ]
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
+ )
1509
1166
  }
1510
1167
  );
1511
1168
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1512
- header,
1513
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-my-4" }),
1514
- /* @__PURE__ */ jsxRuntime.jsxs(
1515
- "div",
1516
- {
1517
- className: ui.textVariants({
1518
- size: "sm",
1519
- intensity: 54,
1520
- className: "oui-orderEntry-orderConfirmDialog-content oui-space-y-1"
1521
- }),
1522
- children: [
1523
- quantityItem,
1524
- triggerPriceItem,
1525
- renderPriceAndTotal()
1526
- ]
1527
- }
1528
- ),
1529
- tpslTriggerPrice,
1530
- orderConfirmCheckbox,
1531
- buttons
1532
- ] });
1533
- };
1534
- var OrderItem = (props) => {
1535
- const { title, value, unit, dp } = props;
1536
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { justify: "between", children: [
1537
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: title }),
1538
- /* @__PURE__ */ jsxRuntime.jsx(
1539
- ui.Text.numeral,
1540
- {
1541
- unit,
1542
- rule: "price",
1543
- dp,
1544
- padding: false,
1545
- className: "oui-text-base-contrast",
1546
- unitClassName: "oui-text-base-contrast-36 oui-ml-1",
1547
- children: value
1548
- }
1549
- )
1169
+ content,
1170
+ checkboxSection,
1171
+ confirmButton
1550
1172
  ] });
1551
1173
  };
1552
- OrderConfirmDialog.displayName = "OrderConfirmDialog";
1553
- var OrderTypeTag = (props) => {
1554
- const { t } = i18n.useTranslation();
1555
- const typeStr = React3.useMemo(() => {
1556
- switch (props.type) {
1557
- case types.OrderType.LIMIT:
1558
- return t("orderEntry.orderType.limit");
1559
- case types.OrderType.MARKET:
1560
- return t("common.marketPrice");
1561
- case types.OrderType.STOP_LIMIT:
1562
- return t("orderEntry.orderType.stopLimit");
1563
- case types.OrderType.STOP_MARKET:
1564
- return t("orderEntry.orderType.stopMarket");
1565
- case types.OrderType.TRAILING_STOP:
1566
- return t("orderEntry.orderType.trailingStop");
1567
- default:
1568
- return "";
1569
- }
1570
- }, [props.type]);
1571
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "neutral", size: "sm", children: typeStr });
1572
- };
1573
- var Dialog = (props) => {
1574
- const { close, resolve, reject, ...rest } = props;
1174
+ PermissionlessMarketNoticeDialog.displayName = "PermissionlessMarketNoticeDialog";
1175
+ var Dialog2 = (props) => {
1176
+ const { close, resolve, reject } = props;
1575
1177
  return /* @__PURE__ */ jsxRuntime.jsx(
1576
- OrderConfirmDialog,
1178
+ PermissionlessMarketNoticeDialog,
1577
1179
  {
1578
- ...rest,
1579
1180
  onCancel: () => {
1580
1181
  reject();
1581
1182
  close();
@@ -1587,178 +1188,15 @@ var Dialog = (props) => {
1587
1188
  }
1588
1189
  );
1589
1190
  };
1590
- var orderConfirmDialogId = "orderConfirm";
1591
- ui.registerSimpleDialog(orderConfirmDialogId, Dialog, {
1191
+ var permissionlessMarketNoticeDialogId = "permissionlessMarketNotice";
1192
+ var permissionlessMarketNoticeDesktopDialogId = "permissionlessMarketNoticeDesktop";
1193
+ ui.registerSimpleDialog(permissionlessMarketNoticeDialogId, Dialog2, {
1592
1194
  size: "sm",
1593
- title: () => i18n.i18n.t("orderEntry.orderConfirm")
1195
+ title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1594
1196
  });
1595
- var MaxQtyConfirm = React3.memo((props) => {
1596
- const { t } = i18n.useTranslation();
1597
- return /* @__PURE__ */ jsxRuntime.jsx(
1598
- ui.SimpleDialog,
1599
- {
1600
- open: props.open,
1601
- title: t("orderEntry.orderConfirm"),
1602
- closable: true,
1603
- onOpenChange: props.onOpenChange,
1604
- size: "sm",
1605
- classNames: {
1606
- footer: "oui-maxQtyConfirm-footer",
1607
- body: "oui-maxQtyConfirm-body"
1608
- },
1609
- actions: {
1610
- primary: {
1611
- label: t("orderEntry.placeOrderNow"),
1612
- className: "oui-primary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1613
- onClick: () => {
1614
- props.onConfirm();
1615
- return Promise.resolve();
1616
- }
1617
- },
1618
- secondary: {
1619
- label: t("common.cancel"),
1620
- className: "oui-secondary-btn oui-text-sm oui-font-semibold oui-w-[100%] oui-h-8",
1621
- onClick: () => {
1622
- props.onOpenChange(false);
1623
- return Promise.resolve();
1624
- }
1625
- }
1626
- },
1627
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-maxQtyConfirm-content oui-text-2xs lg:oui-text-sm", children: t("orderEntry.maxQty.reminder.content", {
1628
- maxQty: `${props.maxQty} ${props.base}`
1629
- }) })
1630
- }
1631
- );
1632
- });
1633
- var PermissionlessMarketNoticeDialog = (props) => {
1634
- const { onConfirm, onCancel } = props;
1635
- const { t } = i18n.useTranslation();
1636
- const [checked, setChecked] = React3.useState(false);
1637
- const content = /* @__PURE__ */ jsxRuntime.jsxs(
1638
- ui.Flex,
1639
- {
1640
- direction: "column",
1641
- gap: 3,
1642
- itemAlign: "start",
1643
- className: "oui-permissionlessNotice-content",
1644
- children: [
1645
- /* @__PURE__ */ jsxRuntime.jsx(
1646
- ui.Text,
1647
- {
1648
- className: ui.textVariants({
1649
- size: "sm",
1650
- intensity: 54
1651
- }),
1652
- children: t("orderEntry.permissionlessNotice.content1")
1653
- }
1654
- ),
1655
- /* @__PURE__ */ jsxRuntime.jsx(
1656
- ui.Text,
1657
- {
1658
- className: ui.textVariants({
1659
- size: "sm",
1660
- intensity: 54
1661
- }),
1662
- children: t("orderEntry.permissionlessNotice.content2")
1663
- }
1664
- ),
1665
- /* @__PURE__ */ jsxRuntime.jsx(
1666
- ui.Text,
1667
- {
1668
- className: ui.textVariants({
1669
- size: "sm",
1670
- intensity: 54
1671
- }),
1672
- children: t("orderEntry.permissionlessNotice.content3")
1673
- }
1674
- )
1675
- ]
1676
- }
1677
- );
1678
- const checkboxSection = /* @__PURE__ */ jsxRuntime.jsxs(
1679
- ui.Flex,
1680
- {
1681
- gapX: 1,
1682
- pt: 4,
1683
- pb: 5,
1684
- itemAlign: "start",
1685
- className: "oui-permissionlessNotice-checkbox oui-orderEntry-orderConfirmDialog-disableConfirm oui-cursor-pointer",
1686
- children: [
1687
- /* @__PURE__ */ jsxRuntime.jsx(
1688
- ui.Checkbox,
1689
- {
1690
- id: "permissionlessNotice",
1691
- color: "white",
1692
- className: "oui-permissionlessNotice-checkbox-input oui-mt-1",
1693
- checked,
1694
- onCheckedChange: (value) => setChecked(!!value)
1695
- }
1696
- ),
1697
- /* @__PURE__ */ jsxRuntime.jsx(
1698
- "label",
1699
- {
1700
- htmlFor: "permissionlessNotice",
1701
- className: ui.textVariants({
1702
- size: "xs",
1703
- intensity: 54,
1704
- className: "oui-cursor-pointer"
1705
- }),
1706
- children: t("orderEntry.permissionlessNotice.checkbox")
1707
- }
1708
- )
1709
- ]
1710
- }
1711
- );
1712
- const confirmButton = /* @__PURE__ */ jsxRuntime.jsx(
1713
- ui.Flex,
1714
- {
1715
- className: "oui-permissionlessNotice-confirm-button oui-w-full",
1716
- justify: "center",
1717
- children: /* @__PURE__ */ jsxRuntime.jsx(
1718
- ui.Button,
1719
- {
1720
- fullWidth: true,
1721
- size: "md",
1722
- className: "oui-permissionlessNotice-confirm oui-confirm-btn oui-max-w-[244px]",
1723
- disabled: !checked,
1724
- onClick: () => onConfirm(),
1725
- children: t("common.confirm")
1726
- }
1727
- )
1728
- }
1729
- );
1730
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1731
- content,
1732
- checkboxSection,
1733
- confirmButton
1734
- ] });
1735
- };
1736
- PermissionlessMarketNoticeDialog.displayName = "PermissionlessMarketNoticeDialog";
1737
- var Dialog2 = (props) => {
1738
- const { close, resolve, reject } = props;
1739
- return /* @__PURE__ */ jsxRuntime.jsx(
1740
- PermissionlessMarketNoticeDialog,
1741
- {
1742
- onCancel: () => {
1743
- reject();
1744
- close();
1745
- },
1746
- onConfirm: () => {
1747
- resolve();
1748
- close();
1749
- }
1750
- }
1751
- );
1752
- };
1753
- var permissionlessMarketNoticeDialogId = "permissionlessMarketNotice";
1754
- var permissionlessMarketNoticeDesktopDialogId = "permissionlessMarketNoticeDesktop";
1755
- ui.registerSimpleDialog(permissionlessMarketNoticeDialogId, Dialog2, {
1756
- size: "sm",
1757
- title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1758
- });
1759
- ui.registerSimpleDialog(permissionlessMarketNoticeDesktopDialogId, Dialog2, {
1760
- size: "xl",
1761
- title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1197
+ ui.registerSimpleDialog(permissionlessMarketNoticeDesktopDialogId, Dialog2, {
1198
+ size: "xl",
1199
+ title: () => i18n.i18n.t("orderEntry.permissionlessNotice.title")
1762
1200
  });
1763
1201
  var ScaledOrderConfirm = (props) => {
1764
1202
  const { order, symbolInfo, dataSource, national, askAndBid, totalQuantity } = props;
@@ -1987,14 +1425,576 @@ var ScaledOrderConfirmWidget = (props) => {
1987
1425
  const state = useScaledOrderConfirmScript(props);
1988
1426
  return /* @__PURE__ */ jsxRuntime.jsx(ScaledOrderConfirm, { ...props, ...state });
1989
1427
  };
1990
- var scaledOrderConfirmDialogId = "scaledOrderConfirm";
1991
- ui.registerSimpleDialog(scaledOrderConfirmDialogId, ScaledOrderConfirmWidget, {
1992
- size: "md",
1993
- title: () => i18n.i18n.t("orderEntry.confirmScaledOrder"),
1994
- contentProps: {
1995
- // className: "oui-p-0",
1996
- }
1997
- });
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
+ };
1998
1998
  var OrderTypeSelect = (props) => {
1999
1999
  const { t } = i18n.useTranslation();
2000
2000
  const { isMobile } = ui.useScreen();
@@ -2146,49 +2146,317 @@ var OrderTypeSelect = (props) => {
2146
2146
  ]
2147
2147
  }
2148
2148
  );
2149
- }
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
- };
2160
- return /* @__PURE__ */ jsxRuntime.jsx(
2161
- ui.Select.options,
2162
- {
2163
- testid: "oui-testid-orderEntry-orderType-button",
2164
- currentValue: props.type,
2165
- value: props.type,
2166
- options: mobileOptions,
2167
- onValueChange: handleMobileValueChange,
2168
- contentProps: {
2169
- className: ui.cn(
2170
- "oui-orderEntry-orderTypeSelect-content",
2171
- "oui-bg-base-8"
2172
- )
2173
- },
2174
- classNames: {
2175
- trigger: ui.cn(
2176
- "oui-orderEntry-orderTypeSelect-btn",
2177
- "oui-bg-base-7 oui-border-line-12 oui-h-8 oui-rounded-md"
2178
- )
2179
- },
2180
- valueFormatter: (value, option) => {
2181
- const item = allOptions.find((o) => o.value === value);
2182
- if (!item) {
2183
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: option.placeholder });
2149
+ }
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
+ };
2160
+ return /* @__PURE__ */ jsxRuntime.jsx(
2161
+ ui.Select.options,
2162
+ {
2163
+ testid: "oui-testid-orderEntry-orderType-button",
2164
+ currentValue: props.type,
2165
+ value: props.type,
2166
+ options: mobileOptions,
2167
+ onValueChange: handleMobileValueChange,
2168
+ contentProps: {
2169
+ className: ui.cn(
2170
+ "oui-orderEntry-orderTypeSelect-content",
2171
+ "oui-bg-base-8"
2172
+ )
2173
+ },
2174
+ classNames: {
2175
+ trigger: ui.cn(
2176
+ "oui-orderEntry-orderTypeSelect-btn",
2177
+ "oui-bg-base-7 oui-border-line-12 oui-h-8 oui-rounded-md"
2178
+ )
2179
+ },
2180
+ valueFormatter: (value, option) => {
2181
+ const item = allOptions.find((o) => o.value === value);
2182
+ if (!item) {
2183
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xs", children: option.placeholder });
2184
+ }
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
2184
2435
  }
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
- };
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
+ );
2192
2460
  var MarginModeSwitch = (props) => {
2193
2461
  const { t } = i18n.useTranslation();
2194
2462
  const handleSelect = (mode) => {
@@ -3049,7 +3317,6 @@ var LeverageBadge = (props) => {
3049
3317
  };
3050
3318
  function OrderEntryHeader(props) {
3051
3319
  const { canTrade, side, order_type, setOrderValue } = props;
3052
- const { t } = i18n.useTranslation();
3053
3320
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3054
3321
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
3055
3322
  LeverageBadge,
@@ -3061,8 +3328,8 @@ function OrderEntryHeader(props) {
3061
3328
  disabled: !props.canTrade
3062
3329
  }
3063
3330
  ) }),
3064
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
3065
- OrderTypeSelect,
3331
+ /* @__PURE__ */ jsxRuntime.jsx(
3332
+ OrderEntryTypeTabsInjectabled,
3066
3333
  {
3067
3334
  type: order_type,
3068
3335
  side,
@@ -3073,61 +3340,19 @@ function OrderEntryHeader(props) {
3073
3340
  marketOrderDisabled: props.marketOrderDisabled,
3074
3341
  marketOrderDisabledTooltip: props.marketOrderDisabledTooltip
3075
3342
  }
3076
- ) }),
3077
- /* @__PURE__ */ jsxRuntime.jsxs(
3078
- "div",
3343
+ ),
3344
+ /* @__PURE__ */ jsxRuntime.jsx(
3345
+ OrderEntryBuySellSwitchInjectabled,
3079
3346
  {
3080
- className: ui.cn(
3081
- "oui-orderEntry-side",
3082
- "oui-grid oui-w-full oui-flex-1 oui-gap-x-2 lg:oui-flex lg:oui-gap-x-[6px]",
3083
- "oui-grid-cols-2"
3084
- ),
3085
- children: [
3086
- /* @__PURE__ */ jsxRuntime.jsx(
3087
- ui.Button,
3088
- {
3089
- onClick: () => {
3090
- props.setOrderValue("side", types.OrderSide.BUY);
3091
- },
3092
- size: "md",
3093
- fullWidth: true,
3094
- "data-type": types.OrderSide.BUY,
3095
- className: ui.cn(
3096
- "oui-orderEntry-side-buy-btn",
3097
- 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"
3098
- ),
3099
- "data-testid": "oui-testid-orderEntry-side-buy-button",
3100
- children: t("common.buy")
3101
- }
3102
- ),
3103
- /* @__PURE__ */ jsxRuntime.jsx(
3104
- ui.Button,
3105
- {
3106
- onClick: () => {
3107
- props.setOrderValue("side", types.OrderSide.SELL);
3108
- },
3109
- "data-type": types.OrderSide.SELL,
3110
- fullWidth: true,
3111
- size: "md",
3112
- className: ui.cn(
3113
- "oui-orderEntry-side-sell-btn",
3114
- 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"
3115
- ),
3116
- "data-testid": "oui-testid-orderEntry-side-sell-button",
3117
- children: t("common.sell")
3118
- }
3119
- )
3120
- ]
3347
+ side,
3348
+ canTrade,
3349
+ onSideChange: (nextSide) => {
3350
+ props.setOrderValue("side", nextSide);
3351
+ }
3121
3352
  }
3122
3353
  )
3123
3354
  ] });
3124
3355
  }
3125
- var OrderEntryContext = React3.createContext(
3126
- {}
3127
- );
3128
- var useOrderEntryContext = () => {
3129
- return React3.useContext(OrderEntryContext);
3130
- };
3131
3356
  var OrderEntryProvider = (props) => {
3132
3357
  const {
3133
3358
  errorMsgVisible,
@@ -4598,129 +4823,6 @@ function OrderInput(props) {
4598
4823
  )
4599
4824
  ] });
4600
4825
  }
4601
- var SLIDER_MIN = 0;
4602
- var SLIDER_MAX = 100;
4603
- var QuantitySlider = React3.memo((props) => {
4604
- const { canTrade, side, order_quantity, maxQty } = props;
4605
- const [sliderValue, setSliderValue] = React3.useState(0);
4606
- const {
4607
- setOrderValue,
4608
- manualSetOrderValue,
4609
- symbolInfo,
4610
- lastQuantityInputType
4611
- } = useOrderEntryContext();
4612
- const { base_dp, base_tick } = symbolInfo;
4613
- const { t } = i18n.useTranslation();
4614
- const color = React3.useMemo(
4615
- () => canTrade ? side === types.OrderSide.BUY ? "buy" : "sell" : void 0,
4616
- [side, canTrade]
4617
- );
4618
- const maxLabel = React3.useMemo(() => {
4619
- return side === types.OrderSide.BUY ? t("orderEntry.maxBuy") : t("orderEntry.maxSell");
4620
- }, [side, t]);
4621
- const onSliderValueChange = (value) => {
4622
- lastQuantityInputType.current = 4 /* QUANTITY_SLIDER */;
4623
- setSliderValue(value);
4624
- sliderToQuantity(value, true);
4625
- };
4626
- const sliderToQuantity = (value, isManual = false) => {
4627
- const newQty = new utils.Decimal(value).div(SLIDER_MAX).mul(maxQty).toFixed(base_dp, utils.Decimal.ROUND_DOWN);
4628
- if (isManual) {
4629
- manualSetOrderValue?.(
4630
- "order_quantity",
4631
- hooks.utils.formatNumber(newQty, base_tick)
4632
- );
4633
- } else {
4634
- setOrderValue("order_quantity", hooks.utils.formatNumber(newQty, base_tick));
4635
- }
4636
- };
4637
- const onMax = () => {
4638
- onSliderValueChange(SLIDER_MAX);
4639
- if (sliderValue === SLIDER_MAX) {
4640
- sliderToQuantity(SLIDER_MAX, true);
4641
- }
4642
- };
4643
- React3.useEffect(() => {
4644
- if (lastQuantityInputType.current === 4 /* QUANTITY_SLIDER */) {
4645
- sliderToQuantity(sliderValue);
4646
- }
4647
- }, [maxQty]);
4648
- React3.useEffect(() => {
4649
- const quantityToSlider = () => {
4650
- if (order_quantity && Number(order_quantity) !== 0 && maxQty !== 0) {
4651
- return new utils.Decimal(Math.min(Number(order_quantity), maxQty)).div(maxQty).mul(SLIDER_MAX).todp(2, utils.Decimal.ROUND_DOWN).toNumber();
4652
- }
4653
- return 0;
4654
- };
4655
- if (lastQuantityInputType.current !== 4 /* QUANTITY_SLIDER */) {
4656
- setSliderValue(quantityToSlider());
4657
- }
4658
- }, [order_quantity, maxQty]);
4659
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-orderEntry-quantitySlider", children: [
4660
- /* @__PURE__ */ jsxRuntime.jsx(
4661
- ui.Slider,
4662
- {
4663
- disabled: maxQty === 0 || !canTrade,
4664
- value: [sliderValue],
4665
- color,
4666
- markCount: 4,
4667
- showTip: true,
4668
- onValueChange: (e) => {
4669
- onSliderValueChange(e[0]);
4670
- },
4671
- min: SLIDER_MIN,
4672
- max: SLIDER_MAX
4673
- }
4674
- ),
4675
- /* @__PURE__ */ jsxRuntime.jsxs(
4676
- ui.Flex,
4677
- {
4678
- justify: "between",
4679
- className: "oui-quantitySlider-footer oui-pt-1 xl:oui-pt-2",
4680
- children: [
4681
- /* @__PURE__ */ jsxRuntime.jsx(
4682
- ui.Text.numeral,
4683
- {
4684
- size: "2xs",
4685
- color,
4686
- dp: 2,
4687
- padding: false,
4688
- suffix: "%",
4689
- children: canTrade ? sliderValue : 0
4690
- }
4691
- ),
4692
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
4693
- /* @__PURE__ */ jsxRuntime.jsx(
4694
- "button",
4695
- {
4696
- className: ui.textVariants({
4697
- size: "2xs",
4698
- className: "oui-quantitySlider-maxQty-btn oui-mr-1"
4699
- }),
4700
- onClick: onMax,
4701
- "data-testid": "oui-testid-orderEntry-maxQty-value-button",
4702
- children: maxLabel
4703
- }
4704
- ),
4705
- /* @__PURE__ */ jsxRuntime.jsx(
4706
- ui.Text.numeral,
4707
- {
4708
- size: "2xs",
4709
- color,
4710
- dp: base_dp,
4711
- padding: false,
4712
- className: "oui-quantitySlider-maxQty-value",
4713
- "data-testid": "oui-testid-orderEntry-maxQty-value",
4714
- children: canTrade ? maxQty : 0
4715
- }
4716
- )
4717
- ] })
4718
- ]
4719
- }
4720
- )
4721
- ] });
4722
- });
4723
- QuantitySlider.displayName = "QuantitySlider";
4724
4826
  var ReduceOnlySwitch = ({
4725
4827
  checked,
4726
4828
  onCheckedChange,
@@ -5154,8 +5256,8 @@ var OrderTPSL = (props) => {
5154
5256
  {
5155
5257
  className: ui.cn(
5156
5258
  "oui-orderEntry-tpsl-body",
5157
- "oui-max-h-0 oui-overflow-hidden oui-transition-all",
5158
- props.switchState && "oui-max-h-[120px]"
5259
+ "oui-overflow-hidden oui-transition-all",
5260
+ props.switchState ? "oui-max-h-[120px]" : "oui-max-h-0"
5159
5261
  ),
5160
5262
  onTransitionEnd: () => {
5161
5263
  tpslFormRef.current?.style.setProperty(
@@ -5763,7 +5865,7 @@ var OrderEntry = (props) => {
5763
5865
  }
5764
5866
  ),
5765
5867
  /* @__PURE__ */ jsxRuntime.jsx(
5766
- Available,
5868
+ OrderEntryAvailableInjectabled,
5767
5869
  {
5768
5870
  currentLtv,
5769
5871
  canTrade: props.canTrade,
@@ -5787,7 +5889,7 @@ var OrderEntry = (props) => {
5787
5889
  }
5788
5890
  ),
5789
5891
  /* @__PURE__ */ jsxRuntime.jsx(
5790
- QuantitySlider,
5892
+ OrderEntryQuantitySliderInjectabled,
5791
5893
  {
5792
5894
  canTrade: props.canTrade,
5793
5895
  side: props.side,
@@ -5796,38 +5898,29 @@ var OrderEntry = (props) => {
5796
5898
  }
5797
5899
  ),
5798
5900
  /* @__PURE__ */ jsxRuntime.jsx(
5799
- ui.ThrottledButton,
5800
- {
5801
- fullWidth: true,
5802
- id: "order-entry-submit-button",
5803
- "data-type": types.OrderSide.BUY,
5804
- className: ui.cn(
5805
- "oui-orderEntry-submit-btn",
5806
- 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"
5807
- ),
5808
- onClick: validateSubmit,
5809
- loading: props.isMutating,
5810
- disabled: !props.canTrade,
5811
- children: buttonLabel
5812
- }
5813
- ),
5814
- /* @__PURE__ */ jsxRuntime.jsx(
5815
- AssetInfo,
5901
+ OrderEntrySubmitSectionInjectabled,
5816
5902
  {
5903
+ buttonLabel,
5904
+ side,
5817
5905
  canTrade: props.canTrade,
5818
- quote: symbolInfo.quote,
5819
- estLiqPrice: props.estLiqPrice,
5820
- estLiqPriceDistance: props.estLiqPriceDistance,
5821
- estLeverage: props.estLeverage,
5822
- currentLeverage: props.currentLeverage,
5823
- slippage,
5824
- dp: symbolInfo.quote_dp,
5825
- setSlippage,
5826
- estSlippage: props.estSlippage,
5827
- orderType: formattedOrder.order_type,
5828
- disableFeatures,
5829
- symbol: props.symbol,
5830
- side
5906
+ isMutating: props.isMutating,
5907
+ onSubmit: validateSubmit,
5908
+ assetInfo: {
5909
+ canTrade: props.canTrade,
5910
+ quote: symbolInfo.quote,
5911
+ estLiqPrice: props.estLiqPrice,
5912
+ estLiqPriceDistance: props.estLiqPriceDistance,
5913
+ estLeverage: props.estLeverage,
5914
+ currentLeverage: props.currentLeverage,
5915
+ slippage,
5916
+ dp: symbolInfo.quote_dp,
5917
+ setSlippage,
5918
+ estSlippage: props.estSlippage,
5919
+ orderType: formattedOrder.order_type,
5920
+ disableFeatures,
5921
+ symbol: props.symbol,
5922
+ side
5923
+ }
5831
5924
  }
5832
5925
  ),
5833
5926
  /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { className: "oui-w-full" }),
@@ -6481,10 +6574,14 @@ var useOrderEntryScript = (inputs) => {
6481
6574
  isSymbolPostOnly
6482
6575
  };
6483
6576
  };
6577
+ var InjectableOrderEntry = ui.injectable(
6578
+ OrderEntry,
6579
+ "OrderEntry"
6580
+ );
6484
6581
  var OrderEntryWidget = (props) => {
6485
6582
  const state = useOrderEntryScript(props);
6486
6583
  return /* @__PURE__ */ jsxRuntime.jsx(
6487
- OrderEntry,
6584
+ InjectableOrderEntry,
6488
6585
  {
6489
6586
  ...state,
6490
6587
  containerRef: props.containerRef,