@medusajs/draft-order 2.11.0-snapshot-20251019075109 → 2.11.0-snapshot-20251020120939

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.
@@ -7823,12 +7823,10 @@ const CustomerField$1 = ({ control, setValue }) => {
7823
7823
  (option) => option.value === value
7824
7824
  )) == null ? void 0 : _a.label;
7825
7825
  const customerEmail = ((_b = label == null ? void 0 : label.match(/\((.*@.*)\)$/)) == null ? void 0 : _b[1]) || label;
7826
- if (!email && customerEmail) {
7827
- setValue("email", customerEmail, {
7828
- shouldDirty: true,
7829
- shouldTouch: true
7830
- });
7831
- }
7826
+ setValue("email", customerEmail || "", {
7827
+ shouldDirty: true,
7828
+ shouldTouch: true
7829
+ });
7832
7830
  },
7833
7831
  [email, setValue, customers.options]
7834
7832
  );
@@ -9573,27 +9571,6 @@ const ID = () => {
9573
9571
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9574
9572
  ] });
9575
9573
  };
9576
- const CustomItems = () => {
9577
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9578
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9579
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9580
- ] });
9581
- };
9582
- const CustomItemsForm = () => {
9583
- const form = reactHookForm.useForm({
9584
- resolver: zod.zodResolver(schema$5)
9585
- });
9586
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9587
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9588
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9589
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9590
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9591
- ] }) })
9592
- ] }) });
9593
- };
9594
- const schema$5 = objectType({
9595
- email: stringType().email()
9596
- });
9597
9574
  const BillingAddress = () => {
9598
9575
  const { id } = reactRouterDom.useParams();
9599
9576
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9626,7 +9603,7 @@ const BillingAddressForm = ({ order }) => {
9626
9603
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9627
9604
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9628
9605
  },
9629
- resolver: zod.zodResolver(schema$4)
9606
+ resolver: zod.zodResolver(schema$5)
9630
9607
  });
9631
9608
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9632
9609
  const { handleSuccess } = useRouteModal();
@@ -9783,7 +9760,28 @@ const BillingAddressForm = ({ order }) => {
9783
9760
  }
9784
9761
  ) });
9785
9762
  };
9786
- const schema$4 = addressSchema;
9763
+ const schema$5 = addressSchema;
9764
+ const CustomItems = () => {
9765
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9766
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9767
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9768
+ ] });
9769
+ };
9770
+ const CustomItemsForm = () => {
9771
+ const form = reactHookForm.useForm({
9772
+ resolver: zod.zodResolver(schema$4)
9773
+ });
9774
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9775
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9776
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9777
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9778
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9779
+ ] }) })
9780
+ ] }) });
9781
+ };
9782
+ const schema$4 = objectType({
9783
+ email: stringType().email()
9784
+ });
9787
9785
  const Email = () => {
9788
9786
  const { id } = reactRouterDom.useParams();
9789
9787
  const { order, isPending, isError, error } = useOrder(id, {
@@ -10826,128 +10824,405 @@ const customItemSchema = objectType({
10826
10824
  quantity: numberType(),
10827
10825
  unit_price: unionType([numberType(), stringType()])
10828
10826
  });
10829
- const InlineTip = React.forwardRef(
10830
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10831
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10832
- return /* @__PURE__ */ jsxRuntime.jsxs(
10833
- "div",
10834
- {
10835
- ref,
10836
- className: ui.clx(
10837
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10838
- className
10839
- ),
10840
- ...props,
10841
- children: [
10842
- /* @__PURE__ */ jsxRuntime.jsx(
10843
- "div",
10844
- {
10845
- role: "presentation",
10846
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10847
- "bg-ui-tag-orange-icon": variant === "warning"
10848
- })
10849
- }
10850
- ),
10851
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10852
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10853
- labelValue,
10854
- ":"
10855
- ] }),
10856
- " ",
10857
- children
10858
- ] })
10859
- ]
10860
- }
10861
- );
10862
- }
10863
- );
10864
- InlineTip.displayName = "InlineTip";
10865
- const MetadataFieldSchema = objectType({
10866
- key: stringType(),
10867
- disabled: booleanType().optional(),
10868
- value: anyType()
10869
- });
10870
- const MetadataSchema = objectType({
10871
- metadata: arrayType(MetadataFieldSchema)
10872
- });
10873
- const Metadata = () => {
10874
- const { id } = reactRouterDom.useParams();
10875
- const { order, isPending, isError, error } = useOrder(id, {
10876
- fields: "metadata"
10827
+ const PROMOTION_QUERY_KEY = "promotions";
10828
+ const promotionsQueryKeys = {
10829
+ list: (query2) => [
10830
+ PROMOTION_QUERY_KEY,
10831
+ query2 ? query2 : void 0
10832
+ ],
10833
+ detail: (id, query2) => [
10834
+ PROMOTION_QUERY_KEY,
10835
+ id,
10836
+ query2 ? query2 : void 0
10837
+ ]
10838
+ };
10839
+ const usePromotions = (query2, options) => {
10840
+ const { data, ...rest } = reactQuery.useQuery({
10841
+ queryKey: promotionsQueryKeys.list(query2),
10842
+ queryFn: async () => sdk.admin.promotion.list(query2),
10843
+ ...options
10877
10844
  });
10878
- if (isError) {
10879
- throw error;
10845
+ return { ...data, ...rest };
10846
+ };
10847
+ const Promotions = () => {
10848
+ const { id } = reactRouterDom.useParams();
10849
+ const {
10850
+ order: preview,
10851
+ isError: isPreviewError,
10852
+ error: previewError
10853
+ } = useOrderPreview(id, void 0);
10854
+ useInitiateOrderEdit({ preview });
10855
+ const { onCancel } = useCancelOrderEdit({ preview });
10856
+ if (isPreviewError) {
10857
+ throw previewError;
10880
10858
  }
10881
- const isReady = !isPending && !!order;
10882
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10883
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10884
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10885
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10886
- ] }),
10887
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10859
+ const isReady = !!preview;
10860
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10861
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10862
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10888
10863
  ] });
10889
10864
  };
10890
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10891
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10892
- const MetadataForm = ({ orderId, metadata }) => {
10865
+ const PromotionForm = ({ preview }) => {
10866
+ const { items, shipping_methods } = preview;
10867
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10868
+ const [comboboxValue, setComboboxValue] = React.useState("");
10893
10869
  const { handleSuccess } = useRouteModal();
10894
- const hasUneditableRows = getHasUneditableRows(metadata);
10895
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10896
- const form = reactHookForm.useForm({
10897
- defaultValues: {
10898
- metadata: getDefaultValues(metadata)
10870
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10871
+ const promoIds = getPromotionIds(items, shipping_methods);
10872
+ const { promotions, isPending, isError, error } = usePromotions(
10873
+ {
10874
+ id: promoIds
10899
10875
  },
10900
- resolver: zod.zodResolver(MetadataSchema)
10876
+ {
10877
+ enabled: !!promoIds.length
10878
+ }
10879
+ );
10880
+ const comboboxData = useComboboxData({
10881
+ queryKey: ["promotions", "combobox", promoIds],
10882
+ queryFn: async (params) => {
10883
+ return await sdk.admin.promotion.list({
10884
+ ...params,
10885
+ id: {
10886
+ $nin: promoIds
10887
+ }
10888
+ });
10889
+ },
10890
+ getOptions: (data) => {
10891
+ return data.promotions.map((promotion) => ({
10892
+ label: promotion.code,
10893
+ value: promotion.code
10894
+ }));
10895
+ }
10901
10896
  });
10902
- const handleSubmit = form.handleSubmit(async (data) => {
10903
- const parsedData = parseValues(data);
10904
- await mutateAsync(
10897
+ const add = async (value) => {
10898
+ if (!value) {
10899
+ return;
10900
+ }
10901
+ addPromotions(
10905
10902
  {
10906
- metadata: parsedData
10903
+ promo_codes: [value]
10907
10904
  },
10908
10905
  {
10909
- onSuccess: () => {
10910
- ui.toast.success("Metadata updated");
10911
- handleSuccess();
10906
+ onError: (e) => {
10907
+ ui.toast.error(e.message);
10908
+ comboboxData.onSearchValueChange("");
10909
+ setComboboxValue("");
10912
10910
  },
10913
- onError: (error) => {
10914
- ui.toast.error(error.message);
10911
+ onSuccess: () => {
10912
+ comboboxData.onSearchValueChange("");
10913
+ setComboboxValue("");
10915
10914
  }
10916
10915
  }
10917
10916
  );
10918
- });
10919
- const { fields, insert, remove } = reactHookForm.useFieldArray({
10920
- control: form.control,
10921
- name: "metadata"
10922
- });
10923
- function deleteRow(index) {
10924
- remove(index);
10925
- if (fields.length === 1) {
10926
- insert(0, {
10927
- key: "",
10928
- value: "",
10929
- disabled: false
10930
- });
10917
+ };
10918
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10919
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10920
+ const onSubmit = async () => {
10921
+ setIsSubmitting(true);
10922
+ let requestSucceeded = false;
10923
+ await requestOrderEdit(void 0, {
10924
+ onError: (e) => {
10925
+ ui.toast.error(e.message);
10926
+ },
10927
+ onSuccess: () => {
10928
+ requestSucceeded = true;
10929
+ }
10930
+ });
10931
+ if (!requestSucceeded) {
10932
+ setIsSubmitting(false);
10933
+ return;
10931
10934
  }
10932
- }
10933
- function insertRow(index, position) {
10934
- insert(index + (position === "above" ? 0 : 1), {
10935
- key: "",
10936
- value: "",
10937
- disabled: false
10935
+ await confirmOrderEdit(void 0, {
10936
+ onError: (e) => {
10937
+ ui.toast.error(e.message);
10938
+ },
10939
+ onSuccess: () => {
10940
+ handleSuccess();
10941
+ },
10942
+ onSettled: () => {
10943
+ setIsSubmitting(false);
10944
+ }
10938
10945
  });
10946
+ };
10947
+ if (isError) {
10948
+ throw error;
10939
10949
  }
10940
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10941
- KeyboundForm,
10942
- {
10943
- onSubmit: handleSubmit,
10944
- className: "flex flex-1 flex-col overflow-hidden",
10945
- children: [
10946
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10947
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10948
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10949
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10950
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10950
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10951
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10952
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10954
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10955
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10956
+ ] }),
10957
+ /* @__PURE__ */ jsxRuntime.jsx(
10958
+ Combobox,
10959
+ {
10960
+ id: "promotion-combobox",
10961
+ "aria-describedby": "promotion-combobox-hint",
10962
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10963
+ fetchNextPage: comboboxData.fetchNextPage,
10964
+ options: comboboxData.options,
10965
+ onSearchValueChange: comboboxData.onSearchValueChange,
10966
+ searchValue: comboboxData.searchValue,
10967
+ disabled: comboboxData.disabled || isAddingPromotions,
10968
+ onChange: add,
10969
+ value: comboboxValue
10970
+ }
10971
+ )
10972
+ ] }),
10973
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10974
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10975
+ PromotionItem,
10976
+ {
10977
+ promotion,
10978
+ orderId: preview.id,
10979
+ isLoading: isPending
10980
+ },
10981
+ promotion.id
10982
+ )) })
10983
+ ] }) }),
10984
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10985
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10986
+ /* @__PURE__ */ jsxRuntime.jsx(
10987
+ ui.Button,
10988
+ {
10989
+ size: "small",
10990
+ type: "submit",
10991
+ isLoading: isSubmitting || isAddingPromotions,
10992
+ children: "Save"
10993
+ }
10994
+ )
10995
+ ] }) })
10996
+ ] });
10997
+ };
10998
+ const PromotionItem = ({
10999
+ promotion,
11000
+ orderId,
11001
+ isLoading
11002
+ }) => {
11003
+ var _a;
11004
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11005
+ const onRemove = async () => {
11006
+ removePromotions(
11007
+ {
11008
+ promo_codes: [promotion.code]
11009
+ },
11010
+ {
11011
+ onError: (e) => {
11012
+ ui.toast.error(e.message);
11013
+ }
11014
+ }
11015
+ );
11016
+ };
11017
+ const displayValue = getDisplayValue(promotion);
11018
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11019
+ "div",
11020
+ {
11021
+ className: ui.clx(
11022
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11023
+ {
11024
+ "animate-pulse": isLoading
11025
+ }
11026
+ ),
11027
+ children: [
11028
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11029
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11030
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11031
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11032
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11033
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11034
+ ] }),
11035
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11036
+ ] })
11037
+ ] }),
11038
+ /* @__PURE__ */ jsxRuntime.jsx(
11039
+ ui.IconButton,
11040
+ {
11041
+ size: "small",
11042
+ type: "button",
11043
+ variant: "transparent",
11044
+ onClick: onRemove,
11045
+ isLoading: isPending || isLoading,
11046
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11047
+ }
11048
+ )
11049
+ ]
11050
+ },
11051
+ promotion.id
11052
+ );
11053
+ };
11054
+ function getDisplayValue(promotion) {
11055
+ var _a, _b, _c, _d;
11056
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11057
+ if (!value) {
11058
+ return null;
11059
+ }
11060
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11061
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11062
+ if (!currency) {
11063
+ return null;
11064
+ }
11065
+ return getLocaleAmount(value, currency);
11066
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11067
+ return formatPercentage(value);
11068
+ }
11069
+ return null;
11070
+ }
11071
+ const formatter = new Intl.NumberFormat([], {
11072
+ style: "percent",
11073
+ minimumFractionDigits: 2
11074
+ });
11075
+ const formatPercentage = (value, isPercentageValue = false) => {
11076
+ let val = value || 0;
11077
+ if (!isPercentageValue) {
11078
+ val = val / 100;
11079
+ }
11080
+ return formatter.format(val);
11081
+ };
11082
+ function getPromotionIds(items, shippingMethods) {
11083
+ const promotionIds = /* @__PURE__ */ new Set();
11084
+ for (const item of items) {
11085
+ if (item.adjustments) {
11086
+ for (const adjustment of item.adjustments) {
11087
+ if (adjustment.promotion_id) {
11088
+ promotionIds.add(adjustment.promotion_id);
11089
+ }
11090
+ }
11091
+ }
11092
+ }
11093
+ for (const shippingMethod of shippingMethods) {
11094
+ if (shippingMethod.adjustments) {
11095
+ for (const adjustment of shippingMethod.adjustments) {
11096
+ if (adjustment.promotion_id) {
11097
+ promotionIds.add(adjustment.promotion_id);
11098
+ }
11099
+ }
11100
+ }
11101
+ }
11102
+ return Array.from(promotionIds);
11103
+ }
11104
+ const InlineTip = React.forwardRef(
11105
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
11106
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11107
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11108
+ "div",
11109
+ {
11110
+ ref,
11111
+ className: ui.clx(
11112
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11113
+ className
11114
+ ),
11115
+ ...props,
11116
+ children: [
11117
+ /* @__PURE__ */ jsxRuntime.jsx(
11118
+ "div",
11119
+ {
11120
+ role: "presentation",
11121
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11122
+ "bg-ui-tag-orange-icon": variant === "warning"
11123
+ })
11124
+ }
11125
+ ),
11126
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11127
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11128
+ labelValue,
11129
+ ":"
11130
+ ] }),
11131
+ " ",
11132
+ children
11133
+ ] })
11134
+ ]
11135
+ }
11136
+ );
11137
+ }
11138
+ );
11139
+ InlineTip.displayName = "InlineTip";
11140
+ const MetadataFieldSchema = objectType({
11141
+ key: stringType(),
11142
+ disabled: booleanType().optional(),
11143
+ value: anyType()
11144
+ });
11145
+ const MetadataSchema = objectType({
11146
+ metadata: arrayType(MetadataFieldSchema)
11147
+ });
11148
+ const Metadata = () => {
11149
+ const { id } = reactRouterDom.useParams();
11150
+ const { order, isPending, isError, error } = useOrder(id, {
11151
+ fields: "metadata"
11152
+ });
11153
+ if (isError) {
11154
+ throw error;
11155
+ }
11156
+ const isReady = !isPending && !!order;
11157
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11158
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11159
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11160
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11161
+ ] }),
11162
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11163
+ ] });
11164
+ };
11165
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11166
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11167
+ const MetadataForm = ({ orderId, metadata }) => {
11168
+ const { handleSuccess } = useRouteModal();
11169
+ const hasUneditableRows = getHasUneditableRows(metadata);
11170
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11171
+ const form = reactHookForm.useForm({
11172
+ defaultValues: {
11173
+ metadata: getDefaultValues(metadata)
11174
+ },
11175
+ resolver: zod.zodResolver(MetadataSchema)
11176
+ });
11177
+ const handleSubmit = form.handleSubmit(async (data) => {
11178
+ const parsedData = parseValues(data);
11179
+ await mutateAsync(
11180
+ {
11181
+ metadata: parsedData
11182
+ },
11183
+ {
11184
+ onSuccess: () => {
11185
+ ui.toast.success("Metadata updated");
11186
+ handleSuccess();
11187
+ },
11188
+ onError: (error) => {
11189
+ ui.toast.error(error.message);
11190
+ }
11191
+ }
11192
+ );
11193
+ });
11194
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
11195
+ control: form.control,
11196
+ name: "metadata"
11197
+ });
11198
+ function deleteRow(index) {
11199
+ remove(index);
11200
+ if (fields.length === 1) {
11201
+ insert(0, {
11202
+ key: "",
11203
+ value: "",
11204
+ disabled: false
11205
+ });
11206
+ }
11207
+ }
11208
+ function insertRow(index, position) {
11209
+ insert(index + (position === "above" ? 0 : 1), {
11210
+ key: "",
11211
+ value: "",
11212
+ disabled: false
11213
+ });
11214
+ }
11215
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11216
+ KeyboundForm,
11217
+ {
11218
+ onSubmit: handleSubmit,
11219
+ className: "flex flex-1 flex-col overflow-hidden",
11220
+ children: [
11221
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11222
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11223
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11224
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
11225
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10951
11226
  ] }),
10952
11227
  fields.map((field, index) => {
10953
11228
  const isDisabled = field.disabled || false;
@@ -11052,406 +11327,129 @@ const MetadataForm = ({ orderId, metadata }) => {
11052
11327
  /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11053
11328
  /* @__PURE__ */ jsxRuntime.jsxs(
11054
11329
  ui.DropdownMenu.Item,
11055
- {
11056
- className: "gap-x-2",
11057
- onClick: () => deleteRow(index),
11058
- children: [
11059
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11060
- "Delete row"
11061
- ]
11062
- }
11063
- )
11064
- ] })
11065
- ] })
11066
- ] })
11067
- },
11068
- field.id
11069
- );
11070
- })
11071
- ] }),
11072
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11073
- ] }),
11074
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11075
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11076
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11077
- ] }) })
11078
- ]
11079
- }
11080
- ) });
11081
- };
11082
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11083
- return /* @__PURE__ */ jsxRuntime.jsx(
11084
- "input",
11085
- {
11086
- ref,
11087
- ...props,
11088
- autoComplete: "off",
11089
- className: ui.clx(
11090
- "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
11091
- className
11092
- )
11093
- }
11094
- );
11095
- });
11096
- GridInput.displayName = "MetadataForm.GridInput";
11097
- const PlaceholderInner = () => {
11098
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11099
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11100
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11101
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11102
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11103
- ] }) })
11104
- ] });
11105
- };
11106
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11107
- function getDefaultValues(metadata) {
11108
- if (!metadata || !Object.keys(metadata).length) {
11109
- return [
11110
- {
11111
- key: "",
11112
- value: "",
11113
- disabled: false
11114
- }
11115
- ];
11116
- }
11117
- return Object.entries(metadata).map(([key, value]) => {
11118
- if (!EDITABLE_TYPES.includes(typeof value)) {
11119
- return {
11120
- key,
11121
- value,
11122
- disabled: true
11123
- };
11124
- }
11125
- let stringValue = value;
11126
- if (typeof value !== "string") {
11127
- stringValue = JSON.stringify(value);
11128
- }
11129
- return {
11130
- key,
11131
- value: stringValue,
11132
- original_key: key
11133
- };
11134
- });
11135
- }
11136
- function parseValues(values) {
11137
- const metadata = values.metadata;
11138
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11139
- if (isEmpty) {
11140
- return null;
11141
- }
11142
- const update = {};
11143
- metadata.forEach((field) => {
11144
- let key = field.key;
11145
- let value = field.value;
11146
- const disabled = field.disabled;
11147
- if (!key || !value) {
11148
- return;
11149
- }
11150
- if (disabled) {
11151
- update[key] = value;
11152
- return;
11153
- }
11154
- key = key.trim();
11155
- value = value.trim();
11156
- if (value === "true") {
11157
- update[key] = true;
11158
- } else if (value === "false") {
11159
- update[key] = false;
11160
- } else {
11161
- const parsedNumber = parseFloat(value);
11162
- if (!isNaN(parsedNumber)) {
11163
- update[key] = parsedNumber;
11164
- } else {
11165
- update[key] = value;
11166
- }
11167
- }
11168
- });
11169
- return update;
11170
- }
11171
- function getHasUneditableRows(metadata) {
11172
- if (!metadata) {
11173
- return false;
11174
- }
11175
- return Object.values(metadata).some(
11176
- (value) => !EDITABLE_TYPES.includes(typeof value)
11177
- );
11178
- }
11179
- const PROMOTION_QUERY_KEY = "promotions";
11180
- const promotionsQueryKeys = {
11181
- list: (query2) => [
11182
- PROMOTION_QUERY_KEY,
11183
- query2 ? query2 : void 0
11184
- ],
11185
- detail: (id, query2) => [
11186
- PROMOTION_QUERY_KEY,
11187
- id,
11188
- query2 ? query2 : void 0
11189
- ]
11190
- };
11191
- const usePromotions = (query2, options) => {
11192
- const { data, ...rest } = reactQuery.useQuery({
11193
- queryKey: promotionsQueryKeys.list(query2),
11194
- queryFn: async () => sdk.admin.promotion.list(query2),
11195
- ...options
11196
- });
11197
- return { ...data, ...rest };
11198
- };
11199
- const Promotions = () => {
11200
- const { id } = reactRouterDom.useParams();
11201
- const {
11202
- order: preview,
11203
- isError: isPreviewError,
11204
- error: previewError
11205
- } = useOrderPreview(id, void 0);
11206
- useInitiateOrderEdit({ preview });
11207
- const { onCancel } = useCancelOrderEdit({ preview });
11208
- if (isPreviewError) {
11209
- throw previewError;
11210
- }
11211
- const isReady = !!preview;
11212
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11213
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11214
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11215
- ] });
11216
- };
11217
- const PromotionForm = ({ preview }) => {
11218
- const { items, shipping_methods } = preview;
11219
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11220
- const [comboboxValue, setComboboxValue] = React.useState("");
11221
- const { handleSuccess } = useRouteModal();
11222
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11223
- const promoIds = getPromotionIds(items, shipping_methods);
11224
- const { promotions, isPending, isError, error } = usePromotions(
11225
- {
11226
- id: promoIds
11227
- },
11228
- {
11229
- enabled: !!promoIds.length
11230
- }
11231
- );
11232
- const comboboxData = useComboboxData({
11233
- queryKey: ["promotions", "combobox", promoIds],
11234
- queryFn: async (params) => {
11235
- return await sdk.admin.promotion.list({
11236
- ...params,
11237
- id: {
11238
- $nin: promoIds
11239
- }
11240
- });
11241
- },
11242
- getOptions: (data) => {
11243
- return data.promotions.map((promotion) => ({
11244
- label: promotion.code,
11245
- value: promotion.code
11246
- }));
11247
- }
11248
- });
11249
- const add = async (value) => {
11250
- if (!value) {
11251
- return;
11252
- }
11253
- addPromotions(
11254
- {
11255
- promo_codes: [value]
11256
- },
11257
- {
11258
- onError: (e) => {
11259
- ui.toast.error(e.message);
11260
- comboboxData.onSearchValueChange("");
11261
- setComboboxValue("");
11262
- },
11263
- onSuccess: () => {
11264
- comboboxData.onSearchValueChange("");
11265
- setComboboxValue("");
11266
- }
11267
- }
11268
- );
11269
- };
11270
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11271
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11272
- const onSubmit = async () => {
11273
- setIsSubmitting(true);
11274
- let requestSucceeded = false;
11275
- await requestOrderEdit(void 0, {
11276
- onError: (e) => {
11277
- ui.toast.error(e.message);
11278
- },
11279
- onSuccess: () => {
11280
- requestSucceeded = true;
11281
- }
11282
- });
11283
- if (!requestSucceeded) {
11284
- setIsSubmitting(false);
11285
- return;
11286
- }
11287
- await confirmOrderEdit(void 0, {
11288
- onError: (e) => {
11289
- ui.toast.error(e.message);
11290
- },
11291
- onSuccess: () => {
11292
- handleSuccess();
11293
- },
11294
- onSettled: () => {
11295
- setIsSubmitting(false);
11296
- }
11297
- });
11298
- };
11299
- if (isError) {
11300
- throw error;
11301
- }
11302
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11303
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11304
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11305
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11306
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11330
+ {
11331
+ className: "gap-x-2",
11332
+ onClick: () => deleteRow(index),
11333
+ children: [
11334
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11335
+ "Delete row"
11336
+ ]
11337
+ }
11338
+ )
11339
+ ] })
11340
+ ] })
11341
+ ] })
11342
+ },
11343
+ field.id
11344
+ );
11345
+ })
11346
+ ] }),
11347
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11308
11348
  ] }),
11309
- /* @__PURE__ */ jsxRuntime.jsx(
11310
- Combobox,
11311
- {
11312
- id: "promotion-combobox",
11313
- "aria-describedby": "promotion-combobox-hint",
11314
- isFetchingNextPage: comboboxData.isFetchingNextPage,
11315
- fetchNextPage: comboboxData.fetchNextPage,
11316
- options: comboboxData.options,
11317
- onSearchValueChange: comboboxData.onSearchValueChange,
11318
- searchValue: comboboxData.searchValue,
11319
- disabled: comboboxData.disabled || isAddingPromotions,
11320
- onChange: add,
11321
- value: comboboxValue
11322
- }
11323
- )
11324
- ] }),
11325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11326
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11327
- PromotionItem,
11328
- {
11329
- promotion,
11330
- orderId: preview.id,
11331
- isLoading: isPending
11332
- },
11333
- promotion.id
11334
- )) })
11335
- ] }) }),
11336
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11337
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11338
- /* @__PURE__ */ jsxRuntime.jsx(
11339
- ui.Button,
11340
- {
11341
- size: "small",
11342
- type: "submit",
11343
- isLoading: isSubmitting || isAddingPromotions,
11344
- children: "Save"
11345
- }
11349
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11350
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11351
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11352
+ ] }) })
11353
+ ]
11354
+ }
11355
+ ) });
11356
+ };
11357
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11358
+ return /* @__PURE__ */ jsxRuntime.jsx(
11359
+ "input",
11360
+ {
11361
+ ref,
11362
+ ...props,
11363
+ autoComplete: "off",
11364
+ className: ui.clx(
11365
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
11366
+ className
11346
11367
  )
11368
+ }
11369
+ );
11370
+ });
11371
+ GridInput.displayName = "MetadataForm.GridInput";
11372
+ const PlaceholderInner = () => {
11373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11374
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11375
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11376
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11377
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11347
11378
  ] }) })
11348
11379
  ] });
11349
11380
  };
11350
- const PromotionItem = ({
11351
- promotion,
11352
- orderId,
11353
- isLoading
11354
- }) => {
11355
- var _a;
11356
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11357
- const onRemove = async () => {
11358
- removePromotions(
11359
- {
11360
- promo_codes: [promotion.code]
11361
- },
11381
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11382
+ function getDefaultValues(metadata) {
11383
+ if (!metadata || !Object.keys(metadata).length) {
11384
+ return [
11362
11385
  {
11363
- onError: (e) => {
11364
- ui.toast.error(e.message);
11365
- }
11386
+ key: "",
11387
+ value: "",
11388
+ disabled: false
11366
11389
  }
11367
- );
11368
- };
11369
- const displayValue = getDisplayValue(promotion);
11370
- return /* @__PURE__ */ jsxRuntime.jsxs(
11371
- "div",
11372
- {
11373
- className: ui.clx(
11374
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11375
- {
11376
- "animate-pulse": isLoading
11377
- }
11378
- ),
11379
- children: [
11380
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11381
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11382
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11383
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11384
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11385
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11386
- ] }),
11387
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11388
- ] })
11389
- ] }),
11390
- /* @__PURE__ */ jsxRuntime.jsx(
11391
- ui.IconButton,
11392
- {
11393
- size: "small",
11394
- type: "button",
11395
- variant: "transparent",
11396
- onClick: onRemove,
11397
- isLoading: isPending || isLoading,
11398
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11399
- }
11400
- )
11401
- ]
11402
- },
11403
- promotion.id
11404
- );
11405
- };
11406
- function getDisplayValue(promotion) {
11407
- var _a, _b, _c, _d;
11408
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11409
- if (!value) {
11410
- return null;
11390
+ ];
11411
11391
  }
11412
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11413
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11414
- if (!currency) {
11415
- return null;
11392
+ return Object.entries(metadata).map(([key, value]) => {
11393
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11394
+ return {
11395
+ key,
11396
+ value,
11397
+ disabled: true
11398
+ };
11416
11399
  }
11417
- return getLocaleAmount(value, currency);
11418
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11419
- return formatPercentage(value);
11420
- }
11421
- return null;
11400
+ let stringValue = value;
11401
+ if (typeof value !== "string") {
11402
+ stringValue = JSON.stringify(value);
11403
+ }
11404
+ return {
11405
+ key,
11406
+ value: stringValue,
11407
+ original_key: key
11408
+ };
11409
+ });
11422
11410
  }
11423
- const formatter = new Intl.NumberFormat([], {
11424
- style: "percent",
11425
- minimumFractionDigits: 2
11426
- });
11427
- const formatPercentage = (value, isPercentageValue = false) => {
11428
- let val = value || 0;
11429
- if (!isPercentageValue) {
11430
- val = val / 100;
11411
+ function parseValues(values) {
11412
+ const metadata = values.metadata;
11413
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11414
+ if (isEmpty) {
11415
+ return null;
11431
11416
  }
11432
- return formatter.format(val);
11433
- };
11434
- function getPromotionIds(items, shippingMethods) {
11435
- const promotionIds = /* @__PURE__ */ new Set();
11436
- for (const item of items) {
11437
- if (item.adjustments) {
11438
- for (const adjustment of item.adjustments) {
11439
- if (adjustment.promotion_id) {
11440
- promotionIds.add(adjustment.promotion_id);
11441
- }
11442
- }
11417
+ const update = {};
11418
+ metadata.forEach((field) => {
11419
+ let key = field.key;
11420
+ let value = field.value;
11421
+ const disabled = field.disabled;
11422
+ if (!key || !value) {
11423
+ return;
11443
11424
  }
11444
- }
11445
- for (const shippingMethod of shippingMethods) {
11446
- if (shippingMethod.adjustments) {
11447
- for (const adjustment of shippingMethod.adjustments) {
11448
- if (adjustment.promotion_id) {
11449
- promotionIds.add(adjustment.promotion_id);
11450
- }
11425
+ if (disabled) {
11426
+ update[key] = value;
11427
+ return;
11428
+ }
11429
+ key = key.trim();
11430
+ value = value.trim();
11431
+ if (value === "true") {
11432
+ update[key] = true;
11433
+ } else if (value === "false") {
11434
+ update[key] = false;
11435
+ } else {
11436
+ const parsedNumber = parseFloat(value);
11437
+ if (!isNaN(parsedNumber)) {
11438
+ update[key] = parsedNumber;
11439
+ } else {
11440
+ update[key] = value;
11451
11441
  }
11452
11442
  }
11443
+ });
11444
+ return update;
11445
+ }
11446
+ function getHasUneditableRows(metadata) {
11447
+ if (!metadata) {
11448
+ return false;
11453
11449
  }
11454
- return Array.from(promotionIds);
11450
+ return Object.values(metadata).some(
11451
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11452
+ );
11455
11453
  }
11456
11454
  const SalesChannel = () => {
11457
11455
  const { id } = reactRouterDom.useParams();
@@ -13065,14 +13063,14 @@ const routeModule = {
13065
13063
  handle,
13066
13064
  loader,
13067
13065
  children: [
13068
- {
13069
- Component: CustomItems,
13070
- path: "/draft-orders/:id/custom-items"
13071
- },
13072
13066
  {
13073
13067
  Component: BillingAddress,
13074
13068
  path: "/draft-orders/:id/billing-address"
13075
13069
  },
13070
+ {
13071
+ Component: CustomItems,
13072
+ path: "/draft-orders/:id/custom-items"
13073
+ },
13076
13074
  {
13077
13075
  Component: Email,
13078
13076
  path: "/draft-orders/:id/email"
@@ -13081,14 +13079,14 @@ const routeModule = {
13081
13079
  Component: Items,
13082
13080
  path: "/draft-orders/:id/items"
13083
13081
  },
13084
- {
13085
- Component: Metadata,
13086
- path: "/draft-orders/:id/metadata"
13087
- },
13088
13082
  {
13089
13083
  Component: Promotions,
13090
13084
  path: "/draft-orders/:id/promotions"
13091
13085
  },
13086
+ {
13087
+ Component: Metadata,
13088
+ path: "/draft-orders/:id/metadata"
13089
+ },
13092
13090
  {
13093
13091
  Component: SalesChannel,
13094
13092
  path: "/draft-orders/:id/sales-channel"