@medusajs/draft-order 2.20.0-snapshot-20260901111536 → 2.20.0
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.
- package/.medusa/server/src/admin/index.js +716 -679
- package/.medusa/server/src/admin/index.mjs +717 -680
- package/package.json +18 -18
|
@@ -6168,6 +6168,27 @@ const BillingAddressForm = ({ order }) => {
|
|
|
6168
6168
|
) });
|
|
6169
6169
|
};
|
|
6170
6170
|
const schema$5 = addressSchema;
|
|
6171
|
+
const CustomItems = () => {
|
|
6172
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
6173
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
6174
|
+
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
6175
|
+
] });
|
|
6176
|
+
};
|
|
6177
|
+
const CustomItemsForm = () => {
|
|
6178
|
+
const form = reactHookForm.useForm({
|
|
6179
|
+
resolver: zod$1.zodResolver(schema$4)
|
|
6180
|
+
});
|
|
6181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
6182
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
6183
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
6184
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
6185
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
6186
|
+
] }) })
|
|
6187
|
+
] }) });
|
|
6188
|
+
};
|
|
6189
|
+
const schema$4 = zod.z.object({
|
|
6190
|
+
email: zod.z.string().email()
|
|
6191
|
+
});
|
|
6171
6192
|
const Email = () => {
|
|
6172
6193
|
const { id } = reactRouterDom.useParams();
|
|
6173
6194
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -6190,7 +6211,7 @@ const EmailForm = ({ order }) => {
|
|
|
6190
6211
|
defaultValues: {
|
|
6191
6212
|
email: order.email ?? ""
|
|
6192
6213
|
},
|
|
6193
|
-
resolver: zod$1.zodResolver(schema$
|
|
6214
|
+
resolver: zod$1.zodResolver(schema$3)
|
|
6194
6215
|
});
|
|
6195
6216
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
6196
6217
|
const { handleSuccess } = useRouteModal();
|
|
@@ -6233,7 +6254,7 @@ const EmailForm = ({ order }) => {
|
|
|
6233
6254
|
}
|
|
6234
6255
|
) });
|
|
6235
6256
|
};
|
|
6236
|
-
const schema$
|
|
6257
|
+
const schema$3 = zod.z.object({
|
|
6237
6258
|
email: zod.z.string().email()
|
|
6238
6259
|
});
|
|
6239
6260
|
const NumberInput = React.forwardRef(
|
|
@@ -6962,7 +6983,8 @@ const ExistingItemsForm = ({ orderId, items }) => {
|
|
|
6962
6983
|
q,
|
|
6963
6984
|
order,
|
|
6964
6985
|
offset: offset ? parseInt(offset) : void 0,
|
|
6965
|
-
limit: LIMIT
|
|
6986
|
+
limit: LIMIT,
|
|
6987
|
+
fields: "*inventory_items.inventory.location_levels,+inventory_quantity,+manage_inventory"
|
|
6966
6988
|
},
|
|
6967
6989
|
{
|
|
6968
6990
|
placeholderData: reactQuery.keepPreviousData
|
|
@@ -7041,6 +7063,23 @@ const ExistingItemsForm = ({ orderId, items }) => {
|
|
|
7041
7063
|
);
|
|
7042
7064
|
};
|
|
7043
7065
|
const columnHelper = ui.createDataTableColumnHelper();
|
|
7066
|
+
const getVariantInventory = (variant) => {
|
|
7067
|
+
if (!variant.manage_inventory) {
|
|
7068
|
+
return { text: "Not managed", hasInventoryKit: false, notManaged: true };
|
|
7069
|
+
}
|
|
7070
|
+
const quantity = variant.inventory_quantity;
|
|
7071
|
+
const inventoryItems = variant.inventory_items?.map((i) => i.inventory).filter(Boolean) ?? [];
|
|
7072
|
+
const hasInventoryKit = inventoryItems.length > 1;
|
|
7073
|
+
const locations = {};
|
|
7074
|
+
inventoryItems.forEach((i) => {
|
|
7075
|
+
i.location_levels?.forEach((l) => {
|
|
7076
|
+
locations[l.id] = true;
|
|
7077
|
+
});
|
|
7078
|
+
});
|
|
7079
|
+
const locationCount = Object.keys(locations).length;
|
|
7080
|
+
const text = hasInventoryKit ? `${quantity} available` : `${quantity} available at ${locationCount} location${locationCount === 1 ? "" : "s"}`;
|
|
7081
|
+
return { text, hasInventoryKit, quantity, notManaged: false };
|
|
7082
|
+
};
|
|
7044
7083
|
const useColumns = () => {
|
|
7045
7084
|
return React.useMemo(() => {
|
|
7046
7085
|
return [
|
|
@@ -7101,6 +7140,25 @@ const useColumns = () => {
|
|
|
7101
7140
|
enableSorting: true,
|
|
7102
7141
|
sortAscLabel: "Oldest first",
|
|
7103
7142
|
sortDescLabel: "Newest first"
|
|
7143
|
+
}),
|
|
7144
|
+
columnHelper.display({
|
|
7145
|
+
id: "inventory",
|
|
7146
|
+
header: "Stock",
|
|
7147
|
+
cell: ({ row }) => {
|
|
7148
|
+
const { text, hasInventoryKit, quantity, notManaged } = getVariantInventory(row.original);
|
|
7149
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: text, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full w-full items-center gap-2 overflow-hidden", children: [
|
|
7150
|
+
hasInventoryKit && /* @__PURE__ */ jsxRuntime.jsx(icons.Component, {}),
|
|
7151
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7152
|
+
"span",
|
|
7153
|
+
{
|
|
7154
|
+
className: ui.clx("truncate", {
|
|
7155
|
+
"text-ui-fg-error": !quantity && !notManaged
|
|
7156
|
+
}),
|
|
7157
|
+
children: text
|
|
7158
|
+
}
|
|
7159
|
+
)
|
|
7160
|
+
] }) });
|
|
7161
|
+
}
|
|
7104
7162
|
})
|
|
7105
7163
|
];
|
|
7106
7164
|
}, []);
|
|
@@ -7218,499 +7276,128 @@ const customItemSchema = zod.z.object({
|
|
|
7218
7276
|
quantity: zod.z.number(),
|
|
7219
7277
|
unit_price: zod.z.union([zod.z.number(), zod.z.string()])
|
|
7220
7278
|
});
|
|
7221
|
-
const
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7279
|
+
const PROMOTION_QUERY_KEY = "promotions";
|
|
7280
|
+
const promotionsQueryKeys = {
|
|
7281
|
+
list: (query2) => [
|
|
7282
|
+
PROMOTION_QUERY_KEY,
|
|
7283
|
+
query2 ? query2 : void 0
|
|
7284
|
+
],
|
|
7285
|
+
detail: (id, query2) => [
|
|
7286
|
+
PROMOTION_QUERY_KEY,
|
|
7287
|
+
id,
|
|
7288
|
+
query2 ? query2 : void 0
|
|
7289
|
+
]
|
|
7226
7290
|
};
|
|
7227
|
-
const
|
|
7228
|
-
const
|
|
7229
|
-
|
|
7291
|
+
const usePromotions = (query2, options) => {
|
|
7292
|
+
const { data, ...rest } = reactQuery.useQuery({
|
|
7293
|
+
queryKey: promotionsQueryKeys.list(query2),
|
|
7294
|
+
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
7295
|
+
...options
|
|
7230
7296
|
});
|
|
7231
|
-
return
|
|
7232
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
7233
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7234
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7235
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
7236
|
-
] }) })
|
|
7237
|
-
] }) });
|
|
7297
|
+
return { ...data, ...rest };
|
|
7238
7298
|
};
|
|
7239
|
-
const
|
|
7240
|
-
email: zod.z.string().email()
|
|
7241
|
-
});
|
|
7242
|
-
const InlineTip = React.forwardRef(
|
|
7243
|
-
({ variant = "tip", label, className, children, ...props }, ref) => {
|
|
7244
|
-
const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
|
|
7245
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7246
|
-
"div",
|
|
7247
|
-
{
|
|
7248
|
-
ref,
|
|
7249
|
-
className: ui.clx(
|
|
7250
|
-
"bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
|
|
7251
|
-
className
|
|
7252
|
-
),
|
|
7253
|
-
...props,
|
|
7254
|
-
children: [
|
|
7255
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7256
|
-
"div",
|
|
7257
|
-
{
|
|
7258
|
-
role: "presentation",
|
|
7259
|
-
className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
|
|
7260
|
-
"bg-ui-tag-orange-icon": variant === "warning"
|
|
7261
|
-
})
|
|
7262
|
-
}
|
|
7263
|
-
),
|
|
7264
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
|
|
7265
|
-
/* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
|
|
7266
|
-
labelValue,
|
|
7267
|
-
":"
|
|
7268
|
-
] }),
|
|
7269
|
-
" ",
|
|
7270
|
-
children
|
|
7271
|
-
] })
|
|
7272
|
-
]
|
|
7273
|
-
}
|
|
7274
|
-
);
|
|
7275
|
-
}
|
|
7276
|
-
);
|
|
7277
|
-
InlineTip.displayName = "InlineTip";
|
|
7278
|
-
const MetadataFieldSchema = zod.z.object({
|
|
7279
|
-
key: zod.z.string(),
|
|
7280
|
-
disabled: zod.z.boolean().optional(),
|
|
7281
|
-
value: zod.z.any()
|
|
7282
|
-
});
|
|
7283
|
-
const MetadataSchema = zod.z.object({
|
|
7284
|
-
metadata: zod.z.array(MetadataFieldSchema)
|
|
7285
|
-
});
|
|
7286
|
-
const Metadata = () => {
|
|
7299
|
+
const Promotions = () => {
|
|
7287
7300
|
const { id } = reactRouterDom.useParams();
|
|
7288
|
-
const {
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7301
|
+
const {
|
|
7302
|
+
order: preview,
|
|
7303
|
+
isError: isPreviewError,
|
|
7304
|
+
error: previewError
|
|
7305
|
+
} = useOrderPreview(id, void 0);
|
|
7306
|
+
useInitiateOrderEdit({ preview });
|
|
7307
|
+
const { onCancel } = useCancelOrderEdit({ preview });
|
|
7308
|
+
if (isPreviewError) {
|
|
7309
|
+
throw previewError;
|
|
7293
7310
|
}
|
|
7294
|
-
const isReady =
|
|
7295
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7296
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7297
|
-
|
|
7298
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
|
|
7299
|
-
] }),
|
|
7300
|
-
!isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order?.metadata })
|
|
7311
|
+
const isReady = !!preview;
|
|
7312
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
|
|
7313
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
|
|
7314
|
+
isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
|
|
7301
7315
|
] });
|
|
7302
7316
|
};
|
|
7303
|
-
const
|
|
7304
|
-
const
|
|
7305
|
-
const
|
|
7317
|
+
const PromotionForm = ({ preview }) => {
|
|
7318
|
+
const { items, shipping_methods } = preview;
|
|
7319
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
7320
|
+
const [comboboxValue, setComboboxValue] = React.useState("");
|
|
7306
7321
|
const { handleSuccess } = useRouteModal();
|
|
7307
|
-
const
|
|
7308
|
-
const
|
|
7309
|
-
const
|
|
7310
|
-
|
|
7311
|
-
|
|
7322
|
+
const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
|
|
7323
|
+
const promoIds = getPromotionIds(items, shipping_methods);
|
|
7324
|
+
const { promotions, isPending, isError, error } = usePromotions(
|
|
7325
|
+
{
|
|
7326
|
+
id: promoIds
|
|
7312
7327
|
},
|
|
7313
|
-
|
|
7328
|
+
{
|
|
7329
|
+
enabled: !!promoIds.length
|
|
7330
|
+
}
|
|
7331
|
+
);
|
|
7332
|
+
const comboboxData = useComboboxData({
|
|
7333
|
+
queryKey: ["promotions", "combobox", promoIds],
|
|
7334
|
+
queryFn: async (params) => {
|
|
7335
|
+
return await sdk.admin.promotion.list({
|
|
7336
|
+
...params,
|
|
7337
|
+
id: {
|
|
7338
|
+
$nin: promoIds
|
|
7339
|
+
}
|
|
7340
|
+
});
|
|
7341
|
+
},
|
|
7342
|
+
getOptions: (data) => {
|
|
7343
|
+
return data.promotions.map((promotion) => ({
|
|
7344
|
+
label: promotion.code,
|
|
7345
|
+
value: promotion.code
|
|
7346
|
+
}));
|
|
7347
|
+
}
|
|
7314
7348
|
});
|
|
7315
|
-
const
|
|
7316
|
-
|
|
7317
|
-
|
|
7349
|
+
const add = async (value) => {
|
|
7350
|
+
if (!value) {
|
|
7351
|
+
return;
|
|
7352
|
+
}
|
|
7353
|
+
addPromotions(
|
|
7318
7354
|
{
|
|
7319
|
-
|
|
7355
|
+
promo_codes: [value]
|
|
7320
7356
|
},
|
|
7321
7357
|
{
|
|
7322
|
-
|
|
7323
|
-
ui.toast.
|
|
7324
|
-
|
|
7358
|
+
onError: (e) => {
|
|
7359
|
+
ui.toast.error(e.message);
|
|
7360
|
+
comboboxData.onSearchValueChange("");
|
|
7361
|
+
setComboboxValue("");
|
|
7325
7362
|
},
|
|
7326
|
-
|
|
7327
|
-
|
|
7363
|
+
onSuccess: () => {
|
|
7364
|
+
comboboxData.onSearchValueChange("");
|
|
7365
|
+
setComboboxValue("");
|
|
7328
7366
|
}
|
|
7329
7367
|
}
|
|
7330
7368
|
);
|
|
7331
|
-
}
|
|
7332
|
-
const {
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
}
|
|
7369
|
+
};
|
|
7370
|
+
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
7371
|
+
const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
|
|
7372
|
+
const onSubmit = async () => {
|
|
7373
|
+
setIsSubmitting(true);
|
|
7374
|
+
let requestSucceeded = false;
|
|
7375
|
+
await requestOrderEdit(void 0, {
|
|
7376
|
+
onError: (e) => {
|
|
7377
|
+
ui.toast.error(e.message);
|
|
7378
|
+
},
|
|
7379
|
+
onSuccess: () => {
|
|
7380
|
+
requestSucceeded = true;
|
|
7381
|
+
}
|
|
7382
|
+
});
|
|
7383
|
+
if (!requestSucceeded) {
|
|
7384
|
+
setIsSubmitting(false);
|
|
7385
|
+
return;
|
|
7344
7386
|
}
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7387
|
+
await confirmOrderEdit(void 0, {
|
|
7388
|
+
onError: (e) => {
|
|
7389
|
+
ui.toast.error(e.message);
|
|
7390
|
+
},
|
|
7391
|
+
onSuccess: () => {
|
|
7392
|
+
handleSuccess();
|
|
7393
|
+
},
|
|
7394
|
+
onSettled: () => {
|
|
7395
|
+
setIsSubmitting(false);
|
|
7396
|
+
}
|
|
7351
7397
|
});
|
|
7352
|
-
}
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
{
|
|
7356
|
-
onSubmit: handleSubmit,
|
|
7357
|
-
className: "flex flex-1 flex-col overflow-hidden",
|
|
7358
|
-
children: [
|
|
7359
|
-
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
|
|
7360
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
|
|
7361
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
|
|
7362
|
-
/* @__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" }) }),
|
|
7363
|
-
/* @__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" }) })
|
|
7364
|
-
] }),
|
|
7365
|
-
fields.map((field, index) => {
|
|
7366
|
-
const isDisabled = field.disabled || false;
|
|
7367
|
-
let placeholder = "-";
|
|
7368
|
-
if (typeof field.value === "object") {
|
|
7369
|
-
placeholder = "{ ... }";
|
|
7370
|
-
}
|
|
7371
|
-
if (Array.isArray(field.value)) {
|
|
7372
|
-
placeholder = "[ ... ]";
|
|
7373
|
-
}
|
|
7374
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7375
|
-
ConditionalTooltip,
|
|
7376
|
-
{
|
|
7377
|
-
showTooltip: isDisabled,
|
|
7378
|
-
content: "This row is disabled because it contains non-primitive data.",
|
|
7379
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
|
|
7380
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7381
|
-
"div",
|
|
7382
|
-
{
|
|
7383
|
-
className: ui.clx("grid grid-cols-2 divide-x", {
|
|
7384
|
-
"overflow-hidden rounded-b-lg": index === fields.length - 1
|
|
7385
|
-
}),
|
|
7386
|
-
children: [
|
|
7387
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7388
|
-
Form$2.Field,
|
|
7389
|
-
{
|
|
7390
|
-
control: form.control,
|
|
7391
|
-
name: `metadata.${index}.key`,
|
|
7392
|
-
render: ({ field: field2 }) => {
|
|
7393
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7394
|
-
GridInput,
|
|
7395
|
-
{
|
|
7396
|
-
"aria-labelledby": METADATA_KEY_LABEL_ID,
|
|
7397
|
-
...field2,
|
|
7398
|
-
disabled: isDisabled,
|
|
7399
|
-
placeholder: "Key"
|
|
7400
|
-
}
|
|
7401
|
-
) }) });
|
|
7402
|
-
}
|
|
7403
|
-
}
|
|
7404
|
-
),
|
|
7405
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7406
|
-
Form$2.Field,
|
|
7407
|
-
{
|
|
7408
|
-
control: form.control,
|
|
7409
|
-
name: `metadata.${index}.value`,
|
|
7410
|
-
render: ({ field: { value, ...field2 } }) => {
|
|
7411
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7412
|
-
GridInput,
|
|
7413
|
-
{
|
|
7414
|
-
"aria-labelledby": METADATA_VALUE_LABEL_ID,
|
|
7415
|
-
...field2,
|
|
7416
|
-
value: isDisabled ? placeholder : value,
|
|
7417
|
-
disabled: isDisabled,
|
|
7418
|
-
placeholder: "Value"
|
|
7419
|
-
}
|
|
7420
|
-
) }) });
|
|
7421
|
-
}
|
|
7422
|
-
}
|
|
7423
|
-
)
|
|
7424
|
-
]
|
|
7425
|
-
}
|
|
7426
|
-
),
|
|
7427
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
7428
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7429
|
-
ui.DropdownMenu.Trigger,
|
|
7430
|
-
{
|
|
7431
|
-
className: ui.clx(
|
|
7432
|
-
"invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
|
|
7433
|
-
{
|
|
7434
|
-
hidden: isDisabled
|
|
7435
|
-
}
|
|
7436
|
-
),
|
|
7437
|
-
disabled: isDisabled,
|
|
7438
|
-
asChild: true,
|
|
7439
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
|
|
7440
|
-
}
|
|
7441
|
-
),
|
|
7442
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
|
|
7443
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7444
|
-
ui.DropdownMenu.Item,
|
|
7445
|
-
{
|
|
7446
|
-
className: "gap-x-2",
|
|
7447
|
-
onClick: () => insertRow(index, "above"),
|
|
7448
|
-
children: [
|
|
7449
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
|
|
7450
|
-
"Insert row above"
|
|
7451
|
-
]
|
|
7452
|
-
}
|
|
7453
|
-
),
|
|
7454
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7455
|
-
ui.DropdownMenu.Item,
|
|
7456
|
-
{
|
|
7457
|
-
className: "gap-x-2",
|
|
7458
|
-
onClick: () => insertRow(index, "below"),
|
|
7459
|
-
children: [
|
|
7460
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
|
|
7461
|
-
"Insert row below"
|
|
7462
|
-
]
|
|
7463
|
-
}
|
|
7464
|
-
),
|
|
7465
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
|
|
7466
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7467
|
-
ui.DropdownMenu.Item,
|
|
7468
|
-
{
|
|
7469
|
-
className: "gap-x-2",
|
|
7470
|
-
onClick: () => deleteRow(index),
|
|
7471
|
-
children: [
|
|
7472
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
|
|
7473
|
-
"Delete row"
|
|
7474
|
-
]
|
|
7475
|
-
}
|
|
7476
|
-
)
|
|
7477
|
-
] })
|
|
7478
|
-
] })
|
|
7479
|
-
] })
|
|
7480
|
-
},
|
|
7481
|
-
field.id
|
|
7482
|
-
);
|
|
7483
|
-
})
|
|
7484
|
-
] }),
|
|
7485
|
-
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." })
|
|
7486
|
-
] }),
|
|
7487
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
7488
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
|
|
7489
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7490
|
-
] }) })
|
|
7491
|
-
]
|
|
7492
|
-
}
|
|
7493
|
-
) });
|
|
7494
|
-
};
|
|
7495
|
-
const GridInput = React.forwardRef(({ className, ...props }, ref) => {
|
|
7496
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7497
|
-
"input",
|
|
7498
|
-
{
|
|
7499
|
-
ref,
|
|
7500
|
-
...props,
|
|
7501
|
-
autoComplete: "off",
|
|
7502
|
-
className: ui.clx(
|
|
7503
|
-
"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",
|
|
7504
|
-
className
|
|
7505
|
-
)
|
|
7506
|
-
}
|
|
7507
|
-
);
|
|
7508
|
-
});
|
|
7509
|
-
GridInput.displayName = "MetadataForm.GridInput";
|
|
7510
|
-
const PlaceholderInner = () => {
|
|
7511
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
7512
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
|
|
7513
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
7514
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
|
|
7515
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
|
|
7516
|
-
] }) })
|
|
7517
|
-
] });
|
|
7518
|
-
};
|
|
7519
|
-
const EDITABLE_TYPES = ["string", "number", "boolean"];
|
|
7520
|
-
function getDefaultValues(metadata) {
|
|
7521
|
-
if (!metadata || !Object.keys(metadata).length) {
|
|
7522
|
-
return [
|
|
7523
|
-
{
|
|
7524
|
-
key: "",
|
|
7525
|
-
value: "",
|
|
7526
|
-
disabled: false
|
|
7527
|
-
}
|
|
7528
|
-
];
|
|
7529
|
-
}
|
|
7530
|
-
return Object.entries(metadata).map(([key, value]) => {
|
|
7531
|
-
if (!EDITABLE_TYPES.includes(typeof value)) {
|
|
7532
|
-
return {
|
|
7533
|
-
key,
|
|
7534
|
-
value,
|
|
7535
|
-
disabled: true
|
|
7536
|
-
};
|
|
7537
|
-
}
|
|
7538
|
-
let stringValue = value;
|
|
7539
|
-
if (typeof value !== "string") {
|
|
7540
|
-
stringValue = JSON.stringify(value);
|
|
7541
|
-
}
|
|
7542
|
-
return {
|
|
7543
|
-
key,
|
|
7544
|
-
value: stringValue,
|
|
7545
|
-
original_key: key
|
|
7546
|
-
};
|
|
7547
|
-
});
|
|
7548
|
-
}
|
|
7549
|
-
function parseValues(values) {
|
|
7550
|
-
const metadata = values.metadata;
|
|
7551
|
-
const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
|
|
7552
|
-
if (isEmpty) {
|
|
7553
|
-
return null;
|
|
7554
|
-
}
|
|
7555
|
-
const update = {};
|
|
7556
|
-
metadata.forEach((field) => {
|
|
7557
|
-
let key = field.key;
|
|
7558
|
-
let value = field.value;
|
|
7559
|
-
const disabled = field.disabled;
|
|
7560
|
-
if (!key || !value) {
|
|
7561
|
-
return;
|
|
7562
|
-
}
|
|
7563
|
-
if (disabled) {
|
|
7564
|
-
update[key] = value;
|
|
7565
|
-
return;
|
|
7566
|
-
}
|
|
7567
|
-
key = key.trim();
|
|
7568
|
-
value = value.trim();
|
|
7569
|
-
if (value === "true") {
|
|
7570
|
-
update[key] = true;
|
|
7571
|
-
} else if (value === "false") {
|
|
7572
|
-
update[key] = false;
|
|
7573
|
-
} else {
|
|
7574
|
-
const parsedNumber = parseFloat(value);
|
|
7575
|
-
if (!isNaN(parsedNumber)) {
|
|
7576
|
-
update[key] = parsedNumber;
|
|
7577
|
-
} else {
|
|
7578
|
-
update[key] = value;
|
|
7579
|
-
}
|
|
7580
|
-
}
|
|
7581
|
-
});
|
|
7582
|
-
return update;
|
|
7583
|
-
}
|
|
7584
|
-
function getHasUneditableRows(metadata) {
|
|
7585
|
-
if (!metadata) {
|
|
7586
|
-
return false;
|
|
7587
|
-
}
|
|
7588
|
-
return Object.values(metadata).some(
|
|
7589
|
-
(value) => !EDITABLE_TYPES.includes(typeof value)
|
|
7590
|
-
);
|
|
7591
|
-
}
|
|
7592
|
-
const PROMOTION_QUERY_KEY = "promotions";
|
|
7593
|
-
const promotionsQueryKeys = {
|
|
7594
|
-
list: (query2) => [
|
|
7595
|
-
PROMOTION_QUERY_KEY,
|
|
7596
|
-
query2 ? query2 : void 0
|
|
7597
|
-
],
|
|
7598
|
-
detail: (id, query2) => [
|
|
7599
|
-
PROMOTION_QUERY_KEY,
|
|
7600
|
-
id,
|
|
7601
|
-
query2 ? query2 : void 0
|
|
7602
|
-
]
|
|
7603
|
-
};
|
|
7604
|
-
const usePromotions = (query2, options) => {
|
|
7605
|
-
const { data, ...rest } = reactQuery.useQuery({
|
|
7606
|
-
queryKey: promotionsQueryKeys.list(query2),
|
|
7607
|
-
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
7608
|
-
...options
|
|
7609
|
-
});
|
|
7610
|
-
return { ...data, ...rest };
|
|
7611
|
-
};
|
|
7612
|
-
const Promotions = () => {
|
|
7613
|
-
const { id } = reactRouterDom.useParams();
|
|
7614
|
-
const {
|
|
7615
|
-
order: preview,
|
|
7616
|
-
isError: isPreviewError,
|
|
7617
|
-
error: previewError
|
|
7618
|
-
} = useOrderPreview(id, void 0);
|
|
7619
|
-
useInitiateOrderEdit({ preview });
|
|
7620
|
-
const { onCancel } = useCancelOrderEdit({ preview });
|
|
7621
|
-
if (isPreviewError) {
|
|
7622
|
-
throw previewError;
|
|
7623
|
-
}
|
|
7624
|
-
const isReady = !!preview;
|
|
7625
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
|
|
7626
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
|
|
7627
|
-
isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
|
|
7628
|
-
] });
|
|
7629
|
-
};
|
|
7630
|
-
const PromotionForm = ({ preview }) => {
|
|
7631
|
-
const { items, shipping_methods } = preview;
|
|
7632
|
-
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
7633
|
-
const [comboboxValue, setComboboxValue] = React.useState("");
|
|
7634
|
-
const { handleSuccess } = useRouteModal();
|
|
7635
|
-
const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
|
|
7636
|
-
const promoIds = getPromotionIds(items, shipping_methods);
|
|
7637
|
-
const { promotions, isPending, isError, error } = usePromotions(
|
|
7638
|
-
{
|
|
7639
|
-
id: promoIds
|
|
7640
|
-
},
|
|
7641
|
-
{
|
|
7642
|
-
enabled: !!promoIds.length
|
|
7643
|
-
}
|
|
7644
|
-
);
|
|
7645
|
-
const comboboxData = useComboboxData({
|
|
7646
|
-
queryKey: ["promotions", "combobox", promoIds],
|
|
7647
|
-
queryFn: async (params) => {
|
|
7648
|
-
return await sdk.admin.promotion.list({
|
|
7649
|
-
...params,
|
|
7650
|
-
id: {
|
|
7651
|
-
$nin: promoIds
|
|
7652
|
-
}
|
|
7653
|
-
});
|
|
7654
|
-
},
|
|
7655
|
-
getOptions: (data) => {
|
|
7656
|
-
return data.promotions.map((promotion) => ({
|
|
7657
|
-
label: promotion.code,
|
|
7658
|
-
value: promotion.code
|
|
7659
|
-
}));
|
|
7660
|
-
}
|
|
7661
|
-
});
|
|
7662
|
-
const add = async (value) => {
|
|
7663
|
-
if (!value) {
|
|
7664
|
-
return;
|
|
7665
|
-
}
|
|
7666
|
-
addPromotions(
|
|
7667
|
-
{
|
|
7668
|
-
promo_codes: [value]
|
|
7669
|
-
},
|
|
7670
|
-
{
|
|
7671
|
-
onError: (e) => {
|
|
7672
|
-
ui.toast.error(e.message);
|
|
7673
|
-
comboboxData.onSearchValueChange("");
|
|
7674
|
-
setComboboxValue("");
|
|
7675
|
-
},
|
|
7676
|
-
onSuccess: () => {
|
|
7677
|
-
comboboxData.onSearchValueChange("");
|
|
7678
|
-
setComboboxValue("");
|
|
7679
|
-
}
|
|
7680
|
-
}
|
|
7681
|
-
);
|
|
7682
|
-
};
|
|
7683
|
-
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
7684
|
-
const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
|
|
7685
|
-
const onSubmit = async () => {
|
|
7686
|
-
setIsSubmitting(true);
|
|
7687
|
-
let requestSucceeded = false;
|
|
7688
|
-
await requestOrderEdit(void 0, {
|
|
7689
|
-
onError: (e) => {
|
|
7690
|
-
ui.toast.error(e.message);
|
|
7691
|
-
},
|
|
7692
|
-
onSuccess: () => {
|
|
7693
|
-
requestSucceeded = true;
|
|
7694
|
-
}
|
|
7695
|
-
});
|
|
7696
|
-
if (!requestSucceeded) {
|
|
7697
|
-
setIsSubmitting(false);
|
|
7698
|
-
return;
|
|
7699
|
-
}
|
|
7700
|
-
await confirmOrderEdit(void 0, {
|
|
7701
|
-
onError: (e) => {
|
|
7702
|
-
ui.toast.error(e.message);
|
|
7703
|
-
},
|
|
7704
|
-
onSuccess: () => {
|
|
7705
|
-
handleSuccess();
|
|
7706
|
-
},
|
|
7707
|
-
onSettled: () => {
|
|
7708
|
-
setIsSubmitting(false);
|
|
7709
|
-
}
|
|
7710
|
-
});
|
|
7711
|
-
};
|
|
7712
|
-
if (isError) {
|
|
7713
|
-
throw error;
|
|
7398
|
+
};
|
|
7399
|
+
if (isError) {
|
|
7400
|
+
throw error;
|
|
7714
7401
|
}
|
|
7715
7402
|
return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
|
|
7716
7403
|
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
@@ -7760,109 +7447,565 @@ const PromotionForm = ({ preview }) => {
|
|
|
7760
7447
|
] }) })
|
|
7761
7448
|
] });
|
|
7762
7449
|
};
|
|
7763
|
-
const PromotionItem = ({
|
|
7764
|
-
promotion,
|
|
7765
|
-
orderId,
|
|
7766
|
-
isLoading
|
|
7767
|
-
}) => {
|
|
7768
|
-
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
7769
|
-
const onRemove = async () => {
|
|
7770
|
-
removePromotions(
|
|
7450
|
+
const PromotionItem = ({
|
|
7451
|
+
promotion,
|
|
7452
|
+
orderId,
|
|
7453
|
+
isLoading
|
|
7454
|
+
}) => {
|
|
7455
|
+
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
7456
|
+
const onRemove = async () => {
|
|
7457
|
+
removePromotions(
|
|
7458
|
+
{
|
|
7459
|
+
promo_codes: [promotion.code]
|
|
7460
|
+
},
|
|
7461
|
+
{
|
|
7462
|
+
onError: (e) => {
|
|
7463
|
+
ui.toast.error(e.message);
|
|
7464
|
+
}
|
|
7465
|
+
}
|
|
7466
|
+
);
|
|
7467
|
+
};
|
|
7468
|
+
const displayValue = getDisplayValue(promotion);
|
|
7469
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7470
|
+
"div",
|
|
7471
|
+
{
|
|
7472
|
+
className: ui.clx(
|
|
7473
|
+
"bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
|
|
7474
|
+
{
|
|
7475
|
+
"animate-pulse": isLoading
|
|
7476
|
+
}
|
|
7477
|
+
),
|
|
7478
|
+
children: [
|
|
7479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7480
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
|
|
7481
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
|
|
7482
|
+
displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
7483
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
|
|
7484
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
7485
|
+
] }),
|
|
7486
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
|
|
7487
|
+
] })
|
|
7488
|
+
] }),
|
|
7489
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7490
|
+
ui.IconButton,
|
|
7491
|
+
{
|
|
7492
|
+
size: "small",
|
|
7493
|
+
type: "button",
|
|
7494
|
+
variant: "transparent",
|
|
7495
|
+
onClick: onRemove,
|
|
7496
|
+
isLoading: isPending || isLoading,
|
|
7497
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
7498
|
+
}
|
|
7499
|
+
)
|
|
7500
|
+
]
|
|
7501
|
+
},
|
|
7502
|
+
promotion.id
|
|
7503
|
+
);
|
|
7504
|
+
};
|
|
7505
|
+
function getDisplayValue(promotion) {
|
|
7506
|
+
const value = promotion.application_method?.value;
|
|
7507
|
+
if (!value) {
|
|
7508
|
+
return null;
|
|
7509
|
+
}
|
|
7510
|
+
if (promotion.application_method?.type === "fixed") {
|
|
7511
|
+
const currency = promotion.application_method?.currency_code;
|
|
7512
|
+
if (!currency) {
|
|
7513
|
+
return null;
|
|
7514
|
+
}
|
|
7515
|
+
return getLocaleAmount(value, currency);
|
|
7516
|
+
} else if (promotion.application_method?.type === "percentage") {
|
|
7517
|
+
return formatPercentage(value);
|
|
7518
|
+
}
|
|
7519
|
+
return null;
|
|
7520
|
+
}
|
|
7521
|
+
const formatter = new Intl.NumberFormat([], {
|
|
7522
|
+
style: "percent",
|
|
7523
|
+
minimumFractionDigits: 2
|
|
7524
|
+
});
|
|
7525
|
+
const formatPercentage = (value, isPercentageValue = false) => {
|
|
7526
|
+
let val = value || 0;
|
|
7527
|
+
if (!isPercentageValue) {
|
|
7528
|
+
val = val / 100;
|
|
7529
|
+
}
|
|
7530
|
+
return formatter.format(val);
|
|
7531
|
+
};
|
|
7532
|
+
function getPromotionIds(items, shippingMethods) {
|
|
7533
|
+
const promotionIds = /* @__PURE__ */ new Set();
|
|
7534
|
+
for (const item of items) {
|
|
7535
|
+
if (item.adjustments) {
|
|
7536
|
+
for (const adjustment of item.adjustments) {
|
|
7537
|
+
if (adjustment.promotion_id) {
|
|
7538
|
+
promotionIds.add(adjustment.promotion_id);
|
|
7539
|
+
}
|
|
7540
|
+
}
|
|
7541
|
+
}
|
|
7542
|
+
}
|
|
7543
|
+
for (const shippingMethod of shippingMethods) {
|
|
7544
|
+
if (shippingMethod.adjustments) {
|
|
7545
|
+
for (const adjustment of shippingMethod.adjustments) {
|
|
7546
|
+
if (adjustment.promotion_id) {
|
|
7547
|
+
promotionIds.add(adjustment.promotion_id);
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
}
|
|
7551
|
+
}
|
|
7552
|
+
return Array.from(promotionIds);
|
|
7553
|
+
}
|
|
7554
|
+
const SalesChannel = () => {
|
|
7555
|
+
const { id } = reactRouterDom.useParams();
|
|
7556
|
+
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
7557
|
+
id,
|
|
7558
|
+
{
|
|
7559
|
+
fields: "+sales_channel_id"
|
|
7560
|
+
},
|
|
7561
|
+
{
|
|
7562
|
+
enabled: !!id
|
|
7563
|
+
}
|
|
7564
|
+
);
|
|
7565
|
+
if (isError) {
|
|
7566
|
+
throw error;
|
|
7567
|
+
}
|
|
7568
|
+
const ISrEADY = !!draft_order && !isPending;
|
|
7569
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7570
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
7571
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
7572
|
+
/* @__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" }) })
|
|
7573
|
+
] }),
|
|
7574
|
+
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
7575
|
+
] });
|
|
7576
|
+
};
|
|
7577
|
+
const SalesChannelForm = ({ order }) => {
|
|
7578
|
+
const form = reactHookForm.useForm({
|
|
7579
|
+
defaultValues: {
|
|
7580
|
+
sales_channel_id: order.sales_channel_id || ""
|
|
7581
|
+
},
|
|
7582
|
+
resolver: zod$1.zodResolver(schema$2)
|
|
7583
|
+
});
|
|
7584
|
+
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
7585
|
+
const { handleSuccess } = useRouteModal();
|
|
7586
|
+
const onSubmit = form.handleSubmit(async (data) => {
|
|
7587
|
+
await mutateAsync(
|
|
7588
|
+
{
|
|
7589
|
+
sales_channel_id: data.sales_channel_id
|
|
7590
|
+
},
|
|
7591
|
+
{
|
|
7592
|
+
onSuccess: () => {
|
|
7593
|
+
ui.toast.success("Sales channel updated");
|
|
7594
|
+
handleSuccess();
|
|
7595
|
+
},
|
|
7596
|
+
onError: (error) => {
|
|
7597
|
+
ui.toast.error(error.message);
|
|
7598
|
+
}
|
|
7599
|
+
}
|
|
7600
|
+
);
|
|
7601
|
+
});
|
|
7602
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7603
|
+
KeyboundForm,
|
|
7604
|
+
{
|
|
7605
|
+
className: "flex flex-1 flex-col overflow-hidden",
|
|
7606
|
+
onSubmit,
|
|
7607
|
+
children: [
|
|
7608
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
7609
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7610
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7611
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7612
|
+
] }) })
|
|
7613
|
+
]
|
|
7614
|
+
}
|
|
7615
|
+
) });
|
|
7616
|
+
};
|
|
7617
|
+
const SalesChannelField = ({ control, order }) => {
|
|
7618
|
+
const salesChannels = useComboboxData({
|
|
7619
|
+
queryFn: async (params) => {
|
|
7620
|
+
return await sdk.admin.salesChannel.list(params);
|
|
7621
|
+
},
|
|
7622
|
+
queryKey: ["sales-channels"],
|
|
7623
|
+
getOptions: (data) => {
|
|
7624
|
+
return data.sales_channels.map((salesChannel) => ({
|
|
7625
|
+
label: salesChannel.name,
|
|
7626
|
+
value: salesChannel.id
|
|
7627
|
+
}));
|
|
7628
|
+
},
|
|
7629
|
+
defaultValue: order.sales_channel_id || void 0
|
|
7630
|
+
});
|
|
7631
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7632
|
+
Form$2.Field,
|
|
7633
|
+
{
|
|
7634
|
+
control,
|
|
7635
|
+
name: "sales_channel_id",
|
|
7636
|
+
render: ({ field }) => {
|
|
7637
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
7638
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
7639
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7640
|
+
Combobox,
|
|
7641
|
+
{
|
|
7642
|
+
options: salesChannels.options,
|
|
7643
|
+
fetchNextPage: salesChannels.fetchNextPage,
|
|
7644
|
+
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
7645
|
+
searchValue: salesChannels.searchValue,
|
|
7646
|
+
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
7647
|
+
placeholder: "Select sales channel",
|
|
7648
|
+
...field
|
|
7649
|
+
}
|
|
7650
|
+
) }),
|
|
7651
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
7652
|
+
] });
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
);
|
|
7656
|
+
};
|
|
7657
|
+
const schema$2 = zod.z.object({
|
|
7658
|
+
sales_channel_id: zod.z.string().min(1)
|
|
7659
|
+
});
|
|
7660
|
+
const InlineTip = React.forwardRef(
|
|
7661
|
+
({ variant = "tip", label, className, children, ...props }, ref) => {
|
|
7662
|
+
const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
|
|
7663
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7664
|
+
"div",
|
|
7665
|
+
{
|
|
7666
|
+
ref,
|
|
7667
|
+
className: ui.clx(
|
|
7668
|
+
"bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
|
|
7669
|
+
className
|
|
7670
|
+
),
|
|
7671
|
+
...props,
|
|
7672
|
+
children: [
|
|
7673
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7674
|
+
"div",
|
|
7675
|
+
{
|
|
7676
|
+
role: "presentation",
|
|
7677
|
+
className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
|
|
7678
|
+
"bg-ui-tag-orange-icon": variant === "warning"
|
|
7679
|
+
})
|
|
7680
|
+
}
|
|
7681
|
+
),
|
|
7682
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
|
|
7683
|
+
/* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
|
|
7684
|
+
labelValue,
|
|
7685
|
+
":"
|
|
7686
|
+
] }),
|
|
7687
|
+
" ",
|
|
7688
|
+
children
|
|
7689
|
+
] })
|
|
7690
|
+
]
|
|
7691
|
+
}
|
|
7692
|
+
);
|
|
7693
|
+
}
|
|
7694
|
+
);
|
|
7695
|
+
InlineTip.displayName = "InlineTip";
|
|
7696
|
+
const MetadataFieldSchema = zod.z.object({
|
|
7697
|
+
key: zod.z.string(),
|
|
7698
|
+
disabled: zod.z.boolean().optional(),
|
|
7699
|
+
value: zod.z.any()
|
|
7700
|
+
});
|
|
7701
|
+
const MetadataSchema = zod.z.object({
|
|
7702
|
+
metadata: zod.z.array(MetadataFieldSchema)
|
|
7703
|
+
});
|
|
7704
|
+
const Metadata = () => {
|
|
7705
|
+
const { id } = reactRouterDom.useParams();
|
|
7706
|
+
const { order, isPending, isError, error } = useOrder(id, {
|
|
7707
|
+
fields: "metadata"
|
|
7708
|
+
});
|
|
7709
|
+
if (isError) {
|
|
7710
|
+
throw error;
|
|
7711
|
+
}
|
|
7712
|
+
const isReady = !isPending && !!order;
|
|
7713
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7714
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
7715
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
|
|
7716
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
|
|
7717
|
+
] }),
|
|
7718
|
+
!isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order?.metadata })
|
|
7719
|
+
] });
|
|
7720
|
+
};
|
|
7721
|
+
const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
|
|
7722
|
+
const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
|
|
7723
|
+
const MetadataForm = ({ orderId, metadata }) => {
|
|
7724
|
+
const { handleSuccess } = useRouteModal();
|
|
7725
|
+
const hasUneditableRows = getHasUneditableRows(metadata);
|
|
7726
|
+
const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
|
|
7727
|
+
const form = reactHookForm.useForm({
|
|
7728
|
+
defaultValues: {
|
|
7729
|
+
metadata: getDefaultValues(metadata)
|
|
7730
|
+
},
|
|
7731
|
+
resolver: zod$1.zodResolver(MetadataSchema)
|
|
7732
|
+
});
|
|
7733
|
+
const handleSubmit = form.handleSubmit(async (data) => {
|
|
7734
|
+
const parsedData = parseValues(data);
|
|
7735
|
+
await mutateAsync(
|
|
7771
7736
|
{
|
|
7772
|
-
|
|
7737
|
+
metadata: parsedData
|
|
7773
7738
|
},
|
|
7774
7739
|
{
|
|
7775
|
-
|
|
7776
|
-
ui.toast.
|
|
7740
|
+
onSuccess: () => {
|
|
7741
|
+
ui.toast.success("Metadata updated");
|
|
7742
|
+
handleSuccess();
|
|
7743
|
+
},
|
|
7744
|
+
onError: (error) => {
|
|
7745
|
+
ui.toast.error(error.message);
|
|
7777
7746
|
}
|
|
7778
7747
|
}
|
|
7779
7748
|
);
|
|
7780
|
-
};
|
|
7781
|
-
const
|
|
7782
|
-
|
|
7783
|
-
"
|
|
7749
|
+
});
|
|
7750
|
+
const { fields, insert, remove } = reactHookForm.useFieldArray({
|
|
7751
|
+
control: form.control,
|
|
7752
|
+
name: "metadata"
|
|
7753
|
+
});
|
|
7754
|
+
function deleteRow(index) {
|
|
7755
|
+
remove(index);
|
|
7756
|
+
if (fields.length === 1) {
|
|
7757
|
+
insert(0, {
|
|
7758
|
+
key: "",
|
|
7759
|
+
value: "",
|
|
7760
|
+
disabled: false
|
|
7761
|
+
});
|
|
7762
|
+
}
|
|
7763
|
+
}
|
|
7764
|
+
function insertRow(index, position) {
|
|
7765
|
+
insert(index + (position === "above" ? 0 : 1), {
|
|
7766
|
+
key: "",
|
|
7767
|
+
value: "",
|
|
7768
|
+
disabled: false
|
|
7769
|
+
});
|
|
7770
|
+
}
|
|
7771
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7772
|
+
KeyboundForm,
|
|
7784
7773
|
{
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
{
|
|
7788
|
-
"animate-pulse": isLoading
|
|
7789
|
-
}
|
|
7790
|
-
),
|
|
7774
|
+
onSubmit: handleSubmit,
|
|
7775
|
+
className: "flex flex-1 flex-col overflow-hidden",
|
|
7791
7776
|
children: [
|
|
7792
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
7793
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7797
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
7777
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
|
|
7778
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
|
|
7779
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
|
|
7780
|
+
/* @__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" }) }),
|
|
7781
|
+
/* @__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" }) })
|
|
7798
7782
|
] }),
|
|
7799
|
-
|
|
7800
|
-
|
|
7783
|
+
fields.map((field, index) => {
|
|
7784
|
+
const isDisabled = field.disabled || false;
|
|
7785
|
+
let placeholder = "-";
|
|
7786
|
+
if (typeof field.value === "object") {
|
|
7787
|
+
placeholder = "{ ... }";
|
|
7788
|
+
}
|
|
7789
|
+
if (Array.isArray(field.value)) {
|
|
7790
|
+
placeholder = "[ ... ]";
|
|
7791
|
+
}
|
|
7792
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7793
|
+
ConditionalTooltip,
|
|
7794
|
+
{
|
|
7795
|
+
showTooltip: isDisabled,
|
|
7796
|
+
content: "This row is disabled because it contains non-primitive data.",
|
|
7797
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
|
|
7798
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7799
|
+
"div",
|
|
7800
|
+
{
|
|
7801
|
+
className: ui.clx("grid grid-cols-2 divide-x", {
|
|
7802
|
+
"overflow-hidden rounded-b-lg": index === fields.length - 1
|
|
7803
|
+
}),
|
|
7804
|
+
children: [
|
|
7805
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7806
|
+
Form$2.Field,
|
|
7807
|
+
{
|
|
7808
|
+
control: form.control,
|
|
7809
|
+
name: `metadata.${index}.key`,
|
|
7810
|
+
render: ({ field: field2 }) => {
|
|
7811
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7812
|
+
GridInput,
|
|
7813
|
+
{
|
|
7814
|
+
"aria-labelledby": METADATA_KEY_LABEL_ID,
|
|
7815
|
+
...field2,
|
|
7816
|
+
disabled: isDisabled,
|
|
7817
|
+
placeholder: "Key"
|
|
7818
|
+
}
|
|
7819
|
+
) }) });
|
|
7820
|
+
}
|
|
7821
|
+
}
|
|
7822
|
+
),
|
|
7823
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7824
|
+
Form$2.Field,
|
|
7825
|
+
{
|
|
7826
|
+
control: form.control,
|
|
7827
|
+
name: `metadata.${index}.value`,
|
|
7828
|
+
render: ({ field: { value, ...field2 } }) => {
|
|
7829
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7830
|
+
GridInput,
|
|
7831
|
+
{
|
|
7832
|
+
"aria-labelledby": METADATA_VALUE_LABEL_ID,
|
|
7833
|
+
...field2,
|
|
7834
|
+
value: isDisabled ? placeholder : value,
|
|
7835
|
+
disabled: isDisabled,
|
|
7836
|
+
placeholder: "Value"
|
|
7837
|
+
}
|
|
7838
|
+
) }) });
|
|
7839
|
+
}
|
|
7840
|
+
}
|
|
7841
|
+
)
|
|
7842
|
+
]
|
|
7843
|
+
}
|
|
7844
|
+
),
|
|
7845
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
7846
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7847
|
+
ui.DropdownMenu.Trigger,
|
|
7848
|
+
{
|
|
7849
|
+
className: ui.clx(
|
|
7850
|
+
"invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
|
|
7851
|
+
{
|
|
7852
|
+
hidden: isDisabled
|
|
7853
|
+
}
|
|
7854
|
+
),
|
|
7855
|
+
disabled: isDisabled,
|
|
7856
|
+
asChild: true,
|
|
7857
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
|
|
7858
|
+
}
|
|
7859
|
+
),
|
|
7860
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
|
|
7861
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7862
|
+
ui.DropdownMenu.Item,
|
|
7863
|
+
{
|
|
7864
|
+
className: "gap-x-2",
|
|
7865
|
+
onClick: () => insertRow(index, "above"),
|
|
7866
|
+
children: [
|
|
7867
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
|
|
7868
|
+
"Insert row above"
|
|
7869
|
+
]
|
|
7870
|
+
}
|
|
7871
|
+
),
|
|
7872
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7873
|
+
ui.DropdownMenu.Item,
|
|
7874
|
+
{
|
|
7875
|
+
className: "gap-x-2",
|
|
7876
|
+
onClick: () => insertRow(index, "below"),
|
|
7877
|
+
children: [
|
|
7878
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
|
|
7879
|
+
"Insert row below"
|
|
7880
|
+
]
|
|
7881
|
+
}
|
|
7882
|
+
),
|
|
7883
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
|
|
7884
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7885
|
+
ui.DropdownMenu.Item,
|
|
7886
|
+
{
|
|
7887
|
+
className: "gap-x-2",
|
|
7888
|
+
onClick: () => deleteRow(index),
|
|
7889
|
+
children: [
|
|
7890
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
|
|
7891
|
+
"Delete row"
|
|
7892
|
+
]
|
|
7893
|
+
}
|
|
7894
|
+
)
|
|
7895
|
+
] })
|
|
7896
|
+
] })
|
|
7897
|
+
] })
|
|
7898
|
+
},
|
|
7899
|
+
field.id
|
|
7900
|
+
);
|
|
7901
|
+
})
|
|
7902
|
+
] }),
|
|
7903
|
+
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." })
|
|
7801
7904
|
] }),
|
|
7802
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7803
|
-
ui.
|
|
7804
|
-
{
|
|
7805
|
-
|
|
7806
|
-
type: "button",
|
|
7807
|
-
variant: "transparent",
|
|
7808
|
-
onClick: onRemove,
|
|
7809
|
-
isLoading: isPending || isLoading,
|
|
7810
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
7811
|
-
}
|
|
7812
|
-
)
|
|
7905
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
7906
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
|
|
7907
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7908
|
+
] }) })
|
|
7813
7909
|
]
|
|
7814
|
-
}
|
|
7815
|
-
|
|
7910
|
+
}
|
|
7911
|
+
) });
|
|
7912
|
+
};
|
|
7913
|
+
const GridInput = React.forwardRef(({ className, ...props }, ref) => {
|
|
7914
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7915
|
+
"input",
|
|
7916
|
+
{
|
|
7917
|
+
ref,
|
|
7918
|
+
...props,
|
|
7919
|
+
autoComplete: "off",
|
|
7920
|
+
className: ui.clx(
|
|
7921
|
+
"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",
|
|
7922
|
+
className
|
|
7923
|
+
)
|
|
7924
|
+
}
|
|
7816
7925
|
);
|
|
7926
|
+
});
|
|
7927
|
+
GridInput.displayName = "MetadataForm.GridInput";
|
|
7928
|
+
const PlaceholderInner = () => {
|
|
7929
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
7930
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
|
|
7931
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
7932
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
|
|
7933
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
|
|
7934
|
+
] }) })
|
|
7935
|
+
] });
|
|
7817
7936
|
};
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
if (!
|
|
7821
|
-
return
|
|
7937
|
+
const EDITABLE_TYPES = ["string", "number", "boolean"];
|
|
7938
|
+
function getDefaultValues(metadata) {
|
|
7939
|
+
if (!metadata || !Object.keys(metadata).length) {
|
|
7940
|
+
return [
|
|
7941
|
+
{
|
|
7942
|
+
key: "",
|
|
7943
|
+
value: "",
|
|
7944
|
+
disabled: false
|
|
7945
|
+
}
|
|
7946
|
+
];
|
|
7822
7947
|
}
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7948
|
+
return Object.entries(metadata).map(([key, value]) => {
|
|
7949
|
+
if (!EDITABLE_TYPES.includes(typeof value)) {
|
|
7950
|
+
return {
|
|
7951
|
+
key,
|
|
7952
|
+
value,
|
|
7953
|
+
disabled: true
|
|
7954
|
+
};
|
|
7827
7955
|
}
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7956
|
+
let stringValue = value;
|
|
7957
|
+
if (typeof value !== "string") {
|
|
7958
|
+
stringValue = JSON.stringify(value);
|
|
7959
|
+
}
|
|
7960
|
+
return {
|
|
7961
|
+
key,
|
|
7962
|
+
value: stringValue,
|
|
7963
|
+
original_key: key
|
|
7964
|
+
};
|
|
7965
|
+
});
|
|
7833
7966
|
}
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
let val = value || 0;
|
|
7840
|
-
if (!isPercentageValue) {
|
|
7841
|
-
val = val / 100;
|
|
7967
|
+
function parseValues(values) {
|
|
7968
|
+
const metadata = values.metadata;
|
|
7969
|
+
const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
|
|
7970
|
+
if (isEmpty) {
|
|
7971
|
+
return null;
|
|
7842
7972
|
}
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
if (
|
|
7849
|
-
|
|
7850
|
-
if (adjustment.promotion_id) {
|
|
7851
|
-
promotionIds.add(adjustment.promotion_id);
|
|
7852
|
-
}
|
|
7853
|
-
}
|
|
7973
|
+
const update = {};
|
|
7974
|
+
metadata.forEach((field) => {
|
|
7975
|
+
let key = field.key;
|
|
7976
|
+
let value = field.value;
|
|
7977
|
+
const disabled = field.disabled;
|
|
7978
|
+
if (!key || !value) {
|
|
7979
|
+
return;
|
|
7854
7980
|
}
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7981
|
+
if (disabled) {
|
|
7982
|
+
update[key] = value;
|
|
7983
|
+
return;
|
|
7984
|
+
}
|
|
7985
|
+
key = key.trim();
|
|
7986
|
+
value = value.trim();
|
|
7987
|
+
if (value === "true") {
|
|
7988
|
+
update[key] = true;
|
|
7989
|
+
} else if (value === "false") {
|
|
7990
|
+
update[key] = false;
|
|
7991
|
+
} else {
|
|
7992
|
+
const parsedNumber = parseFloat(value);
|
|
7993
|
+
if (!isNaN(parsedNumber)) {
|
|
7994
|
+
update[key] = parsedNumber;
|
|
7995
|
+
} else {
|
|
7996
|
+
update[key] = value;
|
|
7862
7997
|
}
|
|
7863
7998
|
}
|
|
7999
|
+
});
|
|
8000
|
+
return update;
|
|
8001
|
+
}
|
|
8002
|
+
function getHasUneditableRows(metadata) {
|
|
8003
|
+
if (!metadata) {
|
|
8004
|
+
return false;
|
|
7864
8005
|
}
|
|
7865
|
-
return
|
|
8006
|
+
return Object.values(metadata).some(
|
|
8007
|
+
(value) => !EDITABLE_TYPES.includes(typeof value)
|
|
8008
|
+
);
|
|
7866
8009
|
}
|
|
7867
8010
|
const STACKED_FOCUS_MODAL_ID = "shipping-form";
|
|
7868
8011
|
const Shipping = () => {
|
|
@@ -8689,7 +8832,7 @@ const ShippingAddressForm = ({ order }) => {
|
|
|
8689
8832
|
postal_code: order.shipping_address?.postal_code ?? "",
|
|
8690
8833
|
phone: order.shipping_address?.phone ?? ""
|
|
8691
8834
|
},
|
|
8692
|
-
resolver: zod$1.zodResolver(schema$
|
|
8835
|
+
resolver: zod$1.zodResolver(schema$1)
|
|
8693
8836
|
});
|
|
8694
8837
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
8695
8838
|
const { handleSuccess } = useRouteModal();
|
|
@@ -8859,7 +9002,7 @@ const ShippingAddressForm = ({ order }) => {
|
|
|
8859
9002
|
}
|
|
8860
9003
|
) });
|
|
8861
9004
|
};
|
|
8862
|
-
const schema$
|
|
9005
|
+
const schema$1 = addressSchema;
|
|
8863
9006
|
const TransferOwnership = () => {
|
|
8864
9007
|
const { id } = reactRouterDom.useParams();
|
|
8865
9008
|
const { draft_order, isPending, isError, error } = useDraftOrder(id, {
|
|
@@ -8882,7 +9025,7 @@ const TransferOwnershipForm = ({ order }) => {
|
|
|
8882
9025
|
defaultValues: {
|
|
8883
9026
|
customer_id: order.customer_id || ""
|
|
8884
9027
|
},
|
|
8885
|
-
resolver: zod$1.zodResolver(schema
|
|
9028
|
+
resolver: zod$1.zodResolver(schema)
|
|
8886
9029
|
});
|
|
8887
9030
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
8888
9031
|
const { handleSuccess } = useRouteModal();
|
|
@@ -9332,114 +9475,8 @@ const Illustration = () => {
|
|
|
9332
9475
|
}
|
|
9333
9476
|
);
|
|
9334
9477
|
};
|
|
9335
|
-
const schema$1 = zod.z.object({
|
|
9336
|
-
customer_id: zod.z.string().min(1)
|
|
9337
|
-
});
|
|
9338
|
-
const SalesChannel = () => {
|
|
9339
|
-
const { id } = reactRouterDom.useParams();
|
|
9340
|
-
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
9341
|
-
id,
|
|
9342
|
-
{
|
|
9343
|
-
fields: "+sales_channel_id"
|
|
9344
|
-
},
|
|
9345
|
-
{
|
|
9346
|
-
enabled: !!id
|
|
9347
|
-
}
|
|
9348
|
-
);
|
|
9349
|
-
if (isError) {
|
|
9350
|
-
throw error;
|
|
9351
|
-
}
|
|
9352
|
-
const ISrEADY = !!draft_order && !isPending;
|
|
9353
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
9354
|
-
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
9355
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
9356
|
-
/* @__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" }) })
|
|
9357
|
-
] }),
|
|
9358
|
-
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
9359
|
-
] });
|
|
9360
|
-
};
|
|
9361
|
-
const SalesChannelForm = ({ order }) => {
|
|
9362
|
-
const form = reactHookForm.useForm({
|
|
9363
|
-
defaultValues: {
|
|
9364
|
-
sales_channel_id: order.sales_channel_id || ""
|
|
9365
|
-
},
|
|
9366
|
-
resolver: zod$1.zodResolver(schema)
|
|
9367
|
-
});
|
|
9368
|
-
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
9369
|
-
const { handleSuccess } = useRouteModal();
|
|
9370
|
-
const onSubmit = form.handleSubmit(async (data) => {
|
|
9371
|
-
await mutateAsync(
|
|
9372
|
-
{
|
|
9373
|
-
sales_channel_id: data.sales_channel_id
|
|
9374
|
-
},
|
|
9375
|
-
{
|
|
9376
|
-
onSuccess: () => {
|
|
9377
|
-
ui.toast.success("Sales channel updated");
|
|
9378
|
-
handleSuccess();
|
|
9379
|
-
},
|
|
9380
|
-
onError: (error) => {
|
|
9381
|
-
ui.toast.error(error.message);
|
|
9382
|
-
}
|
|
9383
|
-
}
|
|
9384
|
-
);
|
|
9385
|
-
});
|
|
9386
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9387
|
-
KeyboundForm,
|
|
9388
|
-
{
|
|
9389
|
-
className: "flex flex-1 flex-col overflow-hidden",
|
|
9390
|
-
onSubmit,
|
|
9391
|
-
children: [
|
|
9392
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
9393
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
9394
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
9395
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
9396
|
-
] }) })
|
|
9397
|
-
]
|
|
9398
|
-
}
|
|
9399
|
-
) });
|
|
9400
|
-
};
|
|
9401
|
-
const SalesChannelField = ({ control, order }) => {
|
|
9402
|
-
const salesChannels = useComboboxData({
|
|
9403
|
-
queryFn: async (params) => {
|
|
9404
|
-
return await sdk.admin.salesChannel.list(params);
|
|
9405
|
-
},
|
|
9406
|
-
queryKey: ["sales-channels"],
|
|
9407
|
-
getOptions: (data) => {
|
|
9408
|
-
return data.sales_channels.map((salesChannel) => ({
|
|
9409
|
-
label: salesChannel.name,
|
|
9410
|
-
value: salesChannel.id
|
|
9411
|
-
}));
|
|
9412
|
-
},
|
|
9413
|
-
defaultValue: order.sales_channel_id || void 0
|
|
9414
|
-
});
|
|
9415
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9416
|
-
Form$2.Field,
|
|
9417
|
-
{
|
|
9418
|
-
control,
|
|
9419
|
-
name: "sales_channel_id",
|
|
9420
|
-
render: ({ field }) => {
|
|
9421
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
9422
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
9423
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9424
|
-
Combobox,
|
|
9425
|
-
{
|
|
9426
|
-
options: salesChannels.options,
|
|
9427
|
-
fetchNextPage: salesChannels.fetchNextPage,
|
|
9428
|
-
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
9429
|
-
searchValue: salesChannels.searchValue,
|
|
9430
|
-
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
9431
|
-
placeholder: "Select sales channel",
|
|
9432
|
-
...field
|
|
9433
|
-
}
|
|
9434
|
-
) }),
|
|
9435
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
9436
|
-
] });
|
|
9437
|
-
}
|
|
9438
|
-
}
|
|
9439
|
-
);
|
|
9440
|
-
};
|
|
9441
9478
|
const schema = zod.z.object({
|
|
9442
|
-
|
|
9479
|
+
customer_id: zod.z.string().min(1)
|
|
9443
9480
|
});
|
|
9444
9481
|
const widgetModule = { widgets: [] };
|
|
9445
9482
|
const routeModule = {
|
|
@@ -9465,6 +9502,10 @@ const routeModule = {
|
|
|
9465
9502
|
Component: BillingAddress,
|
|
9466
9503
|
path: "/draft-orders/:id/billing-address"
|
|
9467
9504
|
},
|
|
9505
|
+
{
|
|
9506
|
+
Component: CustomItems,
|
|
9507
|
+
path: "/draft-orders/:id/custom-items"
|
|
9508
|
+
},
|
|
9468
9509
|
{
|
|
9469
9510
|
Component: Email,
|
|
9470
9511
|
path: "/draft-orders/:id/email"
|
|
@@ -9474,16 +9515,16 @@ const routeModule = {
|
|
|
9474
9515
|
path: "/draft-orders/:id/items"
|
|
9475
9516
|
},
|
|
9476
9517
|
{
|
|
9477
|
-
Component:
|
|
9478
|
-
path: "/draft-orders/:id/
|
|
9518
|
+
Component: Promotions,
|
|
9519
|
+
path: "/draft-orders/:id/promotions"
|
|
9479
9520
|
},
|
|
9480
9521
|
{
|
|
9481
|
-
Component:
|
|
9482
|
-
path: "/draft-orders/:id/
|
|
9522
|
+
Component: SalesChannel,
|
|
9523
|
+
path: "/draft-orders/:id/sales-channel"
|
|
9483
9524
|
},
|
|
9484
9525
|
{
|
|
9485
|
-
Component:
|
|
9486
|
-
path: "/draft-orders/:id/
|
|
9526
|
+
Component: Metadata,
|
|
9527
|
+
path: "/draft-orders/:id/metadata"
|
|
9487
9528
|
},
|
|
9488
9529
|
{
|
|
9489
9530
|
Component: Shipping,
|
|
@@ -9496,10 +9537,6 @@ const routeModule = {
|
|
|
9496
9537
|
{
|
|
9497
9538
|
Component: TransferOwnership,
|
|
9498
9539
|
path: "/draft-orders/:id/transfer-ownership"
|
|
9499
|
-
},
|
|
9500
|
-
{
|
|
9501
|
-
Component: SalesChannel,
|
|
9502
|
-
path: "/draft-orders/:id/sales-channel"
|
|
9503
9540
|
}
|
|
9504
9541
|
]
|
|
9505
9542
|
}
|