@shipengine/elements 2.26.2 → 2.26.4

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.
Files changed (81) hide show
  1. package/dist/cjs/components/cc-provider-logo/cc-provider-logo.cjs +2 -1
  2. package/dist/cjs/components/forms/wallet-form/wallet-schema.cjs +1 -1
  3. package/dist/cjs/components/shipment-not-found-error/shipment-not-found-error.cjs +17 -2
  4. package/dist/cjs/components/suspend-purchase/suspend-purchase.cjs +3 -3
  5. package/dist/cjs/elements/purchase-label/hooks/use-address.cjs +1 -1
  6. package/dist/cjs/elements/purchase-label/purchase-label.cjs +7 -1
  7. package/dist/cjs/hooks/use-configure-shipment.cjs +127 -17
  8. package/dist/cjs/hooks/use-import-sales-order.cjs +45 -20
  9. package/dist/cjs/locales/en/common.json.cjs +1 -1
  10. package/dist/cjs/locales/en/purchase-label.json.cjs +7 -0
  11. package/dist/cjs/package.json.cjs +1 -1
  12. package/dist/cjs/workflows/connect-external-carrier/components/custom-external-carrier-form/custom-form-fedex.cjs +11 -11
  13. package/dist/cjs/workflows/connect-external-carrier/connect-external-carrier.cjs +3 -63
  14. package/dist/cjs/workflows/label-workflow/label-workflow.cjs +26 -2
  15. package/dist/esm/components/cc-provider-logo/cc-provider-logo.js +2 -1
  16. package/dist/esm/components/forms/wallet-form/wallet-schema.js +1 -1
  17. package/dist/esm/components/shipment-not-found-error/shipment-not-found-error.js +17 -2
  18. package/dist/esm/components/suspend-purchase/suspend-purchase.js +3 -3
  19. package/dist/esm/elements/purchase-label/hooks/use-address.js +1 -1
  20. package/dist/esm/elements/purchase-label/purchase-label.js +7 -1
  21. package/dist/esm/hooks/use-configure-shipment.js +127 -17
  22. package/dist/esm/hooks/use-import-sales-order.js +47 -22
  23. package/dist/esm/locales/en/common.json.js +1 -1
  24. package/dist/esm/locales/en/purchase-label.json.js +7 -0
  25. package/dist/esm/package.json.js +1 -1
  26. package/dist/esm/workflows/connect-external-carrier/components/custom-external-carrier-form/custom-form-fedex.js +11 -11
  27. package/dist/esm/workflows/connect-external-carrier/connect-external-carrier.js +3 -44
  28. package/dist/esm/workflows/label-workflow/label-workflow.js +26 -2
  29. package/dist/types/components/cc-provider-logo/cc-provider-logo.d.ts.map +1 -1
  30. package/dist/types/components/forms/wallet-form/wallet-schema.d.ts.map +1 -1
  31. package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts +3 -2
  32. package/dist/types/components/shipment-not-found-error/shipment-not-found-error.d.ts.map +1 -1
  33. package/dist/types/components/suspend-purchase/suspend-purchase.d.ts +3 -2
  34. package/dist/types/components/suspend-purchase/suspend-purchase.d.ts.map +1 -1
  35. package/dist/types/elements/labels-grid/labels-grid.d.ts +7 -0
  36. package/dist/types/elements/labels-grid/labels-grid.d.ts.map +1 -1
  37. package/dist/types/elements/manage-carriers/manage-carriers.d.ts +7 -0
  38. package/dist/types/elements/manage-carriers/manage-carriers.d.ts.map +1 -1
  39. package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts +7 -0
  40. package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts.map +1 -1
  41. package/dist/types/elements/manage-funding/manage-funding-element.d.ts +7 -0
  42. package/dist/types/elements/manage-funding/manage-funding-element.d.ts.map +1 -1
  43. package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts +7 -0
  44. package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts.map +1 -1
  45. package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts +7 -0
  46. package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts.map +1 -1
  47. package/dist/types/elements/purchase-label/hooks/use-address.d.ts.map +1 -1
  48. package/dist/types/elements/purchase-label/purchase-label.d.ts +7 -0
  49. package/dist/types/elements/purchase-label/purchase-label.d.ts.map +1 -1
  50. package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts +7 -0
  51. package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts.map +1 -1
  52. package/dist/types/elements/shipment-summary/shipment-summary.d.ts +7 -0
  53. package/dist/types/elements/shipment-summary/shipment-summary.d.ts.map +1 -1
  54. package/dist/types/elements/shipments-grid/shipments-grid.d.ts +7 -0
  55. package/dist/types/elements/shipments-grid/shipments-grid.d.ts.map +1 -1
  56. package/dist/types/elements/theme-creator/theme-creator.d.ts +7 -0
  57. package/dist/types/elements/theme-creator/theme-creator.d.ts.map +1 -1
  58. package/dist/types/elements/transaction-history/transaction-history-element.d.ts +7 -0
  59. package/dist/types/elements/transaction-history/transaction-history-element.d.ts.map +1 -1
  60. package/dist/types/elements/unit-settings/unit-settings-element.d.ts +7 -0
  61. package/dist/types/elements/unit-settings/unit-settings-element.d.ts.map +1 -1
  62. package/dist/types/elements/vat-settings/vat-settings-element.d.ts +7 -0
  63. package/dist/types/elements/vat-settings/vat-settings-element.d.ts.map +1 -1
  64. package/dist/types/elements/void-label/void-label.d.ts +7 -0
  65. package/dist/types/elements/void-label/void-label.d.ts.map +1 -1
  66. package/dist/types/hooks/use-configure-shipment.d.ts.map +1 -1
  67. package/dist/types/hooks/use-import-sales-order.d.ts +20 -1
  68. package/dist/types/hooks/use-import-sales-order.d.ts.map +1 -1
  69. package/dist/types/locales/en/index.d.ts +7 -0
  70. package/dist/types/locales/en/index.d.ts.map +1 -1
  71. package/dist/types/workflows/account-settings/account-settings.d.ts +7 -0
  72. package/dist/types/workflows/account-settings/account-settings.d.ts.map +1 -1
  73. package/dist/types/workflows/carrier-services/carrier-services.d.ts +7 -0
  74. package/dist/types/workflows/carrier-services/carrier-services.d.ts.map +1 -1
  75. package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts +7 -0
  76. package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts.map +1 -1
  77. package/dist/types/workflows/label-workflow/label-workflow.d.ts +7 -0
  78. package/dist/types/workflows/label-workflow/label-workflow.d.ts.map +1 -1
  79. package/dist/types/workflows/onboarding/onboarding.d.ts +7 -0
  80. package/dist/types/workflows/onboarding/onboarding.d.ts.map +1 -1
  81. package/package.json +137 -10
@@ -14,7 +14,7 @@ const CcProviderLogo = ({
14
14
  height = 36
15
15
  }) => {
16
16
  const providerLogos = {
17
- americanExpress: amex,
17
+ american_express: amex,
18
18
  discover,
19
19
  mastercard,
20
20
  visa
@@ -25,6 +25,7 @@ const CcProviderLogo = ({
25
25
  size: giger.IconSize.SIZE_LARGE
26
26
  });
27
27
  }
28
+ // TODO: LMNT-1810 - Add missing provider logos
28
29
  const Logo = providerLogos[provider];
29
30
  return jsxRuntime.jsx(Logo, {
30
31
  height: height,
@@ -77,7 +77,7 @@ const creditCardSchema = zod.z.object({
77
77
  expirationMonth: expirationMonth,
78
78
  expirationYear: expirationYear,
79
79
  name: creditCard.name,
80
- provider: creditCardVendor === "american-express" ? "americanExpress" : creditCardVendor
80
+ provider: creditCardVendor === "american-express" ? "american_express" : creditCardVendor
81
81
  };
82
82
  });
83
83
  const getWalletSchema = (emailRequirement, blackboxRequirement) => {
@@ -7,12 +7,26 @@ var reactI18next = require('react-i18next');
7
7
  var shipmentNotFoundError_styles = require('./shipment-not-found-error.styles.cjs');
8
8
 
9
9
  const ShipmentNotFoundError = ({
10
- shipmentId,
10
+ identifier,
11
11
  onCreateNewShipment
12
12
  }) => {
13
13
  const {
14
14
  t
15
15
  } = reactI18next.useTranslation(["common", "purchase-label"]);
16
+ const getIdentifierInfo = identifier => {
17
+ // Order should match the actual search priority in useConfigureShipment:
18
+ const identifierKeys = ["shipmentId", "externalShipmentId", "salesOrderId", "externalOrderId", "externalOrderNumber"];
19
+ const foundKey = identifierKeys.find(key => identifier === null || identifier === void 0 ? void 0 : identifier[key]);
20
+ const identifierKey = foundKey || "shipmentId";
21
+ return {
22
+ type: t(`purchase-label:identifierTypes.${identifierKey}`),
23
+ value: identifier === null || identifier === void 0 ? void 0 : identifier[identifierKey]
24
+ };
25
+ };
26
+ const {
27
+ type: identifierType,
28
+ value: identifierNumber
29
+ } = getIdentifierInfo(identifier);
16
30
  return jsxRuntime.jsxs("div", {
17
31
  css: shipmentNotFoundError_styles.styles.container,
18
32
  children: [jsxRuntime.jsx("div", {
@@ -24,7 +38,8 @@ const ShipmentNotFoundError = ({
24
38
  }), jsxRuntime.jsx("div", {
25
39
  css: shipmentNotFoundError_styles.styles.message,
26
40
  children: t("common:errorMessages.shipmentNotFound", {
27
- id: shipmentId
41
+ identifierType,
42
+ identifierNumber
28
43
  })
29
44
  }), jsxRuntime.jsx(giger.Button, {
30
45
  "data-testid": "create-new-shipment",
@@ -11,7 +11,7 @@ const SuspendPurchase = ({
11
11
  isLoading,
12
12
  data,
13
13
  onCreateNewShipment,
14
- shipmentId
14
+ identifier
15
15
  }) => {
16
16
  const {
17
17
  t
@@ -38,8 +38,8 @@ const SuspendPurchase = ({
38
38
  throw new Error(t("common:errorMessages.labelHasBeenPurchased"));
39
39
  case "shipment_not_found":
40
40
  return jsxRuntime.jsx(shipmentNotFoundError.ShipmentNotFoundError, {
41
- onCreateNewShipment: onCreateNewShipment,
42
- shipmentId: shipmentId
41
+ identifier: identifier,
42
+ onCreateNewShipment: onCreateNewShipment
43
43
  });
44
44
  }
45
45
  }
@@ -162,7 +162,7 @@ const useAddress = ({
162
162
  if (warning && warning.error) return warning;
163
163
  const value = addressMinusGeolocation[key];
164
164
  if (!value) return warning;
165
- if (/^[0-9\p{Script=Latin}\p{P}\p{S}\s]+$/u.test(value)) return warning;
165
+ if (/^[0-9A-Za-z\u00C0-\u017F\u0100-\u024F\u1E00-\u1EFF\u0020-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007E\u00A0-\u00BF\u2000-\u206F\u2E00-\u2E7F\s]+$/u.test(value)) return warning;
166
166
  if (key === "name" || key === "companyName") {
167
167
  return {
168
168
  error: false,
@@ -92,9 +92,15 @@ const Component = _a => {
92
92
  return jsxRuntime.jsx(suspendPurchase.SuspendPurchase, {
93
93
  data: shipment || salesOrder,
94
94
  errors: errors,
95
+ identifier: {
96
+ externalOrderId,
97
+ externalOrderNumber,
98
+ externalShipmentId,
99
+ salesOrderId,
100
+ shipmentId
101
+ },
95
102
  isLoading: isLoading || insuranceIsLoading,
96
103
  onCreateNewShipment: createNewShipmentForNotFound,
97
- shipmentId: shipmentId,
98
104
  children: jsxRuntime.jsx(configureShipment.ConfigureShipment, Object.assign({
99
105
  currency: currency,
100
106
  features: features,
@@ -22,8 +22,8 @@ const useConfigureShipment = ({
22
22
  warehouseId,
23
23
  useWarehouses = true
24
24
  }) => {
25
- // Track when we've created a replacement shipment for a "not found" case
26
- const [replacementShipmentId, setReplacementShipmentId] = React.useState();
25
+ // Track when user manually created a shipment for a "not found" case
26
+ const [manuallyCreatedShipmentId, setManuallyCreatedShipmentId] = React.useState();
27
27
  // Queue of incomplete requirement keys (i.e., Ship From addresses, Warehouses, Carriers)
28
28
  const incompleteRequirementsKeys = React.useMemo(() => [], []);
29
29
  const {
@@ -47,6 +47,7 @@ const useConfigureShipment = ({
47
47
  // Dont run Sales Order Import unless the Sales order info is present
48
48
  enabled: !!externalOrderNumber || !!orderSourceCode || !!salesOrderId || !!externalOrderId,
49
49
  externalOrderId,
50
+ externalOrderNumber,
50
51
  orderSourceCode,
51
52
  salesOrderId
52
53
  });
@@ -63,24 +64,49 @@ const useConfigureShipment = ({
63
64
  isInitialLoading: isExternalShipmentInitialLoading,
64
65
  isFetching: isExternalShipmentFetching
65
66
  } = reactApi.useGetShipmentByExternalId({
66
- enabled: !!externalShipmentId && !shipmentId,
67
+ enabled: !!externalShipmentId && !shipmentId && !manuallyCreatedShipmentId,
67
68
  queryFnParams: {
68
69
  externalId: externalShipmentId !== null && externalShipmentId !== void 0 ? externalShipmentId : ""
69
70
  }
71
+ // TODO: weird refetch on focus behavior
70
72
  });
73
+ // #region List Sales Order Shipments
74
+ const externalOrderIds = React.useMemo(() => {
75
+ return externalOrderId ? [externalOrderId] : undefined;
76
+ }, [externalOrderId]);
77
+ const salesOrderIds = React.useMemo(() => {
78
+ return salesOrderId ? [salesOrderId] : salesOrder$1 ? [salesOrder$1.salesOrderId] :
79
+ // TODO: current workaround - revert to being undefined rather than empty list
80
+ [];
81
+ }, [salesOrderId, salesOrder$1]);
82
+ const shipmentIds = React.useMemo(() => {
83
+ return manuallyCreatedShipmentId ? [manuallyCreatedShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined;
84
+ }, [manuallyCreatedShipmentId, shipmentId, externalShipment, newV1Shipment]);
85
+ const listSalesOrderShipmentsParams = React.useMemo(() => {
86
+ // TODO: useListSalesOrderShipments needs to be able to use the enabled prop, this is a workaround
87
+ // Prevent query with stale params during shipment creation or when V1 shipment exists but manuallyCreatedShipmentId not set
88
+ if (creatingV1Shipment && !manuallyCreatedShipmentId || newV1Shipment && !manuallyCreatedShipmentId) {
89
+ return {};
90
+ }
91
+ if (manuallyCreatedShipmentId) {
92
+ return {
93
+ shipmentIds
94
+ };
95
+ }
96
+ return {
97
+ externalOrderIds,
98
+ salesOrderIds,
99
+ shipmentIds
100
+ };
101
+ }, [manuallyCreatedShipmentId, externalOrderIds, salesOrderIds, shipmentIds, creatingV1Shipment, newV1Shipment]);
71
102
  const {
72
103
  data: salesOrderShipments,
73
104
  error: listSalesOrderShipmentsErrors,
74
105
  refetch: refetchSalesOrderShipments,
75
106
  isInitialLoading: listSalesOrderShipmentsInitiallyLoading,
76
107
  isFetching: listSalesOrderShipmentsIsFetching
77
- } = reactApi.useListSalesOrderShipments({
78
- externalOrderIds: externalOrderId ? [externalOrderId] : undefined,
79
- salesOrderIds: salesOrderId ? [salesOrderId] : salesOrder$1 ? [salesOrder$1.salesOrderId] :
80
- // TODO: current workaround - revert to being undefined rather than empty list
81
- [],
82
- shipmentIds: replacementShipmentId ? [replacementShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined
83
- });
108
+ } = reactApi.useListSalesOrderShipments(listSalesOrderShipmentsParams);
109
+ // #endregion
84
110
  const {
85
111
  error: createSalesOrderShipmentErrors,
86
112
  mutateAsync: createSalesOrderShipment,
@@ -105,6 +131,7 @@ const useConfigureShipment = ({
105
131
  }
106
132
  return null;
107
133
  }), [createV1Shipment, defaultShipFromAddress, defaultWarehouse, warehouseId, refetchSalesOrderShipments]);
134
+ // #region Create Sales Order Shipment
108
135
  // Handles the creation of new shipments for the sales order flow and one-off flow
109
136
  const handleShipmentCreation = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
110
137
  var _a, _b, _c;
@@ -154,17 +181,23 @@ const useConfigureShipment = ({
154
181
  }
155
182
  // Create a Shipment for one-off flow
156
183
  if (!salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId) {
157
- yield createV1ShipmentWithDefaults();
184
+ const v1Shipment = yield createV1ShipmentWithDefaults();
185
+ // Set manuallyCreatedShipmentId to ensure proper query parameter handling
186
+ if (v1Shipment) {
187
+ setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
188
+ }
158
189
  }
159
190
  }), [createSalesOrderShipment, createV1ShipmentWithDefaults, creatingSalesOrderShipment, creatingV1Shipment, defaultShipFromAddress, defaultWarehouse, externalOrderId, externalOrderNumber, externalShipmentId, incompleteRequirementsKeys, isExternalShipmentFetching, isExternalShipmentInitialLoading, isFetchingWarehouses, isInitialLoadingWarehouses, labelPurchasedSalesOrderShipment, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, orderSourceCode, pendingSalesOrderShipment, salesOrder$1, salesOrderId, salesOrderShipmentCreated, shipFromAddresses === null || shipFromAddresses === void 0 ? void 0 : shipFromAddresses.length, shipmentId, useWarehouses, v1shipmentCreated, warehouseId, warehouses$1]);
191
+ // #endregion
160
192
  const createNewShipmentForNotFound = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
161
193
  // Force create a new shipment even if shipmentId exists (for shipment_not_found case)
162
194
  const v1Shipment = yield createV1ShipmentWithDefaults();
163
195
  if (v1Shipment) {
164
- // Store the new shipment ID to override the stale one
165
- setReplacementShipmentId(v1Shipment.shipments[0].shipmentId);
196
+ setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
197
+ // Refetch to ensure we have the latest shipment data
198
+ yield refetchSalesOrderShipments();
166
199
  }
167
- }), [createV1ShipmentWithDefaults]);
200
+ }), [createV1ShipmentWithDefaults, refetchSalesOrderShipments]);
168
201
  const refetchPendingSalesOrderShipments = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
169
202
  const {
170
203
  data: shipments
@@ -188,7 +221,83 @@ const useConfigureShipment = ({
188
221
  if (isInitialLoadingCarriers || isFetchingCarriers) return;
189
222
  if ((carriers === null || carriers === void 0 ? void 0 : carriers.length) === 0) incompleteRequirementsKeys.push("no_carriers");
190
223
  }, [carriers, incompleteRequirementsKeys, isFetchingCarriers, isInitialLoadingCarriers]);
191
- const errors = [...(listWarehouseErrors !== null && listWarehouseErrors !== void 0 ? listWarehouseErrors : []), ...(createSalesOrderShipmentErrors !== null && createSalesOrderShipmentErrors !== void 0 ? createSalesOrderShipmentErrors : []), ...(createV1ShipmentErrors !== null && createV1ShipmentErrors !== void 0 ? createV1ShipmentErrors : []), ...(listSalesOrderShipmentsErrors !== null && listSalesOrderShipmentsErrors !== void 0 ? listSalesOrderShipmentsErrors : []), ...(getExternalShipmentErrors !== null && getExternalShipmentErrors !== void 0 ? getExternalShipmentErrors : []), ...(importSalesOrderErrors !== null && importSalesOrderErrors !== void 0 ? importSalesOrderErrors : []), ...(errorWhenShipmentCancelled && cancelledShipment ? [new reactApi.CodedError("shipment_cancelled", {
224
+ const isConfigureShipmentLoading = React.useMemo(() => {
225
+ if (isSalesOrderLoading) return true;
226
+ if (listSalesOrderShipmentsInitiallyLoading) return true;
227
+ if (listSalesOrderShipmentsIsFetching) return true;
228
+ if (creatingSalesOrderShipment) return true;
229
+ if (creatingV1Shipment) return true;
230
+ // Include external shipment loading states to prevent premature error display
231
+ // Only keep loading if we're actually fetching and don't have an error yet
232
+ // Skip this check if we already have an error to avoid infinite loading
233
+ if (externalShipmentId && isExternalShipmentFetching && !getExternalShipmentErrors && !isExternalShipmentInitialLoading) {
234
+ return true;
235
+ }
236
+ // Check if this is a one-off flow (no identifiers provided)
237
+ const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
238
+ // For one-off flow, keep loading until we have shipment data or V1 creation is complete
239
+ if (isOneOffFlow && !pendingSalesOrderShipment && !labelPurchasedSalesOrderShipment) {
240
+ return true;
241
+ }
242
+ // Only consider empty salesOrderShipments array as loading if we're not initially loading and have valid identifiers
243
+ const shouldReturnTrueForEmptyShipments = (salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching;
244
+ if (shouldReturnTrueForEmptyShipments) {
245
+ return true;
246
+ }
247
+ return false;
248
+ }, [isSalesOrderLoading, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, creatingSalesOrderShipment, creatingV1Shipment, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors,
249
+ // This was missing!
250
+ salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, pendingSalesOrderShipment, labelPurchasedSalesOrderShipment, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length]);
251
+ // #region Custom Error Mapping
252
+ const hasGetShipmentErrors = React.useMemo(() => {
253
+ // Check for explicit API errors
254
+ if (listSalesOrderShipmentsErrors) return true;
255
+ if (getExternalShipmentErrors) return true;
256
+ if (importSalesOrderErrors) return true;
257
+ // Only treat empty results as error if we're not loading and have finished initial fetch
258
+ if ((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && shipmentId && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching) {
259
+ return true;
260
+ }
261
+ return false;
262
+ }, [listSalesOrderShipmentsErrors, getExternalShipmentErrors, importSalesOrderErrors, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length, shipmentId, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching]);
263
+ const hasValidShipmentData = React.useMemo(() => {
264
+ if (manuallyCreatedShipmentId) return true;
265
+ if (pendingSalesOrderShipment) return true;
266
+ if (labelPurchasedSalesOrderShipment) return true;
267
+ return false;
268
+ }, [labelPurchasedSalesOrderShipment, manuallyCreatedShipmentId, pendingSalesOrderShipment]);
269
+ const showShipmentNotFoundError = React.useMemo(() => {
270
+ // Don't show error if we have a manually created shipment
271
+ if (manuallyCreatedShipmentId) {
272
+ return false;
273
+ }
274
+ // Don't show error if we're creating a V1 shipment
275
+ if (creatingV1Shipment || newV1Shipment) {
276
+ return false;
277
+ }
278
+ // For external shipment ID, show error if we're not in loading state
279
+ // and we don't have valid shipment data
280
+ if (externalShipmentId && !isConfigureShipmentLoading && !hasValidShipmentData) {
281
+ return true;
282
+ }
283
+ // Don't show error if external shipment is still loading, unless we have explicit errors
284
+ if (externalShipmentId && (isExternalShipmentInitialLoading || isExternalShipmentFetching) && !getExternalShipmentErrors) {
285
+ return false;
286
+ }
287
+ // Show error immediately if we have shipment errors, even if still loading
288
+ if (hasGetShipmentErrors) {
289
+ return true;
290
+ }
291
+ // Check if this is a one-off flow (no identifiers provided)
292
+ const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
293
+ // Don't show error for one-off flow until we've attempted shipment creation
294
+ if (isOneOffFlow && !v1shipmentCreated) {
295
+ return false;
296
+ }
297
+ // Otherwise, only show if not loading and no valid shipment data
298
+ return !isConfigureShipmentLoading && !hasValidShipmentData;
299
+ }, [manuallyCreatedShipmentId, creatingV1Shipment, newV1Shipment, hasGetShipmentErrors, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors, listSalesOrderShipmentsErrors, importSalesOrderErrors, salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, v1shipmentCreated, isConfigureShipmentLoading, hasValidShipmentData, pendingSalesOrderShipment, externalShipment]);
300
+ const errors = [...(listWarehouseErrors !== null && listWarehouseErrors !== void 0 ? listWarehouseErrors : []), ...(createSalesOrderShipmentErrors !== null && createSalesOrderShipmentErrors !== void 0 ? createSalesOrderShipmentErrors : []), ...(createV1ShipmentErrors !== null && createV1ShipmentErrors !== void 0 ? createV1ShipmentErrors : []), ...(errorWhenShipmentCancelled && cancelledShipment ? [new reactApi.CodedError("shipment_cancelled", {
192
301
  errorCode: "invalid_status",
193
302
  errorSource: "elements",
194
303
  errorType: "business_rules"
@@ -200,16 +309,17 @@ const useConfigureShipment = ({
200
309
  errorCode: "unknown",
201
310
  errorSource: "elements",
202
311
  errorType: "business_rules"
203
- })] : []), ...((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && shipmentId ? [new reactApi.CodedError("shipment_not_found", {
312
+ })] : []), ...(showShipmentNotFoundError ? [new reactApi.CodedError("shipment_not_found", {
204
313
  errorCode: "invalid_status",
205
314
  errorSource: "elements",
206
315
  errorType: "business_rules"
207
316
  })] : [])];
317
+ // #endregion
208
318
  return {
209
319
  carriers,
210
320
  createNewShipmentForNotFound,
211
321
  errors: errors.length > 0 ? errors : undefined,
212
- isLoading: (isSalesOrderLoading || !(salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) || creatingSalesOrderShipment) && errors.length === 0,
322
+ isLoading: isConfigureShipmentLoading && errors.length === 0,
213
323
  refetchPendingSalesOrderShipments,
214
324
  salesOrder: salesOrder$1,
215
325
  shipment: pendingSalesOrderShipment !== null && pendingSalesOrderShipment !== void 0 ? pendingSalesOrderShipment : labelPurchasedSalesOrderShipment,
@@ -5,26 +5,49 @@ var reactApi = require('@shipengine/react-api');
5
5
  var reactQuery = require('@tanstack/react-query');
6
6
  var React = require('react');
7
7
 
8
+ /**
9
+ * Imports and retrieves sales orders by either:
10
+ * - Sales order ID lookup
11
+ * - External order ID/number search
12
+ *
13
+ * 1. First attempts to find the sales order using provided identifiers
14
+ * 2. If no order is found and initial fetches have run, automatically refreshes order sources
15
+ * 3. Invalidates relevant queries after successful refresh to refetch updated data
16
+ *
17
+ * @returns Object:
18
+ * - `salesOrder`: The found sales order, or undefined
19
+ * - `isLoading`: Boolean indicating if the hook is currently loading data
20
+ * - `errors`: Array of errors from failed queries, or undefined
21
+ */
8
22
  const useImportSalesOrder = ({
9
23
  enabled,
10
24
  externalOrderId,
25
+ externalOrderNumber,
11
26
  orderSourceCode,
12
27
  salesOrderId
13
28
  }) => {
14
29
  var _a, _b, _c;
15
30
  const queryClient = reactQuery.useQueryClient();
16
31
  const [refreshAttempted, setRefreshAttempted] = React.useState(false);
17
- // attempt to get sales order through external id means
18
- const orderByExternalIdQuery = reactApi.useGetSalesOrderByExternalOrderId(externalOrderId, {
19
- enabled: enabled && !!externalOrderId && !salesOrderId
32
+ // Fetch sales order by External Order ID or External Order Number
33
+ const salesOrderByExternalIdQuery = reactApi.useListSalesOrders({
34
+ externalOrderId,
35
+ externalOrderNumber
20
36
  });
21
37
  // if an order was found through external search disable this query
22
- const orderByIdQuery = reactApi.useGetSalesOrder(salesOrderId, {
38
+ const salesOrderByIdQuery = reactApi.useGetSalesOrder(salesOrderId, {
23
39
  enabled: enabled && !!salesOrderId
24
40
  });
25
- const salesOrder = React.useMemo(() => salesOrderId ? orderByIdQuery.data : orderByExternalIdQuery.data, [salesOrderId, orderByIdQuery.data, orderByExternalIdQuery.data]);
41
+ const salesOrder = React.useMemo(() => {
42
+ if (salesOrderId) {
43
+ return salesOrderByIdQuery.data;
44
+ } else if (salesOrderByExternalIdQuery.data && salesOrderByExternalIdQuery.data.length > 0) {
45
+ return salesOrderByExternalIdQuery.data[0];
46
+ }
47
+ return undefined;
48
+ }, [salesOrderId, salesOrderByIdQuery.data, salesOrderByExternalIdQuery.data]);
26
49
  // Determine if the initial fetch attempts (if applicable) have settled without finding data
27
- const initialFetchSettled = (salesOrderId ? !orderByIdQuery.isInitialLoading && !orderByIdQuery.isFetching : true) && (externalOrderId && !salesOrderId ? !orderByExternalIdQuery.isLoading && !orderByExternalIdQuery.isFetching : true);
50
+ const initialFetchSettled = (salesOrderId ? !salesOrderByIdQuery.isInitialLoading && !salesOrderByIdQuery.isFetching : true) && ((externalOrderNumber || externalOrderId) && !salesOrderId ? !salesOrderByExternalIdQuery.isLoading && !salesOrderByExternalIdQuery.isFetching : true);
28
51
  const shouldAttemptRefresh = enabled && initialFetchSettled && !salesOrder && !refreshAttempted;
29
52
  const listOrderSourcesQuery = reactApi.useListOrderSources({
30
53
  enabled: shouldAttemptRefresh
@@ -34,6 +57,17 @@ const useImportSalesOrder = ({
34
57
  isLoading: isRefreshingOrderSource,
35
58
  mutateAsync: refreshOrderSource
36
59
  } = reactApi.useRefreshOrderSource();
60
+ const invalidateSalesOrderQueries = React.useCallback(() => {
61
+ if (salesOrderId) {
62
+ void queryClient.invalidateQueries({
63
+ queryKey: ["useGetSalesOrder", salesOrderId]
64
+ });
65
+ } else if (externalOrderId || externalOrderNumber) {
66
+ void queryClient.invalidateQueries({
67
+ queryKey: ["useListSalesOrders", externalOrderId, externalOrderNumber]
68
+ });
69
+ }
70
+ }, [queryClient, salesOrderId, externalOrderId, externalOrderNumber]);
37
71
  React.useEffect(() => {
38
72
  if (listOrderSourcesQuery.isSuccess && listOrderSourcesQuery.data && shouldAttemptRefresh && !isRefreshingOrderSource) {
39
73
  const orderSourcesToRefresh = orderSourceCode ? listOrderSourcesQuery.data.filter(o => o.orderSourceCode.includes(orderSourceCode) && o.active) : listOrderSourcesQuery.data.filter(o => o.active);
@@ -41,29 +75,20 @@ const useImportSalesOrder = ({
41
75
  setRefreshAttempted(true);
42
76
  void (() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
43
77
  yield Promise.all(orderSourcesToRefresh.map(o => refreshOrderSource(o.orderSourceId, {
44
- // Invalidate relevant queries on successful refresh
78
+ // Invalidate relevant queries
45
79
  onSuccess: () => {
46
- if (salesOrderId) {
47
- void queryClient.invalidateQueries({
48
- queryKey: ["useGetSalesOrder", salesOrderId]
49
- });
50
- }
51
- if (externalOrderId && !salesOrderId) {
52
- void queryClient.invalidateQueries({
53
- queryKey: ["useGetSalesOrderByExternalOrderId", externalOrderId]
54
- });
55
- }
80
+ invalidateSalesOrderQueries();
56
81
  }
57
82
  })));
58
83
  }))();
59
84
  }
60
85
  }
61
86
  }, [externalOrderId, isRefreshingOrderSource, listOrderSourcesQuery.data, listOrderSourcesQuery.isSuccess, orderSourceCode, queryClient, refreshOrderSource, salesOrderId, shouldAttemptRefresh]);
62
- const isLoading = orderByIdQuery.isInitialLoading || orderByExternalIdQuery.isInitialLoading || listOrderSourcesQuery.isInitialLoading || isRefreshingOrderSource;
63
- const errors = [...((_a = orderByIdQuery.error) !== null && _a !== void 0 ? _a : []), ...((_b = orderByExternalIdQuery.error) !== null && _b !== void 0 ? _b : []), ...((_c = listOrderSourcesQuery.error) !== null && _c !== void 0 ? _c : []), ...(refreshOrderSourceErrors !== null && refreshOrderSourceErrors !== void 0 ? refreshOrderSourceErrors : [])];
87
+ const isLoading = salesOrderByIdQuery.isInitialLoading || salesOrderByExternalIdQuery.isInitialLoading || listOrderSourcesQuery.isInitialLoading || isRefreshingOrderSource;
88
+ const errors = [...((_a = salesOrderByIdQuery.error) !== null && _a !== void 0 ? _a : []), ...((_b = salesOrderByExternalIdQuery.error) !== null && _b !== void 0 ? _b : []), ...((_c = listOrderSourcesQuery.error) !== null && _c !== void 0 ? _c : []), ...(refreshOrderSourceErrors !== null && refreshOrderSourceErrors !== void 0 ? refreshOrderSourceErrors : [])];
64
89
  return {
65
90
  errors: errors.length > 0 ? errors : undefined,
66
- isLoading,
91
+ isLoading: isLoading && errors.length === 0,
67
92
  salesOrder
68
93
  };
69
94
  };
@@ -170,7 +170,7 @@ var common = {
170
170
  invalidNameOrCompany: "Recipient name and company name (if provided) must have two characters in first and last name.",
171
171
  parsingFailure: "Parsing failed. Please check address and try again.",
172
172
  incompleteLabelPurchaseRequirements: "Please add your {{requirements}} to continue purchasing a label.",
173
- shipmentNotFound: "Cannot find shipment with ID: {{id}}.",
173
+ shipmentNotFound: "Cannot find {{identifierType}}: {{identifierNumber}}",
174
174
  shipmentCancelled: "This shipment is Cancelled in ShipStation. Log into ShipStation to restore the order to Awaiting Shipment status.",
175
175
  unableToLoad: {
176
176
  accountSettings: "Unable to load account settings",
@@ -32,6 +32,13 @@ var purchaseLabel = {
32
32
  saveRateFailedMessage: "Saving DHL Express Worldwide rates is temporarily unavailable. Please try again later.",
33
33
  saveRateFailedTitle: "Unable To Save Rate"
34
34
  },
35
+ identifierTypes: {
36
+ externalOrderId: "External Order ID",
37
+ externalOrderNumber: "External Order Number",
38
+ externalShipmentId: "External Shipment ID",
39
+ salesOrderId: "Sales Order ID",
40
+ shipmentId: "Shipment ID"
41
+ },
35
42
  errorTypes: {
36
43
  results: "No results returned"
37
44
  },
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var version = "2.26.2";
3
+ var version = "2.26.4";
4
4
 
5
5
  exports.version = version;
@@ -112,7 +112,7 @@ const supportedCountriesUK = [{
112
112
  const fedexJsonSchema = isUK => ({
113
113
  description: `You'll need an existing FedEx account to complete this form. If you don't have a FedEx account, please <a href="${newAccountHref}" target="_blank" rel="noopener noreferrer">click here to open one now!</a>`,
114
114
  properties: {
115
- accountNumber: {
115
+ account_number: {
116
116
  maxLength: 50,
117
117
  title: "FedEx Account No",
118
118
  type: "string"
@@ -129,7 +129,7 @@ const fedexJsonSchema = isUK => ({
129
129
  title: "Address Line 2",
130
130
  type: "string"
131
131
  },
132
- agreeToEula: {
132
+ agree_to_eula: {
133
133
  title: "I agree to the End-User License Agreement",
134
134
  type: "boolean"
135
135
  },
@@ -143,7 +143,7 @@ const fedexJsonSchema = isUK => ({
143
143
  title: "Company Name",
144
144
  type: "string"
145
145
  },
146
- countryCode: {
146
+ country_code: {
147
147
  oneOf: isUK ? supportedCountriesUK : supportedCountries,
148
148
  title: "Country",
149
149
  type: "string"
@@ -153,13 +153,13 @@ const fedexJsonSchema = isUK => ({
153
153
  title: "Email",
154
154
  type: "string"
155
155
  },
156
- firstName: {
156
+ first_name: {
157
157
  // TODO: Can we make firstname/lastname in the same row?
158
158
  maxLength: 50,
159
159
  title: "Contact First Name",
160
160
  type: "string"
161
161
  },
162
- lastName: {
162
+ last_name: {
163
163
  // TODO: Can we make firstname/lastname in the same row?
164
164
  maxLength: 50,
165
165
  title: "Contact Last Name",
@@ -174,7 +174,7 @@ const fedexJsonSchema = isUK => ({
174
174
  title: "Phone #",
175
175
  type: "string"
176
176
  },
177
- postalCode: {
177
+ postal_code: {
178
178
  // TODO: Can we make this reactive to country selection? Can we group State/Zip?
179
179
  maxLength: 8,
180
180
  title: "Zip/Postal Code",
@@ -187,16 +187,16 @@ const fedexJsonSchema = isUK => ({
187
187
  type: "string"
188
188
  }
189
189
  },
190
- required: ["accountNumber", "firstName", "lastName", "email", "countryCode", "address1", "city", "state", "postalCode", "phone", "nickname"],
190
+ required: ["account_number", "first_name", "last_name", "email", "country_code", "address1", "city", "state", "postal_code", "phone", "nickname"],
191
191
  title: "Connect Your FedEx Account",
192
192
  type: "object"
193
193
  });
194
194
  const fedexUiSchema = {
195
- accountNumber: {
195
+ account_number: {
196
196
  "ui:autofocus": true,
197
197
  "ui:emptyValue": ""
198
198
  },
199
- agreeToEula: {
199
+ agree_to_eula: {
200
200
  "ui:widget": "hidden"
201
201
  },
202
202
  email: {
@@ -209,7 +209,7 @@ const fedexUiSchema = {
209
209
  inputType: "tel"
210
210
  }
211
211
  },
212
- "ui:order": ["accountNumber", "firstName", "lastName", "company", "email", "countryCode", "address1", "address2", "city", "state", "postalCode", "phone", "agreeToEula", "nickname"]
212
+ "ui:order": ["account_number", "first_name", "last_name", "company", "email", "country_code", "address1", "address2", "city", "state", "postal_code", "phone", "agree_to_eula", "nickname"]
213
213
  };
214
214
  const CustomExternalCarrierFormFedex = ({
215
215
  carrierName,
@@ -232,7 +232,7 @@ const CustomExternalCarrierFormFedex = ({
232
232
  displayName: displayName,
233
233
  iconUrl: iconUrl,
234
234
  initialFormData: {
235
- agreeToEula,
235
+ agree_to_eula: agreeToEula,
236
236
  nickname: ""
237
237
  },
238
238
  isBeta: isBeta,