@aglyn/plugins-commerce 1.0.0-beta.218 → 1.0.0-beta.219
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/README.md +1 -0
- package/package.json +13 -13
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -19
- package/src/index.js.map +1 -1
- package/src/lib/components/cart.js +2 -1
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/console/catalog-organization-card.component.js +44 -18
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +2 -1
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/member-posts-card.component.js +1 -1
- package/src/lib/components/console/member-posts-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +8 -7
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/payments-settings-card.component.js +1 -1
- package/src/lib/components/console/payments-settings-card.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +114 -63
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-zones.d.ts +184 -0
- package/src/lib/components/console/product-zones.js +54 -0
- package/src/lib/components/console/product-zones.js.map +1 -0
- package/src/lib/components/console/products-hub-card.component.js +3 -2
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/products-hub-zone.component.d.ts +1 -1
- package/src/lib/components/console/products-hub-zone.component.js +2 -1
- package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
- package/src/lib/components/console/store-settings-card.component.js +2 -2
- package/src/lib/components/console/store-settings-card.component.js.map +1 -1
- package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -1
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
- package/src/lib/components/product-detail.js +2 -1
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/product-grid.js +1 -1
- package/src/lib/components/product-grid.js.map +1 -1
- package/src/lib/constants/storefront-payments.d.ts +33 -0
- package/src/lib/constants/storefront-payments.js +35 -0
- package/src/lib/constants/storefront-payments.js.map +1 -0
- package/src/lib/declarations.server.d.ts +3 -1
- package/src/lib/declarations.server.js +19 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/commerce-record-routes.d.ts +27 -0
- package/src/lib/model/commerce-record-routes.js +72 -0
- package/src/lib/model/commerce-record-routes.js.map +1 -0
- package/src/lib/model/commerce-search-sources.d.ts +21 -0
- package/src/lib/model/commerce-search-sources.js +40 -0
- package/src/lib/model/commerce-search-sources.js.map +1 -0
- package/src/lib/model/storefront-tax-summary.d.ts +121 -0
- package/src/lib/model/storefront-tax-summary.js +148 -0
- package/src/lib/model/storefront-tax-summary.js.map +1 -0
- package/src/lib/plan-entitlements.d.ts +35 -0
- package/src/lib/plan-entitlements.js +54 -0
- package/src/lib/plan-entitlements.js.map +1 -0
- package/src/lib/plugin.js +9 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/billing-webhook.js +135 -168
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cart-checkout.js +2 -2
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/checkout.js +2 -2
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/connect.js +5 -5
- package/src/lib/server/connect.js.map +1 -1
- package/src/lib/server/draft-order.js +2 -2
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/membership-content.js +1 -1
- package/src/lib/server/membership-content.js.map +1 -1
- package/src/lib/server/pos-order.js +2 -2
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/product-record-index.d.ts +19 -0
- package/src/lib/server/product-record-index.js +115 -0
- package/src/lib/server/product-record-index.js.map +1 -0
- package/src/lib/server/reserve.js +2 -2
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/revenue-source.d.ts +130 -0
- package/src/lib/server/revenue-source.js +286 -0
- package/src/lib/server/revenue-source.js.map +1 -0
- package/src/lib/server/tax-profile.d.ts +8 -5
- package/src/lib/server/tax-profile.js +22 -5
- package/src/lib/server/tax-profile.js.map +1 -1
- package/src/lib/server/tax-return-source.d.ts +125 -0
- package/src/lib/server/tax-return-source.js +524 -0
- package/src/lib/server/tax-return-source.js.map +1 -0
- package/src/lib/server/tax-summary.d.ts +92 -0
- package/src/lib/server/tax-summary.js +258 -0
- package/src/lib/server/tax-summary.js.map +1 -0
- package/src/lib/server.d.ts +1 -0
- package/src/lib/server.js +23 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.d.ts +33 -0
- package/src/lib/tenant-emails.js +511 -0
- package/src/lib/tenant-emails.js.map +1 -0
- package/src/lib/testing/stand-in-crm-record-routes.d.ts +25 -0
- package/src/lib/testing/stand-in-crm-record-routes.js +46 -0
- package/src/lib/testing/stand-in-crm-record-routes.js.map +1 -0
|
@@ -23,7 +23,7 @@ import { Timestamp } from "@aglyn/shared-util-timestamp";
|
|
|
23
23
|
import { Alert, Autocomplete, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider, IconButton, MenuItem, Stack, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from "@mui/material";
|
|
24
24
|
import { collection, doc, getDoc } from "firebase/firestore";
|
|
25
25
|
import { productCollectionFields } from "./smart-collections.js";
|
|
26
|
-
import { useCallback, useMemo, useState } from "react";
|
|
26
|
+
import { memo, useCallback, useMemo, useRef, useState } from "react";
|
|
27
27
|
import { ceilingedWindow, collectionCeiling, useFirestore, useFirestoreCollection, useHostResourceApi, writeGuardedBySeed, useUser } from "@aglyn/tenant-feature-instance";
|
|
28
28
|
import { writeSiteWideChange } from "@aglyn/tenant-feature-instance/hooks/helpers/site-wide-change";
|
|
29
29
|
import { useMediaPicker } from "@aglyn/aglyn";
|
|
@@ -31,6 +31,7 @@ import { useConsoleWidgetSlot } from "@aglyn/aglyn/app-utils/console-widget-slot
|
|
|
31
31
|
import { seoListingFieldCount, seoListingFieldTooLong } from "@aglyn/aglyn/app-utils/seo-listing-fields";
|
|
32
32
|
import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
|
|
33
33
|
import { EntitlementUpsell, useCommerceEntitlement } from "./entitlement-gate.component.js";
|
|
34
|
+
import { PRODUCT_EDITOR_ZONE } from "./product-zones.js";
|
|
34
35
|
import { MembersVideosField, PaidDownloadAddButton, PaidMediaProtection } from "./paid-media.js";
|
|
35
36
|
/**
|
|
36
37
|
* What each picker in this dialog will offer.
|
|
@@ -72,6 +73,49 @@ function comboLabel(options) {
|
|
|
72
73
|
const values = Object.values(options != null ? options : {});
|
|
73
74
|
return values.length ? values.join(' / ') : 'Default';
|
|
74
75
|
}
|
|
76
|
+
/** Stand-in for a list the product does not hold yet, the same one each render. */ const NO_ITEMS = [];
|
|
77
|
+
const FILL_ROW = {
|
|
78
|
+
flex: 1
|
|
79
|
+
};
|
|
80
|
+
const categoryLabel = (category)=>category.name;
|
|
81
|
+
const recordLabel = (item)=>{
|
|
82
|
+
var _item_name;
|
|
83
|
+
return (_item_name = item.name) != null ? _item_name : item.$id;
|
|
84
|
+
};
|
|
85
|
+
const sameRecord = (option, value)=>option.$id === value.$id;
|
|
86
|
+
/**
|
|
87
|
+
* One of the editor's chip lists — tags, categories, an option's values,
|
|
88
|
+
* related products — MEMOIZED, and every prop it takes is stable while its
|
|
89
|
+
* own list is (AGL-3423).
|
|
90
|
+
*
|
|
91
|
+
* A multiple Autocomplete hands its input a new chip array as
|
|
92
|
+
* `startAdornment` on every render, and MUI's `InputBase` copies that into
|
|
93
|
+
* its `FormControl` from a passive effect: a state update left pending after
|
|
94
|
+
* every commit the field takes part in. React 19 counts each such commit as a
|
|
95
|
+
* nested update, and keystrokes delivered back to back commit one after
|
|
96
|
+
* another with nothing to clear the count, so the fifty-first throws
|
|
97
|
+
* "Maximum update depth exceeded" (#185). Every field in this editor writes
|
|
98
|
+
* one draft, so every keystroke in any of them re-rendered all four lists;
|
|
99
|
+
* kept out of those renders, a list commits only when it changes.
|
|
100
|
+
*/ const ProductChipsField = /*#__PURE__*/ memo(function ProductChipsField(props) {
|
|
101
|
+
const { index = 0, onChange } = props;
|
|
102
|
+
return /*#__PURE__*/ _jsx(Autocomplete, {
|
|
103
|
+
multiple: true,
|
|
104
|
+
freeSolo: props.freeSolo,
|
|
105
|
+
options: props.options,
|
|
106
|
+
value: props.value,
|
|
107
|
+
getOptionLabel: props.getOptionLabel,
|
|
108
|
+
isOptionEqualToValue: props.isOptionEqualToValue,
|
|
109
|
+
onChange: (_event, next)=>onChange(next, index),
|
|
110
|
+
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
111
|
+
label: props.label,
|
|
112
|
+
size: "small",
|
|
113
|
+
placeholder: props.placeholder,
|
|
114
|
+
helperText: props.helperText
|
|
115
|
+
})),
|
|
116
|
+
sx: props.fill ? FILL_ROW : undefined
|
|
117
|
+
});
|
|
118
|
+
});
|
|
75
119
|
/**
|
|
76
120
|
* Products hub editor (AGL-279): the full catalog editor — basics,
|
|
77
121
|
* media, tags, options → variants matrix, per-variant pricing/stock, and
|
|
@@ -161,6 +205,42 @@ function comboLabel(options) {
|
|
|
161
205
|
// Lazy-init per open; parent remounts via `key` on product change.
|
|
162
206
|
const current = (_ref = draft != null ? draft : lifted) != null ? _ref : blankProduct();
|
|
163
207
|
const update = (patch)=>setDraft(_extends({}, current, patch));
|
|
208
|
+
/*
|
|
209
|
+
* `update` for the memoized chip lists: the same write from the last
|
|
210
|
+
* rendered draft, from a callback that keeps its identity across renders.
|
|
211
|
+
*/ const latest = useRef(current);
|
|
212
|
+
latest.current = current;
|
|
213
|
+
const updateLatest = useCallback((patch)=>setDraft(_extends({}, latest.current, patch)), []);
|
|
214
|
+
const setTags = useCallback((tags)=>updateLatest({
|
|
215
|
+
tags: tags.map((tag)=>String(tag).trim()).filter(Boolean)
|
|
216
|
+
}), [
|
|
217
|
+
updateLatest
|
|
218
|
+
]);
|
|
219
|
+
const setCategories = useCallback((picked)=>updateLatest({
|
|
220
|
+
categoryIds: picked.map((category)=>category.$id)
|
|
221
|
+
}), [
|
|
222
|
+
updateLatest
|
|
223
|
+
]);
|
|
224
|
+
const setRelatedProducts = useCallback((picked)=>updateLatest({
|
|
225
|
+
relatedProductIds: picked.map((item)=>item.$id)
|
|
226
|
+
}), [
|
|
227
|
+
updateLatest
|
|
228
|
+
]);
|
|
229
|
+
const categoryIds = current.categoryIds;
|
|
230
|
+
const pickedCategories = useMemo(()=>categories.rows.filter((category)=>(categoryIds != null ? categoryIds : []).includes(category.$id)), [
|
|
231
|
+
categories.rows,
|
|
232
|
+
categoryIds
|
|
233
|
+
]);
|
|
234
|
+
const relatedProductIds = current.relatedProductIds;
|
|
235
|
+
const productId = product == null ? void 0 : product.$id;
|
|
236
|
+
const relatedOptions = useMemo(()=>relatedProducts.rows.filter((item)=>!item.deletedAt && item.$id !== productId), [
|
|
237
|
+
relatedProducts.rows,
|
|
238
|
+
productId
|
|
239
|
+
]);
|
|
240
|
+
const pickedRelated = useMemo(()=>relatedProducts.rows.filter((item)=>(relatedProductIds != null ? relatedProductIds : []).includes(item.$id)), [
|
|
241
|
+
relatedProducts.rows,
|
|
242
|
+
relatedProductIds
|
|
243
|
+
]);
|
|
164
244
|
/** The shell's zone renderer (AGL-2910); `null` outside the console shell. */ const WidgetSlot = useConsoleWidgetSlot();
|
|
165
245
|
/**
|
|
166
246
|
* A listing zone widget's proposal, staged into the draft like typing.
|
|
@@ -303,6 +383,11 @@ function comboLabel(options) {
|
|
|
303
383
|
}, [
|
|
304
384
|
current
|
|
305
385
|
]);
|
|
386
|
+
const latestOptionsChange = useRef(handleOptionsChange);
|
|
387
|
+
latestOptionsChange.current = handleOptionsChange;
|
|
388
|
+
const setOptionValues = useCallback((values, index)=>latestOptionsChange.current(index, {
|
|
389
|
+
values: values.map((value)=>String(value).trim()).filter(Boolean)
|
|
390
|
+
}), []);
|
|
306
391
|
const handleVariantField = (index, field, raw)=>{
|
|
307
392
|
const variants = [
|
|
308
393
|
...current.variants
|
|
@@ -633,39 +718,24 @@ function comboLabel(options) {
|
|
|
633
718
|
multiline: true,
|
|
634
719
|
minRows: 2
|
|
635
720
|
}),
|
|
636
|
-
/*#__PURE__*/ _jsx(
|
|
637
|
-
multiple: true,
|
|
721
|
+
/*#__PURE__*/ _jsx(ProductChipsField, {
|
|
638
722
|
freeSolo: true,
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
645
|
-
label: "Tags",
|
|
646
|
-
size: "small",
|
|
647
|
-
placeholder: "Type and press Enter"
|
|
648
|
-
}))
|
|
723
|
+
label: "Tags",
|
|
724
|
+
placeholder: "Type and press Enter",
|
|
725
|
+
options: NO_ITEMS,
|
|
726
|
+
value: (_current_tags1 = current.tags) != null ? _current_tags1 : NO_ITEMS,
|
|
727
|
+
onChange: setTags
|
|
649
728
|
}),
|
|
650
|
-
categories.rows.length > 0 ? /*#__PURE__*/ _jsx(
|
|
651
|
-
|
|
729
|
+
categories.rows.length > 0 ? /*#__PURE__*/ _jsx(ProductChipsField, {
|
|
730
|
+
label: "Categories",
|
|
652
731
|
options: categories.rows,
|
|
653
|
-
getOptionLabel:
|
|
654
|
-
isOptionEqualToValue:
|
|
655
|
-
value:
|
|
656
|
-
|
|
657
|
-
return ((_current_categoryIds = current.categoryIds) != null ? _current_categoryIds : []).includes(category.$id);
|
|
658
|
-
}),
|
|
659
|
-
onChange: (_event, picked)=>update({
|
|
660
|
-
categoryIds: picked.map((category)=>category.$id)
|
|
661
|
-
}),
|
|
662
|
-
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
663
|
-
label: "Categories",
|
|
664
|
-
size: "small"
|
|
665
|
-
}))
|
|
732
|
+
getOptionLabel: categoryLabel,
|
|
733
|
+
isOptionEqualToValue: sameRecord,
|
|
734
|
+
value: pickedCategories,
|
|
735
|
+
onChange: setCategories
|
|
666
736
|
}) : null,
|
|
667
737
|
WidgetSlot ? /*#__PURE__*/ _jsx(WidgetSlot, {
|
|
668
|
-
slot:
|
|
738
|
+
slot: PRODUCT_EDITOR_ZONE.id,
|
|
669
739
|
hostId: hostId,
|
|
670
740
|
orgId: undefined,
|
|
671
741
|
product: zoneProduct,
|
|
@@ -761,22 +831,15 @@ function comboLabel(options) {
|
|
|
761
831
|
},
|
|
762
832
|
placeholder: "Size"
|
|
763
833
|
}),
|
|
764
|
-
/*#__PURE__*/ _jsx(
|
|
765
|
-
multiple: true,
|
|
834
|
+
/*#__PURE__*/ _jsx(ProductChipsField, {
|
|
766
835
|
freeSolo: true,
|
|
767
|
-
|
|
836
|
+
fill: true,
|
|
837
|
+
label: "Values",
|
|
838
|
+
placeholder: "S, M, L…",
|
|
839
|
+
options: NO_ITEMS,
|
|
768
840
|
value: option.values,
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
}),
|
|
772
|
-
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
773
|
-
label: "Values",
|
|
774
|
-
size: "small",
|
|
775
|
-
placeholder: "S, M, L…"
|
|
776
|
-
})),
|
|
777
|
-
sx: {
|
|
778
|
-
flex: 1
|
|
779
|
-
}
|
|
841
|
+
index: index,
|
|
842
|
+
onChange: setOptionValues
|
|
780
843
|
}),
|
|
781
844
|
/*#__PURE__*/ _jsx(Button, {
|
|
782
845
|
size: "small",
|
|
@@ -1283,26 +1346,14 @@ function comboLabel(options) {
|
|
|
1283
1346
|
})
|
|
1284
1347
|
]
|
|
1285
1348
|
}) : null,
|
|
1286
|
-
/*#__PURE__*/ _jsx(
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
value: relatedProducts.rows.filter((item)=>{
|
|
1295
|
-
var _current_relatedProductIds;
|
|
1296
|
-
return ((_current_relatedProductIds = current.relatedProductIds) != null ? _current_relatedProductIds : []).includes(item.$id);
|
|
1297
|
-
}),
|
|
1298
|
-
onChange: (_event, picked)=>update({
|
|
1299
|
-
relatedProductIds: picked.map((item)=>item.$id)
|
|
1300
|
-
}),
|
|
1301
|
-
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
1302
|
-
label: "Related products (upsells)",
|
|
1303
|
-
size: "small",
|
|
1304
|
-
helperText: "Shown by the Related products block; blank falls back to frequently-bought-together"
|
|
1305
|
-
}))
|
|
1349
|
+
/*#__PURE__*/ _jsx(ProductChipsField, {
|
|
1350
|
+
label: "Related products (upsells)",
|
|
1351
|
+
helperText: "Shown by the Related products block; blank falls back to frequently-bought-together",
|
|
1352
|
+
options: relatedOptions,
|
|
1353
|
+
getOptionLabel: recordLabel,
|
|
1354
|
+
isOptionEqualToValue: sameRecord,
|
|
1355
|
+
value: pickedRelated,
|
|
1356
|
+
onChange: setRelatedProducts
|
|
1306
1357
|
}),
|
|
1307
1358
|
/*#__PURE__*/ _jsx(Divider, {
|
|
1308
1359
|
textAlign: "left",
|