@medusajs/draft-order 2.11.4-preview-20251118120154 → 2.11.4-preview-20251118180132

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.
@@ -9762,27 +9762,6 @@ const BillingAddressForm = ({ order }) => {
9762
9762
  ) });
9763
9763
  };
9764
9764
  const schema$5 = addressSchema;
9765
- const CustomItems = () => {
9766
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9767
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9768
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9769
- ] });
9770
- };
9771
- const CustomItemsForm = () => {
9772
- const form = reactHookForm.useForm({
9773
- resolver: zod.zodResolver(schema$4)
9774
- });
9775
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9776
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9777
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9778
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9779
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9780
- ] }) })
9781
- ] }) });
9782
- };
9783
- const schema$4 = objectType({
9784
- email: stringType().email()
9785
- });
9786
9765
  const Email = () => {
9787
9766
  const { id } = reactRouterDom.useParams();
9788
9767
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9805,7 +9784,7 @@ const EmailForm = ({ order }) => {
9805
9784
  defaultValues: {
9806
9785
  email: order.email ?? ""
9807
9786
  },
9808
- resolver: zod.zodResolver(schema$3)
9787
+ resolver: zod.zodResolver(schema$4)
9809
9788
  });
9810
9789
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9811
9790
  const { handleSuccess } = useRouteModal();
@@ -9848,6 +9827,27 @@ const EmailForm = ({ order }) => {
9848
9827
  }
9849
9828
  ) });
9850
9829
  };
9830
+ const schema$4 = objectType({
9831
+ email: stringType().email()
9832
+ });
9833
+ const CustomItems = () => {
9834
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9835
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9836
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9837
+ ] });
9838
+ };
9839
+ const CustomItemsForm = () => {
9840
+ const form = reactHookForm.useForm({
9841
+ resolver: zod.zodResolver(schema$3)
9842
+ });
9843
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9844
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9845
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9846
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9847
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9848
+ ] }) })
9849
+ ] }) });
9850
+ };
9851
9851
  const schema$3 = objectType({
9852
9852
  email: stringType().email()
9853
9853
  });
@@ -11102,88 +11102,46 @@ function getPromotionIds(items, shippingMethods) {
11102
11102
  }
11103
11103
  return Array.from(promotionIds);
11104
11104
  }
11105
- const InlineTip = React.forwardRef(
11106
- ({ variant = "tip", label, className, children, ...props }, ref) => {
11107
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11108
- return /* @__PURE__ */ jsxRuntime.jsxs(
11109
- "div",
11110
- {
11111
- ref,
11112
- className: ui.clx(
11113
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11114
- className
11115
- ),
11116
- ...props,
11117
- children: [
11118
- /* @__PURE__ */ jsxRuntime.jsx(
11119
- "div",
11120
- {
11121
- role: "presentation",
11122
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11123
- "bg-ui-tag-orange-icon": variant === "warning"
11124
- })
11125
- }
11126
- ),
11127
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11128
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11129
- labelValue,
11130
- ":"
11131
- ] }),
11132
- " ",
11133
- children
11134
- ] })
11135
- ]
11136
- }
11137
- );
11138
- }
11139
- );
11140
- InlineTip.displayName = "InlineTip";
11141
- const MetadataFieldSchema = objectType({
11142
- key: stringType(),
11143
- disabled: booleanType().optional(),
11144
- value: anyType()
11145
- });
11146
- const MetadataSchema = objectType({
11147
- metadata: arrayType(MetadataFieldSchema)
11148
- });
11149
- const Metadata = () => {
11105
+ const SalesChannel = () => {
11150
11106
  const { id } = reactRouterDom.useParams();
11151
- const { order, isPending, isError, error } = useOrder(id, {
11152
- fields: "metadata"
11153
- });
11107
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11108
+ id,
11109
+ {
11110
+ fields: "+sales_channel_id"
11111
+ },
11112
+ {
11113
+ enabled: !!id
11114
+ }
11115
+ );
11154
11116
  if (isError) {
11155
11117
  throw error;
11156
11118
  }
11157
- const isReady = !isPending && !!order;
11119
+ const ISrEADY = !!draft_order && !isPending;
11158
11120
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11159
11121
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11160
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11161
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11122
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11123
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11162
11124
  ] }),
11163
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11125
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11164
11126
  ] });
11165
11127
  };
11166
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11167
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11168
- const MetadataForm = ({ orderId, metadata }) => {
11169
- const { handleSuccess } = useRouteModal();
11170
- const hasUneditableRows = getHasUneditableRows(metadata);
11171
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11128
+ const SalesChannelForm = ({ order }) => {
11172
11129
  const form = reactHookForm.useForm({
11173
11130
  defaultValues: {
11174
- metadata: getDefaultValues(metadata)
11131
+ sales_channel_id: order.sales_channel_id || ""
11175
11132
  },
11176
- resolver: zod.zodResolver(MetadataSchema)
11133
+ resolver: zod.zodResolver(schema$2)
11177
11134
  });
11178
- const handleSubmit = form.handleSubmit(async (data) => {
11179
- const parsedData = parseValues(data);
11135
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11136
+ const { handleSuccess } = useRouteModal();
11137
+ const onSubmit = form.handleSubmit(async (data) => {
11180
11138
  await mutateAsync(
11181
11139
  {
11182
- metadata: parsedData
11140
+ sales_channel_id: data.sales_channel_id
11183
11141
  },
11184
11142
  {
11185
11143
  onSuccess: () => {
11186
- ui.toast.success("Metadata updated");
11144
+ ui.toast.success("Sales channel updated");
11187
11145
  handleSuccess();
11188
11146
  },
11189
11147
  onError: (error) => {
@@ -11192,319 +11150,11 @@ const MetadataForm = ({ orderId, metadata }) => {
11192
11150
  }
11193
11151
  );
11194
11152
  });
11195
- const { fields, insert, remove } = reactHookForm.useFieldArray({
11196
- control: form.control,
11197
- name: "metadata"
11198
- });
11199
- function deleteRow(index) {
11200
- remove(index);
11201
- if (fields.length === 1) {
11202
- insert(0, {
11203
- key: "",
11204
- value: "",
11205
- disabled: false
11206
- });
11207
- }
11208
- }
11209
- function insertRow(index, position) {
11210
- insert(index + (position === "above" ? 0 : 1), {
11211
- key: "",
11212
- value: "",
11213
- disabled: false
11214
- });
11215
- }
11216
11153
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11217
11154
  KeyboundForm,
11218
11155
  {
11219
- onSubmit: handleSubmit,
11220
11156
  className: "flex flex-1 flex-col overflow-hidden",
11221
- children: [
11222
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11223
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11224
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11225
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
11226
- /* @__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" }) })
11227
- ] }),
11228
- fields.map((field, index) => {
11229
- const isDisabled = field.disabled || false;
11230
- let placeholder = "-";
11231
- if (typeof field.value === "object") {
11232
- placeholder = "{ ... }";
11233
- }
11234
- if (Array.isArray(field.value)) {
11235
- placeholder = "[ ... ]";
11236
- }
11237
- return /* @__PURE__ */ jsxRuntime.jsx(
11238
- ConditionalTooltip,
11239
- {
11240
- showTooltip: isDisabled,
11241
- content: "This row is disabled because it contains non-primitive data.",
11242
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11243
- /* @__PURE__ */ jsxRuntime.jsxs(
11244
- "div",
11245
- {
11246
- className: ui.clx("grid grid-cols-2 divide-x", {
11247
- "overflow-hidden rounded-b-lg": index === fields.length - 1
11248
- }),
11249
- children: [
11250
- /* @__PURE__ */ jsxRuntime.jsx(
11251
- Form$2.Field,
11252
- {
11253
- control: form.control,
11254
- name: `metadata.${index}.key`,
11255
- render: ({ field: field2 }) => {
11256
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11257
- GridInput,
11258
- {
11259
- "aria-labelledby": METADATA_KEY_LABEL_ID,
11260
- ...field2,
11261
- disabled: isDisabled,
11262
- placeholder: "Key"
11263
- }
11264
- ) }) });
11265
- }
11266
- }
11267
- ),
11268
- /* @__PURE__ */ jsxRuntime.jsx(
11269
- Form$2.Field,
11270
- {
11271
- control: form.control,
11272
- name: `metadata.${index}.value`,
11273
- render: ({ field: { value, ...field2 } }) => {
11274
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11275
- GridInput,
11276
- {
11277
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11278
- ...field2,
11279
- value: isDisabled ? placeholder : value,
11280
- disabled: isDisabled,
11281
- placeholder: "Value"
11282
- }
11283
- ) }) });
11284
- }
11285
- }
11286
- )
11287
- ]
11288
- }
11289
- ),
11290
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11291
- /* @__PURE__ */ jsxRuntime.jsx(
11292
- ui.DropdownMenu.Trigger,
11293
- {
11294
- className: ui.clx(
11295
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11296
- {
11297
- hidden: isDisabled
11298
- }
11299
- ),
11300
- disabled: isDisabled,
11301
- asChild: true,
11302
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11303
- }
11304
- ),
11305
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11306
- /* @__PURE__ */ jsxRuntime.jsxs(
11307
- ui.DropdownMenu.Item,
11308
- {
11309
- className: "gap-x-2",
11310
- onClick: () => insertRow(index, "above"),
11311
- children: [
11312
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11313
- "Insert row above"
11314
- ]
11315
- }
11316
- ),
11317
- /* @__PURE__ */ jsxRuntime.jsxs(
11318
- ui.DropdownMenu.Item,
11319
- {
11320
- className: "gap-x-2",
11321
- onClick: () => insertRow(index, "below"),
11322
- children: [
11323
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11324
- "Insert row below"
11325
- ]
11326
- }
11327
- ),
11328
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11329
- /* @__PURE__ */ jsxRuntime.jsxs(
11330
- ui.DropdownMenu.Item,
11331
- {
11332
- className: "gap-x-2",
11333
- onClick: () => deleteRow(index),
11334
- children: [
11335
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11336
- "Delete row"
11337
- ]
11338
- }
11339
- )
11340
- ] })
11341
- ] })
11342
- ] })
11343
- },
11344
- field.id
11345
- );
11346
- })
11347
- ] }),
11348
- 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." })
11349
- ] }),
11350
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11351
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11352
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11353
- ] }) })
11354
- ]
11355
- }
11356
- ) });
11357
- };
11358
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11359
- return /* @__PURE__ */ jsxRuntime.jsx(
11360
- "input",
11361
- {
11362
- ref,
11363
- ...props,
11364
- autoComplete: "off",
11365
- className: ui.clx(
11366
- "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",
11367
- className
11368
- )
11369
- }
11370
- );
11371
- });
11372
- GridInput.displayName = "MetadataForm.GridInput";
11373
- const PlaceholderInner = () => {
11374
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11375
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11376
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11377
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11378
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11379
- ] }) })
11380
- ] });
11381
- };
11382
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11383
- function getDefaultValues(metadata) {
11384
- if (!metadata || !Object.keys(metadata).length) {
11385
- return [
11386
- {
11387
- key: "",
11388
- value: "",
11389
- disabled: false
11390
- }
11391
- ];
11392
- }
11393
- return Object.entries(metadata).map(([key, value]) => {
11394
- if (!EDITABLE_TYPES.includes(typeof value)) {
11395
- return {
11396
- key,
11397
- value,
11398
- disabled: true
11399
- };
11400
- }
11401
- let stringValue = value;
11402
- if (typeof value !== "string") {
11403
- stringValue = JSON.stringify(value);
11404
- }
11405
- return {
11406
- key,
11407
- value: stringValue,
11408
- original_key: key
11409
- };
11410
- });
11411
- }
11412
- function parseValues(values) {
11413
- const metadata = values.metadata;
11414
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11415
- if (isEmpty) {
11416
- return null;
11417
- }
11418
- const update = {};
11419
- metadata.forEach((field) => {
11420
- let key = field.key;
11421
- let value = field.value;
11422
- const disabled = field.disabled;
11423
- if (!key || !value) {
11424
- return;
11425
- }
11426
- if (disabled) {
11427
- update[key] = value;
11428
- return;
11429
- }
11430
- key = key.trim();
11431
- value = value.trim();
11432
- if (value === "true") {
11433
- update[key] = true;
11434
- } else if (value === "false") {
11435
- update[key] = false;
11436
- } else {
11437
- const parsedNumber = parseFloat(value);
11438
- if (!isNaN(parsedNumber)) {
11439
- update[key] = parsedNumber;
11440
- } else {
11441
- update[key] = value;
11442
- }
11443
- }
11444
- });
11445
- return update;
11446
- }
11447
- function getHasUneditableRows(metadata) {
11448
- if (!metadata) {
11449
- return false;
11450
- }
11451
- return Object.values(metadata).some(
11452
- (value) => !EDITABLE_TYPES.includes(typeof value)
11453
- );
11454
- }
11455
- const SalesChannel = () => {
11456
- const { id } = reactRouterDom.useParams();
11457
- const { draft_order, isPending, isError, error } = useDraftOrder(
11458
- id,
11459
- {
11460
- fields: "+sales_channel_id"
11461
- },
11462
- {
11463
- enabled: !!id
11464
- }
11465
- );
11466
- if (isError) {
11467
- throw error;
11468
- }
11469
- const ISrEADY = !!draft_order && !isPending;
11470
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11471
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11472
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11473
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11474
- ] }),
11475
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11476
- ] });
11477
- };
11478
- const SalesChannelForm = ({ order }) => {
11479
- const form = reactHookForm.useForm({
11480
- defaultValues: {
11481
- sales_channel_id: order.sales_channel_id || ""
11482
- },
11483
- resolver: zod.zodResolver(schema$2)
11484
- });
11485
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11486
- const { handleSuccess } = useRouteModal();
11487
- const onSubmit = form.handleSubmit(async (data) => {
11488
- await mutateAsync(
11489
- {
11490
- sales_channel_id: data.sales_channel_id
11491
- },
11492
- {
11493
- onSuccess: () => {
11494
- ui.toast.success("Sales channel updated");
11495
- handleSuccess();
11496
- },
11497
- onError: (error) => {
11498
- ui.toast.error(error.message);
11499
- }
11500
- }
11501
- );
11502
- });
11503
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11504
- KeyboundForm,
11505
- {
11506
- className: "flex flex-1 flex-col overflow-hidden",
11507
- onSubmit,
11157
+ onSubmit,
11508
11158
  children: [
11509
11159
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11510
11160
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
@@ -13044,65 +12694,415 @@ const Illustration = () => {
13044
12694
  const schema = objectType({
13045
12695
  customer_id: stringType().min(1)
13046
12696
  });
13047
- const widgetModule = { widgets: [] };
13048
- const routeModule = {
13049
- routes: [
13050
- {
13051
- Component: List,
13052
- path: "/draft-orders",
13053
- handle: handle$1,
13054
- children: [
13055
- {
13056
- Component: Create,
13057
- path: "/draft-orders/create"
13058
- }
13059
- ]
13060
- },
13061
- {
13062
- Component: ID,
13063
- path: "/draft-orders/:id",
13064
- handle,
13065
- loader,
13066
- children: [
13067
- {
13068
- Component: BillingAddress,
13069
- path: "/draft-orders/:id/billing-address"
13070
- },
13071
- {
13072
- Component: CustomItems,
13073
- path: "/draft-orders/:id/custom-items"
13074
- },
13075
- {
13076
- Component: Email,
13077
- path: "/draft-orders/:id/email"
13078
- },
13079
- {
13080
- Component: Items,
13081
- path: "/draft-orders/:id/items"
13082
- },
13083
- {
13084
- Component: Promotions,
13085
- path: "/draft-orders/:id/promotions"
13086
- },
13087
- {
13088
- Component: Metadata,
13089
- path: "/draft-orders/:id/metadata"
13090
- },
13091
- {
13092
- Component: SalesChannel,
13093
- path: "/draft-orders/:id/sales-channel"
13094
- },
13095
- {
13096
- Component: Shipping,
13097
- path: "/draft-orders/:id/shipping"
13098
- },
13099
- {
13100
- Component: ShippingAddress,
13101
- path: "/draft-orders/:id/shipping-address"
13102
- },
13103
- {
13104
- Component: TransferOwnership,
13105
- path: "/draft-orders/:id/transfer-ownership"
12697
+ const InlineTip = React.forwardRef(
12698
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
12699
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
12700
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12701
+ "div",
12702
+ {
12703
+ ref,
12704
+ className: ui.clx(
12705
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
12706
+ className
12707
+ ),
12708
+ ...props,
12709
+ children: [
12710
+ /* @__PURE__ */ jsxRuntime.jsx(
12711
+ "div",
12712
+ {
12713
+ role: "presentation",
12714
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
12715
+ "bg-ui-tag-orange-icon": variant === "warning"
12716
+ })
12717
+ }
12718
+ ),
12719
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
12720
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
12721
+ labelValue,
12722
+ ":"
12723
+ ] }),
12724
+ " ",
12725
+ children
12726
+ ] })
12727
+ ]
12728
+ }
12729
+ );
12730
+ }
12731
+ );
12732
+ InlineTip.displayName = "InlineTip";
12733
+ const MetadataFieldSchema = objectType({
12734
+ key: stringType(),
12735
+ disabled: booleanType().optional(),
12736
+ value: anyType()
12737
+ });
12738
+ const MetadataSchema = objectType({
12739
+ metadata: arrayType(MetadataFieldSchema)
12740
+ });
12741
+ const Metadata = () => {
12742
+ const { id } = reactRouterDom.useParams();
12743
+ const { order, isPending, isError, error } = useOrder(id, {
12744
+ fields: "metadata"
12745
+ });
12746
+ if (isError) {
12747
+ throw error;
12748
+ }
12749
+ const isReady = !isPending && !!order;
12750
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12751
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12752
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
12753
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
12754
+ ] }),
12755
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
12756
+ ] });
12757
+ };
12758
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
12759
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
12760
+ const MetadataForm = ({ orderId, metadata }) => {
12761
+ const { handleSuccess } = useRouteModal();
12762
+ const hasUneditableRows = getHasUneditableRows(metadata);
12763
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
12764
+ const form = reactHookForm.useForm({
12765
+ defaultValues: {
12766
+ metadata: getDefaultValues(metadata)
12767
+ },
12768
+ resolver: zod.zodResolver(MetadataSchema)
12769
+ });
12770
+ const handleSubmit = form.handleSubmit(async (data) => {
12771
+ const parsedData = parseValues(data);
12772
+ await mutateAsync(
12773
+ {
12774
+ metadata: parsedData
12775
+ },
12776
+ {
12777
+ onSuccess: () => {
12778
+ ui.toast.success("Metadata updated");
12779
+ handleSuccess();
12780
+ },
12781
+ onError: (error) => {
12782
+ ui.toast.error(error.message);
12783
+ }
12784
+ }
12785
+ );
12786
+ });
12787
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
12788
+ control: form.control,
12789
+ name: "metadata"
12790
+ });
12791
+ function deleteRow(index) {
12792
+ remove(index);
12793
+ if (fields.length === 1) {
12794
+ insert(0, {
12795
+ key: "",
12796
+ value: "",
12797
+ disabled: false
12798
+ });
12799
+ }
12800
+ }
12801
+ function insertRow(index, position) {
12802
+ insert(index + (position === "above" ? 0 : 1), {
12803
+ key: "",
12804
+ value: "",
12805
+ disabled: false
12806
+ });
12807
+ }
12808
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12809
+ KeyboundForm,
12810
+ {
12811
+ onSubmit: handleSubmit,
12812
+ className: "flex flex-1 flex-col overflow-hidden",
12813
+ children: [
12814
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
12815
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
12816
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
12817
+ /* @__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" }) }),
12818
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
12819
+ ] }),
12820
+ fields.map((field, index) => {
12821
+ const isDisabled = field.disabled || false;
12822
+ let placeholder = "-";
12823
+ if (typeof field.value === "object") {
12824
+ placeholder = "{ ... }";
12825
+ }
12826
+ if (Array.isArray(field.value)) {
12827
+ placeholder = "[ ... ]";
12828
+ }
12829
+ return /* @__PURE__ */ jsxRuntime.jsx(
12830
+ ConditionalTooltip,
12831
+ {
12832
+ showTooltip: isDisabled,
12833
+ content: "This row is disabled because it contains non-primitive data.",
12834
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
12835
+ /* @__PURE__ */ jsxRuntime.jsxs(
12836
+ "div",
12837
+ {
12838
+ className: ui.clx("grid grid-cols-2 divide-x", {
12839
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
12840
+ }),
12841
+ children: [
12842
+ /* @__PURE__ */ jsxRuntime.jsx(
12843
+ Form$2.Field,
12844
+ {
12845
+ control: form.control,
12846
+ name: `metadata.${index}.key`,
12847
+ render: ({ field: field2 }) => {
12848
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12849
+ GridInput,
12850
+ {
12851
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
12852
+ ...field2,
12853
+ disabled: isDisabled,
12854
+ placeholder: "Key"
12855
+ }
12856
+ ) }) });
12857
+ }
12858
+ }
12859
+ ),
12860
+ /* @__PURE__ */ jsxRuntime.jsx(
12861
+ Form$2.Field,
12862
+ {
12863
+ control: form.control,
12864
+ name: `metadata.${index}.value`,
12865
+ render: ({ field: { value, ...field2 } }) => {
12866
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12867
+ GridInput,
12868
+ {
12869
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
12870
+ ...field2,
12871
+ value: isDisabled ? placeholder : value,
12872
+ disabled: isDisabled,
12873
+ placeholder: "Value"
12874
+ }
12875
+ ) }) });
12876
+ }
12877
+ }
12878
+ )
12879
+ ]
12880
+ }
12881
+ ),
12882
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
12883
+ /* @__PURE__ */ jsxRuntime.jsx(
12884
+ ui.DropdownMenu.Trigger,
12885
+ {
12886
+ className: ui.clx(
12887
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
12888
+ {
12889
+ hidden: isDisabled
12890
+ }
12891
+ ),
12892
+ disabled: isDisabled,
12893
+ asChild: true,
12894
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
12895
+ }
12896
+ ),
12897
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
12898
+ /* @__PURE__ */ jsxRuntime.jsxs(
12899
+ ui.DropdownMenu.Item,
12900
+ {
12901
+ className: "gap-x-2",
12902
+ onClick: () => insertRow(index, "above"),
12903
+ children: [
12904
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
12905
+ "Insert row above"
12906
+ ]
12907
+ }
12908
+ ),
12909
+ /* @__PURE__ */ jsxRuntime.jsxs(
12910
+ ui.DropdownMenu.Item,
12911
+ {
12912
+ className: "gap-x-2",
12913
+ onClick: () => insertRow(index, "below"),
12914
+ children: [
12915
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
12916
+ "Insert row below"
12917
+ ]
12918
+ }
12919
+ ),
12920
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
12921
+ /* @__PURE__ */ jsxRuntime.jsxs(
12922
+ ui.DropdownMenu.Item,
12923
+ {
12924
+ className: "gap-x-2",
12925
+ onClick: () => deleteRow(index),
12926
+ children: [
12927
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
12928
+ "Delete row"
12929
+ ]
12930
+ }
12931
+ )
12932
+ ] })
12933
+ ] })
12934
+ ] })
12935
+ },
12936
+ field.id
12937
+ );
12938
+ })
12939
+ ] }),
12940
+ 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." })
12941
+ ] }),
12942
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12943
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12944
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12945
+ ] }) })
12946
+ ]
12947
+ }
12948
+ ) });
12949
+ };
12950
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
12951
+ return /* @__PURE__ */ jsxRuntime.jsx(
12952
+ "input",
12953
+ {
12954
+ ref,
12955
+ ...props,
12956
+ autoComplete: "off",
12957
+ className: ui.clx(
12958
+ "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",
12959
+ className
12960
+ )
12961
+ }
12962
+ );
12963
+ });
12964
+ GridInput.displayName = "MetadataForm.GridInput";
12965
+ const PlaceholderInner = () => {
12966
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
12967
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
12968
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12969
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
12970
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
12971
+ ] }) })
12972
+ ] });
12973
+ };
12974
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
12975
+ function getDefaultValues(metadata) {
12976
+ if (!metadata || !Object.keys(metadata).length) {
12977
+ return [
12978
+ {
12979
+ key: "",
12980
+ value: "",
12981
+ disabled: false
12982
+ }
12983
+ ];
12984
+ }
12985
+ return Object.entries(metadata).map(([key, value]) => {
12986
+ if (!EDITABLE_TYPES.includes(typeof value)) {
12987
+ return {
12988
+ key,
12989
+ value,
12990
+ disabled: true
12991
+ };
12992
+ }
12993
+ let stringValue = value;
12994
+ if (typeof value !== "string") {
12995
+ stringValue = JSON.stringify(value);
12996
+ }
12997
+ return {
12998
+ key,
12999
+ value: stringValue,
13000
+ original_key: key
13001
+ };
13002
+ });
13003
+ }
13004
+ function parseValues(values) {
13005
+ const metadata = values.metadata;
13006
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
13007
+ if (isEmpty) {
13008
+ return null;
13009
+ }
13010
+ const update = {};
13011
+ metadata.forEach((field) => {
13012
+ let key = field.key;
13013
+ let value = field.value;
13014
+ const disabled = field.disabled;
13015
+ if (!key || !value) {
13016
+ return;
13017
+ }
13018
+ if (disabled) {
13019
+ update[key] = value;
13020
+ return;
13021
+ }
13022
+ key = key.trim();
13023
+ value = value.trim();
13024
+ if (value === "true") {
13025
+ update[key] = true;
13026
+ } else if (value === "false") {
13027
+ update[key] = false;
13028
+ } else {
13029
+ const parsedNumber = parseFloat(value);
13030
+ if (!isNaN(parsedNumber)) {
13031
+ update[key] = parsedNumber;
13032
+ } else {
13033
+ update[key] = value;
13034
+ }
13035
+ }
13036
+ });
13037
+ return update;
13038
+ }
13039
+ function getHasUneditableRows(metadata) {
13040
+ if (!metadata) {
13041
+ return false;
13042
+ }
13043
+ return Object.values(metadata).some(
13044
+ (value) => !EDITABLE_TYPES.includes(typeof value)
13045
+ );
13046
+ }
13047
+ const widgetModule = { widgets: [] };
13048
+ const routeModule = {
13049
+ routes: [
13050
+ {
13051
+ Component: List,
13052
+ path: "/draft-orders",
13053
+ handle: handle$1,
13054
+ children: [
13055
+ {
13056
+ Component: Create,
13057
+ path: "/draft-orders/create"
13058
+ }
13059
+ ]
13060
+ },
13061
+ {
13062
+ Component: ID,
13063
+ path: "/draft-orders/:id",
13064
+ handle,
13065
+ loader,
13066
+ children: [
13067
+ {
13068
+ Component: BillingAddress,
13069
+ path: "/draft-orders/:id/billing-address"
13070
+ },
13071
+ {
13072
+ Component: Email,
13073
+ path: "/draft-orders/:id/email"
13074
+ },
13075
+ {
13076
+ Component: CustomItems,
13077
+ path: "/draft-orders/:id/custom-items"
13078
+ },
13079
+ {
13080
+ Component: Items,
13081
+ path: "/draft-orders/:id/items"
13082
+ },
13083
+ {
13084
+ Component: Promotions,
13085
+ path: "/draft-orders/:id/promotions"
13086
+ },
13087
+ {
13088
+ Component: SalesChannel,
13089
+ path: "/draft-orders/:id/sales-channel"
13090
+ },
13091
+ {
13092
+ Component: Shipping,
13093
+ path: "/draft-orders/:id/shipping"
13094
+ },
13095
+ {
13096
+ Component: ShippingAddress,
13097
+ path: "/draft-orders/:id/shipping-address"
13098
+ },
13099
+ {
13100
+ Component: TransferOwnership,
13101
+ path: "/draft-orders/:id/transfer-ownership"
13102
+ },
13103
+ {
13104
+ Component: Metadata,
13105
+ path: "/draft-orders/:id/metadata"
13106
13106
  }
13107
13107
  ]
13108
13108
  }