@medusajs/draft-order 2.20.0-snapshot-20260901131559 → 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 +717 -680
- package/.medusa/server/src/admin/index.mjs +718 -681
- package/package.json +18 -18
|
@@ -5979,27 +5979,6 @@ const ID = () => {
|
|
|
5979
5979
|
}
|
|
5980
5980
|
);
|
|
5981
5981
|
};
|
|
5982
|
-
const CustomItems = () => {
|
|
5983
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
5984
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
5985
|
-
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
5986
|
-
] });
|
|
5987
|
-
};
|
|
5988
|
-
const CustomItemsForm = () => {
|
|
5989
|
-
const form = reactHookForm.useForm({
|
|
5990
|
-
resolver: zod$1.zodResolver(schema$5)
|
|
5991
|
-
});
|
|
5992
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
5993
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
5994
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
5995
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
5996
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
5997
|
-
] }) })
|
|
5998
|
-
] }) });
|
|
5999
|
-
};
|
|
6000
|
-
const schema$5 = zod.z.object({
|
|
6001
|
-
email: zod.z.string().email()
|
|
6002
|
-
});
|
|
6003
5982
|
const BillingAddress = () => {
|
|
6004
5983
|
const { id } = reactRouterDom.useParams();
|
|
6005
5984
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -6031,7 +6010,7 @@ const BillingAddressForm = ({ order }) => {
|
|
|
6031
6010
|
postal_code: order.billing_address?.postal_code ?? "",
|
|
6032
6011
|
phone: order.billing_address?.phone ?? ""
|
|
6033
6012
|
},
|
|
6034
|
-
resolver: zod$1.zodResolver(schema$
|
|
6013
|
+
resolver: zod$1.zodResolver(schema$5)
|
|
6035
6014
|
});
|
|
6036
6015
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
6037
6016
|
const { handleSuccess } = useRouteModal();
|
|
@@ -6188,7 +6167,28 @@ const BillingAddressForm = ({ order }) => {
|
|
|
6188
6167
|
}
|
|
6189
6168
|
) });
|
|
6190
6169
|
};
|
|
6191
|
-
const schema$
|
|
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
|
+
});
|
|
6192
6192
|
const Email = () => {
|
|
6193
6193
|
const { id } = reactRouterDom.useParams();
|
|
6194
6194
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -6983,7 +6983,8 @@ const ExistingItemsForm = ({ orderId, items }) => {
|
|
|
6983
6983
|
q,
|
|
6984
6984
|
order,
|
|
6985
6985
|
offset: offset ? parseInt(offset) : void 0,
|
|
6986
|
-
limit: LIMIT
|
|
6986
|
+
limit: LIMIT,
|
|
6987
|
+
fields: "*inventory_items.inventory.location_levels,+inventory_quantity,+manage_inventory"
|
|
6987
6988
|
},
|
|
6988
6989
|
{
|
|
6989
6990
|
placeholderData: reactQuery.keepPreviousData
|
|
@@ -7062,6 +7063,23 @@ const ExistingItemsForm = ({ orderId, items }) => {
|
|
|
7062
7063
|
);
|
|
7063
7064
|
};
|
|
7064
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
|
+
};
|
|
7065
7083
|
const useColumns = () => {
|
|
7066
7084
|
return React.useMemo(() => {
|
|
7067
7085
|
return [
|
|
@@ -7122,6 +7140,25 @@ const useColumns = () => {
|
|
|
7122
7140
|
enableSorting: true,
|
|
7123
7141
|
sortAscLabel: "Oldest first",
|
|
7124
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
|
+
}
|
|
7125
7162
|
})
|
|
7126
7163
|
];
|
|
7127
7164
|
}, []);
|
|
@@ -7239,478 +7276,128 @@ const customItemSchema = zod.z.object({
|
|
|
7239
7276
|
quantity: zod.z.number(),
|
|
7240
7277
|
unit_price: zod.z.union([zod.z.number(), zod.z.string()])
|
|
7241
7278
|
});
|
|
7242
|
-
const
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
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 = () => {
|
|
7287
|
-
const { id } = reactRouterDom.useParams();
|
|
7288
|
-
const { order, isPending, isError, error } = useOrder(id, {
|
|
7289
|
-
fields: "metadata"
|
|
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
|
+
]
|
|
7290
|
+
};
|
|
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
|
|
7290
7296
|
});
|
|
7291
|
-
|
|
7292
|
-
|
|
7297
|
+
return { ...data, ...rest };
|
|
7298
|
+
};
|
|
7299
|
+
const Promotions = () => {
|
|
7300
|
+
const { id } = reactRouterDom.useParams();
|
|
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
|
-
|
|
7816
|
-
);
|
|
7910
|
+
}
|
|
7911
|
+
) });
|
|
7817
7912
|
};
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
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
|
+
)
|
|
7827
7924
|
}
|
|
7828
|
-
|
|
7829
|
-
} else if (promotion.application_method?.type === "percentage") {
|
|
7830
|
-
return formatPercentage(value);
|
|
7831
|
-
}
|
|
7832
|
-
return null;
|
|
7833
|
-
}
|
|
7834
|
-
const formatter = new Intl.NumberFormat([], {
|
|
7835
|
-
style: "percent",
|
|
7836
|
-
minimumFractionDigits: 2
|
|
7925
|
+
);
|
|
7837
7926
|
});
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
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
|
+
] });
|
|
7844
7936
|
};
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
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
|
|
7853
7945
|
}
|
|
7946
|
+
];
|
|
7947
|
+
}
|
|
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
|
+
};
|
|
7955
|
+
}
|
|
7956
|
+
let stringValue = value;
|
|
7957
|
+
if (typeof value !== "string") {
|
|
7958
|
+
stringValue = JSON.stringify(value);
|
|
7854
7959
|
}
|
|
7960
|
+
return {
|
|
7961
|
+
key,
|
|
7962
|
+
value: stringValue,
|
|
7963
|
+
original_key: key
|
|
7964
|
+
};
|
|
7965
|
+
});
|
|
7966
|
+
}
|
|
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;
|
|
7855
7972
|
}
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
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;
|
|
7980
|
+
}
|
|
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 = () => {
|
|
@@ -8658,112 +8801,6 @@ const CustomAmountField = ({
|
|
|
8658
8801
|
}
|
|
8659
8802
|
);
|
|
8660
8803
|
};
|
|
8661
|
-
const SalesChannel = () => {
|
|
8662
|
-
const { id } = reactRouterDom.useParams();
|
|
8663
|
-
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
8664
|
-
id,
|
|
8665
|
-
{
|
|
8666
|
-
fields: "+sales_channel_id"
|
|
8667
|
-
},
|
|
8668
|
-
{
|
|
8669
|
-
enabled: !!id
|
|
8670
|
-
}
|
|
8671
|
-
);
|
|
8672
|
-
if (isError) {
|
|
8673
|
-
throw error;
|
|
8674
|
-
}
|
|
8675
|
-
const ISrEADY = !!draft_order && !isPending;
|
|
8676
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
8677
|
-
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
8678
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
8679
|
-
/* @__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" }) })
|
|
8680
|
-
] }),
|
|
8681
|
-
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
8682
|
-
] });
|
|
8683
|
-
};
|
|
8684
|
-
const SalesChannelForm = ({ order }) => {
|
|
8685
|
-
const form = reactHookForm.useForm({
|
|
8686
|
-
defaultValues: {
|
|
8687
|
-
sales_channel_id: order.sales_channel_id || ""
|
|
8688
|
-
},
|
|
8689
|
-
resolver: zod$1.zodResolver(schema$2)
|
|
8690
|
-
});
|
|
8691
|
-
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
8692
|
-
const { handleSuccess } = useRouteModal();
|
|
8693
|
-
const onSubmit = form.handleSubmit(async (data) => {
|
|
8694
|
-
await mutateAsync(
|
|
8695
|
-
{
|
|
8696
|
-
sales_channel_id: data.sales_channel_id
|
|
8697
|
-
},
|
|
8698
|
-
{
|
|
8699
|
-
onSuccess: () => {
|
|
8700
|
-
ui.toast.success("Sales channel updated");
|
|
8701
|
-
handleSuccess();
|
|
8702
|
-
},
|
|
8703
|
-
onError: (error) => {
|
|
8704
|
-
ui.toast.error(error.message);
|
|
8705
|
-
}
|
|
8706
|
-
}
|
|
8707
|
-
);
|
|
8708
|
-
});
|
|
8709
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8710
|
-
KeyboundForm,
|
|
8711
|
-
{
|
|
8712
|
-
className: "flex flex-1 flex-col overflow-hidden",
|
|
8713
|
-
onSubmit,
|
|
8714
|
-
children: [
|
|
8715
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
8716
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
8717
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
8718
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
8719
|
-
] }) })
|
|
8720
|
-
]
|
|
8721
|
-
}
|
|
8722
|
-
) });
|
|
8723
|
-
};
|
|
8724
|
-
const SalesChannelField = ({ control, order }) => {
|
|
8725
|
-
const salesChannels = useComboboxData({
|
|
8726
|
-
queryFn: async (params) => {
|
|
8727
|
-
return await sdk.admin.salesChannel.list(params);
|
|
8728
|
-
},
|
|
8729
|
-
queryKey: ["sales-channels"],
|
|
8730
|
-
getOptions: (data) => {
|
|
8731
|
-
return data.sales_channels.map((salesChannel) => ({
|
|
8732
|
-
label: salesChannel.name,
|
|
8733
|
-
value: salesChannel.id
|
|
8734
|
-
}));
|
|
8735
|
-
},
|
|
8736
|
-
defaultValue: order.sales_channel_id || void 0
|
|
8737
|
-
});
|
|
8738
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8739
|
-
Form$2.Field,
|
|
8740
|
-
{
|
|
8741
|
-
control,
|
|
8742
|
-
name: "sales_channel_id",
|
|
8743
|
-
render: ({ field }) => {
|
|
8744
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
8745
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
8746
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8747
|
-
Combobox,
|
|
8748
|
-
{
|
|
8749
|
-
options: salesChannels.options,
|
|
8750
|
-
fetchNextPage: salesChannels.fetchNextPage,
|
|
8751
|
-
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
8752
|
-
searchValue: salesChannels.searchValue,
|
|
8753
|
-
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
8754
|
-
placeholder: "Select sales channel",
|
|
8755
|
-
...field
|
|
8756
|
-
}
|
|
8757
|
-
) }),
|
|
8758
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
8759
|
-
] });
|
|
8760
|
-
}
|
|
8761
|
-
}
|
|
8762
|
-
);
|
|
8763
|
-
};
|
|
8764
|
-
const schema$2 = zod.z.object({
|
|
8765
|
-
sales_channel_id: zod.z.string().min(1)
|
|
8766
|
-
});
|
|
8767
8804
|
const ShippingAddress = () => {
|
|
8768
8805
|
const { id } = reactRouterDom.useParams();
|
|
8769
8806
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -9461,14 +9498,14 @@ const routeModule = {
|
|
|
9461
9498
|
handle,
|
|
9462
9499
|
loader,
|
|
9463
9500
|
children: [
|
|
9464
|
-
{
|
|
9465
|
-
Component: CustomItems,
|
|
9466
|
-
path: "/draft-orders/:id/custom-items"
|
|
9467
|
-
},
|
|
9468
9501
|
{
|
|
9469
9502
|
Component: BillingAddress,
|
|
9470
9503
|
path: "/draft-orders/:id/billing-address"
|
|
9471
9504
|
},
|
|
9505
|
+
{
|
|
9506
|
+
Component: CustomItems,
|
|
9507
|
+
path: "/draft-orders/:id/custom-items"
|
|
9508
|
+
},
|
|
9472
9509
|
{
|
|
9473
9510
|
Component: Email,
|
|
9474
9511
|
path: "/draft-orders/:id/email"
|
|
@@ -9477,22 +9514,22 @@ const routeModule = {
|
|
|
9477
9514
|
Component: Items,
|
|
9478
9515
|
path: "/draft-orders/:id/items"
|
|
9479
9516
|
},
|
|
9480
|
-
{
|
|
9481
|
-
Component: Metadata,
|
|
9482
|
-
path: "/draft-orders/:id/metadata"
|
|
9483
|
-
},
|
|
9484
9517
|
{
|
|
9485
9518
|
Component: Promotions,
|
|
9486
9519
|
path: "/draft-orders/:id/promotions"
|
|
9487
9520
|
},
|
|
9488
|
-
{
|
|
9489
|
-
Component: Shipping,
|
|
9490
|
-
path: "/draft-orders/:id/shipping"
|
|
9491
|
-
},
|
|
9492
9521
|
{
|
|
9493
9522
|
Component: SalesChannel,
|
|
9494
9523
|
path: "/draft-orders/:id/sales-channel"
|
|
9495
9524
|
},
|
|
9525
|
+
{
|
|
9526
|
+
Component: Metadata,
|
|
9527
|
+
path: "/draft-orders/:id/metadata"
|
|
9528
|
+
},
|
|
9529
|
+
{
|
|
9530
|
+
Component: Shipping,
|
|
9531
|
+
path: "/draft-orders/:id/shipping"
|
|
9532
|
+
},
|
|
9496
9533
|
{
|
|
9497
9534
|
Component: ShippingAddress,
|
|
9498
9535
|
path: "/draft-orders/:id/shipping-address"
|