@medusajs/draft-order 2.11.4-preview-20251108090128 → 2.11.4-preview-20251108120149

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