@shipengine/elements 2.26.4 → 2.27.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/dist/cjs/assets/xcover/logo.svg.cjs +44 -0
- package/dist/cjs/components/field/rate-select/rate-card/rate-attribute-item/index.cjs +7 -0
- package/dist/cjs/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.cjs +56 -0
- package/dist/cjs/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.styles.cjs +27 -0
- package/dist/cjs/components/field/rate-select/rate-card/rate-card.cjs +52 -42
- package/dist/cjs/components/field/rate-select/rate-card/rate-card.styles.cjs +4 -0
- package/dist/cjs/components/field/rate-select/rate-select.cjs +80 -49
- package/dist/cjs/components/forms/register-funding-source-insurance-form/register-funding-source-insurance-form.cjs +1 -1
- package/dist/cjs/components/shipment-not-found-error/shipment-not-found-error.cjs +2 -17
- package/dist/cjs/components/suspend-purchase/suspend-purchase.cjs +3 -3
- package/dist/cjs/data/insurance-provider-metadatas.json.cjs +10 -4
- package/dist/cjs/elements/customs-form/customs-form-element.cjs +294 -0
- package/dist/cjs/elements/customs-form/customs-form-element.stories.cjs +243 -0
- package/dist/cjs/elements/customs-form/customs-form-schema.cjs +59 -0
- package/dist/cjs/elements/customs-form/customs-form-types.cjs +63 -0
- package/dist/cjs/elements/customs-form/index.cjs +10 -0
- package/dist/cjs/elements/index.cjs +5 -0
- package/dist/cjs/elements/manage-carriers/manage-carriers.cjs +1 -1
- package/dist/cjs/elements/purchase-label/components/customs-forms/tax-ids/tax-ids.cjs +1 -1
- package/dist/cjs/elements/purchase-label/components/index.cjs +2 -0
- package/dist/cjs/elements/purchase-label/components/rate-form/rate-view.cjs +1 -1
- package/dist/cjs/elements/purchase-label/components/shipment-form/shipment-form.cjs +4 -3
- package/dist/cjs/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.cjs +35 -11
- package/dist/cjs/elements/purchase-label/hooks/use-insurance-provider-options.cjs +2 -2
- package/dist/cjs/elements/purchase-label/purchase-label.cjs +1 -7
- package/dist/cjs/factories/shipengine/address.cjs +114 -0
- package/dist/cjs/factories/shipengine/money.cjs +21 -0
- package/dist/cjs/factories/shipengine/order-source.cjs +37 -0
- package/dist/cjs/factories/shipengine/package.cjs +41 -0
- package/dist/cjs/factories/shipengine/resource.cjs +23 -0
- package/dist/cjs/factories/shipengine/shipment.cjs +176 -0
- package/dist/cjs/factories/shipengine/weight.cjs +44 -0
- package/dist/cjs/factories/utils.cjs +19 -0
- package/dist/cjs/features/manage-carriers/hooks/use-list-funding-source-carriers.cjs +4 -6
- package/dist/cjs/features/manage-carriers/manage-carriers.cjs +8 -6
- package/dist/cjs/hooks/use-configure-shipment.cjs +3 -80
- package/dist/cjs/hooks/use-get-funding-source-insurance-provider.cjs +7 -7
- package/dist/cjs/hooks/use-manage-funding-source-insurance.cjs +15 -23
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/locales/en/common.json.cjs +2 -2
- package/dist/cjs/locales/en/purchase-label.json.cjs +9 -8
- package/dist/cjs/package.json.cjs +1 -1
- package/dist/cjs/utilities/feature-flags/feature-flags.cjs +1 -0
- package/dist/cjs/utilities/shipengine/carrier.cjs +4 -0
- package/dist/cjs/utilities/shipengine/index.cjs +3 -0
- package/dist/cjs/utilities/shipengine/insurance.cjs +63 -0
- package/dist/cjs/workflows/label-workflow/label-workflow.cjs +2 -26
- package/dist/cjs/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.cjs +9 -9
- package/dist/cjs/workflows/onboarding/components/terms-agreement-form/terms-agreement-form.cjs +3 -2
- package/dist/cjs/workflows/onboarding/components/terms-agreement-step/terms-agreement-step.cjs +8 -6
- package/dist/cjs/workflows/onboarding/components/terms-agreement-step/use-terms-agreement-step.cjs +4 -19
- package/dist/esm/assets/xcover/logo.svg.js +23 -0
- package/dist/esm/components/field/rate-select/rate-card/rate-attribute-item/index.js +1 -0
- package/dist/esm/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.js +54 -0
- package/dist/esm/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.styles.js +25 -0
- package/dist/esm/components/field/rate-select/rate-card/rate-card.js +52 -42
- package/dist/esm/components/field/rate-select/rate-card/rate-card.styles.js +4 -0
- package/dist/esm/components/field/rate-select/rate-select.js +80 -49
- package/dist/esm/components/forms/register-funding-source-insurance-form/register-funding-source-insurance-form.js +1 -1
- package/dist/esm/components/shipment-not-found-error/shipment-not-found-error.js +2 -17
- package/dist/esm/components/suspend-purchase/suspend-purchase.js +3 -3
- package/dist/esm/data/insurance-provider-metadatas.json.js +9 -4
- package/dist/esm/elements/customs-form/customs-form-element.js +291 -0
- package/dist/esm/elements/customs-form/customs-form-element.stories.js +232 -0
- package/dist/esm/elements/customs-form/customs-form-schema.js +56 -0
- package/dist/esm/elements/customs-form/customs-form-types.js +60 -0
- package/dist/esm/elements/customs-form/index.js +3 -0
- package/dist/esm/elements/index.js +3 -0
- package/dist/esm/elements/manage-carriers/manage-carriers.js +1 -1
- package/dist/esm/elements/purchase-label/components/customs-forms/tax-ids/tax-ids.js +1 -1
- package/dist/esm/elements/purchase-label/components/index.js +1 -0
- package/dist/esm/elements/purchase-label/components/rate-form/rate-view.js +1 -1
- package/dist/esm/elements/purchase-label/components/shipment-form/shipment-form.js +4 -3
- package/dist/esm/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.js +35 -11
- package/dist/esm/elements/purchase-label/hooks/use-insurance-provider-options.js +2 -2
- package/dist/esm/elements/purchase-label/purchase-label.js +1 -7
- package/dist/esm/elements-provider/elements-context-provider.js +1 -1
- package/dist/esm/factories/shipengine/address.js +111 -0
- package/dist/esm/factories/shipengine/money.js +19 -0
- package/dist/esm/factories/shipengine/order-source.js +34 -0
- package/dist/esm/factories/shipengine/package.js +39 -0
- package/dist/esm/factories/shipengine/resource.js +21 -0
- package/dist/esm/factories/shipengine/shipment.js +168 -0
- package/dist/esm/factories/shipengine/weight.js +40 -0
- package/dist/esm/factories/utils.js +15 -0
- package/dist/esm/features/manage-carriers/hooks/use-list-funding-source-carriers.js +5 -7
- package/dist/esm/features/manage-carriers/manage-carriers.js +8 -6
- package/dist/esm/hooks/use-configure-shipment.js +3 -80
- package/dist/esm/hooks/use-get-funding-source-insurance-provider.js +7 -7
- package/dist/esm/hooks/use-manage-funding-source-insurance.js +15 -23
- package/dist/esm/index.js +3 -0
- package/dist/esm/locales/en/common.json.js +2 -2
- package/dist/esm/locales/en/purchase-label.json.js +9 -8
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/utilities/feature-flags/feature-flags.js +1 -0
- package/dist/esm/utilities/shipengine/carrier.js +4 -0
- package/dist/esm/utilities/shipengine/index.js +1 -1
- package/dist/esm/utilities/shipengine/insurance.js +61 -1
- package/dist/esm/workflows/label-workflow/label-workflow.js +2 -26
- package/dist/esm/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.js +9 -9
- package/dist/esm/workflows/onboarding/components/terms-agreement-form/terms-agreement-form.js +3 -2
- package/dist/esm/workflows/onboarding/components/terms-agreement-step/terms-agreement-step.js +8 -6
- package/dist/esm/workflows/onboarding/components/terms-agreement-step/use-terms-agreement-step.js +5 -20
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/index.d.ts +2 -0
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/index.d.ts.map +1 -0
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.d.ts +8 -0
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.d.ts.map +1 -0
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.styles.d.ts +22 -0
- package/dist/types/components/field/rate-select/rate-card/rate-attribute-item/rate-attribute-item.styles.d.ts.map +1 -0
- package/dist/types/components/field/rate-select/rate-card/rate-card.d.ts +3 -2
- package/dist/types/components/field/rate-select/rate-card/rate-card.d.ts.map +1 -1
- package/dist/types/components/field/rate-select/rate-card/rate-card.styles.d.ts +4 -0
- package/dist/types/components/field/rate-select/rate-card/rate-card.styles.d.ts.map +1 -1
- package/dist/types/components/field/rate-select/rate-select.d.ts.map +1 -1
- package/dist/types/components/forms/register-funding-source-insurance-form/register-funding-source-insurance-form.d.ts.map +1 -1
- package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts +2 -3
- package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts.map +1 -1
- package/dist/types/components/suspend-purchase/suspend-purchase.d.ts +2 -3
- package/dist/types/components/suspend-purchase/suspend-purchase.d.ts.map +1 -1
- package/dist/types/elements/customs-form/customs-form-element.d.ts +1219 -0
- package/dist/types/elements/customs-form/customs-form-element.d.ts.map +1 -0
- package/dist/types/elements/customs-form/customs-form-element.stories.d.ts +12 -0
- package/dist/types/elements/customs-form/customs-form-element.stories.d.ts.map +1 -0
- package/dist/types/elements/customs-form/customs-form-schema.d.ts +398 -0
- package/dist/types/elements/customs-form/customs-form-schema.d.ts.map +1 -0
- package/dist/types/elements/customs-form/customs-form-types.d.ts +139 -0
- package/dist/types/elements/customs-form/customs-form-types.d.ts.map +1 -0
- package/dist/types/elements/customs-form/index.d.ts +4 -0
- package/dist/types/elements/customs-form/index.d.ts.map +1 -0
- package/dist/types/elements/index.d.ts +1 -0
- package/dist/types/elements/index.d.ts.map +1 -1
- package/dist/types/elements/labels-grid/labels-grid.d.ts +9 -8
- package/dist/types/elements/labels-grid/labels-grid.d.ts.map +1 -1
- package/dist/types/elements/manage-carriers/manage-carriers.d.ts +9 -8
- package/dist/types/elements/manage-carriers/manage-carriers.d.ts.map +1 -1
- package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts +9 -8
- package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts.map +1 -1
- package/dist/types/elements/manage-funding/manage-funding-element.d.ts +9 -8
- package/dist/types/elements/manage-funding/manage-funding-element.d.ts.map +1 -1
- package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts +9 -8
- package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts.map +1 -1
- package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts +9 -8
- package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/components/index.d.ts +1 -0
- package/dist/types/elements/purchase-label/components/index.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/components/shipment-form/shipment-form.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.d.ts +5 -1
- package/dist/types/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/hooks/use-insurance-provider-options.d.ts.map +1 -1
- package/dist/types/elements/purchase-label/purchase-label.d.ts +9 -8
- package/dist/types/elements/purchase-label/purchase-label.d.ts.map +1 -1
- package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts +9 -8
- package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts.map +1 -1
- package/dist/types/elements/shipment-summary/shipment-summary.d.ts +9 -8
- package/dist/types/elements/shipment-summary/shipment-summary.d.ts.map +1 -1
- package/dist/types/elements/shipments-grid/shipments-grid.d.ts +9 -8
- package/dist/types/elements/shipments-grid/shipments-grid.d.ts.map +1 -1
- package/dist/types/elements/theme-creator/theme-creator.d.ts +9 -8
- package/dist/types/elements/theme-creator/theme-creator.d.ts.map +1 -1
- package/dist/types/elements/transaction-history/transaction-history-element.d.ts +9 -8
- package/dist/types/elements/transaction-history/transaction-history-element.d.ts.map +1 -1
- package/dist/types/elements/unit-settings/unit-settings-element.d.ts +9 -8
- package/dist/types/elements/unit-settings/unit-settings-element.d.ts.map +1 -1
- package/dist/types/elements/vat-settings/vat-settings-element.d.ts +9 -8
- package/dist/types/elements/vat-settings/vat-settings-element.d.ts.map +1 -1
- package/dist/types/elements/void-label/void-label.d.ts +9 -8
- package/dist/types/elements/void-label/void-label.d.ts.map +1 -1
- package/dist/types/features/manage-carriers/hooks/use-list-funding-source-carriers.d.ts.map +1 -1
- package/dist/types/features/manage-carriers/manage-carriers.d.ts.map +1 -1
- package/dist/types/hooks/use-configure-shipment.d.ts.map +1 -1
- package/dist/types/hooks/use-get-funding-source-insurance-provider.d.ts.map +1 -1
- package/dist/types/hooks/use-manage-funding-source-insurance.d.ts +3 -4
- package/dist/types/hooks/use-manage-funding-source-insurance.d.ts.map +1 -1
- package/dist/types/locales/en/index.d.ts +9 -8
- package/dist/types/locales/en/index.d.ts.map +1 -1
- package/dist/types/types/insurance-metadata.d.ts +1 -1
- package/dist/types/types/insurance-metadata.d.ts.map +1 -1
- package/dist/types/types/rates.d.ts +1 -0
- package/dist/types/types/rates.d.ts.map +1 -1
- package/dist/types/utilities/feature-flags/feature-flags.d.ts.map +1 -1
- package/dist/types/utilities/feature-flags/types.d.ts +4 -0
- package/dist/types/utilities/feature-flags/types.d.ts.map +1 -1
- package/dist/types/utilities/shipengine/carrier.d.ts.map +1 -1
- package/dist/types/utilities/shipengine/insurance.d.ts +31 -0
- package/dist/types/utilities/shipengine/insurance.d.ts.map +1 -1
- package/dist/types/workflows/account-settings/account-settings.d.ts +9 -8
- package/dist/types/workflows/account-settings/account-settings.d.ts.map +1 -1
- package/dist/types/workflows/carrier-services/carrier-services.d.ts +9 -8
- package/dist/types/workflows/carrier-services/carrier-services.d.ts.map +1 -1
- package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts +9 -8
- package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts.map +1 -1
- package/dist/types/workflows/label-workflow/label-workflow.d.ts +9 -8
- package/dist/types/workflows/label-workflow/label-workflow.d.ts.map +1 -1
- package/dist/types/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.d.ts.map +1 -1
- package/dist/types/workflows/onboarding/components/terms-agreement-step/terms-agreement-step.d.ts.map +1 -1
- package/dist/types/workflows/onboarding/components/terms-agreement-step/use-terms-agreement-step.d.ts +1 -5
- package/dist/types/workflows/onboarding/components/terms-agreement-step/use-terms-agreement-step.d.ts.map +1 -1
- package/dist/types/workflows/onboarding/onboarding.d.ts +9 -8
- package/dist/types/workflows/onboarding/onboarding.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { jsx, jsxs } from '@emotion/react/jsx-runtime';
|
|
2
|
+
import { useShipmentMetadata } from '../../hooks/options/use-shipment-metadata.js';
|
|
3
|
+
import { Button, ButtonVariant } from '@shipengine/giger';
|
|
4
|
+
import { validationResolver } from '../../utilities/validation.js';
|
|
5
|
+
import { useState, useMemo, useCallback, useEffect } from 'react';
|
|
6
|
+
import { useForm } from 'react-hook-form';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
import { CustomsForms } from '../purchase-label/components/customs-forms/customs-forms.js';
|
|
9
|
+
import { getShipmentSchema } from '../purchase-label/components/shipment-form/shipment-schema.js';
|
|
10
|
+
import { extractCustomsFormData } from './customs-form-types.js';
|
|
11
|
+
import { useWindsorFramework } from '../purchase-label/hooks/use-windsor-framework.js';
|
|
12
|
+
import en from '../../locales/en/index.js';
|
|
13
|
+
import { createElement } from '../../create-element/create-element.js';
|
|
14
|
+
import { ButtonGroup } from '../../components/button-group/button-group.js';
|
|
15
|
+
import { ErrorFallback } from '../../components/error-fallback/error-fallback.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* # Customs Form Element Component
|
|
19
|
+
*
|
|
20
|
+
* - The `<CustomsForm />` component is a standalone element that wraps the `CustomsForms`
|
|
21
|
+
* component with its own form management. This allows you to use customs forms independently
|
|
22
|
+
* outside of the full `PurchaseLabel` workflow while managing its own internal form state.
|
|
23
|
+
*
|
|
24
|
+
* @param CustomsFormProps The props necessary to render the `<CustomsForm />` component.
|
|
25
|
+
*
|
|
26
|
+
* @returns Element An EmotionJSX.Element that will render the `<CustomsForm />` component
|
|
27
|
+
* with all the appropriate wrappers.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* You can see how the `<Component />` is used in the `createElement` function call below.
|
|
31
|
+
* ```tsx
|
|
32
|
+
* export const Element = createElement(Component, ErrorFallback, {
|
|
33
|
+
* css: { width: "100%" },
|
|
34
|
+
* resources: { en },
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* <br />
|
|
39
|
+
*
|
|
40
|
+
* @see {@link CustomsForm.Element | The **Element** created to render `<CustomsForm />`}
|
|
41
|
+
*/
|
|
42
|
+
const Component = ({
|
|
43
|
+
shipment,
|
|
44
|
+
betaEnableWindsorFramework = false,
|
|
45
|
+
currency,
|
|
46
|
+
harmonizedTariffCodes,
|
|
47
|
+
onModify,
|
|
48
|
+
onSubmit,
|
|
49
|
+
onCancel,
|
|
50
|
+
className,
|
|
51
|
+
"data-testid": dataTestId
|
|
52
|
+
}) => {
|
|
53
|
+
var _a, _b, _c, _d, _e, _f;
|
|
54
|
+
const {
|
|
55
|
+
t
|
|
56
|
+
} = useTranslation();
|
|
57
|
+
// Track additional state for tax identifiers and products that aren't directly in the form
|
|
58
|
+
const [taxIdentifiers, setTaxIdentifiers] = useState(shipment.taxIdentifiers || []);
|
|
59
|
+
// We onliy support a single package within Elements, so track products for only first package
|
|
60
|
+
const [products, setProducts] = useState(((_b = (_a = shipment.packages) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.products) || []);
|
|
61
|
+
// Get shipment metadata to determine form requirements
|
|
62
|
+
const {
|
|
63
|
+
isCustomsRequired,
|
|
64
|
+
isCanadaDeliveredDutyEligible,
|
|
65
|
+
isContentDescriptionRequired,
|
|
66
|
+
hasAllZeroMeasurements
|
|
67
|
+
} = useShipmentMetadata(shipment);
|
|
68
|
+
const {
|
|
69
|
+
requiresWindsorFramework
|
|
70
|
+
} = useWindsorFramework(shipment, betaEnableWindsorFramework);
|
|
71
|
+
// Get the shipment schema for form validation
|
|
72
|
+
const shipmentSchema = useMemo(() => {
|
|
73
|
+
var _a, _b, _c, _d, _e, _f;
|
|
74
|
+
return getShipmentSchema({
|
|
75
|
+
isCustomsRequired,
|
|
76
|
+
requiresWindsorFramework,
|
|
77
|
+
isContentDescriptionRequired,
|
|
78
|
+
requireMeasurements: !hasAllZeroMeasurements,
|
|
79
|
+
dimensionsUnit: (_c = (_b = (_a = shipment.packages) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.dimensions) === null || _c === void 0 ? void 0 : _c.unit,
|
|
80
|
+
weightUnit: (_f = (_e = (_d = shipment.packages) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.weight) === null || _f === void 0 ? void 0 : _f.unit
|
|
81
|
+
});
|
|
82
|
+
}, [isCustomsRequired, requiresWindsorFramework, isContentDescriptionRequired, hasAllZeroMeasurements, shipment.packages]);
|
|
83
|
+
// Create form with shipment data
|
|
84
|
+
const form = useForm({
|
|
85
|
+
defaultValues: {
|
|
86
|
+
__mode: "browse_rates",
|
|
87
|
+
customs: shipment.customs ? {
|
|
88
|
+
contents: shipment.customs.contents,
|
|
89
|
+
nonDelivery: shipment.customs.nonDelivery
|
|
90
|
+
} : undefined,
|
|
91
|
+
packages: ((_c = shipment.packages) === null || _c === void 0 ? void 0 : _c.map(pkg => ({
|
|
92
|
+
type: {
|
|
93
|
+
code: pkg.packageCode || "package",
|
|
94
|
+
carrierId: null,
|
|
95
|
+
packageId: pkg.packageId
|
|
96
|
+
},
|
|
97
|
+
products: pkg.products || [],
|
|
98
|
+
dimensions: pkg.dimensions ? {
|
|
99
|
+
length: pkg.dimensions.length,
|
|
100
|
+
width: pkg.dimensions.width,
|
|
101
|
+
height: pkg.dimensions.height
|
|
102
|
+
} : null,
|
|
103
|
+
weight: pkg.weight ? {
|
|
104
|
+
whole: Math.floor(pkg.weight.value),
|
|
105
|
+
fractional: Math.round(pkg.weight.value % 1 * 16) // Convert decimal to oz
|
|
106
|
+
} : null,
|
|
107
|
+
contentDescription: pkg.contentDescription,
|
|
108
|
+
insuredValue: pkg.insuredValue
|
|
109
|
+
}))) || [{
|
|
110
|
+
type: {
|
|
111
|
+
code: "package",
|
|
112
|
+
carrierId: null,
|
|
113
|
+
packageId: null
|
|
114
|
+
},
|
|
115
|
+
products: [],
|
|
116
|
+
dimensions: null,
|
|
117
|
+
weight: null,
|
|
118
|
+
contentDescription: null,
|
|
119
|
+
insuredValue: null
|
|
120
|
+
}],
|
|
121
|
+
advancedOptions: {
|
|
122
|
+
additionalHandling: (_d = shipment.advancedOptions) === null || _d === void 0 ? void 0 : _d.additionalHandling,
|
|
123
|
+
canadaDeliveredDuty: (_e = shipment.advancedOptions) === null || _e === void 0 ? void 0 : _e.canadaDeliveredDuty,
|
|
124
|
+
windsorFrameworkDetails: (_f = shipment.advancedOptions) === null || _f === void 0 ? void 0 : _f.windsorFrameworkDetails
|
|
125
|
+
},
|
|
126
|
+
shipDate: new Date().toLocaleDateString(),
|
|
127
|
+
shipmentId: shipment.shipmentId
|
|
128
|
+
},
|
|
129
|
+
resolver: validationResolver(shipmentSchema),
|
|
130
|
+
mode: "onChange"
|
|
131
|
+
});
|
|
132
|
+
// Watch for form changes and call onModify
|
|
133
|
+
const watchedValues = form.watch();
|
|
134
|
+
// Create updated shipment data with current form values and tracked state
|
|
135
|
+
const getUpdatedShipment = useCallback(() => {
|
|
136
|
+
var _a;
|
|
137
|
+
return Object.assign(Object.assign({}, shipment), {
|
|
138
|
+
customs: watchedValues.customs,
|
|
139
|
+
taxIdentifiers,
|
|
140
|
+
packages: ((_a = watchedValues.packages) === null || _a === void 0 ? void 0 : _a.map((pkg, index) => {
|
|
141
|
+
var _a, _b, _c;
|
|
142
|
+
return Object.assign(Object.assign(Object.assign({}, (_a = shipment.packages) === null || _a === void 0 ? void 0 : _a[index]), pkg), {
|
|
143
|
+
products: index === 0 ? products : pkg.products || ((_c = (_b = shipment.packages) === null || _b === void 0 ? void 0 : _b[index]) === null || _c === void 0 ? void 0 : _c.products) || []
|
|
144
|
+
});
|
|
145
|
+
})) || [],
|
|
146
|
+
advancedOptions: Object.assign(Object.assign({}, shipment.advancedOptions), watchedValues.advancedOptions)
|
|
147
|
+
});
|
|
148
|
+
}, [shipment, watchedValues, taxIdentifiers, products]);
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (onModify && form.formState.isDirty) {
|
|
151
|
+
// Extract customs data from the updated shipment
|
|
152
|
+
const updatedShipment = getUpdatedShipment();
|
|
153
|
+
const customsData = extractCustomsFormData(updatedShipment);
|
|
154
|
+
onModify(customsData);
|
|
155
|
+
}
|
|
156
|
+
}, [watchedValues, onModify, form.formState.isDirty, shipment, getUpdatedShipment]);
|
|
157
|
+
// Update tracked state when shipment changes
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
var _a, _b;
|
|
160
|
+
setTaxIdentifiers(shipment.taxIdentifiers || []);
|
|
161
|
+
setProducts(((_b = (_a = shipment.packages) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.products) || []);
|
|
162
|
+
}, [shipment]);
|
|
163
|
+
// Handle form submission
|
|
164
|
+
const handleSubmit = useCallback(e => {
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
if (onSubmit) {
|
|
167
|
+
const updatedShipment = getUpdatedShipment();
|
|
168
|
+
const customsData = extractCustomsFormData(updatedShipment);
|
|
169
|
+
void onSubmit(customsData);
|
|
170
|
+
}
|
|
171
|
+
}, [onSubmit, getUpdatedShipment]);
|
|
172
|
+
// Handle dirty state changes
|
|
173
|
+
const handleDirty = useCallback(() => {
|
|
174
|
+
// This is called by CustomsForms when the form becomes dirty
|
|
175
|
+
}, []);
|
|
176
|
+
// Handle customs updates - this updates the form and triggers onModify
|
|
177
|
+
const handleUpdateCustoms = useCallback((_customs, products) => {
|
|
178
|
+
setProducts(products);
|
|
179
|
+
const updatedShipment = getUpdatedShipment();
|
|
180
|
+
// Trigger onModify with the updated data
|
|
181
|
+
if (onModify) {
|
|
182
|
+
const customsData = extractCustomsFormData(updatedShipment);
|
|
183
|
+
onModify(customsData);
|
|
184
|
+
}
|
|
185
|
+
return Promise.resolve(updatedShipment);
|
|
186
|
+
}, [getUpdatedShipment, onModify]);
|
|
187
|
+
// Handle tax identifier updates - this updates our tracked state and triggers onModify
|
|
188
|
+
const handleUpdateTaxableIds = useCallback(updatedTaxIds => {
|
|
189
|
+
setTaxIdentifiers(updatedTaxIds);
|
|
190
|
+
const updatedShipment = Object.assign(Object.assign({}, getUpdatedShipment()), {
|
|
191
|
+
taxIdentifiers: updatedTaxIds
|
|
192
|
+
});
|
|
193
|
+
// Trigger onModify with the updated data
|
|
194
|
+
if (onModify) {
|
|
195
|
+
const customsData = extractCustomsFormData(updatedShipment);
|
|
196
|
+
onModify(customsData);
|
|
197
|
+
}
|
|
198
|
+
return Promise.resolve(updatedShipment);
|
|
199
|
+
}, [getUpdatedShipment, onModify]);
|
|
200
|
+
// Create enhanced shipment with current tracked state for CustomsForms
|
|
201
|
+
const enhancedShipment = useMemo(() => {
|
|
202
|
+
var _a;
|
|
203
|
+
return Object.assign(Object.assign({}, shipment), {
|
|
204
|
+
taxIdentifiers,
|
|
205
|
+
packages: ((_a = shipment.packages) === null || _a === void 0 ? void 0 : _a.map((pkg, index) => Object.assign(Object.assign({}, pkg), {
|
|
206
|
+
products: index === 0 ? products : pkg.products || []
|
|
207
|
+
}))) || []
|
|
208
|
+
});
|
|
209
|
+
}, [shipment, taxIdentifiers, products]);
|
|
210
|
+
return jsx("div", {
|
|
211
|
+
className: className,
|
|
212
|
+
"data-testid": dataTestId,
|
|
213
|
+
children: jsxs("form", {
|
|
214
|
+
onSubmit: handleSubmit,
|
|
215
|
+
children: [jsx(CustomsForms, {
|
|
216
|
+
currency: currency,
|
|
217
|
+
form: form,
|
|
218
|
+
harmonizedTariffCodes: harmonizedTariffCodes,
|
|
219
|
+
isCanadaDeliveredDutyEligible: isCanadaDeliveredDutyEligible,
|
|
220
|
+
onDirty: handleDirty,
|
|
221
|
+
onUpdateCustoms: handleUpdateCustoms,
|
|
222
|
+
onUpdateTaxableIds: handleUpdateTaxableIds,
|
|
223
|
+
requiresWindsorFramework: requiresWindsorFramework,
|
|
224
|
+
shipment: enhancedShipment
|
|
225
|
+
}), (onSubmit || onCancel) && jsxs(ButtonGroup, {
|
|
226
|
+
justify: "end",
|
|
227
|
+
children: [onCancel && jsx(Button, {
|
|
228
|
+
bold: false,
|
|
229
|
+
onClick: onCancel,
|
|
230
|
+
type: "button",
|
|
231
|
+
variant: ButtonVariant.OUTLINED,
|
|
232
|
+
children: t("actions.cancel")
|
|
233
|
+
}), onSubmit && jsx(Button, {
|
|
234
|
+
bold: false,
|
|
235
|
+
disabled: !form.formState.isValid || form.formState.isSubmitting,
|
|
236
|
+
type: "submit",
|
|
237
|
+
variant: ButtonVariant.FILLED,
|
|
238
|
+
children: form.formState.isSubmitting ? t("actions.submitting") : t("actions.submit")
|
|
239
|
+
})]
|
|
240
|
+
})]
|
|
241
|
+
})
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
Component.displayName = "CustomsForm";
|
|
245
|
+
/**
|
|
246
|
+
* # Registered Customs Form Element
|
|
247
|
+
*
|
|
248
|
+
* - This is the registered `<CustomsForm />` element that will be used to render the
|
|
249
|
+
* `<CustomsForm.Element />` component.
|
|
250
|
+
*
|
|
251
|
+
* @param ElementProps The props, callbacks, and resources necessary to render
|
|
252
|
+
* the `<CustomsForm.Element />` component.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* The `<Component />` is the source JSX that is rendered when you make use of the `CustomsForm`
|
|
256
|
+
* Element directly. Here is a brief example of how you would use it within your application.
|
|
257
|
+
* ```tsx
|
|
258
|
+
* <CustomsForm.Element
|
|
259
|
+
* shipment={salesOrderShipment}
|
|
260
|
+
* currency={SE.Currency.USD}
|
|
261
|
+
* harmonizedTariffCodes={htsCodes}
|
|
262
|
+
* betaEnableWindsorFramework={true}
|
|
263
|
+
* onModify={(customsData) => {
|
|
264
|
+
* console.log('Customs form modified:', customsData);
|
|
265
|
+
* }}
|
|
266
|
+
* onSubmit={async (customsData) => {
|
|
267
|
+
* console.log('Customs form submitted:', customsData);
|
|
268
|
+
* await updateShipmentCustoms(customsData);
|
|
269
|
+
* }}
|
|
270
|
+
* onCancel={() => {
|
|
271
|
+
* console.log('Form cancelled');
|
|
272
|
+
* }}
|
|
273
|
+
* />
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* <br />
|
|
277
|
+
*
|
|
278
|
+
* @see {@link CustomsForm.ComponentProps | The **props** that can be passed into the `<CustomsForm.Element />` component}
|
|
279
|
+
*
|
|
280
|
+
* @see {@link PurchaseLabel.Element | See how this element is used within the full label purchase workflow `<PurchaseLabel.Element />`}
|
|
281
|
+
*/
|
|
282
|
+
const Element = createElement(Component, ErrorFallback, {
|
|
283
|
+
css: {
|
|
284
|
+
width: "100%"
|
|
285
|
+
},
|
|
286
|
+
resources: {
|
|
287
|
+
en
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
export { Component, Element };
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { action } from '@storybook/addon-actions';
|
|
4
|
+
import { SE } from '@shipengine/react-api';
|
|
5
|
+
import { Element } from './customs-form-element.js';
|
|
6
|
+
import { salesOrderShipmentFactory } from '../../factories/shipengine/shipment.js';
|
|
7
|
+
|
|
8
|
+
var customsFormElement_stories = {
|
|
9
|
+
title: "Label Workflow/Nested Elements/CustomsForm Element",
|
|
10
|
+
component: Element,
|
|
11
|
+
parameters: {
|
|
12
|
+
controls: {
|
|
13
|
+
expanded: false
|
|
14
|
+
},
|
|
15
|
+
previewTabs: {
|
|
16
|
+
"storybook/docs/panel": {
|
|
17
|
+
hidden: true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
viewMode: "story",
|
|
21
|
+
docs: {
|
|
22
|
+
description: {
|
|
23
|
+
component: "A higher-order component that wraps CustomsForms with its own react-hook-form context, allowing it to be used outside of existing form contexts."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
shipment: {
|
|
29
|
+
control: false,
|
|
30
|
+
description: "The shipment data to populate the form with"
|
|
31
|
+
},
|
|
32
|
+
currency: {
|
|
33
|
+
control: {
|
|
34
|
+
type: "select"
|
|
35
|
+
},
|
|
36
|
+
options: Object.values(SE.Currency),
|
|
37
|
+
description: "Currency for monetary values"
|
|
38
|
+
},
|
|
39
|
+
betaEnableWindsorFramework: {
|
|
40
|
+
control: {
|
|
41
|
+
type: "boolean"
|
|
42
|
+
},
|
|
43
|
+
description: "Enable Windsor Framework features"
|
|
44
|
+
},
|
|
45
|
+
onModify: {
|
|
46
|
+
action: "onModify",
|
|
47
|
+
description: "Called when form data changes"
|
|
48
|
+
},
|
|
49
|
+
onSubmit: {
|
|
50
|
+
action: "onSubmit",
|
|
51
|
+
description: "Called when form is submitted"
|
|
52
|
+
},
|
|
53
|
+
onCancel: {
|
|
54
|
+
action: "onCancel",
|
|
55
|
+
description: "Called when cancel button is clicked"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const Template = args => {
|
|
60
|
+
return jsx("div", {
|
|
61
|
+
style: {
|
|
62
|
+
maxWidth: "800px",
|
|
63
|
+
padding: "20px"
|
|
64
|
+
},
|
|
65
|
+
children: jsx(Element, Object.assign({}, args))
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
// Create mock shipment data for different scenarios
|
|
69
|
+
const createMockShipment = (isInternational = true, hasCustoms = true) => {
|
|
70
|
+
return salesOrderShipmentFactory.build({}, {
|
|
71
|
+
transient: {
|
|
72
|
+
isInternational
|
|
73
|
+
},
|
|
74
|
+
associations: {
|
|
75
|
+
customs: hasCustoms ? {
|
|
76
|
+
contents: SE.CustomsContentsType.MERCHANDISE,
|
|
77
|
+
nonDelivery: SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
78
|
+
} : undefined
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const Default = Template.bind({});
|
|
83
|
+
Default.args = {
|
|
84
|
+
shipment: createMockShipment(true, true),
|
|
85
|
+
currency: SE.Currency.USD,
|
|
86
|
+
onModify: action("onModify"),
|
|
87
|
+
onSubmit: action("onSubmit"),
|
|
88
|
+
onCancel: action("onCancel")
|
|
89
|
+
};
|
|
90
|
+
Default.storyName = "Default International Shipment";
|
|
91
|
+
const DomesticShipment = Template.bind({});
|
|
92
|
+
DomesticShipment.args = {
|
|
93
|
+
shipment: createMockShipment(false, false),
|
|
94
|
+
currency: SE.Currency.USD,
|
|
95
|
+
onModify: action("onModify"),
|
|
96
|
+
onSubmit: action("onSubmit")
|
|
97
|
+
};
|
|
98
|
+
DomesticShipment.storyName = "Domestic Shipment (No Customs)";
|
|
99
|
+
const CanadaDeliveredDuty = Template.bind({});
|
|
100
|
+
CanadaDeliveredDuty.args = {
|
|
101
|
+
shipment: salesOrderShipmentFactory.build({}, {
|
|
102
|
+
transient: {
|
|
103
|
+
isInternational: true
|
|
104
|
+
},
|
|
105
|
+
associations: {
|
|
106
|
+
shipTo: {
|
|
107
|
+
countryCode: "CA",
|
|
108
|
+
name: "John Doe",
|
|
109
|
+
phone: "555-123-4567",
|
|
110
|
+
addressLine1: "123 Main St",
|
|
111
|
+
cityLocality: "Toronto",
|
|
112
|
+
stateProvince: "ON",
|
|
113
|
+
postalCode: "M5V 3A8"
|
|
114
|
+
},
|
|
115
|
+
shipFrom: {
|
|
116
|
+
countryCode: "US",
|
|
117
|
+
name: "Warehouse",
|
|
118
|
+
phone: "555-987-6543",
|
|
119
|
+
addressLine1: "456 Warehouse Ave",
|
|
120
|
+
cityLocality: "Los Angeles",
|
|
121
|
+
stateProvince: "CA",
|
|
122
|
+
postalCode: "90210"
|
|
123
|
+
},
|
|
124
|
+
customs: {
|
|
125
|
+
contents: SE.CustomsContentsType.GIFT,
|
|
126
|
+
nonDelivery: SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}),
|
|
130
|
+
currency: SE.Currency.USD,
|
|
131
|
+
onModify: action("onModify"),
|
|
132
|
+
onSubmit: action("onSubmit")
|
|
133
|
+
};
|
|
134
|
+
CanadaDeliveredDuty.storyName = "Canada Delivered Duty Eligible";
|
|
135
|
+
const WithWindsorFramework = Template.bind({});
|
|
136
|
+
WithWindsorFramework.args = {
|
|
137
|
+
shipment: salesOrderShipmentFactory.build({}, {
|
|
138
|
+
transient: {
|
|
139
|
+
isInternational: true
|
|
140
|
+
},
|
|
141
|
+
associations: {
|
|
142
|
+
shipTo: {
|
|
143
|
+
countryCode: "IE",
|
|
144
|
+
// Ireland - EU country for Windsor Framework
|
|
145
|
+
name: "Jane Smith",
|
|
146
|
+
phone: "353-1-234-5678",
|
|
147
|
+
addressLine1: "789 Dublin St",
|
|
148
|
+
cityLocality: "Dublin",
|
|
149
|
+
stateProvince: "Dublin",
|
|
150
|
+
postalCode: "D01 F5P2"
|
|
151
|
+
},
|
|
152
|
+
shipFrom: {
|
|
153
|
+
countryCode: "GB",
|
|
154
|
+
// UK for Windsor Framework
|
|
155
|
+
name: "UK Warehouse",
|
|
156
|
+
phone: "44-20-7946-0958",
|
|
157
|
+
addressLine1: "123 London Rd",
|
|
158
|
+
cityLocality: "London",
|
|
159
|
+
stateProvince: "England",
|
|
160
|
+
postalCode: "SW1A 1AA"
|
|
161
|
+
},
|
|
162
|
+
customs: {
|
|
163
|
+
contents: SE.CustomsContentsType.MERCHANDISE,
|
|
164
|
+
nonDelivery: SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}),
|
|
168
|
+
currency: SE.Currency.GBP,
|
|
169
|
+
betaEnableWindsorFramework: true,
|
|
170
|
+
onModify: action("onModify"),
|
|
171
|
+
onSubmit: action("onSubmit")
|
|
172
|
+
};
|
|
173
|
+
WithWindsorFramework.storyName = "With Windsor Framework";
|
|
174
|
+
const WithExistingProducts = Template.bind({});
|
|
175
|
+
WithExistingProducts.args = {
|
|
176
|
+
shipment: salesOrderShipmentFactory.build({}, {
|
|
177
|
+
transient: {
|
|
178
|
+
isInternational: true
|
|
179
|
+
},
|
|
180
|
+
associations: {
|
|
181
|
+
customs: {
|
|
182
|
+
contents: SE.CustomsContentsType.MERCHANDISE,
|
|
183
|
+
nonDelivery: SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}),
|
|
187
|
+
currency: SE.Currency.USD,
|
|
188
|
+
harmonizedTariffCodes: [{
|
|
189
|
+
code: "6109.10.00",
|
|
190
|
+
description: "T-shirts, singlets and other vests, knitted or crocheted, of cotton"
|
|
191
|
+
}, {
|
|
192
|
+
code: "6912.00.48",
|
|
193
|
+
description: "Ceramic tableware, kitchenware, other household articles"
|
|
194
|
+
}],
|
|
195
|
+
onModify: action("onModify"),
|
|
196
|
+
onSubmit: action("onSubmit")
|
|
197
|
+
};
|
|
198
|
+
WithExistingProducts.storyName = "With Existing Products";
|
|
199
|
+
const InteractiveExample = Template.bind({});
|
|
200
|
+
InteractiveExample.args = {
|
|
201
|
+
shipment: createMockShipment(true, true),
|
|
202
|
+
currency: SE.Currency.USD,
|
|
203
|
+
onModify: data => {
|
|
204
|
+
action("onModify")(data);
|
|
205
|
+
console.log("Form modified:", data);
|
|
206
|
+
},
|
|
207
|
+
onSubmit: data => __awaiter(void 0, void 0, void 0, function* () {
|
|
208
|
+
action("onSubmit")(data);
|
|
209
|
+
console.log("Form submitted:", data);
|
|
210
|
+
// Simulate async operation
|
|
211
|
+
yield new Promise(resolve => setTimeout(resolve, 1000));
|
|
212
|
+
alert("Form submitted successfully! Check the console for data.");
|
|
213
|
+
}),
|
|
214
|
+
onCancel: () => {
|
|
215
|
+
action("onCancel")();
|
|
216
|
+
console.log("Form cancelled");
|
|
217
|
+
alert("Form cancelled!");
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
InteractiveExample.storyName = "Interactive Example";
|
|
221
|
+
const WithoutButtons = Template.bind({});
|
|
222
|
+
WithoutButtons.args = {
|
|
223
|
+
shipment: createMockShipment(true, true),
|
|
224
|
+
currency: SE.Currency.USD,
|
|
225
|
+
onModify: action("onModify"),
|
|
226
|
+
// Explicitly set to undefined to override default actions and hide buttons
|
|
227
|
+
onSubmit: undefined,
|
|
228
|
+
onCancel: undefined
|
|
229
|
+
};
|
|
230
|
+
WithoutButtons.storyName = "Without Buttons (Form Only)";
|
|
231
|
+
|
|
232
|
+
export { CanadaDeliveredDuty, Default, DomesticShipment, InteractiveExample, WithExistingProducts, WithWindsorFramework, WithoutButtons, customsFormElement_stories as default };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SE } from '@shipengine/react-api';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { extendZod } from '../../extensions/zod.js';
|
|
4
|
+
import { CanadaDeliveredDutyOptions } from '../../types/canada-ddp.js';
|
|
5
|
+
import { moneySchema } from '../../schemas/shipengine/money.js';
|
|
6
|
+
|
|
7
|
+
extendZod();
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Zod schema for customs form data
|
|
10
|
+
*/
|
|
11
|
+
const getCustomsFormSchema = ({
|
|
12
|
+
isCustomsRequired = true,
|
|
13
|
+
requiresWindsorFramework = false
|
|
14
|
+
} = {}) => {
|
|
15
|
+
const customsSchema = z.object({
|
|
16
|
+
customs: z.object({
|
|
17
|
+
contents: z.nativeEnum(SE.CustomsContentsType),
|
|
18
|
+
nonDelivery: z.nativeEnum(SE.CustomsNonDeliveryType)
|
|
19
|
+
}),
|
|
20
|
+
products: isCustomsRequired ? z.array(z.object({
|
|
21
|
+
countryOfOrigin: z.string().nullishDefault(undefined),
|
|
22
|
+
description: z.string().nullishDefault(undefined),
|
|
23
|
+
harmonizedTariffCode: z.string().nullishDefault(undefined),
|
|
24
|
+
quantity: z.number().int().positive(),
|
|
25
|
+
value: moneySchema
|
|
26
|
+
})).min(1, "At least one product is required") : z.array(z.object({
|
|
27
|
+
countryOfOrigin: z.string().nullishDefault(undefined),
|
|
28
|
+
description: z.string().nullishDefault(undefined),
|
|
29
|
+
harmonizedTariffCode: z.string().nullishDefault(undefined),
|
|
30
|
+
quantity: z.number().int().positive(),
|
|
31
|
+
value: moneySchema
|
|
32
|
+
})).optional(),
|
|
33
|
+
taxIdentifiers: z.array(z.any()).optional(),
|
|
34
|
+
// SE.TaxIdentifier type is complex, using any for now
|
|
35
|
+
advancedOptions: z.object({
|
|
36
|
+
canadaDeliveredDuty: z.nativeEnum(CanadaDeliveredDutyOptions).nullish(),
|
|
37
|
+
windsorFrameworkDetails: requiresWindsorFramework ? z.object({
|
|
38
|
+
movementIndicator: z.nativeEnum(SE.MovementIndicator),
|
|
39
|
+
notAtRisk: z.boolean().optional().default(false)
|
|
40
|
+
}) : z.object({
|
|
41
|
+
movementIndicator: z.nativeEnum(SE.MovementIndicator),
|
|
42
|
+
notAtRisk: z.boolean().optional().default(false)
|
|
43
|
+
}).optional()
|
|
44
|
+
}).optional()
|
|
45
|
+
});
|
|
46
|
+
return customsSchema;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Default schema for customs forms
|
|
50
|
+
*/
|
|
51
|
+
const defaultCustomsFormSchema = getCustomsFormSchema({
|
|
52
|
+
isCustomsRequired: true,
|
|
53
|
+
requiresWindsorFramework: false
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export { defaultCustomsFormSchema, getCustomsFormSchema };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SE } from '@shipengine/react-api';
|
|
2
|
+
import { CanadaDeliveredDutyOptions } from '../../types/canada-ddp.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extracts customs form data from a `SalesOrderShipment` object.
|
|
6
|
+
*
|
|
7
|
+
* - This utility function transforms a `SalesOrderShipment` (or `Shipment`) into the `CustomsFormData`
|
|
8
|
+
* structure used by the `CustomsForm`. It extracts products from the first package and gathers
|
|
9
|
+
* all relevant customs information into a flat structure.
|
|
10
|
+
*
|
|
11
|
+
* @param shipment - The `SalesOrderShipment` to extract customs data from
|
|
12
|
+
* @returns CustomsFormData object containing customs information
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const customsData = extractCustomsFormData(shipment);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @see {@link CustomsFormData | The structure of the returned data}
|
|
20
|
+
*/
|
|
21
|
+
const extractCustomsFormData = shipment => {
|
|
22
|
+
var _a, _b, _c, _d, _e, _f;
|
|
23
|
+
// Extract products from the first package (customs forms typically work with single package)
|
|
24
|
+
const products = ((_b = (_a = shipment.packages) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.products) || [];
|
|
25
|
+
return {
|
|
26
|
+
customs: {
|
|
27
|
+
contents: ((_c = shipment.customs) === null || _c === void 0 ? void 0 : _c.contents) || SE.CustomsContentsType.MERCHANDISE,
|
|
28
|
+
nonDelivery: ((_d = shipment.customs) === null || _d === void 0 ? void 0 : _d.nonDelivery) || SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
29
|
+
},
|
|
30
|
+
products,
|
|
31
|
+
taxIdentifiers: shipment.taxIdentifiers,
|
|
32
|
+
advancedOptions: {
|
|
33
|
+
canadaDeliveredDuty: (_e = shipment.advancedOptions) === null || _e === void 0 ? void 0 : _e.canadaDeliveredDuty,
|
|
34
|
+
windsorFrameworkDetails: (_f = shipment.advancedOptions) === null || _f === void 0 ? void 0 : _f.windsorFrameworkDetails
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Returns default values for a new customs form.
|
|
40
|
+
*
|
|
41
|
+
* - Use this utility function when you need to initialize a customs form with sensible defaults
|
|
42
|
+
* before any shipment data is available. Sets MERCHANDISE as contents type and RETURN_TO_SENDER
|
|
43
|
+
* as the non-delivery option.
|
|
44
|
+
*
|
|
45
|
+
* @returns CustomsFormData object with default values
|
|
46
|
+
*
|
|
47
|
+
* @see {@link CustomsFormData | The structure of the returned data}
|
|
48
|
+
*/
|
|
49
|
+
const getDefaultCustomsFormValues = () => ({
|
|
50
|
+
customs: {
|
|
51
|
+
contents: SE.CustomsContentsType.MERCHANDISE,
|
|
52
|
+
nonDelivery: SE.CustomsNonDeliveryType.RETURN_TO_SENDER
|
|
53
|
+
},
|
|
54
|
+
products: [],
|
|
55
|
+
advancedOptions: {
|
|
56
|
+
canadaDeliveredDuty: CanadaDeliveredDutyOptions.RECIPIENT_PAYS
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export { extractCustomsFormData, getDefaultCustomsFormValues };
|
|
@@ -29,3 +29,6 @@ import * as carrierServices from '../workflows/carrier-services/carrier-services
|
|
|
29
29
|
export { carrierServices as CarrierServices };
|
|
30
30
|
import * as transactionHistoryElement from './transaction-history/transaction-history-element.js';
|
|
31
31
|
export { transactionHistoryElement as TransactionHistory };
|
|
32
|
+
import * as customsFormElement from './customs-form/customs-form-element.js';
|
|
33
|
+
export { customsFormElement as CustomsForm };
|
|
34
|
+
export { extractCustomsFormData, getDefaultCustomsFormValues } from './customs-form/customs-form-types.js';
|
|
@@ -4,8 +4,8 @@ import { useFundingSourcesAddFunds } from '@shipengine/react-api';
|
|
|
4
4
|
import { useCallback } from 'react';
|
|
5
5
|
import { createElement } from '../../create-element/create-element.js';
|
|
6
6
|
import { ShipEngineCarriers } from '../../features/manage-carriers/manage-carriers.js';
|
|
7
|
-
import en from '../../locales/en/index.js';
|
|
8
7
|
import { ErrorFallback } from '../../components/error-fallback/error-fallback.js';
|
|
8
|
+
import en from '../../locales/en/index.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* # Manage-Carriers Element
|
|
@@ -127,7 +127,7 @@ const TaxIds = ({
|
|
|
127
127
|
})]
|
|
128
128
|
}), jsxs(Grid, {
|
|
129
129
|
noPadding: true,
|
|
130
|
-
children: [((_a = shipment.taxIdentifiers) === null || _a === void 0 ? void 0 : _a.length) && jsx(GridChild, {
|
|
130
|
+
children: [!!((_a = shipment.taxIdentifiers) === null || _a === void 0 ? void 0 : _a.length) && jsx(GridChild, {
|
|
131
131
|
colSpan: 12,
|
|
132
132
|
children: jsx(TaxIdList, {
|
|
133
133
|
handleActionsClick: handleActionsClick,
|
|
@@ -78,7 +78,7 @@ const RateView = ({
|
|
|
78
78
|
collapsedRateOptionList,
|
|
79
79
|
COLLAPSED_RATE_VIEW_LIMIT,
|
|
80
80
|
filterVisibleRateOptions
|
|
81
|
-
} = useFilterVisibleRateOptions(expandedRateOptionList
|
|
81
|
+
} = useFilterVisibleRateOptions(expandedRateOptionList);
|
|
82
82
|
const handleShowMoreRates = useCallback(() => {
|
|
83
83
|
var _a;
|
|
84
84
|
setShowHiddenRates === null || setShowHiddenRates === void 0 ? void 0 : setShowHiddenRates(!showHiddenRates);
|