@medusajs/draft-order 2.10.4-preview-20251005060154 → 2.10.4-preview-20251005090149

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.
@@ -9763,6 +9763,27 @@ const BillingAddressForm = ({ order }) => {
9763
9763
  ) });
9764
9764
  };
9765
9765
  const schema$5 = addressSchema;
9766
+ const CustomItems = () => {
9767
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9768
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9769
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9770
+ ] });
9771
+ };
9772
+ const CustomItemsForm = () => {
9773
+ const form = reactHookForm.useForm({
9774
+ resolver: zod.zodResolver(schema$4)
9775
+ });
9776
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9777
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9778
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9779
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9780
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9781
+ ] }) })
9782
+ ] }) });
9783
+ };
9784
+ const schema$4 = objectType({
9785
+ email: stringType().email()
9786
+ });
9766
9787
  const Email = () => {
9767
9788
  const { id } = reactRouterDom.useParams();
9768
9789
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9785,7 +9806,7 @@ const EmailForm = ({ order }) => {
9785
9806
  defaultValues: {
9786
9807
  email: order.email ?? ""
9787
9808
  },
9788
- resolver: zod.zodResolver(schema$4)
9809
+ resolver: zod.zodResolver(schema$3)
9789
9810
  });
9790
9811
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9791
9812
  const { handleSuccess } = useRouteModal();
@@ -9828,7 +9849,7 @@ const EmailForm = ({ order }) => {
9828
9849
  }
9829
9850
  ) });
9830
9851
  };
9831
- const schema$4 = objectType({
9852
+ const schema$3 = objectType({
9832
9853
  email: stringType().email()
9833
9854
  });
9834
9855
  const NumberInput = React.forwardRef(
@@ -10805,478 +10826,128 @@ const customItemSchema = objectType({
10805
10826
  quantity: numberType(),
10806
10827
  unit_price: unionType([numberType(), stringType()])
10807
10828
  });
10808
- const InlineTip = React.forwardRef(
10809
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10810
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10811
- return /* @__PURE__ */ jsxRuntime.jsxs(
10812
- "div",
10813
- {
10814
- ref,
10815
- className: ui.clx(
10816
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10817
- className
10818
- ),
10819
- ...props,
10820
- children: [
10821
- /* @__PURE__ */ jsxRuntime.jsx(
10822
- "div",
10823
- {
10824
- role: "presentation",
10825
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10826
- "bg-ui-tag-orange-icon": variant === "warning"
10827
- })
10828
- }
10829
- ),
10830
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10831
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10832
- labelValue,
10833
- ":"
10834
- ] }),
10835
- " ",
10836
- children
10837
- ] })
10838
- ]
10839
- }
10840
- );
10841
- }
10842
- );
10843
- InlineTip.displayName = "InlineTip";
10844
- const MetadataFieldSchema = objectType({
10845
- key: stringType(),
10846
- disabled: booleanType().optional(),
10847
- value: anyType()
10848
- });
10849
- const MetadataSchema = objectType({
10850
- metadata: arrayType(MetadataFieldSchema)
10851
- });
10852
- const Metadata = () => {
10853
- const { id } = reactRouterDom.useParams();
10854
- const { order, isPending, isError, error } = useOrder(id, {
10855
- fields: "metadata"
10829
+ const PROMOTION_QUERY_KEY = "promotions";
10830
+ const promotionsQueryKeys = {
10831
+ list: (query2) => [
10832
+ PROMOTION_QUERY_KEY,
10833
+ query2 ? query2 : void 0
10834
+ ],
10835
+ detail: (id, query2) => [
10836
+ PROMOTION_QUERY_KEY,
10837
+ id,
10838
+ query2 ? query2 : void 0
10839
+ ]
10840
+ };
10841
+ const usePromotions = (query2, options) => {
10842
+ const { data, ...rest } = reactQuery.useQuery({
10843
+ queryKey: promotionsQueryKeys.list(query2),
10844
+ queryFn: async () => sdk.admin.promotion.list(query2),
10845
+ ...options
10856
10846
  });
10857
- if (isError) {
10858
- throw error;
10847
+ return { ...data, ...rest };
10848
+ };
10849
+ const Promotions = () => {
10850
+ const { id } = reactRouterDom.useParams();
10851
+ const {
10852
+ order: preview,
10853
+ isError: isPreviewError,
10854
+ error: previewError
10855
+ } = useOrderPreview(id, void 0);
10856
+ useInitiateOrderEdit({ preview });
10857
+ const { onCancel } = useCancelOrderEdit({ preview });
10858
+ if (isPreviewError) {
10859
+ throw previewError;
10859
10860
  }
10860
- const isReady = !isPending && !!order;
10861
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10862
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10863
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10864
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10865
- ] }),
10866
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10861
+ const isReady = !!preview;
10862
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10863
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10864
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10867
10865
  ] });
10868
10866
  };
10869
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10870
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10871
- const MetadataForm = ({ orderId, metadata }) => {
10867
+ const PromotionForm = ({ preview }) => {
10868
+ const { items, shipping_methods } = preview;
10869
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10870
+ const [comboboxValue, setComboboxValue] = React.useState("");
10872
10871
  const { handleSuccess } = useRouteModal();
10873
- const hasUneditableRows = getHasUneditableRows(metadata);
10874
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10875
- const form = reactHookForm.useForm({
10876
- defaultValues: {
10877
- metadata: getDefaultValues(metadata)
10872
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10873
+ const promoIds = getPromotionIds(items, shipping_methods);
10874
+ const { promotions, isPending, isError, error } = usePromotions(
10875
+ {
10876
+ id: promoIds
10878
10877
  },
10879
- resolver: zod.zodResolver(MetadataSchema)
10878
+ {
10879
+ enabled: !!promoIds.length
10880
+ }
10881
+ );
10882
+ const comboboxData = useComboboxData({
10883
+ queryKey: ["promotions", "combobox", promoIds],
10884
+ queryFn: async (params) => {
10885
+ return await sdk.admin.promotion.list({
10886
+ ...params,
10887
+ id: {
10888
+ $nin: promoIds
10889
+ }
10890
+ });
10891
+ },
10892
+ getOptions: (data) => {
10893
+ return data.promotions.map((promotion) => ({
10894
+ label: promotion.code,
10895
+ value: promotion.code
10896
+ }));
10897
+ }
10880
10898
  });
10881
- const handleSubmit = form.handleSubmit(async (data) => {
10882
- const parsedData = parseValues(data);
10883
- await mutateAsync(
10899
+ const add = async (value) => {
10900
+ if (!value) {
10901
+ return;
10902
+ }
10903
+ addPromotions(
10884
10904
  {
10885
- metadata: parsedData
10905
+ promo_codes: [value]
10886
10906
  },
10887
10907
  {
10888
- onSuccess: () => {
10889
- ui.toast.success("Metadata updated");
10890
- handleSuccess();
10908
+ onError: (e) => {
10909
+ ui.toast.error(e.message);
10910
+ comboboxData.onSearchValueChange("");
10911
+ setComboboxValue("");
10891
10912
  },
10892
- onError: (error) => {
10893
- ui.toast.error(error.message);
10913
+ onSuccess: () => {
10914
+ comboboxData.onSearchValueChange("");
10915
+ setComboboxValue("");
10894
10916
  }
10895
10917
  }
10896
10918
  );
10897
- });
10898
- const { fields, insert, remove } = reactHookForm.useFieldArray({
10899
- control: form.control,
10900
- name: "metadata"
10901
- });
10902
- function deleteRow(index) {
10903
- remove(index);
10904
- if (fields.length === 1) {
10905
- insert(0, {
10906
- key: "",
10907
- value: "",
10908
- disabled: false
10909
- });
10919
+ };
10920
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10921
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10922
+ const onSubmit = async () => {
10923
+ setIsSubmitting(true);
10924
+ let requestSucceeded = false;
10925
+ await requestOrderEdit(void 0, {
10926
+ onError: (e) => {
10927
+ ui.toast.error(e.message);
10928
+ },
10929
+ onSuccess: () => {
10930
+ requestSucceeded = true;
10931
+ }
10932
+ });
10933
+ if (!requestSucceeded) {
10934
+ setIsSubmitting(false);
10935
+ return;
10910
10936
  }
10911
- }
10912
- function insertRow(index, position) {
10913
- insert(index + (position === "above" ? 0 : 1), {
10914
- key: "",
10915
- value: "",
10916
- disabled: false
10937
+ await confirmOrderEdit(void 0, {
10938
+ onError: (e) => {
10939
+ ui.toast.error(e.message);
10940
+ },
10941
+ onSuccess: () => {
10942
+ handleSuccess();
10943
+ },
10944
+ onSettled: () => {
10945
+ setIsSubmitting(false);
10946
+ }
10917
10947
  });
10918
- }
10919
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10920
- KeyboundForm,
10921
- {
10922
- onSubmit: handleSubmit,
10923
- className: "flex flex-1 flex-col overflow-hidden",
10924
- children: [
10925
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10926
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10927
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10928
- /* @__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" }) }),
10929
- /* @__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" }) })
10930
- ] }),
10931
- fields.map((field, index) => {
10932
- const isDisabled = field.disabled || false;
10933
- let placeholder = "-";
10934
- if (typeof field.value === "object") {
10935
- placeholder = "{ ... }";
10936
- }
10937
- if (Array.isArray(field.value)) {
10938
- placeholder = "[ ... ]";
10939
- }
10940
- return /* @__PURE__ */ jsxRuntime.jsx(
10941
- ConditionalTooltip,
10942
- {
10943
- showTooltip: isDisabled,
10944
- content: "This row is disabled because it contains non-primitive data.",
10945
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10946
- /* @__PURE__ */ jsxRuntime.jsxs(
10947
- "div",
10948
- {
10949
- className: ui.clx("grid grid-cols-2 divide-x", {
10950
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10951
- }),
10952
- children: [
10953
- /* @__PURE__ */ jsxRuntime.jsx(
10954
- Form$2.Field,
10955
- {
10956
- control: form.control,
10957
- name: `metadata.${index}.key`,
10958
- render: ({ field: field2 }) => {
10959
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10960
- GridInput,
10961
- {
10962
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10963
- ...field2,
10964
- disabled: isDisabled,
10965
- placeholder: "Key"
10966
- }
10967
- ) }) });
10968
- }
10969
- }
10970
- ),
10971
- /* @__PURE__ */ jsxRuntime.jsx(
10972
- Form$2.Field,
10973
- {
10974
- control: form.control,
10975
- name: `metadata.${index}.value`,
10976
- render: ({ field: { value, ...field2 } }) => {
10977
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10978
- GridInput,
10979
- {
10980
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10981
- ...field2,
10982
- value: isDisabled ? placeholder : value,
10983
- disabled: isDisabled,
10984
- placeholder: "Value"
10985
- }
10986
- ) }) });
10987
- }
10988
- }
10989
- )
10990
- ]
10991
- }
10992
- ),
10993
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10994
- /* @__PURE__ */ jsxRuntime.jsx(
10995
- ui.DropdownMenu.Trigger,
10996
- {
10997
- className: ui.clx(
10998
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10999
- {
11000
- hidden: isDisabled
11001
- }
11002
- ),
11003
- disabled: isDisabled,
11004
- asChild: true,
11005
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11006
- }
11007
- ),
11008
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11009
- /* @__PURE__ */ jsxRuntime.jsxs(
11010
- ui.DropdownMenu.Item,
11011
- {
11012
- className: "gap-x-2",
11013
- onClick: () => insertRow(index, "above"),
11014
- children: [
11015
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11016
- "Insert row above"
11017
- ]
11018
- }
11019
- ),
11020
- /* @__PURE__ */ jsxRuntime.jsxs(
11021
- ui.DropdownMenu.Item,
11022
- {
11023
- className: "gap-x-2",
11024
- onClick: () => insertRow(index, "below"),
11025
- children: [
11026
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11027
- "Insert row below"
11028
- ]
11029
- }
11030
- ),
11031
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11032
- /* @__PURE__ */ jsxRuntime.jsxs(
11033
- ui.DropdownMenu.Item,
11034
- {
11035
- className: "gap-x-2",
11036
- onClick: () => deleteRow(index),
11037
- children: [
11038
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11039
- "Delete row"
11040
- ]
11041
- }
11042
- )
11043
- ] })
11044
- ] })
11045
- ] })
11046
- },
11047
- field.id
11048
- );
11049
- })
11050
- ] }),
11051
- 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." })
11052
- ] }),
11053
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11054
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11056
- ] }) })
11057
- ]
11058
- }
11059
- ) });
11060
- };
11061
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11062
- return /* @__PURE__ */ jsxRuntime.jsx(
11063
- "input",
11064
- {
11065
- ref,
11066
- ...props,
11067
- autoComplete: "off",
11068
- className: ui.clx(
11069
- "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",
11070
- className
11071
- )
11072
- }
11073
- );
11074
- });
11075
- GridInput.displayName = "MetadataForm.GridInput";
11076
- const PlaceholderInner = () => {
11077
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11078
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11079
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11080
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11081
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11082
- ] }) })
11083
- ] });
11084
- };
11085
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11086
- function getDefaultValues(metadata) {
11087
- if (!metadata || !Object.keys(metadata).length) {
11088
- return [
11089
- {
11090
- key: "",
11091
- value: "",
11092
- disabled: false
11093
- }
11094
- ];
11095
- }
11096
- return Object.entries(metadata).map(([key, value]) => {
11097
- if (!EDITABLE_TYPES.includes(typeof value)) {
11098
- return {
11099
- key,
11100
- value,
11101
- disabled: true
11102
- };
11103
- }
11104
- let stringValue = value;
11105
- if (typeof value !== "string") {
11106
- stringValue = JSON.stringify(value);
11107
- }
11108
- return {
11109
- key,
11110
- value: stringValue,
11111
- original_key: key
11112
- };
11113
- });
11114
- }
11115
- function parseValues(values) {
11116
- const metadata = values.metadata;
11117
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11118
- if (isEmpty) {
11119
- return null;
11120
- }
11121
- const update = {};
11122
- metadata.forEach((field) => {
11123
- let key = field.key;
11124
- let value = field.value;
11125
- const disabled = field.disabled;
11126
- if (!key || !value) {
11127
- return;
11128
- }
11129
- if (disabled) {
11130
- update[key] = value;
11131
- return;
11132
- }
11133
- key = key.trim();
11134
- value = value.trim();
11135
- if (value === "true") {
11136
- update[key] = true;
11137
- } else if (value === "false") {
11138
- update[key] = false;
11139
- } else {
11140
- const parsedNumber = parseFloat(value);
11141
- if (!isNaN(parsedNumber)) {
11142
- update[key] = parsedNumber;
11143
- } else {
11144
- update[key] = value;
11145
- }
11146
- }
11147
- });
11148
- return update;
11149
- }
11150
- function getHasUneditableRows(metadata) {
11151
- if (!metadata) {
11152
- return false;
11153
- }
11154
- return Object.values(metadata).some(
11155
- (value) => !EDITABLE_TYPES.includes(typeof value)
11156
- );
11157
- }
11158
- const PROMOTION_QUERY_KEY = "promotions";
11159
- const promotionsQueryKeys = {
11160
- list: (query2) => [
11161
- PROMOTION_QUERY_KEY,
11162
- query2 ? query2 : void 0
11163
- ],
11164
- detail: (id, query2) => [
11165
- PROMOTION_QUERY_KEY,
11166
- id,
11167
- query2 ? query2 : void 0
11168
- ]
11169
- };
11170
- const usePromotions = (query2, options) => {
11171
- const { data, ...rest } = reactQuery.useQuery({
11172
- queryKey: promotionsQueryKeys.list(query2),
11173
- queryFn: async () => sdk.admin.promotion.list(query2),
11174
- ...options
11175
- });
11176
- return { ...data, ...rest };
11177
- };
11178
- const Promotions = () => {
11179
- const { id } = reactRouterDom.useParams();
11180
- const {
11181
- order: preview,
11182
- isError: isPreviewError,
11183
- error: previewError
11184
- } = useOrderPreview(id, void 0);
11185
- useInitiateOrderEdit({ preview });
11186
- const { onCancel } = useCancelOrderEdit({ preview });
11187
- if (isPreviewError) {
11188
- throw previewError;
11189
- }
11190
- const isReady = !!preview;
11191
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11192
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11193
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11194
- ] });
11195
- };
11196
- const PromotionForm = ({ preview }) => {
11197
- const { items, shipping_methods } = preview;
11198
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11199
- const [comboboxValue, setComboboxValue] = React.useState("");
11200
- const { handleSuccess } = useRouteModal();
11201
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11202
- const promoIds = getPromotionIds(items, shipping_methods);
11203
- const { promotions, isPending, isError, error } = usePromotions(
11204
- {
11205
- id: promoIds
11206
- },
11207
- {
11208
- enabled: !!promoIds.length
11209
- }
11210
- );
11211
- const comboboxData = useComboboxData({
11212
- queryKey: ["promotions", "combobox", promoIds],
11213
- queryFn: async (params) => {
11214
- return await sdk.admin.promotion.list({
11215
- ...params,
11216
- id: {
11217
- $nin: promoIds
11218
- }
11219
- });
11220
- },
11221
- getOptions: (data) => {
11222
- return data.promotions.map((promotion) => ({
11223
- label: promotion.code,
11224
- value: promotion.code
11225
- }));
11226
- }
11227
- });
11228
- const add = async (value) => {
11229
- if (!value) {
11230
- return;
11231
- }
11232
- addPromotions(
11233
- {
11234
- promo_codes: [value]
11235
- },
11236
- {
11237
- onError: (e) => {
11238
- ui.toast.error(e.message);
11239
- comboboxData.onSearchValueChange("");
11240
- setComboboxValue("");
11241
- },
11242
- onSuccess: () => {
11243
- comboboxData.onSearchValueChange("");
11244
- setComboboxValue("");
11245
- }
11246
- }
11247
- );
11248
- };
11249
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11250
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11251
- const onSubmit = async () => {
11252
- setIsSubmitting(true);
11253
- let requestSucceeded = false;
11254
- await requestOrderEdit(void 0, {
11255
- onError: (e) => {
11256
- ui.toast.error(e.message);
11257
- },
11258
- onSuccess: () => {
11259
- requestSucceeded = true;
11260
- }
11261
- });
11262
- if (!requestSucceeded) {
11263
- setIsSubmitting(false);
11264
- return;
11265
- }
11266
- await confirmOrderEdit(void 0, {
11267
- onError: (e) => {
11268
- ui.toast.error(e.message);
11269
- },
11270
- onSuccess: () => {
11271
- handleSuccess();
11272
- },
11273
- onSettled: () => {
11274
- setIsSubmitting(false);
11275
- }
11276
- });
11277
- };
11278
- if (isError) {
11279
- throw error;
10948
+ };
10949
+ if (isError) {
10950
+ throw error;
11280
10951
  }
11281
10952
  return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11282
10953
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
@@ -11460,7 +11131,7 @@ const SalesChannelForm = ({ order }) => {
11460
11131
  defaultValues: {
11461
11132
  sales_channel_id: order.sales_channel_id || ""
11462
11133
  },
11463
- resolver: zod.zodResolver(schema$3)
11134
+ resolver: zod.zodResolver(schema$2)
11464
11135
  });
11465
11136
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11466
11137
  const { handleSuccess } = useRouteModal();
@@ -11535,7 +11206,7 @@ const SalesChannelField = ({ control, order }) => {
11535
11206
  }
11536
11207
  );
11537
11208
  };
11538
- const schema$3 = objectType({
11209
+ const schema$2 = objectType({
11539
11210
  sales_channel_id: stringType().min(1)
11540
11211
  });
11541
11212
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
@@ -12377,7 +12048,7 @@ const ShippingAddressForm = ({ order }) => {
12377
12048
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12378
12049
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12379
12050
  },
12380
- resolver: zod.zodResolver(schema$2)
12051
+ resolver: zod.zodResolver(schema$1)
12381
12052
  });
12382
12053
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12383
12054
  const { handleSuccess } = useRouteModal();
@@ -12547,7 +12218,7 @@ const ShippingAddressForm = ({ order }) => {
12547
12218
  }
12548
12219
  ) });
12549
12220
  };
12550
- const schema$2 = addressSchema;
12221
+ const schema$1 = addressSchema;
12551
12222
  const TransferOwnership = () => {
12552
12223
  const { id } = reactRouterDom.useParams();
12553
12224
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12571,7 +12242,7 @@ const TransferOwnershipForm = ({ order }) => {
12571
12242
  defaultValues: {
12572
12243
  customer_id: order.customer_id || ""
12573
12244
  },
12574
- resolver: zod.zodResolver(schema$1)
12245
+ resolver: zod.zodResolver(schema)
12575
12246
  });
12576
12247
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12577
12248
  const { handleSuccess } = useRouteModal();
@@ -13019,32 +12690,361 @@ const Illustration = () => {
13019
12690
  ] })
13020
12691
  ]
13021
12692
  }
13022
- );
12693
+ );
12694
+ };
12695
+ const schema = objectType({
12696
+ customer_id: stringType().min(1)
12697
+ });
12698
+ const InlineTip = React.forwardRef(
12699
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
12700
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
12701
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12702
+ "div",
12703
+ {
12704
+ ref,
12705
+ className: ui.clx(
12706
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
12707
+ className
12708
+ ),
12709
+ ...props,
12710
+ children: [
12711
+ /* @__PURE__ */ jsxRuntime.jsx(
12712
+ "div",
12713
+ {
12714
+ role: "presentation",
12715
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
12716
+ "bg-ui-tag-orange-icon": variant === "warning"
12717
+ })
12718
+ }
12719
+ ),
12720
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
12721
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
12722
+ labelValue,
12723
+ ":"
12724
+ ] }),
12725
+ " ",
12726
+ children
12727
+ ] })
12728
+ ]
12729
+ }
12730
+ );
12731
+ }
12732
+ );
12733
+ InlineTip.displayName = "InlineTip";
12734
+ const MetadataFieldSchema = objectType({
12735
+ key: stringType(),
12736
+ disabled: booleanType().optional(),
12737
+ value: anyType()
12738
+ });
12739
+ const MetadataSchema = objectType({
12740
+ metadata: arrayType(MetadataFieldSchema)
12741
+ });
12742
+ const Metadata = () => {
12743
+ const { id } = reactRouterDom.useParams();
12744
+ const { order, isPending, isError, error } = useOrder(id, {
12745
+ fields: "metadata"
12746
+ });
12747
+ if (isError) {
12748
+ throw error;
12749
+ }
12750
+ const isReady = !isPending && !!order;
12751
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12752
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12753
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
12754
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
12755
+ ] }),
12756
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
12757
+ ] });
12758
+ };
12759
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
12760
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
12761
+ const MetadataForm = ({ orderId, metadata }) => {
12762
+ const { handleSuccess } = useRouteModal();
12763
+ const hasUneditableRows = getHasUneditableRows(metadata);
12764
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
12765
+ const form = reactHookForm.useForm({
12766
+ defaultValues: {
12767
+ metadata: getDefaultValues(metadata)
12768
+ },
12769
+ resolver: zod.zodResolver(MetadataSchema)
12770
+ });
12771
+ const handleSubmit = form.handleSubmit(async (data) => {
12772
+ const parsedData = parseValues(data);
12773
+ await mutateAsync(
12774
+ {
12775
+ metadata: parsedData
12776
+ },
12777
+ {
12778
+ onSuccess: () => {
12779
+ ui.toast.success("Metadata updated");
12780
+ handleSuccess();
12781
+ },
12782
+ onError: (error) => {
12783
+ ui.toast.error(error.message);
12784
+ }
12785
+ }
12786
+ );
12787
+ });
12788
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
12789
+ control: form.control,
12790
+ name: "metadata"
12791
+ });
12792
+ function deleteRow(index) {
12793
+ remove(index);
12794
+ if (fields.length === 1) {
12795
+ insert(0, {
12796
+ key: "",
12797
+ value: "",
12798
+ disabled: false
12799
+ });
12800
+ }
12801
+ }
12802
+ function insertRow(index, position) {
12803
+ insert(index + (position === "above" ? 0 : 1), {
12804
+ key: "",
12805
+ value: "",
12806
+ disabled: false
12807
+ });
12808
+ }
12809
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12810
+ KeyboundForm,
12811
+ {
12812
+ onSubmit: handleSubmit,
12813
+ className: "flex flex-1 flex-col overflow-hidden",
12814
+ children: [
12815
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
12816
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
12817
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
12818
+ /* @__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" }) }),
12819
+ /* @__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" }) })
12820
+ ] }),
12821
+ fields.map((field, index) => {
12822
+ const isDisabled = field.disabled || false;
12823
+ let placeholder = "-";
12824
+ if (typeof field.value === "object") {
12825
+ placeholder = "{ ... }";
12826
+ }
12827
+ if (Array.isArray(field.value)) {
12828
+ placeholder = "[ ... ]";
12829
+ }
12830
+ return /* @__PURE__ */ jsxRuntime.jsx(
12831
+ ConditionalTooltip,
12832
+ {
12833
+ showTooltip: isDisabled,
12834
+ content: "This row is disabled because it contains non-primitive data.",
12835
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
12836
+ /* @__PURE__ */ jsxRuntime.jsxs(
12837
+ "div",
12838
+ {
12839
+ className: ui.clx("grid grid-cols-2 divide-x", {
12840
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
12841
+ }),
12842
+ children: [
12843
+ /* @__PURE__ */ jsxRuntime.jsx(
12844
+ Form$2.Field,
12845
+ {
12846
+ control: form.control,
12847
+ name: `metadata.${index}.key`,
12848
+ render: ({ field: field2 }) => {
12849
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12850
+ GridInput,
12851
+ {
12852
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
12853
+ ...field2,
12854
+ disabled: isDisabled,
12855
+ placeholder: "Key"
12856
+ }
12857
+ ) }) });
12858
+ }
12859
+ }
12860
+ ),
12861
+ /* @__PURE__ */ jsxRuntime.jsx(
12862
+ Form$2.Field,
12863
+ {
12864
+ control: form.control,
12865
+ name: `metadata.${index}.value`,
12866
+ render: ({ field: { value, ...field2 } }) => {
12867
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12868
+ GridInput,
12869
+ {
12870
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
12871
+ ...field2,
12872
+ value: isDisabled ? placeholder : value,
12873
+ disabled: isDisabled,
12874
+ placeholder: "Value"
12875
+ }
12876
+ ) }) });
12877
+ }
12878
+ }
12879
+ )
12880
+ ]
12881
+ }
12882
+ ),
12883
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
12884
+ /* @__PURE__ */ jsxRuntime.jsx(
12885
+ ui.DropdownMenu.Trigger,
12886
+ {
12887
+ className: ui.clx(
12888
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
12889
+ {
12890
+ hidden: isDisabled
12891
+ }
12892
+ ),
12893
+ disabled: isDisabled,
12894
+ asChild: true,
12895
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
12896
+ }
12897
+ ),
12898
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
12899
+ /* @__PURE__ */ jsxRuntime.jsxs(
12900
+ ui.DropdownMenu.Item,
12901
+ {
12902
+ className: "gap-x-2",
12903
+ onClick: () => insertRow(index, "above"),
12904
+ children: [
12905
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
12906
+ "Insert row above"
12907
+ ]
12908
+ }
12909
+ ),
12910
+ /* @__PURE__ */ jsxRuntime.jsxs(
12911
+ ui.DropdownMenu.Item,
12912
+ {
12913
+ className: "gap-x-2",
12914
+ onClick: () => insertRow(index, "below"),
12915
+ children: [
12916
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
12917
+ "Insert row below"
12918
+ ]
12919
+ }
12920
+ ),
12921
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
12922
+ /* @__PURE__ */ jsxRuntime.jsxs(
12923
+ ui.DropdownMenu.Item,
12924
+ {
12925
+ className: "gap-x-2",
12926
+ onClick: () => deleteRow(index),
12927
+ children: [
12928
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
12929
+ "Delete row"
12930
+ ]
12931
+ }
12932
+ )
12933
+ ] })
12934
+ ] })
12935
+ ] })
12936
+ },
12937
+ field.id
12938
+ );
12939
+ })
12940
+ ] }),
12941
+ 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." })
12942
+ ] }),
12943
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12944
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12945
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12946
+ ] }) })
12947
+ ]
12948
+ }
12949
+ ) });
13023
12950
  };
13024
- const schema$1 = objectType({
13025
- customer_id: stringType().min(1)
12951
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
12952
+ return /* @__PURE__ */ jsxRuntime.jsx(
12953
+ "input",
12954
+ {
12955
+ ref,
12956
+ ...props,
12957
+ autoComplete: "off",
12958
+ className: ui.clx(
12959
+ "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",
12960
+ className
12961
+ )
12962
+ }
12963
+ );
13026
12964
  });
13027
- const CustomItems = () => {
13028
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
13029
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
13030
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
12965
+ GridInput.displayName = "MetadataForm.GridInput";
12966
+ const PlaceholderInner = () => {
12967
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
12968
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
12969
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12970
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
12971
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
12972
+ ] }) })
13031
12973
  ] });
13032
12974
  };
13033
- const CustomItemsForm = () => {
13034
- const form = reactHookForm.useForm({
13035
- resolver: zod.zodResolver(schema)
12975
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
12976
+ function getDefaultValues(metadata) {
12977
+ if (!metadata || !Object.keys(metadata).length) {
12978
+ return [
12979
+ {
12980
+ key: "",
12981
+ value: "",
12982
+ disabled: false
12983
+ }
12984
+ ];
12985
+ }
12986
+ return Object.entries(metadata).map(([key, value]) => {
12987
+ if (!EDITABLE_TYPES.includes(typeof value)) {
12988
+ return {
12989
+ key,
12990
+ value,
12991
+ disabled: true
12992
+ };
12993
+ }
12994
+ let stringValue = value;
12995
+ if (typeof value !== "string") {
12996
+ stringValue = JSON.stringify(value);
12997
+ }
12998
+ return {
12999
+ key,
13000
+ value: stringValue,
13001
+ original_key: key
13002
+ };
13036
13003
  });
13037
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
13038
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
13039
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13040
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13041
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
13042
- ] }) })
13043
- ] }) });
13044
- };
13045
- const schema = objectType({
13046
- email: stringType().email()
13047
- });
13004
+ }
13005
+ function parseValues(values) {
13006
+ const metadata = values.metadata;
13007
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
13008
+ if (isEmpty) {
13009
+ return null;
13010
+ }
13011
+ const update = {};
13012
+ metadata.forEach((field) => {
13013
+ let key = field.key;
13014
+ let value = field.value;
13015
+ const disabled = field.disabled;
13016
+ if (!key || !value) {
13017
+ return;
13018
+ }
13019
+ if (disabled) {
13020
+ update[key] = value;
13021
+ return;
13022
+ }
13023
+ key = key.trim();
13024
+ value = value.trim();
13025
+ if (value === "true") {
13026
+ update[key] = true;
13027
+ } else if (value === "false") {
13028
+ update[key] = false;
13029
+ } else {
13030
+ const parsedNumber = parseFloat(value);
13031
+ if (!isNaN(parsedNumber)) {
13032
+ update[key] = parsedNumber;
13033
+ } else {
13034
+ update[key] = value;
13035
+ }
13036
+ }
13037
+ });
13038
+ return update;
13039
+ }
13040
+ function getHasUneditableRows(metadata) {
13041
+ if (!metadata) {
13042
+ return false;
13043
+ }
13044
+ return Object.values(metadata).some(
13045
+ (value) => !EDITABLE_TYPES.includes(typeof value)
13046
+ );
13047
+ }
13048
13048
  const widgetModule = { widgets: [] };
13049
13049
  const routeModule = {
13050
13050
  routes: [
@@ -13069,6 +13069,10 @@ const routeModule = {
13069
13069
  Component: BillingAddress,
13070
13070
  path: "/draft-orders/:id/billing-address"
13071
13071
  },
13072
+ {
13073
+ Component: CustomItems,
13074
+ path: "/draft-orders/:id/custom-items"
13075
+ },
13072
13076
  {
13073
13077
  Component: Email,
13074
13078
  path: "/draft-orders/:id/email"
@@ -13077,10 +13081,6 @@ const routeModule = {
13077
13081
  Component: Items,
13078
13082
  path: "/draft-orders/:id/items"
13079
13083
  },
13080
- {
13081
- Component: Metadata,
13082
- path: "/draft-orders/:id/metadata"
13083
- },
13084
13084
  {
13085
13085
  Component: Promotions,
13086
13086
  path: "/draft-orders/:id/promotions"
@@ -13102,8 +13102,8 @@ const routeModule = {
13102
13102
  path: "/draft-orders/:id/transfer-ownership"
13103
13103
  },
13104
13104
  {
13105
- Component: CustomItems,
13106
- path: "/draft-orders/:id/custom-items"
13105
+ Component: Metadata,
13106
+ path: "/draft-orders/:id/metadata"
13107
13107
  }
13108
13108
  ]
13109
13109
  }