@medusajs/draft-order 2.10.4-preview-20250923210152 → 2.10.4-preview-20250924031247

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.
@@ -4,7 +4,7 @@ import { Tooltip, DropdownMenu, clx, IconButton, useDataTable, DataTable as Data
4
4
  import { useQuery, useQueryClient, useMutation, keepPreviousData, useInfiniteQuery } from "@tanstack/react-query";
5
5
  import React, { useState, useCallback, useMemo, Fragment, createContext, forwardRef, useId, useContext, useTransition, useRef, useImperativeHandle, useDeferredValue, useEffect, Suspense } from "react";
6
6
  import { useSearchParams, Link, useNavigate, Outlet, useBlocker, useLocation, useParams } from "react-router-dom";
7
- import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, Minus, PencilSquare, EllipsisVertical, ArrowUpMini, ArrowDownMini } from "@medusajs/icons";
7
+ import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, EllipsisVertical, ArrowUpMini, ArrowDownMini, Minus, PencilSquare } from "@medusajs/icons";
8
8
  import Medusa from "@medusajs/js-sdk";
9
9
  import { format, formatDistance, sub, subDays, subMonths } from "date-fns";
10
10
  import { enUS } from "date-fns/locale";
@@ -9757,6 +9757,27 @@ const BillingAddressForm = ({ order }) => {
9757
9757
  ) });
9758
9758
  };
9759
9759
  const schema$5 = addressSchema;
9760
+ const CustomItems = () => {
9761
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9762
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9763
+ /* @__PURE__ */ jsx(CustomItemsForm, {})
9764
+ ] });
9765
+ };
9766
+ const CustomItemsForm = () => {
9767
+ const form = useForm({
9768
+ resolver: zodResolver(schema$4)
9769
+ });
9770
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9771
+ /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9772
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9773
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9774
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9775
+ ] }) })
9776
+ ] }) });
9777
+ };
9778
+ const schema$4 = objectType({
9779
+ email: stringType().email()
9780
+ });
9760
9781
  const Email = () => {
9761
9782
  const { id } = useParams();
9762
9783
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9779,7 +9800,7 @@ const EmailForm = ({ order }) => {
9779
9800
  defaultValues: {
9780
9801
  email: order.email ?? ""
9781
9802
  },
9782
- resolver: zodResolver(schema$4)
9803
+ resolver: zodResolver(schema$3)
9783
9804
  });
9784
9805
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9785
9806
  const { handleSuccess } = useRouteModal();
@@ -9822,223 +9843,573 @@ const EmailForm = ({ order }) => {
9822
9843
  }
9823
9844
  ) });
9824
9845
  };
9825
- const schema$4 = objectType({
9846
+ const schema$3 = objectType({
9826
9847
  email: stringType().email()
9827
9848
  });
9828
- const NumberInput = forwardRef(
9829
- ({
9830
- value,
9831
- onChange,
9832
- size = "base",
9833
- min = 0,
9834
- max = 100,
9835
- step = 1,
9836
- className,
9837
- disabled,
9838
- ...props
9839
- }, ref) => {
9840
- const handleChange = (event) => {
9841
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9842
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9843
- onChange(newValue);
9844
- }
9845
- };
9846
- const handleIncrement = () => {
9847
- const newValue = value + step;
9848
- if (max === void 0 || newValue <= max) {
9849
- onChange(newValue);
9850
- }
9851
- };
9852
- const handleDecrement = () => {
9853
- const newValue = value - step;
9854
- if (min === void 0 || newValue >= min) {
9855
- onChange(newValue);
9856
- }
9857
- };
9849
+ const InlineTip = forwardRef(
9850
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9851
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9858
9852
  return /* @__PURE__ */ jsxs(
9859
9853
  "div",
9860
9854
  {
9855
+ ref,
9861
9856
  className: clx(
9862
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9863
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9864
- {
9865
- "h-7": size === "small",
9866
- "h-8": size === "base"
9867
- },
9857
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9868
9858
  className
9869
9859
  ),
9860
+ ...props,
9870
9861
  children: [
9871
9862
  /* @__PURE__ */ jsx(
9872
- "input",
9873
- {
9874
- ref,
9875
- type: "number",
9876
- value,
9877
- onChange: handleChange,
9878
- min,
9879
- max,
9880
- step,
9881
- className: clx(
9882
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9883
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9884
- "placeholder:text-ui-fg-muted"
9885
- ),
9886
- ...props
9887
- }
9888
- ),
9889
- /* @__PURE__ */ jsxs(
9890
- "button",
9863
+ "div",
9891
9864
  {
9892
- className: clx(
9893
- "flex items-center justify-center outline-none transition-fg",
9894
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9895
- "focus:bg-ui-bg-field-component-hover",
9896
- "hover:bg-ui-bg-field-component-hover",
9897
- {
9898
- "size-7": size === "small",
9899
- "size-8": size === "base"
9900
- }
9901
- ),
9902
- type: "button",
9903
- onClick: handleDecrement,
9904
- disabled: min !== void 0 && value <= min || disabled,
9905
- children: [
9906
- /* @__PURE__ */ jsx(Minus, {}),
9907
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9908
- ]
9865
+ role: "presentation",
9866
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9867
+ "bg-ui-tag-orange-icon": variant === "warning"
9868
+ })
9909
9869
  }
9910
9870
  ),
9911
- /* @__PURE__ */ jsxs(
9912
- "button",
9913
- {
9914
- className: clx(
9915
- "flex items-center justify-center outline-none transition-fg",
9916
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9917
- "focus:bg-ui-bg-field-hover",
9918
- "hover:bg-ui-bg-field-hover",
9919
- {
9920
- "size-7": size === "small",
9921
- "size-8": size === "base"
9922
- }
9923
- ),
9924
- type: "button",
9925
- onClick: handleIncrement,
9926
- disabled: max !== void 0 && value >= max || disabled,
9927
- children: [
9928
- /* @__PURE__ */ jsx(Plus, {}),
9929
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9930
- ]
9931
- }
9932
- )
9871
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9872
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9873
+ labelValue,
9874
+ ":"
9875
+ ] }),
9876
+ " ",
9877
+ children
9878
+ ] })
9933
9879
  ]
9934
9880
  }
9935
9881
  );
9936
9882
  }
9937
9883
  );
9938
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9939
- const productVariantsQueryKeys = {
9940
- list: (query2) => [
9941
- PRODUCT_VARIANTS_QUERY_KEY,
9942
- query2 ? query2 : void 0
9943
- ]
9944
- };
9945
- const useProductVariants = (query2, options) => {
9946
- const { data, ...rest } = useQuery({
9947
- queryKey: productVariantsQueryKeys.list(query2),
9948
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9949
- ...options
9950
- });
9951
- return { ...data, ...rest };
9952
- };
9953
- const useCancelOrderEdit = ({ preview }) => {
9954
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9955
- const onCancel = useCallback(async () => {
9956
- if (!preview) {
9957
- return true;
9958
- }
9959
- let res = false;
9960
- await cancelOrderEdit(void 0, {
9961
- onError: (e) => {
9962
- toast.error(e.message);
9963
- },
9964
- onSuccess: () => {
9965
- res = true;
9966
- }
9967
- });
9968
- return res;
9969
- }, [preview, cancelOrderEdit]);
9970
- return { onCancel };
9971
- };
9972
- let IS_REQUEST_RUNNING = false;
9973
- const useInitiateOrderEdit = ({
9974
- preview
9975
- }) => {
9976
- const navigate = useNavigate();
9977
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9978
- useEffect(() => {
9979
- async function run() {
9980
- if (IS_REQUEST_RUNNING || !preview) {
9981
- return;
9982
- }
9983
- if (preview.order_change) {
9984
- return;
9985
- }
9986
- IS_REQUEST_RUNNING = true;
9987
- await mutateAsync(void 0, {
9988
- onError: (e) => {
9989
- toast.error(e.message);
9990
- navigate(`/draft-orders/${preview.id}`, { replace: true });
9991
- return;
9992
- }
9993
- });
9994
- IS_REQUEST_RUNNING = false;
9995
- }
9996
- run();
9997
- }, [preview, navigate, mutateAsync]);
9998
- };
9999
- function convertNumber(value) {
10000
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10001
- }
10002
- const STACKED_MODAL_ID = "items_stacked_modal";
10003
- const Items = () => {
9884
+ InlineTip.displayName = "InlineTip";
9885
+ const MetadataFieldSchema = objectType({
9886
+ key: stringType(),
9887
+ disabled: booleanType().optional(),
9888
+ value: anyType()
9889
+ });
9890
+ const MetadataSchema = objectType({
9891
+ metadata: arrayType(MetadataFieldSchema)
9892
+ });
9893
+ const Metadata = () => {
10004
9894
  const { id } = useParams();
10005
- const {
10006
- order: preview,
10007
- isPending: isPreviewPending,
10008
- isError: isPreviewError,
10009
- error: previewError
10010
- } = useOrderPreview(id, void 0, {
10011
- placeholderData: keepPreviousData
9895
+ const { order, isPending, isError, error } = useOrder(id, {
9896
+ fields: "metadata"
10012
9897
  });
10013
- useInitiateOrderEdit({ preview });
10014
- const { draft_order, isPending, isError, error } = useDraftOrder(
10015
- id,
10016
- {
10017
- fields: "currency_code"
10018
- },
10019
- {
10020
- enabled: !!id
10021
- }
10022
- );
10023
- const { onCancel } = useCancelOrderEdit({ preview });
10024
9898
  if (isError) {
10025
9899
  throw error;
10026
9900
  }
10027
- if (isPreviewError) {
10028
- throw previewError;
10029
- }
10030
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10031
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10032
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10033
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10034
- ] }) });
9901
+ const isReady = !isPending && !!order;
9902
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9903
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9904
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9905
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9906
+ ] }),
9907
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9908
+ ] });
10035
9909
  };
10036
- const ItemsForm = ({ preview, currencyCode }) => {
10037
- var _a;
10038
- const [isSubmitting, setIsSubmitting] = useState(false);
10039
- const [modalContent, setModalContent] = useState(
10040
- null
10041
- );
9910
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9911
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9912
+ const MetadataForm = ({ orderId, metadata }) => {
9913
+ const { handleSuccess } = useRouteModal();
9914
+ const hasUneditableRows = getHasUneditableRows(metadata);
9915
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9916
+ const form = useForm({
9917
+ defaultValues: {
9918
+ metadata: getDefaultValues(metadata)
9919
+ },
9920
+ resolver: zodResolver(MetadataSchema)
9921
+ });
9922
+ const handleSubmit = form.handleSubmit(async (data) => {
9923
+ const parsedData = parseValues(data);
9924
+ await mutateAsync(
9925
+ {
9926
+ metadata: parsedData
9927
+ },
9928
+ {
9929
+ onSuccess: () => {
9930
+ toast.success("Metadata updated");
9931
+ handleSuccess();
9932
+ },
9933
+ onError: (error) => {
9934
+ toast.error(error.message);
9935
+ }
9936
+ }
9937
+ );
9938
+ });
9939
+ const { fields, insert, remove } = useFieldArray({
9940
+ control: form.control,
9941
+ name: "metadata"
9942
+ });
9943
+ function deleteRow(index) {
9944
+ remove(index);
9945
+ if (fields.length === 1) {
9946
+ insert(0, {
9947
+ key: "",
9948
+ value: "",
9949
+ disabled: false
9950
+ });
9951
+ }
9952
+ }
9953
+ function insertRow(index, position) {
9954
+ insert(index + (position === "above" ? 0 : 1), {
9955
+ key: "",
9956
+ value: "",
9957
+ disabled: false
9958
+ });
9959
+ }
9960
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9961
+ KeyboundForm,
9962
+ {
9963
+ onSubmit: handleSubmit,
9964
+ className: "flex flex-1 flex-col overflow-hidden",
9965
+ children: [
9966
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9967
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9968
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9969
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9970
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9971
+ ] }),
9972
+ fields.map((field, index) => {
9973
+ const isDisabled = field.disabled || false;
9974
+ let placeholder = "-";
9975
+ if (typeof field.value === "object") {
9976
+ placeholder = "{ ... }";
9977
+ }
9978
+ if (Array.isArray(field.value)) {
9979
+ placeholder = "[ ... ]";
9980
+ }
9981
+ return /* @__PURE__ */ jsx(
9982
+ ConditionalTooltip,
9983
+ {
9984
+ showTooltip: isDisabled,
9985
+ content: "This row is disabled because it contains non-primitive data.",
9986
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9987
+ /* @__PURE__ */ jsxs(
9988
+ "div",
9989
+ {
9990
+ className: clx("grid grid-cols-2 divide-x", {
9991
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9992
+ }),
9993
+ children: [
9994
+ /* @__PURE__ */ jsx(
9995
+ Form$2.Field,
9996
+ {
9997
+ control: form.control,
9998
+ name: `metadata.${index}.key`,
9999
+ render: ({ field: field2 }) => {
10000
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10001
+ GridInput,
10002
+ {
10003
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10004
+ ...field2,
10005
+ disabled: isDisabled,
10006
+ placeholder: "Key"
10007
+ }
10008
+ ) }) });
10009
+ }
10010
+ }
10011
+ ),
10012
+ /* @__PURE__ */ jsx(
10013
+ Form$2.Field,
10014
+ {
10015
+ control: form.control,
10016
+ name: `metadata.${index}.value`,
10017
+ render: ({ field: { value, ...field2 } }) => {
10018
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10019
+ GridInput,
10020
+ {
10021
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10022
+ ...field2,
10023
+ value: isDisabled ? placeholder : value,
10024
+ disabled: isDisabled,
10025
+ placeholder: "Value"
10026
+ }
10027
+ ) }) });
10028
+ }
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ ),
10034
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10035
+ /* @__PURE__ */ jsx(
10036
+ DropdownMenu.Trigger,
10037
+ {
10038
+ className: clx(
10039
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10040
+ {
10041
+ hidden: isDisabled
10042
+ }
10043
+ ),
10044
+ disabled: isDisabled,
10045
+ asChild: true,
10046
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10047
+ }
10048
+ ),
10049
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10050
+ /* @__PURE__ */ jsxs(
10051
+ DropdownMenu.Item,
10052
+ {
10053
+ className: "gap-x-2",
10054
+ onClick: () => insertRow(index, "above"),
10055
+ children: [
10056
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10057
+ "Insert row above"
10058
+ ]
10059
+ }
10060
+ ),
10061
+ /* @__PURE__ */ jsxs(
10062
+ DropdownMenu.Item,
10063
+ {
10064
+ className: "gap-x-2",
10065
+ onClick: () => insertRow(index, "below"),
10066
+ children: [
10067
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10068
+ "Insert row below"
10069
+ ]
10070
+ }
10071
+ ),
10072
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10073
+ /* @__PURE__ */ jsxs(
10074
+ DropdownMenu.Item,
10075
+ {
10076
+ className: "gap-x-2",
10077
+ onClick: () => deleteRow(index),
10078
+ children: [
10079
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10080
+ "Delete row"
10081
+ ]
10082
+ }
10083
+ )
10084
+ ] })
10085
+ ] })
10086
+ ] })
10087
+ },
10088
+ field.id
10089
+ );
10090
+ })
10091
+ ] }),
10092
+ hasUneditableRows && /* @__PURE__ */ 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." })
10093
+ ] }),
10094
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10095
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10096
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10097
+ ] }) })
10098
+ ]
10099
+ }
10100
+ ) });
10101
+ };
10102
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10103
+ return /* @__PURE__ */ jsx(
10104
+ "input",
10105
+ {
10106
+ ref,
10107
+ ...props,
10108
+ autoComplete: "off",
10109
+ className: clx(
10110
+ "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",
10111
+ className
10112
+ )
10113
+ }
10114
+ );
10115
+ });
10116
+ GridInput.displayName = "MetadataForm.GridInput";
10117
+ const PlaceholderInner = () => {
10118
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10119
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10120
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10121
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10122
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10123
+ ] }) })
10124
+ ] });
10125
+ };
10126
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10127
+ function getDefaultValues(metadata) {
10128
+ if (!metadata || !Object.keys(metadata).length) {
10129
+ return [
10130
+ {
10131
+ key: "",
10132
+ value: "",
10133
+ disabled: false
10134
+ }
10135
+ ];
10136
+ }
10137
+ return Object.entries(metadata).map(([key, value]) => {
10138
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10139
+ return {
10140
+ key,
10141
+ value,
10142
+ disabled: true
10143
+ };
10144
+ }
10145
+ let stringValue = value;
10146
+ if (typeof value !== "string") {
10147
+ stringValue = JSON.stringify(value);
10148
+ }
10149
+ return {
10150
+ key,
10151
+ value: stringValue,
10152
+ original_key: key
10153
+ };
10154
+ });
10155
+ }
10156
+ function parseValues(values) {
10157
+ const metadata = values.metadata;
10158
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10159
+ if (isEmpty) {
10160
+ return null;
10161
+ }
10162
+ const update = {};
10163
+ metadata.forEach((field) => {
10164
+ let key = field.key;
10165
+ let value = field.value;
10166
+ const disabled = field.disabled;
10167
+ if (!key || !value) {
10168
+ return;
10169
+ }
10170
+ if (disabled) {
10171
+ update[key] = value;
10172
+ return;
10173
+ }
10174
+ key = key.trim();
10175
+ value = value.trim();
10176
+ if (value === "true") {
10177
+ update[key] = true;
10178
+ } else if (value === "false") {
10179
+ update[key] = false;
10180
+ } else {
10181
+ const parsedNumber = parseFloat(value);
10182
+ if (!isNaN(parsedNumber)) {
10183
+ update[key] = parsedNumber;
10184
+ } else {
10185
+ update[key] = value;
10186
+ }
10187
+ }
10188
+ });
10189
+ return update;
10190
+ }
10191
+ function getHasUneditableRows(metadata) {
10192
+ if (!metadata) {
10193
+ return false;
10194
+ }
10195
+ return Object.values(metadata).some(
10196
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10197
+ );
10198
+ }
10199
+ const NumberInput = forwardRef(
10200
+ ({
10201
+ value,
10202
+ onChange,
10203
+ size = "base",
10204
+ min = 0,
10205
+ max = 100,
10206
+ step = 1,
10207
+ className,
10208
+ disabled,
10209
+ ...props
10210
+ }, ref) => {
10211
+ const handleChange = (event) => {
10212
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10213
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10214
+ onChange(newValue);
10215
+ }
10216
+ };
10217
+ const handleIncrement = () => {
10218
+ const newValue = value + step;
10219
+ if (max === void 0 || newValue <= max) {
10220
+ onChange(newValue);
10221
+ }
10222
+ };
10223
+ const handleDecrement = () => {
10224
+ const newValue = value - step;
10225
+ if (min === void 0 || newValue >= min) {
10226
+ onChange(newValue);
10227
+ }
10228
+ };
10229
+ return /* @__PURE__ */ jsxs(
10230
+ "div",
10231
+ {
10232
+ className: clx(
10233
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10234
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10235
+ {
10236
+ "h-7": size === "small",
10237
+ "h-8": size === "base"
10238
+ },
10239
+ className
10240
+ ),
10241
+ children: [
10242
+ /* @__PURE__ */ jsx(
10243
+ "input",
10244
+ {
10245
+ ref,
10246
+ type: "number",
10247
+ value,
10248
+ onChange: handleChange,
10249
+ min,
10250
+ max,
10251
+ step,
10252
+ className: clx(
10253
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10254
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10255
+ "placeholder:text-ui-fg-muted"
10256
+ ),
10257
+ ...props
10258
+ }
10259
+ ),
10260
+ /* @__PURE__ */ jsxs(
10261
+ "button",
10262
+ {
10263
+ className: clx(
10264
+ "flex items-center justify-center outline-none transition-fg",
10265
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10266
+ "focus:bg-ui-bg-field-component-hover",
10267
+ "hover:bg-ui-bg-field-component-hover",
10268
+ {
10269
+ "size-7": size === "small",
10270
+ "size-8": size === "base"
10271
+ }
10272
+ ),
10273
+ type: "button",
10274
+ onClick: handleDecrement,
10275
+ disabled: min !== void 0 && value <= min || disabled,
10276
+ children: [
10277
+ /* @__PURE__ */ jsx(Minus, {}),
10278
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10279
+ ]
10280
+ }
10281
+ ),
10282
+ /* @__PURE__ */ jsxs(
10283
+ "button",
10284
+ {
10285
+ className: clx(
10286
+ "flex items-center justify-center outline-none transition-fg",
10287
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10288
+ "focus:bg-ui-bg-field-hover",
10289
+ "hover:bg-ui-bg-field-hover",
10290
+ {
10291
+ "size-7": size === "small",
10292
+ "size-8": size === "base"
10293
+ }
10294
+ ),
10295
+ type: "button",
10296
+ onClick: handleIncrement,
10297
+ disabled: max !== void 0 && value >= max || disabled,
10298
+ children: [
10299
+ /* @__PURE__ */ jsx(Plus, {}),
10300
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10301
+ ]
10302
+ }
10303
+ )
10304
+ ]
10305
+ }
10306
+ );
10307
+ }
10308
+ );
10309
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10310
+ const productVariantsQueryKeys = {
10311
+ list: (query2) => [
10312
+ PRODUCT_VARIANTS_QUERY_KEY,
10313
+ query2 ? query2 : void 0
10314
+ ]
10315
+ };
10316
+ const useProductVariants = (query2, options) => {
10317
+ const { data, ...rest } = useQuery({
10318
+ queryKey: productVariantsQueryKeys.list(query2),
10319
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10320
+ ...options
10321
+ });
10322
+ return { ...data, ...rest };
10323
+ };
10324
+ const useCancelOrderEdit = ({ preview }) => {
10325
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10326
+ const onCancel = useCallback(async () => {
10327
+ if (!preview) {
10328
+ return true;
10329
+ }
10330
+ let res = false;
10331
+ await cancelOrderEdit(void 0, {
10332
+ onError: (e) => {
10333
+ toast.error(e.message);
10334
+ },
10335
+ onSuccess: () => {
10336
+ res = true;
10337
+ }
10338
+ });
10339
+ return res;
10340
+ }, [preview, cancelOrderEdit]);
10341
+ return { onCancel };
10342
+ };
10343
+ let IS_REQUEST_RUNNING = false;
10344
+ const useInitiateOrderEdit = ({
10345
+ preview
10346
+ }) => {
10347
+ const navigate = useNavigate();
10348
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10349
+ useEffect(() => {
10350
+ async function run() {
10351
+ if (IS_REQUEST_RUNNING || !preview) {
10352
+ return;
10353
+ }
10354
+ if (preview.order_change) {
10355
+ return;
10356
+ }
10357
+ IS_REQUEST_RUNNING = true;
10358
+ await mutateAsync(void 0, {
10359
+ onError: (e) => {
10360
+ toast.error(e.message);
10361
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10362
+ return;
10363
+ }
10364
+ });
10365
+ IS_REQUEST_RUNNING = false;
10366
+ }
10367
+ run();
10368
+ }, [preview, navigate, mutateAsync]);
10369
+ };
10370
+ function convertNumber(value) {
10371
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10372
+ }
10373
+ const STACKED_MODAL_ID = "items_stacked_modal";
10374
+ const Items = () => {
10375
+ const { id } = useParams();
10376
+ const {
10377
+ order: preview,
10378
+ isPending: isPreviewPending,
10379
+ isError: isPreviewError,
10380
+ error: previewError
10381
+ } = useOrderPreview(id, void 0, {
10382
+ placeholderData: keepPreviousData
10383
+ });
10384
+ useInitiateOrderEdit({ preview });
10385
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10386
+ id,
10387
+ {
10388
+ fields: "currency_code"
10389
+ },
10390
+ {
10391
+ enabled: !!id
10392
+ }
10393
+ );
10394
+ const { onCancel } = useCancelOrderEdit({ preview });
10395
+ if (isError) {
10396
+ throw error;
10397
+ }
10398
+ if (isPreviewError) {
10399
+ throw previewError;
10400
+ }
10401
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10402
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10403
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10404
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10405
+ ] }) });
10406
+ };
10407
+ const ItemsForm = ({ preview, currencyCode }) => {
10408
+ var _a;
10409
+ const [isSubmitting, setIsSubmitting] = useState(false);
10410
+ const [modalContent, setModalContent] = useState(
10411
+ null
10412
+ );
10042
10413
  const { handleSuccess } = useRouteModal();
10043
10414
  const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10044
10415
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
@@ -10326,151 +10697,9 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10326
10697
  render: ({ field }) => {
10327
10698
  return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10328
10699
  }
10329
- }
10330
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10331
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10332
- Form$2.Field,
10333
- {
10334
- control: form.control,
10335
- name: "unit_price",
10336
- render: ({ field: { onChange, ...field } }) => {
10337
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10338
- CurrencyInput,
10339
- {
10340
- ...field,
10341
- symbol: getNativeSymbol(currencyCode),
10342
- code: currencyCode,
10343
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10344
- }
10345
- ) }) });
10346
- }
10347
- }
10348
- ) }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10349
- /* @__PURE__ */ jsx(
10350
- IconButton,
10351
- {
10352
- type: "button",
10353
- size: "small",
10354
- onClick: editing ? onSubmit : () => {
10355
- setEditing(true);
10356
- },
10357
- disabled: isPending,
10358
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10359
- }
10360
- )
10361
- ] }) }) });
10362
- };
10363
- const variantItemSchema = objectType({
10364
- quantity: numberType(),
10365
- unit_price: unionType([numberType(), stringType()])
10366
- });
10367
- const CustomItem = ({ item, preview, currencyCode }) => {
10368
- const [editing, setEditing] = useState(false);
10369
- const { quantity, unit_price, title } = item;
10370
- const form = useForm({
10371
- defaultValues: {
10372
- title,
10373
- quantity,
10374
- unit_price
10375
- },
10376
- resolver: zodResolver(customItemSchema)
10377
- });
10378
- useEffect(() => {
10379
- form.reset({
10380
- title,
10381
- quantity,
10382
- unit_price
10383
- });
10384
- }, [form, title, quantity, unit_price]);
10385
- const actionId = useMemo(() => {
10386
- var _a, _b;
10387
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10388
- }, [item]);
10389
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10390
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10391
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10392
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10393
- const onSubmit = form.handleSubmit(async (data) => {
10394
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10395
- setEditing(false);
10396
- return;
10397
- }
10398
- if (!actionId) {
10399
- await updateOriginalItem(
10400
- {
10401
- item_id: item.id,
10402
- quantity: data.quantity,
10403
- unit_price: convertNumber(data.unit_price)
10404
- },
10405
- {
10406
- onSuccess: () => {
10407
- setEditing(false);
10408
- },
10409
- onError: (e) => {
10410
- toast.error(e.message);
10411
- }
10412
- }
10413
- );
10414
- return;
10415
- }
10416
- if (data.quantity === 0) {
10417
- await removeActionItem(actionId, {
10418
- onSuccess: () => {
10419
- setEditing(false);
10420
- },
10421
- onError: (e) => {
10422
- toast.error(e.message);
10423
- }
10424
- });
10425
- return;
10426
- }
10427
- await updateActionItem(
10428
- {
10429
- action_id: actionId,
10430
- quantity: data.quantity,
10431
- unit_price: convertNumber(data.unit_price)
10432
- },
10433
- {
10434
- onSuccess: () => {
10435
- setEditing(false);
10436
- },
10437
- onError: (e) => {
10438
- toast.error(e.message);
10439
- }
10440
- }
10441
- );
10442
- });
10443
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10444
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10445
- /* @__PURE__ */ jsx(
10446
- Thumbnail,
10447
- {
10448
- thumbnail: item.thumbnail,
10449
- alt: item.title ?? void 0
10450
- }
10451
- ),
10452
- editing ? /* @__PURE__ */ jsx(
10453
- Form$2.Field,
10454
- {
10455
- control: form.control,
10456
- name: "title",
10457
- render: ({ field }) => {
10458
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10459
- }
10460
- }
10461
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10462
- ] }),
10463
- editing ? /* @__PURE__ */ jsx(
10464
- Form$2.Field,
10465
- {
10466
- control: form.control,
10467
- name: "quantity",
10468
- render: ({ field }) => {
10469
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10470
- }
10471
- }
10472
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10473
- editing ? /* @__PURE__ */ jsx(
10700
+ }
10701
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10702
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10474
10703
  Form$2.Field,
10475
10704
  {
10476
10705
  control: form.control,
@@ -10487,7 +10716,7 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10487
10716
  ) }) });
10488
10717
  }
10489
10718
  }
10490
- ) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10719
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10491
10720
  /* @__PURE__ */ jsx(
10492
10721
  IconButton,
10493
10722
  {
@@ -10502,215 +10731,79 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10502
10731
  )
10503
10732
  ] }) }) });
10504
10733
  };
10505
- const StackedModalTrigger$1 = ({
10506
- type,
10507
- setModalContent
10508
- }) => {
10509
- const { setIsOpen } = useStackedModal();
10510
- const onClick = useCallback(() => {
10511
- setModalContent(type);
10512
- setIsOpen(STACKED_MODAL_ID, true);
10513
- }, [setModalContent, setIsOpen, type]);
10514
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10515
- };
10516
- const VARIANT_PREFIX = "items";
10517
- const LIMIT = 50;
10518
- const ExistingItemsForm = ({ orderId, items }) => {
10519
- const { setIsOpen } = useStackedModal();
10520
- const [rowSelection, setRowSelection] = useState(
10521
- items.reduce((acc, item) => {
10522
- acc[item.variant_id] = true;
10523
- return acc;
10524
- }, {})
10525
- );
10734
+ const variantItemSchema = objectType({
10735
+ quantity: numberType(),
10736
+ unit_price: unionType([numberType(), stringType()])
10737
+ });
10738
+ const CustomItem = ({ item, preview, currencyCode }) => {
10739
+ const [editing, setEditing] = useState(false);
10740
+ const { quantity, unit_price, title } = item;
10741
+ const form = useForm({
10742
+ defaultValues: {
10743
+ title,
10744
+ quantity,
10745
+ unit_price
10746
+ },
10747
+ resolver: zodResolver(customItemSchema)
10748
+ });
10526
10749
  useEffect(() => {
10527
- setRowSelection(
10528
- items.reduce((acc, item) => {
10529
- if (item.variant_id) {
10530
- acc[item.variant_id] = true;
10750
+ form.reset({
10751
+ title,
10752
+ quantity,
10753
+ unit_price
10754
+ });
10755
+ }, [form, title, quantity, unit_price]);
10756
+ const actionId = useMemo(() => {
10757
+ var _a, _b;
10758
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10759
+ }, [item]);
10760
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10761
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10762
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10763
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10764
+ const onSubmit = form.handleSubmit(async (data) => {
10765
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10766
+ setEditing(false);
10767
+ return;
10768
+ }
10769
+ if (!actionId) {
10770
+ await updateOriginalItem(
10771
+ {
10772
+ item_id: item.id,
10773
+ quantity: data.quantity,
10774
+ unit_price: convertNumber(data.unit_price)
10775
+ },
10776
+ {
10777
+ onSuccess: () => {
10778
+ setEditing(false);
10779
+ },
10780
+ onError: (e) => {
10781
+ toast.error(e.message);
10782
+ }
10531
10783
  }
10532
- return acc;
10533
- }, {})
10534
- );
10535
- }, [items]);
10536
- const { q, order, offset } = useQueryParams(
10537
- ["q", "order", "offset"],
10538
- VARIANT_PREFIX
10539
- );
10540
- const { variants, count, isPending, isError, error } = useProductVariants(
10541
- {
10542
- q,
10543
- order,
10544
- offset: offset ? parseInt(offset) : void 0,
10545
- limit: LIMIT
10546
- },
10547
- {
10548
- placeholderData: keepPreviousData
10784
+ );
10785
+ return;
10549
10786
  }
10550
- );
10551
- const columns = useColumns();
10552
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10553
- const onSubmit = async () => {
10554
- const ids = Object.keys(rowSelection).filter(
10555
- (id) => !items.find((i) => i.variant_id === id)
10556
- );
10557
- await mutateAsync(
10558
- {
10559
- items: ids.map((id) => ({
10560
- variant_id: id,
10561
- quantity: 1
10562
- }))
10563
- },
10564
- {
10787
+ if (data.quantity === 0) {
10788
+ await removeActionItem(actionId, {
10565
10789
  onSuccess: () => {
10566
- setRowSelection({});
10567
- setIsOpen(STACKED_MODAL_ID, false);
10790
+ setEditing(false);
10568
10791
  },
10569
10792
  onError: (e) => {
10570
10793
  toast.error(e.message);
10571
10794
  }
10572
- }
10573
- );
10574
- };
10575
- if (isError) {
10576
- throw error;
10577
- }
10578
- return /* @__PURE__ */ jsxs(
10579
- StackedFocusModal.Content,
10580
- {
10581
- onOpenAutoFocus: (e) => {
10582
- e.preventDefault();
10583
- const searchInput = document.querySelector(
10584
- "[data-modal-id='modal-search-input']"
10585
- );
10586
- if (searchInput) {
10587
- searchInput.focus();
10588
- }
10589
- },
10590
- children: [
10591
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10592
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10593
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10594
- ] }),
10595
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10596
- DataTable,
10597
- {
10598
- data: variants,
10599
- columns,
10600
- isLoading: isPending,
10601
- getRowId: (row) => row.id,
10602
- rowCount: count,
10603
- prefix: VARIANT_PREFIX,
10604
- layout: "fill",
10605
- rowSelection: {
10606
- state: rowSelection,
10607
- onRowSelectionChange: setRowSelection,
10608
- enableRowSelection: (row) => {
10609
- return !items.find((i) => i.variant_id === row.original.id);
10610
- }
10611
- },
10612
- autoFocusSearch: true
10613
- }
10614
- ) }),
10615
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10616
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10617
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10618
- ] }) })
10619
- ]
10620
- }
10621
- );
10622
- };
10623
- const columnHelper = createDataTableColumnHelper();
10624
- const useColumns = () => {
10625
- return useMemo(() => {
10626
- return [
10627
- columnHelper.select(),
10628
- columnHelper.accessor("product.title", {
10629
- header: "Product",
10630
- cell: ({ row }) => {
10631
- var _a, _b, _c;
10632
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10633
- /* @__PURE__ */ jsx(
10634
- Thumbnail,
10635
- {
10636
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10637
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10638
- }
10639
- ),
10640
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10641
- ] });
10642
- },
10643
- enableSorting: true
10644
- }),
10645
- columnHelper.accessor("title", {
10646
- header: "Variant",
10647
- enableSorting: true
10648
- }),
10649
- columnHelper.accessor("sku", {
10650
- header: "SKU",
10651
- cell: ({ getValue }) => {
10652
- return getValue() ?? "-";
10653
- },
10654
- enableSorting: true
10655
- }),
10656
- columnHelper.accessor("updated_at", {
10657
- header: "Updated",
10658
- cell: ({ getValue }) => {
10659
- return /* @__PURE__ */ jsx(
10660
- Tooltip,
10661
- {
10662
- content: getFullDate({ date: getValue(), includeTime: true }),
10663
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10664
- }
10665
- );
10666
- },
10667
- enableSorting: true,
10668
- sortAscLabel: "Oldest first",
10669
- sortDescLabel: "Newest first"
10670
- }),
10671
- columnHelper.accessor("created_at", {
10672
- header: "Created",
10673
- cell: ({ getValue }) => {
10674
- return /* @__PURE__ */ jsx(
10675
- Tooltip,
10676
- {
10677
- content: getFullDate({ date: getValue(), includeTime: true }),
10678
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10679
- }
10680
- );
10681
- },
10682
- enableSorting: true,
10683
- sortAscLabel: "Oldest first",
10684
- sortDescLabel: "Newest first"
10685
- })
10686
- ];
10687
- }, []);
10688
- };
10689
- const CustomItemForm = ({ orderId, currencyCode }) => {
10690
- const { setIsOpen } = useStackedModal();
10691
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10692
- const form = useForm({
10693
- defaultValues: {
10694
- title: "",
10695
- quantity: 1,
10696
- unit_price: ""
10697
- },
10698
- resolver: zodResolver(customItemSchema)
10699
- });
10700
- const onSubmit = form.handleSubmit(async (data) => {
10701
- await addItems(
10702
- {
10703
- items: [
10704
- {
10705
- title: data.title,
10706
- quantity: data.quantity,
10707
- unit_price: convertNumber(data.unit_price)
10708
- }
10709
- ]
10795
+ });
10796
+ return;
10797
+ }
10798
+ await updateActionItem(
10799
+ {
10800
+ action_id: actionId,
10801
+ quantity: data.quantity,
10802
+ unit_price: convertNumber(data.unit_price)
10710
10803
  },
10711
10804
  {
10712
10805
  onSuccess: () => {
10713
- setIsOpen(STACKED_MODAL_ID, false);
10806
+ setEditing(false);
10714
10807
  },
10715
10808
  onError: (e) => {
10716
10809
  toast.error(e.message);
@@ -10718,437 +10811,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10718
10811
  }
10719
10812
  );
10720
10813
  });
10721
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10722
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10723
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10724
- /* @__PURE__ */ jsxs("div", { children: [
10725
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10726
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10727
- ] }),
10728
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10814
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10815
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10729
10816
  /* @__PURE__ */ jsx(
10730
- Form$2.Field,
10817
+ Thumbnail,
10731
10818
  {
10732
- control: form.control,
10733
- name: "title",
10734
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10735
- /* @__PURE__ */ jsxs("div", { children: [
10736
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10737
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10738
- ] }),
10739
- /* @__PURE__ */ jsxs("div", { children: [
10740
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10741
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10742
- ] })
10743
- ] }) })
10819
+ thumbnail: item.thumbnail,
10820
+ alt: item.title ?? void 0
10744
10821
  }
10745
10822
  ),
10746
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10747
- /* @__PURE__ */ jsx(
10823
+ editing ? /* @__PURE__ */ jsx(
10748
10824
  Form$2.Field,
10749
10825
  {
10750
10826
  control: form.control,
10751
- name: "unit_price",
10752
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10753
- /* @__PURE__ */ jsxs("div", { children: [
10754
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10755
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10756
- ] }),
10757
- /* @__PURE__ */ jsxs("div", { children: [
10758
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10759
- CurrencyInput,
10760
- {
10761
- symbol: getNativeSymbol(currencyCode),
10762
- code: currencyCode,
10763
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10764
- ...field
10765
- }
10766
- ) }),
10767
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10768
- ] })
10769
- ] }) })
10827
+ name: "title",
10828
+ render: ({ field }) => {
10829
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10830
+ }
10770
10831
  }
10771
- ),
10772
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10773
- /* @__PURE__ */ jsx(
10774
- Form$2.Field,
10775
- {
10776
- control: form.control,
10777
- name: "quantity",
10778
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10779
- /* @__PURE__ */ jsxs("div", { children: [
10780
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10781
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10782
- ] }),
10783
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10784
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10785
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10786
- ] })
10787
- ] }) })
10832
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10833
+ ] }),
10834
+ editing ? /* @__PURE__ */ jsx(
10835
+ Form$2.Field,
10836
+ {
10837
+ control: form.control,
10838
+ name: "quantity",
10839
+ render: ({ field }) => {
10840
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10788
10841
  }
10789
- )
10790
- ] }) }) }),
10791
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10792
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10793
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10794
- ] }) })
10795
- ] }) }) });
10796
- };
10797
- const customItemSchema = objectType({
10798
- title: stringType().min(1),
10799
- quantity: numberType(),
10800
- unit_price: unionType([numberType(), stringType()])
10801
- });
10802
- const InlineTip = forwardRef(
10803
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10804
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10805
- return /* @__PURE__ */ jsxs(
10806
- "div",
10842
+ }
10843
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10844
+ editing ? /* @__PURE__ */ jsx(
10845
+ Form$2.Field,
10807
10846
  {
10808
- ref,
10809
- className: clx(
10810
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10811
- className
10812
- ),
10813
- ...props,
10814
- children: [
10815
- /* @__PURE__ */ jsx(
10816
- "div",
10847
+ control: form.control,
10848
+ name: "unit_price",
10849
+ render: ({ field: { onChange, ...field } }) => {
10850
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10851
+ CurrencyInput,
10817
10852
  {
10818
- role: "presentation",
10819
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10820
- "bg-ui-tag-orange-icon": variant === "warning"
10821
- })
10853
+ ...field,
10854
+ symbol: getNativeSymbol(currencyCode),
10855
+ code: currencyCode,
10856
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10822
10857
  }
10823
- ),
10824
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10825
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10826
- labelValue,
10827
- ":"
10828
- ] }),
10829
- " ",
10830
- children
10831
- ] })
10832
- ]
10858
+ ) }) });
10859
+ }
10833
10860
  }
10834
- );
10835
- }
10836
- );
10837
- InlineTip.displayName = "InlineTip";
10838
- const MetadataFieldSchema = objectType({
10839
- key: stringType(),
10840
- disabled: booleanType().optional(),
10841
- value: anyType()
10842
- });
10843
- const MetadataSchema = objectType({
10844
- metadata: arrayType(MetadataFieldSchema)
10845
- });
10846
- const Metadata = () => {
10847
- const { id } = useParams();
10848
- const { order, isPending, isError, error } = useOrder(id, {
10849
- fields: "metadata"
10850
- });
10851
- if (isError) {
10852
- throw error;
10853
- }
10854
- const isReady = !isPending && !!order;
10855
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10856
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10857
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10858
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10859
- ] }),
10860
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10861
- ] });
10861
+ ) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10862
+ /* @__PURE__ */ jsx(
10863
+ IconButton,
10864
+ {
10865
+ type: "button",
10866
+ size: "small",
10867
+ onClick: editing ? onSubmit : () => {
10868
+ setEditing(true);
10869
+ },
10870
+ disabled: isPending,
10871
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10872
+ }
10873
+ )
10874
+ ] }) }) });
10862
10875
  };
10863
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10864
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10865
- const MetadataForm = ({ orderId, metadata }) => {
10866
- const { handleSuccess } = useRouteModal();
10867
- const hasUneditableRows = getHasUneditableRows(metadata);
10868
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10869
- const form = useForm({
10870
- defaultValues: {
10871
- metadata: getDefaultValues(metadata)
10876
+ const StackedModalTrigger$1 = ({
10877
+ type,
10878
+ setModalContent
10879
+ }) => {
10880
+ const { setIsOpen } = useStackedModal();
10881
+ const onClick = useCallback(() => {
10882
+ setModalContent(type);
10883
+ setIsOpen(STACKED_MODAL_ID, true);
10884
+ }, [setModalContent, setIsOpen, type]);
10885
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10886
+ };
10887
+ const VARIANT_PREFIX = "items";
10888
+ const LIMIT = 50;
10889
+ const ExistingItemsForm = ({ orderId, items }) => {
10890
+ const { setIsOpen } = useStackedModal();
10891
+ const [rowSelection, setRowSelection] = useState(
10892
+ items.reduce((acc, item) => {
10893
+ acc[item.variant_id] = true;
10894
+ return acc;
10895
+ }, {})
10896
+ );
10897
+ useEffect(() => {
10898
+ setRowSelection(
10899
+ items.reduce((acc, item) => {
10900
+ if (item.variant_id) {
10901
+ acc[item.variant_id] = true;
10902
+ }
10903
+ return acc;
10904
+ }, {})
10905
+ );
10906
+ }, [items]);
10907
+ const { q, order, offset } = useQueryParams(
10908
+ ["q", "order", "offset"],
10909
+ VARIANT_PREFIX
10910
+ );
10911
+ const { variants, count, isPending, isError, error } = useProductVariants(
10912
+ {
10913
+ q,
10914
+ order,
10915
+ offset: offset ? parseInt(offset) : void 0,
10916
+ limit: LIMIT
10872
10917
  },
10873
- resolver: zodResolver(MetadataSchema)
10874
- });
10875
- const handleSubmit = form.handleSubmit(async (data) => {
10876
- const parsedData = parseValues(data);
10918
+ {
10919
+ placeholderData: keepPreviousData
10920
+ }
10921
+ );
10922
+ const columns = useColumns();
10923
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10924
+ const onSubmit = async () => {
10925
+ const ids = Object.keys(rowSelection).filter(
10926
+ (id) => !items.find((i) => i.variant_id === id)
10927
+ );
10877
10928
  await mutateAsync(
10878
10929
  {
10879
- metadata: parsedData
10930
+ items: ids.map((id) => ({
10931
+ variant_id: id,
10932
+ quantity: 1
10933
+ }))
10880
10934
  },
10881
10935
  {
10882
10936
  onSuccess: () => {
10883
- toast.success("Metadata updated");
10884
- handleSuccess();
10937
+ setRowSelection({});
10938
+ setIsOpen(STACKED_MODAL_ID, false);
10885
10939
  },
10886
- onError: (error) => {
10887
- toast.error(error.message);
10940
+ onError: (e) => {
10941
+ toast.error(e.message);
10888
10942
  }
10889
10943
  }
10890
10944
  );
10891
- });
10892
- const { fields, insert, remove } = useFieldArray({
10893
- control: form.control,
10894
- name: "metadata"
10895
- });
10896
- function deleteRow(index) {
10897
- remove(index);
10898
- if (fields.length === 1) {
10899
- insert(0, {
10900
- key: "",
10901
- value: "",
10902
- disabled: false
10903
- });
10904
- }
10905
- }
10906
- function insertRow(index, position) {
10907
- insert(index + (position === "above" ? 0 : 1), {
10908
- key: "",
10909
- value: "",
10910
- disabled: false
10911
- });
10945
+ };
10946
+ if (isError) {
10947
+ throw error;
10912
10948
  }
10913
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10914
- KeyboundForm,
10949
+ return /* @__PURE__ */ jsxs(
10950
+ StackedFocusModal.Content,
10915
10951
  {
10916
- onSubmit: handleSubmit,
10917
- className: "flex flex-1 flex-col overflow-hidden",
10952
+ onOpenAutoFocus: (e) => {
10953
+ e.preventDefault();
10954
+ const searchInput = document.querySelector(
10955
+ "[data-modal-id='modal-search-input']"
10956
+ );
10957
+ if (searchInput) {
10958
+ searchInput.focus();
10959
+ }
10960
+ },
10918
10961
  children: [
10919
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10920
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10921
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10922
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10923
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10924
- ] }),
10925
- fields.map((field, index) => {
10926
- const isDisabled = field.disabled || false;
10927
- let placeholder = "-";
10928
- if (typeof field.value === "object") {
10929
- placeholder = "{ ... }";
10930
- }
10931
- if (Array.isArray(field.value)) {
10932
- placeholder = "[ ... ]";
10933
- }
10934
- return /* @__PURE__ */ jsx(
10935
- ConditionalTooltip,
10936
- {
10937
- showTooltip: isDisabled,
10938
- content: "This row is disabled because it contains non-primitive data.",
10939
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10940
- /* @__PURE__ */ jsxs(
10941
- "div",
10942
- {
10943
- className: clx("grid grid-cols-2 divide-x", {
10944
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10945
- }),
10946
- children: [
10947
- /* @__PURE__ */ jsx(
10948
- Form$2.Field,
10949
- {
10950
- control: form.control,
10951
- name: `metadata.${index}.key`,
10952
- render: ({ field: field2 }) => {
10953
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10954
- GridInput,
10955
- {
10956
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10957
- ...field2,
10958
- disabled: isDisabled,
10959
- placeholder: "Key"
10960
- }
10961
- ) }) });
10962
- }
10963
- }
10964
- ),
10965
- /* @__PURE__ */ jsx(
10966
- Form$2.Field,
10967
- {
10968
- control: form.control,
10969
- name: `metadata.${index}.value`,
10970
- render: ({ field: { value, ...field2 } }) => {
10971
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10972
- GridInput,
10973
- {
10974
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10975
- ...field2,
10976
- value: isDisabled ? placeholder : value,
10977
- disabled: isDisabled,
10978
- placeholder: "Value"
10979
- }
10980
- ) }) });
10981
- }
10982
- }
10983
- )
10984
- ]
10985
- }
10986
- ),
10987
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10988
- /* @__PURE__ */ jsx(
10989
- DropdownMenu.Trigger,
10990
- {
10991
- className: clx(
10992
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10993
- {
10994
- hidden: isDisabled
10995
- }
10996
- ),
10997
- disabled: isDisabled,
10998
- asChild: true,
10999
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11000
- }
11001
- ),
11002
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11003
- /* @__PURE__ */ jsxs(
11004
- DropdownMenu.Item,
11005
- {
11006
- className: "gap-x-2",
11007
- onClick: () => insertRow(index, "above"),
11008
- children: [
11009
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11010
- "Insert row above"
11011
- ]
11012
- }
11013
- ),
11014
- /* @__PURE__ */ jsxs(
11015
- DropdownMenu.Item,
11016
- {
11017
- className: "gap-x-2",
11018
- onClick: () => insertRow(index, "below"),
11019
- children: [
11020
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11021
- "Insert row below"
11022
- ]
11023
- }
11024
- ),
11025
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11026
- /* @__PURE__ */ jsxs(
11027
- DropdownMenu.Item,
11028
- {
11029
- className: "gap-x-2",
11030
- onClick: () => deleteRow(index),
11031
- children: [
11032
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11033
- "Delete row"
11034
- ]
11035
- }
11036
- )
11037
- ] })
11038
- ] })
11039
- ] })
11040
- },
11041
- field.id
11042
- );
11043
- })
11044
- ] }),
11045
- hasUneditableRows && /* @__PURE__ */ 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." })
10962
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10963
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10964
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11046
10965
  ] }),
11047
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11048
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11049
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10966
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10967
+ DataTable,
10968
+ {
10969
+ data: variants,
10970
+ columns,
10971
+ isLoading: isPending,
10972
+ getRowId: (row) => row.id,
10973
+ rowCount: count,
10974
+ prefix: VARIANT_PREFIX,
10975
+ layout: "fill",
10976
+ rowSelection: {
10977
+ state: rowSelection,
10978
+ onRowSelectionChange: setRowSelection,
10979
+ enableRowSelection: (row) => {
10980
+ return !items.find((i) => i.variant_id === row.original.id);
10981
+ }
10982
+ },
10983
+ autoFocusSearch: true
10984
+ }
10985
+ ) }),
10986
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10987
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10988
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11050
10989
  ] }) })
11051
10990
  ]
11052
10991
  }
11053
- ) });
11054
- };
11055
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11056
- return /* @__PURE__ */ jsx(
11057
- "input",
11058
- {
11059
- ref,
11060
- ...props,
11061
- autoComplete: "off",
11062
- className: clx(
11063
- "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",
11064
- className
11065
- )
11066
- }
11067
10992
  );
11068
- });
11069
- GridInput.displayName = "MetadataForm.GridInput";
11070
- const PlaceholderInner = () => {
11071
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11072
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11073
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11074
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11075
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11076
- ] }) })
11077
- ] });
11078
10993
  };
11079
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11080
- function getDefaultValues(metadata) {
11081
- if (!metadata || !Object.keys(metadata).length) {
10994
+ const columnHelper = createDataTableColumnHelper();
10995
+ const useColumns = () => {
10996
+ return useMemo(() => {
11082
10997
  return [
11083
- {
11084
- key: "",
11085
- value: "",
11086
- disabled: false
11087
- }
10998
+ columnHelper.select(),
10999
+ columnHelper.accessor("product.title", {
11000
+ header: "Product",
11001
+ cell: ({ row }) => {
11002
+ var _a, _b, _c;
11003
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11004
+ /* @__PURE__ */ jsx(
11005
+ Thumbnail,
11006
+ {
11007
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11008
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11009
+ }
11010
+ ),
11011
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11012
+ ] });
11013
+ },
11014
+ enableSorting: true
11015
+ }),
11016
+ columnHelper.accessor("title", {
11017
+ header: "Variant",
11018
+ enableSorting: true
11019
+ }),
11020
+ columnHelper.accessor("sku", {
11021
+ header: "SKU",
11022
+ cell: ({ getValue }) => {
11023
+ return getValue() ?? "-";
11024
+ },
11025
+ enableSorting: true
11026
+ }),
11027
+ columnHelper.accessor("updated_at", {
11028
+ header: "Updated",
11029
+ cell: ({ getValue }) => {
11030
+ return /* @__PURE__ */ jsx(
11031
+ Tooltip,
11032
+ {
11033
+ content: getFullDate({ date: getValue(), includeTime: true }),
11034
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11035
+ }
11036
+ );
11037
+ },
11038
+ enableSorting: true,
11039
+ sortAscLabel: "Oldest first",
11040
+ sortDescLabel: "Newest first"
11041
+ }),
11042
+ columnHelper.accessor("created_at", {
11043
+ header: "Created",
11044
+ cell: ({ getValue }) => {
11045
+ return /* @__PURE__ */ jsx(
11046
+ Tooltip,
11047
+ {
11048
+ content: getFullDate({ date: getValue(), includeTime: true }),
11049
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11050
+ }
11051
+ );
11052
+ },
11053
+ enableSorting: true,
11054
+ sortAscLabel: "Oldest first",
11055
+ sortDescLabel: "Newest first"
11056
+ })
11088
11057
  ];
11089
- }
11090
- return Object.entries(metadata).map(([key, value]) => {
11091
- if (!EDITABLE_TYPES.includes(typeof value)) {
11092
- return {
11093
- key,
11094
- value,
11095
- disabled: true
11096
- };
11097
- }
11098
- let stringValue = value;
11099
- if (typeof value !== "string") {
11100
- stringValue = JSON.stringify(value);
11101
- }
11102
- return {
11103
- key,
11104
- value: stringValue,
11105
- original_key: key
11106
- };
11058
+ }, []);
11059
+ };
11060
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11061
+ const { setIsOpen } = useStackedModal();
11062
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11063
+ const form = useForm({
11064
+ defaultValues: {
11065
+ title: "",
11066
+ quantity: 1,
11067
+ unit_price: ""
11068
+ },
11069
+ resolver: zodResolver(customItemSchema)
11107
11070
  });
11108
- }
11109
- function parseValues(values) {
11110
- const metadata = values.metadata;
11111
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11112
- if (isEmpty) {
11113
- return null;
11114
- }
11115
- const update = {};
11116
- metadata.forEach((field) => {
11117
- let key = field.key;
11118
- let value = field.value;
11119
- const disabled = field.disabled;
11120
- if (!key || !value) {
11121
- return;
11122
- }
11123
- if (disabled) {
11124
- update[key] = value;
11125
- return;
11126
- }
11127
- key = key.trim();
11128
- value = value.trim();
11129
- if (value === "true") {
11130
- update[key] = true;
11131
- } else if (value === "false") {
11132
- update[key] = false;
11133
- } else {
11134
- const parsedNumber = parseFloat(value);
11135
- if (!isNaN(parsedNumber)) {
11136
- update[key] = parsedNumber;
11137
- } else {
11138
- update[key] = value;
11071
+ const onSubmit = form.handleSubmit(async (data) => {
11072
+ await addItems(
11073
+ {
11074
+ items: [
11075
+ {
11076
+ title: data.title,
11077
+ quantity: data.quantity,
11078
+ unit_price: convertNumber(data.unit_price)
11079
+ }
11080
+ ]
11081
+ },
11082
+ {
11083
+ onSuccess: () => {
11084
+ setIsOpen(STACKED_MODAL_ID, false);
11085
+ },
11086
+ onError: (e) => {
11087
+ toast.error(e.message);
11088
+ }
11139
11089
  }
11140
- }
11090
+ );
11141
11091
  });
11142
- return update;
11143
- }
11144
- function getHasUneditableRows(metadata) {
11145
- if (!metadata) {
11146
- return false;
11147
- }
11148
- return Object.values(metadata).some(
11149
- (value) => !EDITABLE_TYPES.includes(typeof value)
11150
- );
11151
- }
11092
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11093
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11094
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
11095
+ /* @__PURE__ */ jsxs("div", { children: [
11096
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11097
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
11098
+ ] }),
11099
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11100
+ /* @__PURE__ */ jsx(
11101
+ Form$2.Field,
11102
+ {
11103
+ control: form.control,
11104
+ name: "title",
11105
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11106
+ /* @__PURE__ */ jsxs("div", { children: [
11107
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11108
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11109
+ ] }),
11110
+ /* @__PURE__ */ jsxs("div", { children: [
11111
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11112
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11113
+ ] })
11114
+ ] }) })
11115
+ }
11116
+ ),
11117
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11118
+ /* @__PURE__ */ jsx(
11119
+ Form$2.Field,
11120
+ {
11121
+ control: form.control,
11122
+ name: "unit_price",
11123
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11124
+ /* @__PURE__ */ jsxs("div", { children: [
11125
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11126
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11127
+ ] }),
11128
+ /* @__PURE__ */ jsxs("div", { children: [
11129
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11130
+ CurrencyInput,
11131
+ {
11132
+ symbol: getNativeSymbol(currencyCode),
11133
+ code: currencyCode,
11134
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11135
+ ...field
11136
+ }
11137
+ ) }),
11138
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11139
+ ] })
11140
+ ] }) })
11141
+ }
11142
+ ),
11143
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11144
+ /* @__PURE__ */ jsx(
11145
+ Form$2.Field,
11146
+ {
11147
+ control: form.control,
11148
+ name: "quantity",
11149
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11150
+ /* @__PURE__ */ jsxs("div", { children: [
11151
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11152
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11153
+ ] }),
11154
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11155
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11156
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11157
+ ] })
11158
+ ] }) })
11159
+ }
11160
+ )
11161
+ ] }) }) }),
11162
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11163
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11164
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11165
+ ] }) })
11166
+ ] }) }) });
11167
+ };
11168
+ const customItemSchema = objectType({
11169
+ title: stringType().min(1),
11170
+ quantity: numberType(),
11171
+ unit_price: unionType([numberType(), stringType()])
11172
+ });
11152
11173
  const PROMOTION_QUERY_KEY = "promotions";
11153
11174
  const promotionsQueryKeys = {
11154
11175
  list: (query2) => [
@@ -11454,7 +11475,7 @@ const SalesChannelForm = ({ order }) => {
11454
11475
  defaultValues: {
11455
11476
  sales_channel_id: order.sales_channel_id || ""
11456
11477
  },
11457
- resolver: zodResolver(schema$3)
11478
+ resolver: zodResolver(schema$2)
11458
11479
  });
11459
11480
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11460
11481
  const { handleSuccess } = useRouteModal();
@@ -11529,7 +11550,7 @@ const SalesChannelField = ({ control, order }) => {
11529
11550
  }
11530
11551
  );
11531
11552
  };
11532
- const schema$3 = objectType({
11553
+ const schema$2 = objectType({
11533
11554
  sales_channel_id: stringType().min(1)
11534
11555
  });
11535
11556
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
@@ -12371,7 +12392,7 @@ const ShippingAddressForm = ({ order }) => {
12371
12392
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12372
12393
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12373
12394
  },
12374
- resolver: zodResolver(schema$2)
12395
+ resolver: zodResolver(schema$1)
12375
12396
  });
12376
12397
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12377
12398
  const { handleSuccess } = useRouteModal();
@@ -12541,7 +12562,7 @@ const ShippingAddressForm = ({ order }) => {
12541
12562
  }
12542
12563
  ) });
12543
12564
  };
12544
- const schema$2 = addressSchema;
12565
+ const schema$1 = addressSchema;
12545
12566
  const TransferOwnership = () => {
12546
12567
  const { id } = useParams();
12547
12568
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12565,7 +12586,7 @@ const TransferOwnershipForm = ({ order }) => {
12565
12586
  defaultValues: {
12566
12587
  customer_id: order.customer_id || ""
12567
12588
  },
12568
- resolver: zodResolver(schema$1)
12589
+ resolver: zodResolver(schema)
12569
12590
  });
12570
12591
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12571
12592
  const { handleSuccess } = useRouteModal();
@@ -13015,29 +13036,8 @@ const Illustration = () => {
13015
13036
  }
13016
13037
  );
13017
13038
  };
13018
- const schema$1 = objectType({
13019
- customer_id: stringType().min(1)
13020
- });
13021
- const CustomItems = () => {
13022
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
13023
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
13024
- /* @__PURE__ */ jsx(CustomItemsForm, {})
13025
- ] });
13026
- };
13027
- const CustomItemsForm = () => {
13028
- const form = useForm({
13029
- resolver: zodResolver(schema)
13030
- });
13031
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
13032
- /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
13033
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13034
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13035
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
13036
- ] }) })
13037
- ] }) });
13038
- };
13039
13039
  const schema = objectType({
13040
- email: stringType().email()
13040
+ customer_id: stringType().min(1)
13041
13041
  });
13042
13042
  const widgetModule = { widgets: [] };
13043
13043
  const routeModule = {
@@ -13064,17 +13064,21 @@ const routeModule = {
13064
13064
  path: "/draft-orders/:id/billing-address"
13065
13065
  },
13066
13066
  {
13067
- Component: Email,
13068
- path: "/draft-orders/:id/email"
13067
+ Component: CustomItems,
13068
+ path: "/draft-orders/:id/custom-items"
13069
13069
  },
13070
13070
  {
13071
- Component: Items,
13072
- path: "/draft-orders/:id/items"
13071
+ Component: Email,
13072
+ path: "/draft-orders/:id/email"
13073
13073
  },
13074
13074
  {
13075
13075
  Component: Metadata,
13076
13076
  path: "/draft-orders/:id/metadata"
13077
13077
  },
13078
+ {
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13081
+ },
13078
13082
  {
13079
13083
  Component: Promotions,
13080
13084
  path: "/draft-orders/:id/promotions"
@@ -13094,10 +13098,6 @@ const routeModule = {
13094
13098
  {
13095
13099
  Component: TransferOwnership,
13096
13100
  path: "/draft-orders/:id/transfer-ownership"
13097
- },
13098
- {
13099
- Component: CustomItems,
13100
- path: "/draft-orders/:id/custom-items"
13101
13101
  }
13102
13102
  ]
13103
13103
  }