@medusajs/draft-order 2.11.2-preview-20251027210155 → 2.11.2-preview-20251028031854

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.
@@ -9761,6 +9761,27 @@ const BillingAddressForm = ({ order }) => {
9761
9761
  ) });
9762
9762
  };
9763
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
+ });
9764
9785
  const Email = () => {
9765
9786
  const { id } = reactRouterDom.useParams();
9766
9787
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9783,7 +9804,7 @@ const EmailForm = ({ order }) => {
9783
9804
  defaultValues: {
9784
9805
  email: order.email ?? ""
9785
9806
  },
9786
- resolver: zod.zodResolver(schema$4)
9807
+ resolver: zod.zodResolver(schema$3)
9787
9808
  });
9788
9809
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9789
9810
  const { handleSuccess } = useRouteModal();
@@ -9826,27 +9847,6 @@ const EmailForm = ({ order }) => {
9826
9847
  }
9827
9848
  ) });
9828
9849
  };
9829
- const schema$4 = objectType({
9830
- email: stringType().email()
9831
- });
9832
- const CustomItems = () => {
9833
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9834
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9835
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9836
- ] });
9837
- };
9838
- const CustomItemsForm = () => {
9839
- const form = reactHookForm.useForm({
9840
- resolver: zod.zodResolver(schema$3)
9841
- });
9842
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9843
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9844
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9845
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9846
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9847
- ] }) })
9848
- ] }) });
9849
- };
9850
9850
  const schema$3 = objectType({
9851
9851
  email: stringType().email()
9852
9852
  });
@@ -10824,478 +10824,128 @@ const customItemSchema = objectType({
10824
10824
  quantity: numberType(),
10825
10825
  unit_price: unionType([numberType(), stringType()])
10826
10826
  });
10827
- const InlineTip = React.forwardRef(
10828
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10829
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10830
- return /* @__PURE__ */ jsxRuntime.jsxs(
10831
- "div",
10832
- {
10833
- ref,
10834
- className: ui.clx(
10835
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10836
- className
10837
- ),
10838
- ...props,
10839
- children: [
10840
- /* @__PURE__ */ jsxRuntime.jsx(
10841
- "div",
10842
- {
10843
- role: "presentation",
10844
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10845
- "bg-ui-tag-orange-icon": variant === "warning"
10846
- })
10847
- }
10848
- ),
10849
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10850
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10851
- labelValue,
10852
- ":"
10853
- ] }),
10854
- " ",
10855
- children
10856
- ] })
10857
- ]
10858
- }
10859
- );
10860
- }
10861
- );
10862
- InlineTip.displayName = "InlineTip";
10863
- const MetadataFieldSchema = objectType({
10864
- key: stringType(),
10865
- disabled: booleanType().optional(),
10866
- value: anyType()
10867
- });
10868
- const MetadataSchema = objectType({
10869
- metadata: arrayType(MetadataFieldSchema)
10870
- });
10871
- const Metadata = () => {
10872
- const { id } = reactRouterDom.useParams();
10873
- const { order, isPending, isError, error } = useOrder(id, {
10874
- 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
10875
10844
  });
10876
- if (isError) {
10877
- 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;
10878
10858
  }
10879
- const isReady = !isPending && !!order;
10880
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10881
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10882
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10883
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10884
- ] }),
10885
- !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 })
10886
10863
  ] });
10887
10864
  };
10888
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10889
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10890
- 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("");
10891
10869
  const { handleSuccess } = useRouteModal();
10892
- const hasUneditableRows = getHasUneditableRows(metadata);
10893
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10894
- const form = reactHookForm.useForm({
10895
- defaultValues: {
10896
- 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
10897
10875
  },
10898
- 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
+ }
10899
10896
  });
10900
- const handleSubmit = form.handleSubmit(async (data) => {
10901
- const parsedData = parseValues(data);
10902
- await mutateAsync(
10897
+ const add = async (value) => {
10898
+ if (!value) {
10899
+ return;
10900
+ }
10901
+ addPromotions(
10903
10902
  {
10904
- metadata: parsedData
10903
+ promo_codes: [value]
10905
10904
  },
10906
10905
  {
10907
- onSuccess: () => {
10908
- ui.toast.success("Metadata updated");
10909
- handleSuccess();
10906
+ onError: (e) => {
10907
+ ui.toast.error(e.message);
10908
+ comboboxData.onSearchValueChange("");
10909
+ setComboboxValue("");
10910
10910
  },
10911
- onError: (error) => {
10912
- ui.toast.error(error.message);
10911
+ onSuccess: () => {
10912
+ comboboxData.onSearchValueChange("");
10913
+ setComboboxValue("");
10913
10914
  }
10914
10915
  }
10915
10916
  );
10916
- });
10917
- const { fields, insert, remove } = reactHookForm.useFieldArray({
10918
- control: form.control,
10919
- name: "metadata"
10920
- });
10921
- function deleteRow(index) {
10922
- remove(index);
10923
- if (fields.length === 1) {
10924
- insert(0, {
10925
- key: "",
10926
- value: "",
10927
- disabled: false
10928
- });
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;
10929
10934
  }
10930
- }
10931
- function insertRow(index, position) {
10932
- insert(index + (position === "above" ? 0 : 1), {
10933
- key: "",
10934
- value: "",
10935
- 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
+ }
10936
10945
  });
10937
- }
10938
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10939
- KeyboundForm,
10940
- {
10941
- onSubmit: handleSubmit,
10942
- className: "flex flex-1 flex-col overflow-hidden",
10943
- children: [
10944
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10945
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10946
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10947
- /* @__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" }) }),
10948
- /* @__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" }) })
10949
- ] }),
10950
- fields.map((field, index) => {
10951
- const isDisabled = field.disabled || false;
10952
- let placeholder = "-";
10953
- if (typeof field.value === "object") {
10954
- placeholder = "{ ... }";
10955
- }
10956
- if (Array.isArray(field.value)) {
10957
- placeholder = "[ ... ]";
10958
- }
10959
- return /* @__PURE__ */ jsxRuntime.jsx(
10960
- ConditionalTooltip,
10961
- {
10962
- showTooltip: isDisabled,
10963
- content: "This row is disabled because it contains non-primitive data.",
10964
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10965
- /* @__PURE__ */ jsxRuntime.jsxs(
10966
- "div",
10967
- {
10968
- className: ui.clx("grid grid-cols-2 divide-x", {
10969
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10970
- }),
10971
- children: [
10972
- /* @__PURE__ */ jsxRuntime.jsx(
10973
- Form$2.Field,
10974
- {
10975
- control: form.control,
10976
- name: `metadata.${index}.key`,
10977
- render: ({ field: field2 }) => {
10978
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10979
- GridInput,
10980
- {
10981
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10982
- ...field2,
10983
- disabled: isDisabled,
10984
- placeholder: "Key"
10985
- }
10986
- ) }) });
10987
- }
10988
- }
10989
- ),
10990
- /* @__PURE__ */ jsxRuntime.jsx(
10991
- Form$2.Field,
10992
- {
10993
- control: form.control,
10994
- name: `metadata.${index}.value`,
10995
- render: ({ field: { value, ...field2 } }) => {
10996
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10997
- GridInput,
10998
- {
10999
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11000
- ...field2,
11001
- value: isDisabled ? placeholder : value,
11002
- disabled: isDisabled,
11003
- placeholder: "Value"
11004
- }
11005
- ) }) });
11006
- }
11007
- }
11008
- )
11009
- ]
11010
- }
11011
- ),
11012
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11013
- /* @__PURE__ */ jsxRuntime.jsx(
11014
- ui.DropdownMenu.Trigger,
11015
- {
11016
- className: ui.clx(
11017
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11018
- {
11019
- hidden: isDisabled
11020
- }
11021
- ),
11022
- disabled: isDisabled,
11023
- asChild: true,
11024
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11025
- }
11026
- ),
11027
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11028
- /* @__PURE__ */ jsxRuntime.jsxs(
11029
- ui.DropdownMenu.Item,
11030
- {
11031
- className: "gap-x-2",
11032
- onClick: () => insertRow(index, "above"),
11033
- children: [
11034
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11035
- "Insert row above"
11036
- ]
11037
- }
11038
- ),
11039
- /* @__PURE__ */ jsxRuntime.jsxs(
11040
- ui.DropdownMenu.Item,
11041
- {
11042
- className: "gap-x-2",
11043
- onClick: () => insertRow(index, "below"),
11044
- children: [
11045
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11046
- "Insert row below"
11047
- ]
11048
- }
11049
- ),
11050
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11051
- /* @__PURE__ */ jsxRuntime.jsxs(
11052
- ui.DropdownMenu.Item,
11053
- {
11054
- className: "gap-x-2",
11055
- onClick: () => deleteRow(index),
11056
- children: [
11057
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11058
- "Delete row"
11059
- ]
11060
- }
11061
- )
11062
- ] })
11063
- ] })
11064
- ] })
11065
- },
11066
- field.id
11067
- );
11068
- })
11069
- ] }),
11070
- 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." })
11071
- ] }),
11072
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11073
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11074
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11075
- ] }) })
11076
- ]
11077
- }
11078
- ) });
11079
- };
11080
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11081
- return /* @__PURE__ */ jsxRuntime.jsx(
11082
- "input",
11083
- {
11084
- ref,
11085
- ...props,
11086
- autoComplete: "off",
11087
- className: ui.clx(
11088
- "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",
11089
- className
11090
- )
11091
- }
11092
- );
11093
- });
11094
- GridInput.displayName = "MetadataForm.GridInput";
11095
- const PlaceholderInner = () => {
11096
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11097
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11098
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11099
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11100
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11101
- ] }) })
11102
- ] });
11103
- };
11104
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11105
- function getDefaultValues(metadata) {
11106
- if (!metadata || !Object.keys(metadata).length) {
11107
- return [
11108
- {
11109
- key: "",
11110
- value: "",
11111
- disabled: false
11112
- }
11113
- ];
11114
- }
11115
- return Object.entries(metadata).map(([key, value]) => {
11116
- if (!EDITABLE_TYPES.includes(typeof value)) {
11117
- return {
11118
- key,
11119
- value,
11120
- disabled: true
11121
- };
11122
- }
11123
- let stringValue = value;
11124
- if (typeof value !== "string") {
11125
- stringValue = JSON.stringify(value);
11126
- }
11127
- return {
11128
- key,
11129
- value: stringValue,
11130
- original_key: key
11131
- };
11132
- });
11133
- }
11134
- function parseValues(values) {
11135
- const metadata = values.metadata;
11136
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11137
- if (isEmpty) {
11138
- return null;
11139
- }
11140
- const update = {};
11141
- metadata.forEach((field) => {
11142
- let key = field.key;
11143
- let value = field.value;
11144
- const disabled = field.disabled;
11145
- if (!key || !value) {
11146
- return;
11147
- }
11148
- if (disabled) {
11149
- update[key] = value;
11150
- return;
11151
- }
11152
- key = key.trim();
11153
- value = value.trim();
11154
- if (value === "true") {
11155
- update[key] = true;
11156
- } else if (value === "false") {
11157
- update[key] = false;
11158
- } else {
11159
- const parsedNumber = parseFloat(value);
11160
- if (!isNaN(parsedNumber)) {
11161
- update[key] = parsedNumber;
11162
- } else {
11163
- update[key] = value;
11164
- }
11165
- }
11166
- });
11167
- return update;
11168
- }
11169
- function getHasUneditableRows(metadata) {
11170
- if (!metadata) {
11171
- return false;
11172
- }
11173
- return Object.values(metadata).some(
11174
- (value) => !EDITABLE_TYPES.includes(typeof value)
11175
- );
11176
- }
11177
- const PROMOTION_QUERY_KEY = "promotions";
11178
- const promotionsQueryKeys = {
11179
- list: (query2) => [
11180
- PROMOTION_QUERY_KEY,
11181
- query2 ? query2 : void 0
11182
- ],
11183
- detail: (id, query2) => [
11184
- PROMOTION_QUERY_KEY,
11185
- id,
11186
- query2 ? query2 : void 0
11187
- ]
11188
- };
11189
- const usePromotions = (query2, options) => {
11190
- const { data, ...rest } = reactQuery.useQuery({
11191
- queryKey: promotionsQueryKeys.list(query2),
11192
- queryFn: async () => sdk.admin.promotion.list(query2),
11193
- ...options
11194
- });
11195
- return { ...data, ...rest };
11196
- };
11197
- const Promotions = () => {
11198
- const { id } = reactRouterDom.useParams();
11199
- const {
11200
- order: preview,
11201
- isError: isPreviewError,
11202
- error: previewError
11203
- } = useOrderPreview(id, void 0);
11204
- useInitiateOrderEdit({ preview });
11205
- const { onCancel } = useCancelOrderEdit({ preview });
11206
- if (isPreviewError) {
11207
- throw previewError;
11208
- }
11209
- const isReady = !!preview;
11210
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11211
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11212
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11213
- ] });
11214
- };
11215
- const PromotionForm = ({ preview }) => {
11216
- const { items, shipping_methods } = preview;
11217
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11218
- const [comboboxValue, setComboboxValue] = React.useState("");
11219
- const { handleSuccess } = useRouteModal();
11220
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11221
- const promoIds = getPromotionIds(items, shipping_methods);
11222
- const { promotions, isPending, isError, error } = usePromotions(
11223
- {
11224
- id: promoIds
11225
- },
11226
- {
11227
- enabled: !!promoIds.length
11228
- }
11229
- );
11230
- const comboboxData = useComboboxData({
11231
- queryKey: ["promotions", "combobox", promoIds],
11232
- queryFn: async (params) => {
11233
- return await sdk.admin.promotion.list({
11234
- ...params,
11235
- id: {
11236
- $nin: promoIds
11237
- }
11238
- });
11239
- },
11240
- getOptions: (data) => {
11241
- return data.promotions.map((promotion) => ({
11242
- label: promotion.code,
11243
- value: promotion.code
11244
- }));
11245
- }
11246
- });
11247
- const add = async (value) => {
11248
- if (!value) {
11249
- return;
11250
- }
11251
- addPromotions(
11252
- {
11253
- promo_codes: [value]
11254
- },
11255
- {
11256
- onError: (e) => {
11257
- ui.toast.error(e.message);
11258
- comboboxData.onSearchValueChange("");
11259
- setComboboxValue("");
11260
- },
11261
- onSuccess: () => {
11262
- comboboxData.onSearchValueChange("");
11263
- setComboboxValue("");
11264
- }
11265
- }
11266
- );
11267
- };
11268
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11269
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11270
- const onSubmit = async () => {
11271
- setIsSubmitting(true);
11272
- let requestSucceeded = false;
11273
- await requestOrderEdit(void 0, {
11274
- onError: (e) => {
11275
- ui.toast.error(e.message);
11276
- },
11277
- onSuccess: () => {
11278
- requestSucceeded = true;
11279
- }
11280
- });
11281
- if (!requestSucceeded) {
11282
- setIsSubmitting(false);
11283
- return;
11284
- }
11285
- await confirmOrderEdit(void 0, {
11286
- onError: (e) => {
11287
- ui.toast.error(e.message);
11288
- },
11289
- onSuccess: () => {
11290
- handleSuccess();
11291
- },
11292
- onSettled: () => {
11293
- setIsSubmitting(false);
11294
- }
11295
- });
11296
- };
11297
- if (isError) {
11298
- throw error;
10946
+ };
10947
+ if (isError) {
10948
+ throw error;
11299
10949
  }
11300
10950
  return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11301
10951
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
@@ -11447,116 +11097,360 @@ function getPromotionIds(items, shippingMethods) {
11447
11097
  promotionIds.add(adjustment.promotion_id);
11448
11098
  }
11449
11099
  }
11450
- }
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
+ );
11451
11137
  }
11452
- return Array.from(promotionIds);
11453
- }
11454
- const SalesChannel = () => {
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 = () => {
11455
11149
  const { id } = reactRouterDom.useParams();
11456
- const { draft_order, isPending, isError, error } = useDraftOrder(
11457
- id,
11458
- {
11459
- fields: "+sales_channel_id"
11460
- },
11461
- {
11462
- enabled: !!id
11463
- }
11464
- );
11150
+ const { order, isPending, isError, error } = useOrder(id, {
11151
+ fields: "metadata"
11152
+ });
11465
11153
  if (isError) {
11466
11154
  throw error;
11467
11155
  }
11468
- const ISrEADY = !!draft_order && !isPending;
11156
+ const isReady = !isPending && !!order;
11469
11157
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11470
11158
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11471
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11472
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
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." }) })
11473
11161
  ] }),
11474
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11162
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11475
11163
  ] });
11476
11164
  };
11477
- const SalesChannelForm = ({ order }) => {
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);
11478
11171
  const form = reactHookForm.useForm({
11479
11172
  defaultValues: {
11480
- sales_channel_id: order.sales_channel_id || ""
11173
+ metadata: getDefaultValues(metadata)
11481
11174
  },
11482
- resolver: zod.zodResolver(schema$2)
11175
+ resolver: zod.zodResolver(MetadataSchema)
11483
11176
  });
11484
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11485
- const { handleSuccess } = useRouteModal();
11486
- const onSubmit = form.handleSubmit(async (data) => {
11177
+ const handleSubmit = form.handleSubmit(async (data) => {
11178
+ const parsedData = parseValues(data);
11487
11179
  await mutateAsync(
11488
11180
  {
11489
- sales_channel_id: data.sales_channel_id
11181
+ metadata: parsedData
11490
11182
  },
11491
11183
  {
11492
- onSuccess: () => {
11493
- ui.toast.success("Sales channel updated");
11494
- handleSuccess();
11495
- },
11496
- onError: (error) => {
11497
- ui.toast.error(error.message);
11498
- }
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" }) })
11226
+ ] }),
11227
+ fields.map((field, index) => {
11228
+ const isDisabled = field.disabled || false;
11229
+ let placeholder = "-";
11230
+ if (typeof field.value === "object") {
11231
+ placeholder = "{ ... }";
11232
+ }
11233
+ if (Array.isArray(field.value)) {
11234
+ placeholder = "[ ... ]";
11235
+ }
11236
+ return /* @__PURE__ */ jsxRuntime.jsx(
11237
+ ConditionalTooltip,
11238
+ {
11239
+ showTooltip: isDisabled,
11240
+ content: "This row is disabled because it contains non-primitive data.",
11241
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11242
+ /* @__PURE__ */ jsxRuntime.jsxs(
11243
+ "div",
11244
+ {
11245
+ className: ui.clx("grid grid-cols-2 divide-x", {
11246
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11247
+ }),
11248
+ children: [
11249
+ /* @__PURE__ */ jsxRuntime.jsx(
11250
+ Form$2.Field,
11251
+ {
11252
+ control: form.control,
11253
+ name: `metadata.${index}.key`,
11254
+ render: ({ field: field2 }) => {
11255
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11256
+ GridInput,
11257
+ {
11258
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11259
+ ...field2,
11260
+ disabled: isDisabled,
11261
+ placeholder: "Key"
11262
+ }
11263
+ ) }) });
11264
+ }
11265
+ }
11266
+ ),
11267
+ /* @__PURE__ */ jsxRuntime.jsx(
11268
+ Form$2.Field,
11269
+ {
11270
+ control: form.control,
11271
+ name: `metadata.${index}.value`,
11272
+ render: ({ field: { value, ...field2 } }) => {
11273
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11274
+ GridInput,
11275
+ {
11276
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11277
+ ...field2,
11278
+ value: isDisabled ? placeholder : value,
11279
+ disabled: isDisabled,
11280
+ placeholder: "Value"
11281
+ }
11282
+ ) }) });
11283
+ }
11284
+ }
11285
+ )
11286
+ ]
11287
+ }
11288
+ ),
11289
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11290
+ /* @__PURE__ */ jsxRuntime.jsx(
11291
+ ui.DropdownMenu.Trigger,
11292
+ {
11293
+ className: ui.clx(
11294
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11295
+ {
11296
+ hidden: isDisabled
11297
+ }
11298
+ ),
11299
+ disabled: isDisabled,
11300
+ asChild: true,
11301
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11302
+ }
11303
+ ),
11304
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11305
+ /* @__PURE__ */ jsxRuntime.jsxs(
11306
+ ui.DropdownMenu.Item,
11307
+ {
11308
+ className: "gap-x-2",
11309
+ onClick: () => insertRow(index, "above"),
11310
+ children: [
11311
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11312
+ "Insert row above"
11313
+ ]
11314
+ }
11315
+ ),
11316
+ /* @__PURE__ */ jsxRuntime.jsxs(
11317
+ ui.DropdownMenu.Item,
11318
+ {
11319
+ className: "gap-x-2",
11320
+ onClick: () => insertRow(index, "below"),
11321
+ children: [
11322
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11323
+ "Insert row below"
11324
+ ]
11325
+ }
11326
+ ),
11327
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11328
+ /* @__PURE__ */ jsxRuntime.jsxs(
11329
+ ui.DropdownMenu.Item,
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." })
11348
+ ] }),
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
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" })
11378
+ ] }) })
11379
+ ] });
11380
+ };
11381
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11382
+ function getDefaultValues(metadata) {
11383
+ if (!metadata || !Object.keys(metadata).length) {
11384
+ return [
11385
+ {
11386
+ key: "",
11387
+ value: "",
11388
+ disabled: false
11499
11389
  }
11500
- );
11501
- });
11502
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11503
- KeyboundForm,
11504
- {
11505
- className: "flex flex-1 flex-col overflow-hidden",
11506
- onSubmit,
11507
- children: [
11508
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11509
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11510
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11511
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11512
- ] }) })
11513
- ]
11390
+ ];
11391
+ }
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
+ };
11514
11399
  }
11515
- ) });
11516
- };
11517
- const SalesChannelField = ({ control, order }) => {
11518
- const salesChannels = useComboboxData({
11519
- queryFn: async (params) => {
11520
- return await sdk.admin.salesChannel.list(params);
11521
- },
11522
- queryKey: ["sales-channels"],
11523
- getOptions: (data) => {
11524
- return data.sales_channels.map((salesChannel) => ({
11525
- label: salesChannel.name,
11526
- value: salesChannel.id
11527
- }));
11528
- },
11529
- defaultValue: order.sales_channel_id || void 0
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
+ };
11530
11409
  });
11531
- return /* @__PURE__ */ jsxRuntime.jsx(
11532
- Form$2.Field,
11533
- {
11534
- control,
11535
- name: "sales_channel_id",
11536
- render: ({ field }) => {
11537
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11538
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11539
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11540
- Combobox,
11541
- {
11542
- options: salesChannels.options,
11543
- fetchNextPage: salesChannels.fetchNextPage,
11544
- isFetchingNextPage: salesChannels.isFetchingNextPage,
11545
- searchValue: salesChannels.searchValue,
11546
- onSearchValueChange: salesChannels.onSearchValueChange,
11547
- placeholder: "Select sales channel",
11548
- ...field
11549
- }
11550
- ) }),
11551
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11552
- ] });
11410
+ }
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;
11416
+ }
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;
11424
+ }
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;
11553
11441
  }
11554
11442
  }
11443
+ });
11444
+ return update;
11445
+ }
11446
+ function getHasUneditableRows(metadata) {
11447
+ if (!metadata) {
11448
+ return false;
11449
+ }
11450
+ return Object.values(metadata).some(
11451
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11555
11452
  );
11556
- };
11557
- const schema$2 = objectType({
11558
- sales_channel_id: stringType().min(1)
11559
- });
11453
+ }
11560
11454
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11561
11455
  const Shipping = () => {
11562
11456
  var _a;
@@ -12396,7 +12290,7 @@ const ShippingAddressForm = ({ order }) => {
12396
12290
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12397
12291
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12398
12292
  },
12399
- resolver: zod.zodResolver(schema$1)
12293
+ resolver: zod.zodResolver(schema$2)
12400
12294
  });
12401
12295
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12402
12296
  const { handleSuccess } = useRouteModal();
@@ -12566,7 +12460,7 @@ const ShippingAddressForm = ({ order }) => {
12566
12460
  }
12567
12461
  ) });
12568
12462
  };
12569
- const schema$1 = addressSchema;
12463
+ const schema$2 = addressSchema;
12570
12464
  const TransferOwnership = () => {
12571
12465
  const { id } = reactRouterDom.useParams();
12572
12466
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12590,7 +12484,7 @@ const TransferOwnershipForm = ({ order }) => {
12590
12484
  defaultValues: {
12591
12485
  customer_id: order.customer_id || ""
12592
12486
  },
12593
- resolver: zod.zodResolver(schema)
12487
+ resolver: zod.zodResolver(schema$1)
12594
12488
  });
12595
12489
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12596
12490
  const { handleSuccess } = useRouteModal();
@@ -13040,9 +12934,115 @@ const Illustration = () => {
13040
12934
  }
13041
12935
  );
13042
12936
  };
13043
- const schema = objectType({
12937
+ const schema$1 = objectType({
13044
12938
  customer_id: stringType().min(1)
13045
12939
  });
12940
+ const SalesChannel = () => {
12941
+ const { id } = reactRouterDom.useParams();
12942
+ const { draft_order, isPending, isError, error } = useDraftOrder(
12943
+ id,
12944
+ {
12945
+ fields: "+sales_channel_id"
12946
+ },
12947
+ {
12948
+ enabled: !!id
12949
+ }
12950
+ );
12951
+ if (isError) {
12952
+ throw error;
12953
+ }
12954
+ const ISrEADY = !!draft_order && !isPending;
12955
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12956
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12957
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
12958
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12959
+ ] }),
12960
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
12961
+ ] });
12962
+ };
12963
+ const SalesChannelForm = ({ order }) => {
12964
+ const form = reactHookForm.useForm({
12965
+ defaultValues: {
12966
+ sales_channel_id: order.sales_channel_id || ""
12967
+ },
12968
+ resolver: zod.zodResolver(schema)
12969
+ });
12970
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12971
+ const { handleSuccess } = useRouteModal();
12972
+ const onSubmit = form.handleSubmit(async (data) => {
12973
+ await mutateAsync(
12974
+ {
12975
+ sales_channel_id: data.sales_channel_id
12976
+ },
12977
+ {
12978
+ onSuccess: () => {
12979
+ ui.toast.success("Sales channel updated");
12980
+ handleSuccess();
12981
+ },
12982
+ onError: (error) => {
12983
+ ui.toast.error(error.message);
12984
+ }
12985
+ }
12986
+ );
12987
+ });
12988
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12989
+ KeyboundForm,
12990
+ {
12991
+ className: "flex flex-1 flex-col overflow-hidden",
12992
+ onSubmit,
12993
+ children: [
12994
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
12995
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12996
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12997
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12998
+ ] }) })
12999
+ ]
13000
+ }
13001
+ ) });
13002
+ };
13003
+ const SalesChannelField = ({ control, order }) => {
13004
+ const salesChannels = useComboboxData({
13005
+ queryFn: async (params) => {
13006
+ return await sdk.admin.salesChannel.list(params);
13007
+ },
13008
+ queryKey: ["sales-channels"],
13009
+ getOptions: (data) => {
13010
+ return data.sales_channels.map((salesChannel) => ({
13011
+ label: salesChannel.name,
13012
+ value: salesChannel.id
13013
+ }));
13014
+ },
13015
+ defaultValue: order.sales_channel_id || void 0
13016
+ });
13017
+ return /* @__PURE__ */ jsxRuntime.jsx(
13018
+ Form$2.Field,
13019
+ {
13020
+ control,
13021
+ name: "sales_channel_id",
13022
+ render: ({ field }) => {
13023
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13024
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
13025
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13026
+ Combobox,
13027
+ {
13028
+ options: salesChannels.options,
13029
+ fetchNextPage: salesChannels.fetchNextPage,
13030
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
13031
+ searchValue: salesChannels.searchValue,
13032
+ onSearchValueChange: salesChannels.onSearchValueChange,
13033
+ placeholder: "Select sales channel",
13034
+ ...field
13035
+ }
13036
+ ) }),
13037
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13038
+ ] });
13039
+ }
13040
+ }
13041
+ );
13042
+ };
13043
+ const schema = objectType({
13044
+ sales_channel_id: stringType().min(1)
13045
+ });
13046
13046
  const widgetModule = { widgets: [] };
13047
13047
  const routeModule = {
13048
13048
  routes: [
@@ -13067,29 +13067,25 @@ const routeModule = {
13067
13067
  Component: BillingAddress,
13068
13068
  path: "/draft-orders/:id/billing-address"
13069
13069
  },
13070
- {
13071
- Component: Email,
13072
- path: "/draft-orders/:id/email"
13073
- },
13074
13070
  {
13075
13071
  Component: CustomItems,
13076
13072
  path: "/draft-orders/:id/custom-items"
13077
13073
  },
13078
13074
  {
13079
- Component: Items,
13080
- path: "/draft-orders/:id/items"
13075
+ Component: Email,
13076
+ path: "/draft-orders/:id/email"
13081
13077
  },
13082
13078
  {
13083
- Component: Metadata,
13084
- path: "/draft-orders/:id/metadata"
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13085
13081
  },
13086
13082
  {
13087
13083
  Component: Promotions,
13088
13084
  path: "/draft-orders/:id/promotions"
13089
13085
  },
13090
13086
  {
13091
- Component: SalesChannel,
13092
- path: "/draft-orders/:id/sales-channel"
13087
+ Component: Metadata,
13088
+ path: "/draft-orders/:id/metadata"
13093
13089
  },
13094
13090
  {
13095
13091
  Component: Shipping,
@@ -13102,6 +13098,10 @@ const routeModule = {
13102
13098
  {
13103
13099
  Component: TransferOwnership,
13104
13100
  path: "/draft-orders/:id/transfer-ownership"
13101
+ },
13102
+ {
13103
+ Component: SalesChannel,
13104
+ path: "/draft-orders/:id/sales-channel"
13105
13105
  }
13106
13106
  ]
13107
13107
  }