@medusajs/draft-order 2.11.4-snapshot-20251106121614 → 2.11.4-snapshot-20251106122834

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.
@@ -9779,54 +9779,10 @@ const CustomItemsForm = () => {
9779
9779
  const schema$4 = objectType({
9780
9780
  email: stringType().email()
9781
9781
  });
9782
- const InlineTip = React.forwardRef(
9783
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9784
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9785
- return /* @__PURE__ */ jsxRuntime.jsxs(
9786
- "div",
9787
- {
9788
- ref,
9789
- className: ui.clx(
9790
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9791
- className
9792
- ),
9793
- ...props,
9794
- children: [
9795
- /* @__PURE__ */ jsxRuntime.jsx(
9796
- "div",
9797
- {
9798
- role: "presentation",
9799
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9800
- "bg-ui-tag-orange-icon": variant === "warning"
9801
- })
9802
- }
9803
- ),
9804
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9805
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9806
- labelValue,
9807
- ":"
9808
- ] }),
9809
- " ",
9810
- children
9811
- ] })
9812
- ]
9813
- }
9814
- );
9815
- }
9816
- );
9817
- InlineTip.displayName = "InlineTip";
9818
- const MetadataFieldSchema = objectType({
9819
- key: stringType(),
9820
- disabled: booleanType().optional(),
9821
- value: anyType()
9822
- });
9823
- const MetadataSchema = objectType({
9824
- metadata: arrayType(MetadataFieldSchema)
9825
- });
9826
- const Metadata = () => {
9782
+ const Email = () => {
9827
9783
  const { id } = reactRouterDom.useParams();
9828
9784
  const { order, isPending, isError, error } = useOrder(id, {
9829
- fields: "metadata"
9785
+ fields: "+email"
9830
9786
  });
9831
9787
  if (isError) {
9832
9788
  throw error;
@@ -9834,33 +9790,26 @@ const Metadata = () => {
9834
9790
  const isReady = !isPending && !!order;
9835
9791
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9836
9792
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9837
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9838
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9793
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9794
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9839
9795
  ] }),
9840
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9796
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9841
9797
  ] });
9842
9798
  };
9843
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9844
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9845
- const MetadataForm = ({ orderId, metadata }) => {
9846
- const { handleSuccess } = useRouteModal();
9847
- const hasUneditableRows = getHasUneditableRows(metadata);
9848
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9799
+ const EmailForm = ({ order }) => {
9849
9800
  const form = reactHookForm.useForm({
9850
9801
  defaultValues: {
9851
- metadata: getDefaultValues(metadata)
9802
+ email: order.email ?? ""
9852
9803
  },
9853
- resolver: zod.zodResolver(MetadataSchema)
9804
+ resolver: zod.zodResolver(schema$3)
9854
9805
  });
9855
- const handleSubmit = form.handleSubmit(async (data) => {
9856
- const parsedData = parseValues(data);
9806
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9807
+ const { handleSuccess } = useRouteModal();
9808
+ const onSubmit = form.handleSubmit(async (data) => {
9857
9809
  await mutateAsync(
9858
- {
9859
- metadata: parsedData
9860
- },
9810
+ { email: data.email },
9861
9811
  {
9862
9812
  onSuccess: () => {
9863
- ui.toast.success("Metadata updated");
9864
9813
  handleSuccess();
9865
9814
  },
9866
9815
  onError: (error) => {
@@ -9869,325 +9818,26 @@ const MetadataForm = ({ orderId, metadata }) => {
9869
9818
  }
9870
9819
  );
9871
9820
  });
9872
- const { fields, insert, remove } = reactHookForm.useFieldArray({
9873
- control: form.control,
9874
- name: "metadata"
9875
- });
9876
- function deleteRow(index) {
9877
- remove(index);
9878
- if (fields.length === 1) {
9879
- insert(0, {
9880
- key: "",
9881
- value: "",
9882
- disabled: false
9883
- });
9884
- }
9885
- }
9886
- function insertRow(index, position) {
9887
- insert(index + (position === "above" ? 0 : 1), {
9888
- key: "",
9889
- value: "",
9890
- disabled: false
9891
- });
9892
- }
9893
9821
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9894
9822
  KeyboundForm,
9895
9823
  {
9896
- onSubmit: handleSubmit,
9897
9824
  className: "flex flex-1 flex-col overflow-hidden",
9825
+ onSubmit,
9898
9826
  children: [
9899
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9900
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9901
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9902
- /* @__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" }) }),
9903
- /* @__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" }) })
9904
- ] }),
9905
- fields.map((field, index) => {
9906
- const isDisabled = field.disabled || false;
9907
- let placeholder = "-";
9908
- if (typeof field.value === "object") {
9909
- placeholder = "{ ... }";
9910
- }
9911
- if (Array.isArray(field.value)) {
9912
- placeholder = "[ ... ]";
9913
- }
9914
- return /* @__PURE__ */ jsxRuntime.jsx(
9915
- ConditionalTooltip,
9916
- {
9917
- showTooltip: isDisabled,
9918
- content: "This row is disabled because it contains non-primitive data.",
9919
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
9920
- /* @__PURE__ */ jsxRuntime.jsxs(
9921
- "div",
9922
- {
9923
- className: ui.clx("grid grid-cols-2 divide-x", {
9924
- "overflow-hidden rounded-b-lg": index === fields.length - 1
9925
- }),
9926
- children: [
9927
- /* @__PURE__ */ jsxRuntime.jsx(
9928
- Form$2.Field,
9929
- {
9930
- control: form.control,
9931
- name: `metadata.${index}.key`,
9932
- render: ({ field: field2 }) => {
9933
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9934
- GridInput,
9935
- {
9936
- "aria-labelledby": METADATA_KEY_LABEL_ID,
9937
- ...field2,
9938
- disabled: isDisabled,
9939
- placeholder: "Key"
9940
- }
9941
- ) }) });
9942
- }
9943
- }
9944
- ),
9945
- /* @__PURE__ */ jsxRuntime.jsx(
9946
- Form$2.Field,
9947
- {
9948
- control: form.control,
9949
- name: `metadata.${index}.value`,
9950
- render: ({ field: { value, ...field2 } }) => {
9951
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9952
- GridInput,
9953
- {
9954
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
9955
- ...field2,
9956
- value: isDisabled ? placeholder : value,
9957
- disabled: isDisabled,
9958
- placeholder: "Value"
9959
- }
9960
- ) }) });
9961
- }
9962
- }
9963
- )
9964
- ]
9965
- }
9966
- ),
9967
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
9968
- /* @__PURE__ */ jsxRuntime.jsx(
9969
- ui.DropdownMenu.Trigger,
9970
- {
9971
- className: ui.clx(
9972
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
9973
- {
9974
- hidden: isDisabled
9975
- }
9976
- ),
9977
- disabled: isDisabled,
9978
- asChild: true,
9979
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
9980
- }
9981
- ),
9982
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
9983
- /* @__PURE__ */ jsxRuntime.jsxs(
9984
- ui.DropdownMenu.Item,
9985
- {
9986
- className: "gap-x-2",
9987
- onClick: () => insertRow(index, "above"),
9988
- children: [
9989
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
9990
- "Insert row above"
9991
- ]
9992
- }
9993
- ),
9994
- /* @__PURE__ */ jsxRuntime.jsxs(
9995
- ui.DropdownMenu.Item,
9996
- {
9997
- className: "gap-x-2",
9998
- onClick: () => insertRow(index, "below"),
9999
- children: [
10000
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10001
- "Insert row below"
10002
- ]
10003
- }
10004
- ),
10005
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10006
- /* @__PURE__ */ jsxRuntime.jsxs(
10007
- ui.DropdownMenu.Item,
10008
- {
10009
- className: "gap-x-2",
10010
- onClick: () => deleteRow(index),
10011
- children: [
10012
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10013
- "Delete row"
10014
- ]
10015
- }
10016
- )
10017
- ] })
10018
- ] })
10019
- ] })
10020
- },
10021
- field.id
10022
- );
10023
- })
10024
- ] }),
10025
- 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." })
10026
- ] }),
10027
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10028
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10029
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10030
- ] }) })
10031
- ]
10032
- }
10033
- ) });
10034
- };
10035
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10036
- return /* @__PURE__ */ jsxRuntime.jsx(
10037
- "input",
10038
- {
10039
- ref,
10040
- ...props,
10041
- autoComplete: "off",
10042
- className: ui.clx(
10043
- "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",
10044
- className
10045
- )
10046
- }
10047
- );
10048
- });
10049
- GridInput.displayName = "MetadataForm.GridInput";
10050
- const PlaceholderInner = () => {
10051
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10052
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10053
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10054
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10056
- ] }) })
10057
- ] });
10058
- };
10059
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10060
- function getDefaultValues(metadata) {
10061
- if (!metadata || !Object.keys(metadata).length) {
10062
- return [
10063
- {
10064
- key: "",
10065
- value: "",
10066
- disabled: false
10067
- }
10068
- ];
10069
- }
10070
- return Object.entries(metadata).map(([key, value]) => {
10071
- if (!EDITABLE_TYPES.includes(typeof value)) {
10072
- return {
10073
- key,
10074
- value,
10075
- disabled: true
10076
- };
10077
- }
10078
- let stringValue = value;
10079
- if (typeof value !== "string") {
10080
- stringValue = JSON.stringify(value);
10081
- }
10082
- return {
10083
- key,
10084
- value: stringValue,
10085
- original_key: key
10086
- };
10087
- });
10088
- }
10089
- function parseValues(values) {
10090
- const metadata = values.metadata;
10091
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10092
- if (isEmpty) {
10093
- return null;
10094
- }
10095
- const update = {};
10096
- metadata.forEach((field) => {
10097
- let key = field.key;
10098
- let value = field.value;
10099
- const disabled = field.disabled;
10100
- if (!key || !value) {
10101
- return;
10102
- }
10103
- if (disabled) {
10104
- update[key] = value;
10105
- return;
10106
- }
10107
- key = key.trim();
10108
- value = value.trim();
10109
- if (value === "true") {
10110
- update[key] = true;
10111
- } else if (value === "false") {
10112
- update[key] = false;
10113
- } else {
10114
- const parsedNumber = parseFloat(value);
10115
- if (!isNaN(parsedNumber)) {
10116
- update[key] = parsedNumber;
10117
- } else {
10118
- update[key] = value;
10119
- }
10120
- }
10121
- });
10122
- return update;
10123
- }
10124
- function getHasUneditableRows(metadata) {
10125
- if (!metadata) {
10126
- return false;
10127
- }
10128
- return Object.values(metadata).some(
10129
- (value) => !EDITABLE_TYPES.includes(typeof value)
10130
- );
10131
- }
10132
- const Email = () => {
10133
- const { id } = reactRouterDom.useParams();
10134
- const { order, isPending, isError, error } = useOrder(id, {
10135
- fields: "+email"
10136
- });
10137
- if (isError) {
10138
- throw error;
10139
- }
10140
- const isReady = !isPending && !!order;
10141
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10142
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10143
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
10144
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
10145
- ] }),
10146
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
10147
- ] });
10148
- };
10149
- const EmailForm = ({ order }) => {
10150
- const form = reactHookForm.useForm({
10151
- defaultValues: {
10152
- email: order.email ?? ""
10153
- },
10154
- resolver: zod.zodResolver(schema$3)
10155
- });
10156
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10157
- const { handleSuccess } = useRouteModal();
10158
- const onSubmit = form.handleSubmit(async (data) => {
10159
- await mutateAsync(
10160
- { email: data.email },
10161
- {
10162
- onSuccess: () => {
10163
- handleSuccess();
10164
- },
10165
- onError: (error) => {
10166
- ui.toast.error(error.message);
10167
- }
10168
- }
10169
- );
10170
- });
10171
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10172
- KeyboundForm,
10173
- {
10174
- className: "flex flex-1 flex-col overflow-hidden",
10175
- onSubmit,
10176
- children: [
10177
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
10178
- Form$2.Field,
10179
- {
10180
- control: form.control,
10181
- name: "email",
10182
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10183
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
10184
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10185
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10186
- ] })
10187
- }
10188
- ) }),
10189
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10190
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9827
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9828
+ Form$2.Field,
9829
+ {
9830
+ control: form.control,
9831
+ name: "email",
9832
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9833
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9834
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9835
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9836
+ ] })
9837
+ }
9838
+ ) }),
9839
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9840
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10191
9841
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10192
9842
  ] }) })
10193
9843
  ]
@@ -10992,185 +10642,535 @@ const ExistingItemsForm = ({ orderId, items }) => {
10992
10642
  }
10993
10643
  );
10994
10644
  };
10995
- const columnHelper = ui.createDataTableColumnHelper();
10996
- const useColumns = () => {
10997
- return React.useMemo(() => {
10645
+ const columnHelper = ui.createDataTableColumnHelper();
10646
+ const useColumns = () => {
10647
+ return React.useMemo(() => {
10648
+ return [
10649
+ columnHelper.select(),
10650
+ columnHelper.accessor("product.title", {
10651
+ header: "Product",
10652
+ cell: ({ row }) => {
10653
+ var _a, _b, _c;
10654
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10655
+ /* @__PURE__ */ jsxRuntime.jsx(
10656
+ Thumbnail,
10657
+ {
10658
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10659
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10660
+ }
10661
+ ),
10662
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10663
+ ] });
10664
+ },
10665
+ enableSorting: true
10666
+ }),
10667
+ columnHelper.accessor("title", {
10668
+ header: "Variant",
10669
+ enableSorting: true
10670
+ }),
10671
+ columnHelper.accessor("sku", {
10672
+ header: "SKU",
10673
+ cell: ({ getValue }) => {
10674
+ return getValue() ?? "-";
10675
+ },
10676
+ enableSorting: true
10677
+ }),
10678
+ columnHelper.accessor("updated_at", {
10679
+ header: "Updated",
10680
+ cell: ({ getValue }) => {
10681
+ return /* @__PURE__ */ jsxRuntime.jsx(
10682
+ ui.Tooltip,
10683
+ {
10684
+ content: getFullDate({ date: getValue(), includeTime: true }),
10685
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10686
+ }
10687
+ );
10688
+ },
10689
+ enableSorting: true,
10690
+ sortAscLabel: "Oldest first",
10691
+ sortDescLabel: "Newest first"
10692
+ }),
10693
+ columnHelper.accessor("created_at", {
10694
+ header: "Created",
10695
+ cell: ({ getValue }) => {
10696
+ return /* @__PURE__ */ jsxRuntime.jsx(
10697
+ ui.Tooltip,
10698
+ {
10699
+ content: getFullDate({ date: getValue(), includeTime: true }),
10700
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10701
+ }
10702
+ );
10703
+ },
10704
+ enableSorting: true,
10705
+ sortAscLabel: "Oldest first",
10706
+ sortDescLabel: "Newest first"
10707
+ })
10708
+ ];
10709
+ }, []);
10710
+ };
10711
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10712
+ const { setIsOpen } = useStackedModal();
10713
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10714
+ const form = reactHookForm.useForm({
10715
+ defaultValues: {
10716
+ title: "",
10717
+ quantity: 1,
10718
+ unit_price: ""
10719
+ },
10720
+ resolver: zod.zodResolver(customItemSchema)
10721
+ });
10722
+ const onSubmit = form.handleSubmit(async (data) => {
10723
+ await addItems(
10724
+ {
10725
+ items: [
10726
+ {
10727
+ title: data.title,
10728
+ quantity: data.quantity,
10729
+ unit_price: convertNumber(data.unit_price)
10730
+ }
10731
+ ]
10732
+ },
10733
+ {
10734
+ onSuccess: () => {
10735
+ setIsOpen(STACKED_MODAL_ID, false);
10736
+ },
10737
+ onError: (e) => {
10738
+ ui.toast.error(e.message);
10739
+ }
10740
+ }
10741
+ );
10742
+ });
10743
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10744
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10745
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10746
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10747
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10748
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
10749
+ ] }),
10750
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10751
+ /* @__PURE__ */ jsxRuntime.jsx(
10752
+ Form$2.Field,
10753
+ {
10754
+ control: form.control,
10755
+ name: "title",
10756
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10757
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10758
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10759
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10760
+ ] }),
10761
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10762
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10763
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10764
+ ] })
10765
+ ] }) })
10766
+ }
10767
+ ),
10768
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10769
+ /* @__PURE__ */ jsxRuntime.jsx(
10770
+ Form$2.Field,
10771
+ {
10772
+ control: form.control,
10773
+ name: "unit_price",
10774
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10775
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10776
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10777
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10778
+ ] }),
10779
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10780
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10781
+ ui.CurrencyInput,
10782
+ {
10783
+ symbol: getNativeSymbol(currencyCode),
10784
+ code: currencyCode,
10785
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10786
+ ...field
10787
+ }
10788
+ ) }),
10789
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10790
+ ] })
10791
+ ] }) })
10792
+ }
10793
+ ),
10794
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10795
+ /* @__PURE__ */ jsxRuntime.jsx(
10796
+ Form$2.Field,
10797
+ {
10798
+ control: form.control,
10799
+ name: "quantity",
10800
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10801
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10802
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10803
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10804
+ ] }),
10805
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
10806
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10807
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10808
+ ] })
10809
+ ] }) })
10810
+ }
10811
+ )
10812
+ ] }) }) }),
10813
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10814
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10815
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10816
+ ] }) })
10817
+ ] }) }) });
10818
+ };
10819
+ const customItemSchema = objectType({
10820
+ title: stringType().min(1),
10821
+ quantity: numberType(),
10822
+ unit_price: unionType([numberType(), stringType()])
10823
+ });
10824
+ const InlineTip = React.forwardRef(
10825
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10826
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10827
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10828
+ "div",
10829
+ {
10830
+ ref,
10831
+ className: ui.clx(
10832
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10833
+ className
10834
+ ),
10835
+ ...props,
10836
+ children: [
10837
+ /* @__PURE__ */ jsxRuntime.jsx(
10838
+ "div",
10839
+ {
10840
+ role: "presentation",
10841
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10842
+ "bg-ui-tag-orange-icon": variant === "warning"
10843
+ })
10844
+ }
10845
+ ),
10846
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10847
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10848
+ labelValue,
10849
+ ":"
10850
+ ] }),
10851
+ " ",
10852
+ children
10853
+ ] })
10854
+ ]
10855
+ }
10856
+ );
10857
+ }
10858
+ );
10859
+ InlineTip.displayName = "InlineTip";
10860
+ const MetadataFieldSchema = objectType({
10861
+ key: stringType(),
10862
+ disabled: booleanType().optional(),
10863
+ value: anyType()
10864
+ });
10865
+ const MetadataSchema = objectType({
10866
+ metadata: arrayType(MetadataFieldSchema)
10867
+ });
10868
+ const Metadata = () => {
10869
+ const { id } = reactRouterDom.useParams();
10870
+ const { order, isPending, isError, error } = useOrder(id, {
10871
+ fields: "metadata"
10872
+ });
10873
+ if (isError) {
10874
+ throw error;
10875
+ }
10876
+ const isReady = !isPending && !!order;
10877
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10878
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10879
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10880
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10881
+ ] }),
10882
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10883
+ ] });
10884
+ };
10885
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10886
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10887
+ const MetadataForm = ({ orderId, metadata }) => {
10888
+ const { handleSuccess } = useRouteModal();
10889
+ const hasUneditableRows = getHasUneditableRows(metadata);
10890
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10891
+ const form = reactHookForm.useForm({
10892
+ defaultValues: {
10893
+ metadata: getDefaultValues(metadata)
10894
+ },
10895
+ resolver: zod.zodResolver(MetadataSchema)
10896
+ });
10897
+ const handleSubmit = form.handleSubmit(async (data) => {
10898
+ const parsedData = parseValues(data);
10899
+ await mutateAsync(
10900
+ {
10901
+ metadata: parsedData
10902
+ },
10903
+ {
10904
+ onSuccess: () => {
10905
+ ui.toast.success("Metadata updated");
10906
+ handleSuccess();
10907
+ },
10908
+ onError: (error) => {
10909
+ ui.toast.error(error.message);
10910
+ }
10911
+ }
10912
+ );
10913
+ });
10914
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10915
+ control: form.control,
10916
+ name: "metadata"
10917
+ });
10918
+ function deleteRow(index) {
10919
+ remove(index);
10920
+ if (fields.length === 1) {
10921
+ insert(0, {
10922
+ key: "",
10923
+ value: "",
10924
+ disabled: false
10925
+ });
10926
+ }
10927
+ }
10928
+ function insertRow(index, position) {
10929
+ insert(index + (position === "above" ? 0 : 1), {
10930
+ key: "",
10931
+ value: "",
10932
+ disabled: false
10933
+ });
10934
+ }
10935
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10936
+ KeyboundForm,
10937
+ {
10938
+ onSubmit: handleSubmit,
10939
+ className: "flex flex-1 flex-col overflow-hidden",
10940
+ children: [
10941
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10942
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10944
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10945
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10946
+ ] }),
10947
+ fields.map((field, index) => {
10948
+ const isDisabled = field.disabled || false;
10949
+ let placeholder = "-";
10950
+ if (typeof field.value === "object") {
10951
+ placeholder = "{ ... }";
10952
+ }
10953
+ if (Array.isArray(field.value)) {
10954
+ placeholder = "[ ... ]";
10955
+ }
10956
+ return /* @__PURE__ */ jsxRuntime.jsx(
10957
+ ConditionalTooltip,
10958
+ {
10959
+ showTooltip: isDisabled,
10960
+ content: "This row is disabled because it contains non-primitive data.",
10961
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10962
+ /* @__PURE__ */ jsxRuntime.jsxs(
10963
+ "div",
10964
+ {
10965
+ className: ui.clx("grid grid-cols-2 divide-x", {
10966
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10967
+ }),
10968
+ children: [
10969
+ /* @__PURE__ */ jsxRuntime.jsx(
10970
+ Form$2.Field,
10971
+ {
10972
+ control: form.control,
10973
+ name: `metadata.${index}.key`,
10974
+ render: ({ field: field2 }) => {
10975
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10976
+ GridInput,
10977
+ {
10978
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10979
+ ...field2,
10980
+ disabled: isDisabled,
10981
+ placeholder: "Key"
10982
+ }
10983
+ ) }) });
10984
+ }
10985
+ }
10986
+ ),
10987
+ /* @__PURE__ */ jsxRuntime.jsx(
10988
+ Form$2.Field,
10989
+ {
10990
+ control: form.control,
10991
+ name: `metadata.${index}.value`,
10992
+ render: ({ field: { value, ...field2 } }) => {
10993
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10994
+ GridInput,
10995
+ {
10996
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10997
+ ...field2,
10998
+ value: isDisabled ? placeholder : value,
10999
+ disabled: isDisabled,
11000
+ placeholder: "Value"
11001
+ }
11002
+ ) }) });
11003
+ }
11004
+ }
11005
+ )
11006
+ ]
11007
+ }
11008
+ ),
11009
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11010
+ /* @__PURE__ */ jsxRuntime.jsx(
11011
+ ui.DropdownMenu.Trigger,
11012
+ {
11013
+ className: ui.clx(
11014
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11015
+ {
11016
+ hidden: isDisabled
11017
+ }
11018
+ ),
11019
+ disabled: isDisabled,
11020
+ asChild: true,
11021
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11022
+ }
11023
+ ),
11024
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11025
+ /* @__PURE__ */ jsxRuntime.jsxs(
11026
+ ui.DropdownMenu.Item,
11027
+ {
11028
+ className: "gap-x-2",
11029
+ onClick: () => insertRow(index, "above"),
11030
+ children: [
11031
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11032
+ "Insert row above"
11033
+ ]
11034
+ }
11035
+ ),
11036
+ /* @__PURE__ */ jsxRuntime.jsxs(
11037
+ ui.DropdownMenu.Item,
11038
+ {
11039
+ className: "gap-x-2",
11040
+ onClick: () => insertRow(index, "below"),
11041
+ children: [
11042
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11043
+ "Insert row below"
11044
+ ]
11045
+ }
11046
+ ),
11047
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11048
+ /* @__PURE__ */ jsxRuntime.jsxs(
11049
+ ui.DropdownMenu.Item,
11050
+ {
11051
+ className: "gap-x-2",
11052
+ onClick: () => deleteRow(index),
11053
+ children: [
11054
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11055
+ "Delete row"
11056
+ ]
11057
+ }
11058
+ )
11059
+ ] })
11060
+ ] })
11061
+ ] })
11062
+ },
11063
+ field.id
11064
+ );
11065
+ })
11066
+ ] }),
11067
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11068
+ ] }),
11069
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11070
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11071
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11072
+ ] }) })
11073
+ ]
11074
+ }
11075
+ ) });
11076
+ };
11077
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11078
+ return /* @__PURE__ */ jsxRuntime.jsx(
11079
+ "input",
11080
+ {
11081
+ ref,
11082
+ ...props,
11083
+ autoComplete: "off",
11084
+ className: ui.clx(
11085
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
11086
+ className
11087
+ )
11088
+ }
11089
+ );
11090
+ });
11091
+ GridInput.displayName = "MetadataForm.GridInput";
11092
+ const PlaceholderInner = () => {
11093
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11094
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11095
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11096
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11097
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11098
+ ] }) })
11099
+ ] });
11100
+ };
11101
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11102
+ function getDefaultValues(metadata) {
11103
+ if (!metadata || !Object.keys(metadata).length) {
10998
11104
  return [
10999
- columnHelper.select(),
11000
- columnHelper.accessor("product.title", {
11001
- header: "Product",
11002
- cell: ({ row }) => {
11003
- var _a, _b, _c;
11004
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11005
- /* @__PURE__ */ jsxRuntime.jsx(
11006
- Thumbnail,
11007
- {
11008
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11009
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11010
- }
11011
- ),
11012
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11013
- ] });
11014
- },
11015
- enableSorting: true
11016
- }),
11017
- columnHelper.accessor("title", {
11018
- header: "Variant",
11019
- enableSorting: true
11020
- }),
11021
- columnHelper.accessor("sku", {
11022
- header: "SKU",
11023
- cell: ({ getValue }) => {
11024
- return getValue() ?? "-";
11025
- },
11026
- enableSorting: true
11027
- }),
11028
- columnHelper.accessor("updated_at", {
11029
- header: "Updated",
11030
- cell: ({ getValue }) => {
11031
- return /* @__PURE__ */ jsxRuntime.jsx(
11032
- ui.Tooltip,
11033
- {
11034
- content: getFullDate({ date: getValue(), includeTime: true }),
11035
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11036
- }
11037
- );
11038
- },
11039
- enableSorting: true,
11040
- sortAscLabel: "Oldest first",
11041
- sortDescLabel: "Newest first"
11042
- }),
11043
- columnHelper.accessor("created_at", {
11044
- header: "Created",
11045
- cell: ({ getValue }) => {
11046
- return /* @__PURE__ */ jsxRuntime.jsx(
11047
- ui.Tooltip,
11048
- {
11049
- content: getFullDate({ date: getValue(), includeTime: true }),
11050
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11051
- }
11052
- );
11053
- },
11054
- enableSorting: true,
11055
- sortAscLabel: "Oldest first",
11056
- sortDescLabel: "Newest first"
11057
- })
11105
+ {
11106
+ key: "",
11107
+ value: "",
11108
+ disabled: false
11109
+ }
11058
11110
  ];
11059
- }, []);
11060
- };
11061
- const CustomItemForm = ({ orderId, currencyCode }) => {
11062
- const { setIsOpen } = useStackedModal();
11063
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11064
- const form = reactHookForm.useForm({
11065
- defaultValues: {
11066
- title: "",
11067
- quantity: 1,
11068
- unit_price: ""
11069
- },
11070
- resolver: zod.zodResolver(customItemSchema)
11111
+ }
11112
+ return Object.entries(metadata).map(([key, value]) => {
11113
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11114
+ return {
11115
+ key,
11116
+ value,
11117
+ disabled: true
11118
+ };
11119
+ }
11120
+ let stringValue = value;
11121
+ if (typeof value !== "string") {
11122
+ stringValue = JSON.stringify(value);
11123
+ }
11124
+ return {
11125
+ key,
11126
+ value: stringValue,
11127
+ original_key: key
11128
+ };
11071
11129
  });
11072
- const onSubmit = form.handleSubmit(async (data) => {
11073
- await addItems(
11074
- {
11075
- items: [
11076
- {
11077
- title: data.title,
11078
- quantity: data.quantity,
11079
- unit_price: convertNumber(data.unit_price)
11080
- }
11081
- ]
11082
- },
11083
- {
11084
- onSuccess: () => {
11085
- setIsOpen(STACKED_MODAL_ID, false);
11086
- },
11087
- onError: (e) => {
11088
- ui.toast.error(e.message);
11089
- }
11130
+ }
11131
+ function parseValues(values) {
11132
+ const metadata = values.metadata;
11133
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11134
+ if (isEmpty) {
11135
+ return null;
11136
+ }
11137
+ const update = {};
11138
+ metadata.forEach((field) => {
11139
+ let key = field.key;
11140
+ let value = field.value;
11141
+ const disabled = field.disabled;
11142
+ if (!key || !value) {
11143
+ return;
11144
+ }
11145
+ if (disabled) {
11146
+ update[key] = value;
11147
+ return;
11148
+ }
11149
+ key = key.trim();
11150
+ value = value.trim();
11151
+ if (value === "true") {
11152
+ update[key] = true;
11153
+ } else if (value === "false") {
11154
+ update[key] = false;
11155
+ } else {
11156
+ const parsedNumber = parseFloat(value);
11157
+ if (!isNaN(parsedNumber)) {
11158
+ update[key] = parsedNumber;
11159
+ } else {
11160
+ update[key] = value;
11090
11161
  }
11091
- );
11162
+ }
11092
11163
  });
11093
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11094
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11095
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
11096
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11097
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
11098
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
11099
- ] }),
11100
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11101
- /* @__PURE__ */ jsxRuntime.jsx(
11102
- Form$2.Field,
11103
- {
11104
- control: form.control,
11105
- name: "title",
11106
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11107
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11108
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
11109
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
11110
- ] }),
11111
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11112
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11113
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11114
- ] })
11115
- ] }) })
11116
- }
11117
- ),
11118
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11119
- /* @__PURE__ */ jsxRuntime.jsx(
11120
- Form$2.Field,
11121
- {
11122
- control: form.control,
11123
- name: "unit_price",
11124
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11125
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11126
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
11127
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11128
- ] }),
11129
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11130
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11131
- ui.CurrencyInput,
11132
- {
11133
- symbol: getNativeSymbol(currencyCode),
11134
- code: currencyCode,
11135
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11136
- ...field
11137
- }
11138
- ) }),
11139
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11140
- ] })
11141
- ] }) })
11142
- }
11143
- ),
11144
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11145
- /* @__PURE__ */ jsxRuntime.jsx(
11146
- Form$2.Field,
11147
- {
11148
- control: form.control,
11149
- name: "quantity",
11150
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11151
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11152
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
11153
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11154
- ] }),
11155
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
11156
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11157
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11158
- ] })
11159
- ] }) })
11160
- }
11161
- )
11162
- ] }) }) }),
11163
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11164
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11165
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11166
- ] }) })
11167
- ] }) }) });
11168
- };
11169
- const customItemSchema = objectType({
11170
- title: stringType().min(1),
11171
- quantity: numberType(),
11172
- unit_price: unionType([numberType(), stringType()])
11173
- });
11164
+ return update;
11165
+ }
11166
+ function getHasUneditableRows(metadata) {
11167
+ if (!metadata) {
11168
+ return false;
11169
+ }
11170
+ return Object.values(metadata).some(
11171
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11172
+ );
11173
+ }
11174
11174
  const PROMOTION_QUERY_KEY = "promotions";
11175
11175
  const promotionsQueryKeys = {
11176
11176
  list: (query2) => [
@@ -13068,10 +13068,6 @@ const routeModule = {
13068
13068
  Component: CustomItems,
13069
13069
  path: "/draft-orders/:id/custom-items"
13070
13070
  },
13071
- {
13072
- Component: Metadata,
13073
- path: "/draft-orders/:id/metadata"
13074
- },
13075
13071
  {
13076
13072
  Component: Email,
13077
13073
  path: "/draft-orders/:id/email"
@@ -13080,6 +13076,10 @@ const routeModule = {
13080
13076
  Component: Items,
13081
13077
  path: "/draft-orders/:id/items"
13082
13078
  },
13079
+ {
13080
+ Component: Metadata,
13081
+ path: "/draft-orders/:id/metadata"
13082
+ },
13083
13083
  {
13084
13084
  Component: Promotions,
13085
13085
  path: "/draft-orders/:id/promotions"