@aglyn/plugins-commerce 1.0.0-beta.221 → 1.0.0-beta.223
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 +4 -2
- package/package.json +14 -13
- package/src/lib/components/console/catalog-organization-card.component.js +9 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/discounts-card.component.js +8 -0
- package/src/lib/components/console/discounts-card.component.js.map +1 -1
- package/src/lib/components/console/gift-cards-card.component.js +8 -0
- package/src/lib/components/console/gift-cards-card.component.js.map +1 -1
- package/src/lib/components/console/host-coupons-card.component.js +8 -0
- package/src/lib/components/console/host-coupons-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +34 -70
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/product-zones.d.ts +7 -6
- package/src/lib/components/console/product-zones.js +5 -4
- package/src/lib/components/console/product-zones.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +86 -284
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/declarations.console-server.d.ts +38 -0
- package/src/lib/declarations.console-server.js +67 -0
- package/src/lib/declarations.console-server.js.map +1 -0
- package/src/lib/model/commerce-gift-cards.d.ts +26 -0
- package/src/lib/model/commerce-gift-cards.js +42 -0
- package/src/lib/model/commerce-gift-cards.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +0 -57
- package/src/lib/model/commerce-orders.js +0 -80
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/index.d.ts +0 -1
- package/src/lib/model/index.js +0 -1
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/plugin.js +5 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/api-v1/openapi.d.ts +27 -0
- package/src/lib/server/api-v1/openapi.js +219 -0
- package/src/lib/server/api-v1/openapi.js.map +1 -0
- package/src/lib/server/api-v1/orders-and-products.d.ts +19 -0
- package/src/lib/server/api-v1/orders-and-products.js +419 -0
- package/src/lib/server/api-v1/orders-and-products.js.map +1 -0
- package/src/lib/server/billing-webhook.js +10 -13
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/download.js +4 -1
- package/src/lib/server/download.js.map +1 -1
- package/src/lib/server/fulfill-order.d.ts +52 -11
- package/src/lib/server/fulfill-order.js +6 -9
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/gift-card-issue.d.ts +57 -0
- package/src/lib/server/gift-card-issue.js +155 -0
- package/src/lib/server/gift-card-issue.js.map +1 -0
- package/src/lib/server/gift-cards.js +25 -84
- package/src/lib/server/gift-cards.js.map +1 -1
- package/src/lib/server/membership-register.js +9 -8
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/newsletter.js +7 -5
- package/src/lib/server/newsletter.js.map +1 -1
- package/src/lib/server/paid-media-delivery.d.ts +21 -0
- package/src/lib/server/paid-media-delivery.js +23 -5
- package/src/lib/server/paid-media-delivery.js.map +1 -1
- package/src/lib/server/paid-media-serve-count.d.ts +28 -0
- package/src/lib/server/paid-media-serve-count.js +46 -0
- package/src/lib/server/paid-media-serve-count.js.map +1 -0
- package/src/lib/server/person-eraser.d.ts +45 -0
- package/src/lib/server/person-eraser.js +57 -0
- package/src/lib/server/person-eraser.js.map +1 -0
- package/src/lib/server/refund.js +15 -15
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/restock-flag.d.ts +2 -2
- package/src/lib/server/restock-flag.js +1 -1
- package/src/lib/server/restock-flag.js.map +1 -1
- package/src/lib/server/stream.js +4 -1
- package/src/lib/server/stream.js.map +1 -1
- package/src/lib/server.js +5 -21
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/stand-in-person-records.d.ts +43 -0
- package/src/lib/testing/stand-in-person-records.js +63 -0
- package/src/lib/testing/stand-in-person-records.js.map +1 -0
- package/src/lib/transfer/gift-card-confirm-step.component.d.ts +22 -0
- package/src/lib/transfer/gift-card-confirm-step.component.js +259 -0
- package/src/lib/transfer/gift-card-confirm-step.component.js.map +1 -0
- package/src/lib/transfer/gift-cards-plan.d.ts +29 -0
- package/src/lib/transfer/gift-cards-plan.js +40 -0
- package/src/lib/transfer/gift-cards-plan.js.map +1 -0
- package/src/lib/transfer/gift-cards.server.d.ts +34 -0
- package/src/lib/transfer/gift-cards.server.js +296 -0
- package/src/lib/transfer/gift-cards.server.js.map +1 -0
- package/src/lib/transfer/list-filter.d.ts +29 -0
- package/src/lib/transfer/list-filter.js +112 -0
- package/src/lib/transfer/list-filter.js.map +1 -0
- package/src/lib/transfer/product-import-results.d.ts +29 -0
- package/src/lib/transfer/product-import-results.js +49 -0
- package/src/lib/transfer/product-import-results.js.map +1 -0
- package/src/lib/transfer/product-import-step.component.d.ts +30 -0
- package/src/lib/transfer/product-import-step.component.js +99 -0
- package/src/lib/transfer/product-import-step.component.js.map +1 -0
- package/src/lib/transfer/product-transfer.d.ts +211 -0
- package/src/lib/transfer/product-transfer.js +1594 -0
- package/src/lib/transfer/product-transfer.js.map +1 -0
- package/src/lib/transfer/products.server.d.ts +44 -0
- package/src/lib/transfer/products.server.js +550 -0
- package/src/lib/transfer/products.server.js.map +1 -0
- package/src/lib/transfer/records-transfer.d.ts +182 -0
- package/src/lib/transfer/records-transfer.js +1153 -0
- package/src/lib/transfer/records-transfer.js.map +1 -0
- package/src/lib/transfer/records.server.d.ts +68 -0
- package/src/lib/transfer/records.server.js +455 -0
- package/src/lib/transfer/records.server.js.map +1 -0
- package/src/lib/transfer/register-transfer-resources.d.ts +17 -0
- package/src/lib/transfer/register-transfer-resources.js +171 -0
- package/src/lib/transfer/register-transfer-resources.js.map +1 -0
- package/src/lib/transfer/register-transfer-ui.d.ts +23 -0
- package/src/lib/transfer/register-transfer-ui.js +78 -0
- package/src/lib/transfer/register-transfer-ui.js.map +1 -0
- package/src/lib/transfer/server-common.d.ts +76 -0
- package/src/lib/transfer/server-common.js +165 -0
- package/src/lib/transfer/server-common.js.map +1 -0
- package/src/lib/transfer/transfer-header-actions.component.d.ts +39 -0
- package/src/lib/transfer/transfer-header-actions.component.js +79 -0
- package/src/lib/transfer/transfer-header-actions.component.js.map +1 -0
- package/src/lib/transfer/transfer-keys.d.ts +31 -0
- package/src/lib/transfer/transfer-keys.js +56 -0
- package/src/lib/transfer/transfer-keys.js.map +1 -0
- package/src/lib/model/commerce-io.d.ts +0 -36
- package/src/lib/model/commerce-io.js +0 -245
- package/src/lib/model/commerce-io.js.map +0 -1
- package/src/lib/server/contact-refund.d.ts +0 -117
- package/src/lib/server/contact-refund.js +0 -196
- package/src/lib/server/contact-refund.js.map +0 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
18
|
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
19
19
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
20
|
+
import { TransferResumeImport } from "@aglyn/aglyn/app-utils/transfer-resume-import";
|
|
20
21
|
import * as Aglyn from "@aglyn/aglyn";
|
|
21
22
|
import * as CommerceModel from "../../model/index.js";
|
|
22
23
|
import { PRODUCT_LIST_BASE, PRODUCT_LIST_FIELDS, PRODUCT_LIST_HEADERS, PRODUCT_LIST_OPTIONS, PRODUCT_LIST_QUERY, PRODUCT_LIST_SELECT_FIELDS, productListRequestClauses } from "../../constants/product-list-query.js";
|
|
@@ -32,30 +33,21 @@ import { useListGridFilter } from "@aglyn/shared-ui-jsx/hooks/use-list-grid-filt
|
|
|
32
33
|
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
33
34
|
import { Timestamp } from "@aglyn/shared-util-timestamp";
|
|
34
35
|
import { Box, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
35
|
-
import { addDoc, collection, doc, documentId, getCountFromServer,
|
|
36
|
+
import { addDoc, collection, doc, documentId, getCountFromServer, limit, orderBy, query, updateDoc, where } from "firebase/firestore";
|
|
36
37
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
37
38
|
import { useFirestore, useUser } from "@aglyn/tenant-feature-instance";
|
|
38
39
|
import { writeSiteWideChange } from "@aglyn/tenant-feature-instance/hooks/helpers/site-wide-change";
|
|
39
40
|
import { useFirestoreCollection, writeGuardedBySeed } from "@aglyn/tenant-feature-instance";
|
|
40
|
-
import {
|
|
41
|
+
import { useListQuery } from "@aglyn/tenant-feature-instance/hooks/use-list-query";
|
|
41
42
|
import { useHostResourceApi } from "@aglyn/tenant-feature-instance";
|
|
42
43
|
import { useOrgPlan } from "@aglyn/tenant-feature-instance";
|
|
43
44
|
import ProductEditorDialog from "./product-editor-dialog.component.js";
|
|
44
45
|
import { productSlugLedger } from "./product-slugs.js";
|
|
45
|
-
import { productCollectionFields
|
|
46
|
+
import { productCollectionFields } from "./smart-collections.js";
|
|
46
47
|
import ProductsHubZone from "./products-hub-zone.component.js";
|
|
47
48
|
import { pluginDocsHelp } from "@aglyn/aglyn";
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
/** Products read per request of the CSV export's walk. */ const EXPORT_PAGE = 500;
|
|
51
|
-
/**
|
|
52
|
-
* The most products one CSV export writes (AGL-3321).
|
|
53
|
-
*
|
|
54
|
-
* The export walks the table's own query page by page, so it writes what the
|
|
55
|
-
* filters and search match across the whole catalog rather than the rows on
|
|
56
|
-
* screen. It stops here because the file is built in the browser, and says
|
|
57
|
-
* so when it does.
|
|
58
|
-
*/ const EXPORT_CEILING = 10000;
|
|
49
|
+
import { commerceListFilter } from "../../transfer/list-filter.js";
|
|
50
|
+
import { COMMERCE_PRODUCTS_TRANSFER } from "../../transfer/transfer-keys.js";
|
|
59
51
|
/**
|
|
60
52
|
* How many of ONE product's license keys the dialog reads.
|
|
61
53
|
*
|
|
@@ -83,8 +75,7 @@ const STATUS_COLOR = {
|
|
|
83
75
|
* gated here on create/duplicate/import (AGL-471); server-side
|
|
84
76
|
* enforcement of the client-write path rides AGL-473.
|
|
85
77
|
*/ export function ProductsHubCard(props) {
|
|
86
|
-
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref10, _ref11
|
|
87
|
-
var _importing_parsed, _importing_parsed1, _importing_parsed2;
|
|
78
|
+
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref10, _ref11;
|
|
88
79
|
const { hostId } = props;
|
|
89
80
|
const firestore = useFirestore();
|
|
90
81
|
const { data: user } = useUser();
|
|
@@ -105,16 +96,14 @@ const STATUS_COLOR = {
|
|
|
105
96
|
const [editing, setEditing] = useState(null);
|
|
106
97
|
const [creating, setCreating] = useState(false);
|
|
107
98
|
const [adjusting, setAdjusting] = useState(null);
|
|
108
|
-
const [importing, setImporting] = useState(null);
|
|
109
99
|
const [keysFor, setKeysFor] = useState(null);
|
|
110
100
|
const [keysText, setKeysText] = useState('');
|
|
111
101
|
/**
|
|
112
|
-
* What the import
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
const WidgetSlot = useConsoleWidgetSlot();
|
|
102
|
+
* What the last import created, with the options its After import step
|
|
103
|
+
* set (AGL-2916, AGL-3531), which the hub's zone hands to its widgets.
|
|
104
|
+
*/ const [lastImport, setLastImport] = useState(null);
|
|
105
|
+
// The console's import wizard and export dialog; none outside the console.
|
|
106
|
+
const transfer = Aglyn.useTransferLauncher();
|
|
118
107
|
const { rows: productDocs, data: productWindow, hasMore, page, setPage, pageSize, setPageSize, plan, status: productsStatus, /**
|
|
119
108
|
* The product rows the stock dialog is seeded from are unconfirmed by
|
|
120
109
|
* the server (AGL-1358). A stock adjustment does not write the delta —
|
|
@@ -416,148 +405,55 @@ const STATUS_COLOR = {
|
|
|
416
405
|
enqueueSnackbar
|
|
417
406
|
]);
|
|
418
407
|
/*
|
|
419
|
-
*
|
|
408
|
+
* Import and export (AGL-3531) run on the console's transfer wizard and
|
|
409
|
+
* dialog, on the `commerce.products` resource: a product matched by
|
|
410
|
+
* handle, SKU or ID is updated, every step is a choice, and the export
|
|
411
|
+
* writes what the table's query matches — its filters and search — on the
|
|
412
|
+
* server, a row per variant, with a Shopify preset.
|
|
420
413
|
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
if (room <= 0) {
|
|
442
|
-
more = !snapshot.empty;
|
|
443
|
-
break;
|
|
444
|
-
}
|
|
445
|
-
for (const product of snapshot.docs){
|
|
446
|
-
exported.push(_extends({}, CommerceModel.liftLegacyProduct(product.data()), {
|
|
447
|
-
$id: product.id
|
|
448
|
-
}));
|
|
449
|
-
}
|
|
450
|
-
if (snapshot.docs.length < Math.min(EXPORT_PAGE, room)) break;
|
|
451
|
-
cursor = snapshot.docs[snapshot.docs.length - 1];
|
|
452
|
-
}
|
|
453
|
-
const csv = CommerceModel.productsToCsv(exported);
|
|
454
|
-
const blob = new Blob([
|
|
455
|
-
csv
|
|
456
|
-
], {
|
|
457
|
-
type: 'text/csv'
|
|
458
|
-
});
|
|
459
|
-
const anchor = document.createElement('a');
|
|
460
|
-
anchor.href = URL.createObjectURL(blob);
|
|
461
|
-
anchor.download = `products-${hostId}.csv`;
|
|
462
|
-
anchor.click();
|
|
463
|
-
URL.revokeObjectURL(anchor.href);
|
|
464
|
-
if (more) {
|
|
465
|
-
enqueueSnackbar(`Exported the first ${EXPORT_CEILING.toLocaleString()} matching ` + 'products — the most one file holds. Filter the list to export the rest.', {
|
|
466
|
-
variant: 'info',
|
|
467
|
-
persist: false
|
|
468
|
-
});
|
|
414
|
+
* When the wizard closes on its results, the products the import created
|
|
415
|
+
* reach the hub's zone with the options its After import step set.
|
|
416
|
+
*/ const openImport = useCallback(()=>{
|
|
417
|
+
transfer == null ? void 0 : transfer.openImport({
|
|
418
|
+
resource: COMMERCE_PRODUCTS_TRANSFER,
|
|
419
|
+
scope: 'host',
|
|
420
|
+
hostId,
|
|
421
|
+
onFinished: ()=>{
|
|
422
|
+
setProductCountEpoch((epoch)=>epoch + 1);
|
|
423
|
+
void (async ()=>{
|
|
424
|
+
const { takeProductImport, createdProductIds } = await import("../../transfer/product-import-results.js");
|
|
425
|
+
const finished = takeProductImport(hostId);
|
|
426
|
+
if (!finished) return;
|
|
427
|
+
const productIds = await createdProductIds(user, finished);
|
|
428
|
+
setLastImport({
|
|
429
|
+
key: `${finished.jobId}-${productIds.length}`,
|
|
430
|
+
productIds,
|
|
431
|
+
options: finished.options
|
|
432
|
+
});
|
|
433
|
+
})();
|
|
469
434
|
}
|
|
470
|
-
}
|
|
471
|
-
var _ref;
|
|
472
|
-
enqueueSnackbar((_ref = error == null ? void 0 : error.message) != null ? _ref : 'Could not export the products', {
|
|
473
|
-
variant: 'warning',
|
|
474
|
-
persist: false
|
|
475
|
-
});
|
|
476
|
-
} finally{
|
|
477
|
-
setExporting(false);
|
|
478
|
-
}
|
|
435
|
+
});
|
|
479
436
|
}, [
|
|
480
|
-
|
|
437
|
+
transfer,
|
|
481
438
|
hostId,
|
|
482
|
-
|
|
483
|
-
enqueueSnackbar
|
|
439
|
+
user
|
|
484
440
|
]);
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (!batchQuota.allowed) {
|
|
495
|
-
return void enqueueSnackbar(`This import needs ${parsed.products.length} product slots — your ` + `plan allows ${batchQuota.limit}. See Billing to upgrade.`, {
|
|
496
|
-
variant: 'info',
|
|
497
|
-
persist: false
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
/*
|
|
501
|
-
* The duplicate-slug check asks the STORE (AGL-3321): every slug the file
|
|
502
|
-
* names, by `slug in […]`, and any suffixed one only when it is needed.
|
|
503
|
-
* It asked the table's rows, which held five hundred products and now
|
|
504
|
-
* hold one page, so a slug past them was handed out a second time.
|
|
505
|
-
*/ const slugs = productSlugLedger(firestore, hostId);
|
|
506
|
-
const created = [];
|
|
507
|
-
try {
|
|
508
|
-
await slugs.ask(parsed.products.map((product)=>product.slug));
|
|
509
|
-
// One read of the host's smart collections for the whole file.
|
|
510
|
-
const smartCollections = await readSmartCollections(firestore, hostId);
|
|
511
|
-
// Each create rides the quota-enforcing API (AGL-473); the batch cap
|
|
512
|
-
// above short-circuits before we start, so this loop stays bounded.
|
|
513
|
-
for (const product of parsed.products){
|
|
514
|
-
var _ref, _ref1;
|
|
515
|
-
var _product_variants_, _product_mediaUrls;
|
|
516
|
-
const slug = await slugs.claim(product.slug);
|
|
517
|
-
const { id } = await createHostResource({
|
|
518
|
-
hostId,
|
|
519
|
-
resource: 'product',
|
|
520
|
-
data: _extends({}, product, CommerceModel.productSearchFields(product), CommerceModel.productStockFields(product), {
|
|
521
|
-
// Its smart collections (AGL-3321).
|
|
522
|
-
collectionIds: CommerceModel.productCollectionIds(product, smartCollections),
|
|
523
|
-
slug,
|
|
524
|
-
priceUsd: (_ref = (_product_variants_ = product.variants[0]) == null ? void 0 : _product_variants_.priceUsd) != null ? _ref : 0,
|
|
525
|
-
imageUrl: (_ref1 = (_product_mediaUrls = product.mediaUrls) == null ? void 0 : _product_mediaUrls[0]) != null ? _ref1 : null,
|
|
526
|
-
createdAtMs: Date.now(),
|
|
527
|
-
updatedAtMs: Date.now()
|
|
528
|
-
})
|
|
529
|
-
});
|
|
530
|
-
created.push(id);
|
|
441
|
+
const openExport = useCallback(()=>{
|
|
442
|
+
transfer == null ? void 0 : transfer.openExport(_extends({
|
|
443
|
+
resource: COMMERCE_PRODUCTS_TRANSFER,
|
|
444
|
+
scope: 'host',
|
|
445
|
+
hostId
|
|
446
|
+
}, filtering ? {
|
|
447
|
+
filter: {
|
|
448
|
+
label: 'the products the list’s filters and search find',
|
|
449
|
+
value: commerceListFilter(plan)
|
|
531
450
|
}
|
|
532
|
-
}
|
|
533
|
-
var _ref2;
|
|
534
|
-
return void enqueueSnackbar((_ref2 = error == null ? void 0 : error.message) != null ? _ref2 : 'Import failed', {
|
|
535
|
-
variant: 'warning',
|
|
536
|
-
persist: false
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
setLastImport({
|
|
540
|
-
key: `${Date.now().toString(36)}-${created.length}`,
|
|
541
|
-
productIds: created,
|
|
542
|
-
options: importOptions
|
|
543
|
-
});
|
|
544
|
-
setImportOptions({});
|
|
545
|
-
setImporting(null);
|
|
546
|
-
setProductCountEpoch((epoch)=>epoch + 1);
|
|
547
|
-
enqueueSnackbar(`Imported ${parsed.products.length} products`, {
|
|
548
|
-
variant: 'success',
|
|
549
|
-
persist: false
|
|
550
|
-
});
|
|
451
|
+
} : {}));
|
|
551
452
|
}, [
|
|
552
|
-
|
|
553
|
-
firestore,
|
|
453
|
+
transfer,
|
|
554
454
|
hostId,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
org,
|
|
558
|
-
planReady,
|
|
559
|
-
productCount,
|
|
560
|
-
importOptions
|
|
455
|
+
filtering,
|
|
456
|
+
plan
|
|
561
457
|
]);
|
|
562
458
|
const handleAdjustSave = useCallback(async ()=>{
|
|
563
459
|
if (!adjusting) return;
|
|
@@ -630,9 +526,6 @@ const STATUS_COLOR = {
|
|
|
630
526
|
productCount
|
|
631
527
|
]);
|
|
632
528
|
const onCatalogCreated = useCallback(()=>setProductCountEpoch((epoch)=>epoch + 1), []);
|
|
633
|
-
const setImportOption = useCallback((key, on)=>setImportOptions((current)=>_extends({}, current, {
|
|
634
|
-
[key]: on
|
|
635
|
-
})), []);
|
|
636
529
|
const formatPrice = (product)=>{
|
|
637
530
|
const [min, max] = CommerceModel.productPriceRange(product);
|
|
638
531
|
return min === max ? `$${min}` : `$${min}–$${max}`;
|
|
@@ -844,25 +737,35 @@ const STATUS_COLOR = {
|
|
|
844
737
|
},
|
|
845
738
|
children: 'Add product'
|
|
846
739
|
}),
|
|
847
|
-
/*#__PURE__*/ _jsx(
|
|
740
|
+
/*#__PURE__*/ _jsx(TransferResumeImport, {
|
|
741
|
+
target: {
|
|
742
|
+
resource: COMMERCE_PRODUCTS_TRANSFER,
|
|
743
|
+
scope: 'host',
|
|
744
|
+
hostId
|
|
745
|
+
},
|
|
746
|
+
onFinished: ()=>setProductCountEpoch((epoch)=>epoch + 1)
|
|
747
|
+
}),
|
|
748
|
+
(transfer == null ? void 0 : transfer.can('import', {
|
|
749
|
+
resource: COMMERCE_PRODUCTS_TRANSFER,
|
|
750
|
+
scope: 'host',
|
|
751
|
+
hostId
|
|
752
|
+
})) ? /*#__PURE__*/ _jsx(Button, {
|
|
848
753
|
size: "small",
|
|
849
754
|
disabled: !planReady,
|
|
850
|
-
onClick:
|
|
851
|
-
setImportOptions({});
|
|
852
|
-
setImporting({
|
|
853
|
-
text: '',
|
|
854
|
-
parsed: null
|
|
855
|
-
});
|
|
856
|
-
},
|
|
755
|
+
onClick: openImport,
|
|
857
756
|
children: 'Import'
|
|
858
|
-
}),
|
|
859
|
-
|
|
757
|
+
}) : null,
|
|
758
|
+
(transfer == null ? void 0 : transfer.can('export', {
|
|
759
|
+
resource: COMMERCE_PRODUCTS_TRANSFER,
|
|
760
|
+
scope: 'host',
|
|
761
|
+
hostId
|
|
762
|
+
})) ? /*#__PURE__*/ _jsx(Button, {
|
|
860
763
|
size: "small",
|
|
861
|
-
// Nothing matches: there is nothing for the
|
|
862
|
-
disabled:
|
|
863
|
-
onClick:
|
|
864
|
-
children:
|
|
865
|
-
})
|
|
764
|
+
// Nothing matches: there is nothing for the export to write.
|
|
765
|
+
disabled: products.length === 0 && page === 0,
|
|
766
|
+
onClick: openExport,
|
|
767
|
+
children: 'Export'
|
|
768
|
+
}) : null
|
|
866
769
|
]
|
|
867
770
|
}),
|
|
868
771
|
/*#__PURE__*/ _jsx(QuotaReadoutComponent, {
|
|
@@ -1037,107 +940,6 @@ const STATUS_COLOR = {
|
|
|
1037
940
|
})
|
|
1038
941
|
]
|
|
1039
942
|
}),
|
|
1040
|
-
/*#__PURE__*/ _jsxs(Dialog, {
|
|
1041
|
-
open: Boolean(importing),
|
|
1042
|
-
onClose: ()=>setImporting(null),
|
|
1043
|
-
maxWidth: "sm",
|
|
1044
|
-
fullWidth: true,
|
|
1045
|
-
children: [
|
|
1046
|
-
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
1047
|
-
children: 'Import products (CSV)'
|
|
1048
|
-
}),
|
|
1049
|
-
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
1050
|
-
sx: {
|
|
1051
|
-
display: 'flex',
|
|
1052
|
-
flexDirection: 'column',
|
|
1053
|
-
gap: 2
|
|
1054
|
-
},
|
|
1055
|
-
children: [
|
|
1056
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
1057
|
-
variant: "body2",
|
|
1058
|
-
color: "text.secondary",
|
|
1059
|
-
sx: {
|
|
1060
|
-
mt: 1
|
|
1061
|
-
},
|
|
1062
|
-
children: 'Shopify-compatible columns (Handle, Title, Option/Variant ' + 'columns, Image Src). Paste the file contents or choose a file.'
|
|
1063
|
-
}),
|
|
1064
|
-
/*#__PURE__*/ _jsxs(Button, {
|
|
1065
|
-
component: "label",
|
|
1066
|
-
size: "small",
|
|
1067
|
-
sx: {
|
|
1068
|
-
alignSelf: 'flex-start'
|
|
1069
|
-
},
|
|
1070
|
-
children: [
|
|
1071
|
-
'Choose file',
|
|
1072
|
-
/*#__PURE__*/ _jsx("input", {
|
|
1073
|
-
type: "file",
|
|
1074
|
-
accept: ".csv,text/csv",
|
|
1075
|
-
hidden: true,
|
|
1076
|
-
onChange: async (event)=>{
|
|
1077
|
-
var _event_target_files;
|
|
1078
|
-
const file = (_event_target_files = event.target.files) == null ? void 0 : _event_target_files[0];
|
|
1079
|
-
if (!file) return;
|
|
1080
|
-
const text = await file.text();
|
|
1081
|
-
setImporting({
|
|
1082
|
-
text,
|
|
1083
|
-
parsed: CommerceModel.parseProductsCsv(text)
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
|
-
})
|
|
1087
|
-
]
|
|
1088
|
-
}),
|
|
1089
|
-
/*#__PURE__*/ _jsx(TextField, {
|
|
1090
|
-
label: "CSV",
|
|
1091
|
-
value: (_ref4 = importing == null ? void 0 : importing.text) != null ? _ref4 : '',
|
|
1092
|
-
onChange: (event)=>setImporting({
|
|
1093
|
-
text: event.target.value,
|
|
1094
|
-
parsed: event.target.value.trim() ? CommerceModel.parseProductsCsv(event.target.value) : null
|
|
1095
|
-
}),
|
|
1096
|
-
size: "small",
|
|
1097
|
-
multiline: true,
|
|
1098
|
-
minRows: 5,
|
|
1099
|
-
maxRows: 10
|
|
1100
|
-
}),
|
|
1101
|
-
(importing == null ? void 0 : importing.parsed) ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
1102
|
-
children: [
|
|
1103
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
1104
|
-
variant: "body2",
|
|
1105
|
-
children: `Ready to import ${importing.parsed.products.length} products` + (importing.parsed.errors.length ? ` — ${importing.parsed.errors.length} rows skipped:` : '')
|
|
1106
|
-
}),
|
|
1107
|
-
importing.parsed.errors.slice(0, 5).map((error)=>/*#__PURE__*/ _jsx(Typography, {
|
|
1108
|
-
variant: "caption",
|
|
1109
|
-
color: "warning.main",
|
|
1110
|
-
children: error
|
|
1111
|
-
}, error))
|
|
1112
|
-
]
|
|
1113
|
-
}) : null,
|
|
1114
|
-
WidgetSlot && (importing == null ? void 0 : (_importing_parsed = importing.parsed) == null ? void 0 : _importing_parsed.products.length) ? /*#__PURE__*/ _jsx(WidgetSlot, {
|
|
1115
|
-
slot: PRODUCT_IMPORT_ZONE.id,
|
|
1116
|
-
hostId: hostId,
|
|
1117
|
-
orgId: undefined,
|
|
1118
|
-
count: importing.parsed.products.length,
|
|
1119
|
-
options: importOptions,
|
|
1120
|
-
setOption: setImportOption
|
|
1121
|
-
}) : null
|
|
1122
|
-
]
|
|
1123
|
-
}),
|
|
1124
|
-
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
1125
|
-
children: [
|
|
1126
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
1127
|
-
onClick: ()=>setImporting(null),
|
|
1128
|
-
children: 'Cancel'
|
|
1129
|
-
}),
|
|
1130
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
1131
|
-
variant: "contained",
|
|
1132
|
-
color: "primary",
|
|
1133
|
-
disabled: !(importing == null ? void 0 : (_importing_parsed1 = importing.parsed) == null ? void 0 : _importing_parsed1.products.length),
|
|
1134
|
-
onClick: handleImportApply,
|
|
1135
|
-
children: `Import${(importing == null ? void 0 : (_importing_parsed2 = importing.parsed) == null ? void 0 : _importing_parsed2.products.length) ? ` ${importing.parsed.products.length}` : ''}`
|
|
1136
|
-
})
|
|
1137
|
-
]
|
|
1138
|
-
})
|
|
1139
|
-
]
|
|
1140
|
-
}),
|
|
1141
943
|
/*#__PURE__*/ _jsxs(Dialog, {
|
|
1142
944
|
open: Boolean(adjusting),
|
|
1143
945
|
onClose: ()=>setAdjusting(null),
|
|
@@ -1145,7 +947,7 @@ const STATUS_COLOR = {
|
|
|
1145
947
|
fullWidth: true,
|
|
1146
948
|
children: [
|
|
1147
949
|
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
1148
|
-
children: `Adjust stock — ${(
|
|
950
|
+
children: `Adjust stock — ${(_ref4 = adjusting == null ? void 0 : adjusting.product.name) != null ? _ref4 : ''}`
|
|
1149
951
|
}),
|
|
1150
952
|
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
1151
953
|
sx: {
|
|
@@ -1156,7 +958,7 @@ const STATUS_COLOR = {
|
|
|
1156
958
|
children: [
|
|
1157
959
|
/*#__PURE__*/ _jsx(TextField, {
|
|
1158
960
|
label: "Variant",
|
|
1159
|
-
value: (
|
|
961
|
+
value: (_ref5 = adjusting == null ? void 0 : adjusting.variantId) != null ? _ref5 : '',
|
|
1160
962
|
onChange: (event)=>setAdjusting((prev)=>prev ? _extends({}, prev, {
|
|
1161
963
|
variantId: event.target.value
|
|
1162
964
|
}) : prev),
|
|
@@ -1165,7 +967,7 @@ const STATUS_COLOR = {
|
|
|
1165
967
|
sx: {
|
|
1166
968
|
mt: 1
|
|
1167
969
|
},
|
|
1168
|
-
children: ((
|
|
970
|
+
children: ((_ref6 = adjusting == null ? void 0 : adjusting.product.variants) != null ? _ref6 : []).filter((variant)=>variant.inventory != null).map((variant)=>{
|
|
1169
971
|
var _variant_options;
|
|
1170
972
|
return /*#__PURE__*/ _jsx(MenuItem, {
|
|
1171
973
|
value: variant.id,
|
|
@@ -1173,9 +975,9 @@ const STATUS_COLOR = {
|
|
|
1173
975
|
}, variant.id);
|
|
1174
976
|
})
|
|
1175
977
|
}),
|
|
1176
|
-
((
|
|
978
|
+
((_ref7 = locationDocs == null ? void 0 : locationDocs.length) != null ? _ref7 : 0) > 1 ? /*#__PURE__*/ _jsx(TextField, {
|
|
1177
979
|
label: "Location",
|
|
1178
|
-
value: (
|
|
980
|
+
value: (_ref8 = adjusting == null ? void 0 : adjusting.locationId) != null ? _ref8 : '',
|
|
1179
981
|
onChange: (event)=>setAdjusting((prev)=>prev ? _extends({}, prev, {
|
|
1180
982
|
locationId: event.target.value
|
|
1181
983
|
}) : prev),
|
|
@@ -1189,7 +991,7 @@ const STATUS_COLOR = {
|
|
|
1189
991
|
/*#__PURE__*/ _jsx(TextField, {
|
|
1190
992
|
label: "Change",
|
|
1191
993
|
placeholder: "+10 or -3",
|
|
1192
|
-
value: (
|
|
994
|
+
value: (_ref9 = adjusting == null ? void 0 : adjusting.delta) != null ? _ref9 : '',
|
|
1193
995
|
onChange: (event)=>setAdjusting((prev)=>prev ? _extends({}, prev, {
|
|
1194
996
|
delta: event.target.value.replace(/[^0-9+-]/g, '')
|
|
1195
997
|
}) : prev),
|
|
@@ -1197,7 +999,7 @@ const STATUS_COLOR = {
|
|
|
1197
999
|
}),
|
|
1198
1000
|
/*#__PURE__*/ _jsxs(TextField, {
|
|
1199
1001
|
label: "Reason",
|
|
1200
|
-
value: (
|
|
1002
|
+
value: (_ref10 = adjusting == null ? void 0 : adjusting.reason) != null ? _ref10 : 'restock',
|
|
1201
1003
|
onChange: (event)=>setAdjusting((prev)=>prev ? _extends({}, prev, {
|
|
1202
1004
|
reason: event.target.value
|
|
1203
1005
|
}) : prev),
|
|
@@ -1258,7 +1060,7 @@ const STATUS_COLOR = {
|
|
|
1258
1060
|
// keeps the cap off the dialog's shoulders (AGL-1716).
|
|
1259
1061
|
setProductCountEpoch((epoch)=>epoch + 1);
|
|
1260
1062
|
}
|
|
1261
|
-
}, (
|
|
1063
|
+
}, (_ref11 = editing == null ? void 0 : editing.$id) != null ? _ref11 : creating ? 'new' : 'closed')
|
|
1262
1064
|
]
|
|
1263
1065
|
});
|
|
1264
1066
|
}
|