@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
@@ -4,7 +4,6 @@ var jsxRuntime = require('@emotion/react/jsx-runtime');
4
4
  var giger = require('@shipengine/giger');
5
5
  var reactApi = require('@shipengine/react-api');
6
6
  var reactQuery = require('@tanstack/react-query');
7
- var humps = require('humps');
8
7
  var React = require('react');
9
8
  var reactI18next = require('react-i18next');
10
9
  var customExternalCarrierForm = require('./components/custom-external-carrier-form/custom-external-carrier-form.cjs');
@@ -18,25 +17,6 @@ var spacer = require('../../components/spacer/spacer.cjs');
18
17
  var buttonGroup = require('../../components/button-group/button-group.cjs');
19
18
  var errorFallback = require('../../components/error-fallback/error-fallback.cjs');
20
19
 
21
- function _interopNamespaceDefault(e) {
22
- var n = Object.create(null);
23
- if (e) {
24
- Object.keys(e).forEach(function (k) {
25
- if (k !== 'default') {
26
- var d = Object.getOwnPropertyDescriptor(e, k);
27
- Object.defineProperty(n, k, d.get ? d : {
28
- enumerable: true,
29
- get: function () { return e[k]; }
30
- });
31
- }
32
- });
33
- }
34
- n.default = e;
35
- return Object.freeze(n);
36
- }
37
-
38
- var humps__namespace = /*#__PURE__*/_interopNamespaceDefault(humps);
39
-
40
20
  /**
41
21
  * # ConnectExternalCarrier Component
42
22
  *
@@ -113,24 +93,6 @@ const Component = ({
113
93
  const formattedJsonSchema = React.useMemo(() => {
114
94
  if (!jsonSchema) return {};
115
95
  const jsonSchemaClone = JSON.parse(JSON.stringify(jsonSchema));
116
- // if property has a ref key, map the property value to the value of the path
117
- const mapRefPath = schema => {
118
- const {
119
- properties
120
- } = schema;
121
- if (!properties) return schema;
122
- for (const key in properties) {
123
- const property = properties[key];
124
- if (property.$ref) {
125
- const propKey = `${property.$ref}`.replace("#/", "");
126
- const refPath = humps__namespace.camelize(propKey).split("/");
127
- properties[key] = refPath.reduce((acc, path) => {
128
- return acc === null || acc === void 0 ? void 0 : acc[path];
129
- }, schema);
130
- }
131
- }
132
- return schema;
133
- };
134
96
  // add nickname to properties if it doesn't exist
135
97
  const addNicknameProperty = schema => {
136
98
  if (!(schema === null || schema === void 0 ? void 0 : schema.properties)) return schema;
@@ -147,27 +109,7 @@ const Component = ({
147
109
  updatedSchema.properties = updatedProperties;
148
110
  return updatedSchema;
149
111
  };
150
- const standardizeCasing = schema => {
151
- if (!schema) return schema;
152
- const updatedSchema = Object.assign({}, schema);
153
- // camelize required fields, as casing varies between carriers
154
- if (updatedSchema.required && Array.isArray(updatedSchema.required)) {
155
- updatedSchema.required = updatedSchema.required.map(item => {
156
- return typeof item === "string" ? humps__namespace.camelize(item) : item;
157
- });
158
- }
159
- // camelize property keys
160
- // fail safe to ensure schema properties and required array match in the event the camelizeKeys from shipengine/js-api isn't consistent
161
- // TODO: Fix edge cases with camelizeKeys in js-api and remove this
162
- if (updatedSchema.properties && typeof updatedSchema.properties === "object") {
163
- updatedSchema.properties = Object.entries(updatedSchema.properties).reduce((acc, [key, value]) => {
164
- acc[humps__namespace.camelize(key)] = value;
165
- return acc;
166
- }, {});
167
- }
168
- return updatedSchema;
169
- };
170
- const newJsonSchema = standardizeCasing(addNicknameProperty(mapRefPath(jsonSchemaClone)));
112
+ const newJsonSchema = addNicknameProperty(jsonSchemaClone);
171
113
  return newJsonSchema;
172
114
  }, [jsonSchema, hasNicknameProperty]);
173
115
  const formattedUiSchema = React.useMemo(() => {
@@ -176,9 +118,7 @@ const Component = ({
176
118
  const updatedUiSchema = Object.assign({}, uiSchemaClone);
177
119
  // add nickname to ui:order and camelize the values to ensure consistency with jsonSchema properties and required array
178
120
  if (!hasNicknameProperty && updatedUiSchema["ui:order"]) {
179
- // ui:order is typically an array of strings, but apparently can also be an array of arrays of strings, so we need to recursively camelize the items
180
- const camelizeUIOrderItem = item => typeof item === "string" ? humps__namespace.camelize(item) : item.map(i => humps__namespace.camelize(i));
181
- updatedUiSchema["ui:order"] = [...updatedUiSchema["ui:order"], "nickname"].map(camelizeUIOrderItem);
121
+ updatedUiSchema["ui:order"] = [...updatedUiSchema["ui:order"], "nickname"];
182
122
  }
183
123
  return updatedUiSchema;
184
124
  }, [uiSchema, hasNicknameProperty]);
@@ -196,7 +136,7 @@ const Component = ({
196
136
  if (schemaLoading || carriersLoading || needsRefetch) return jsxRuntime.jsx(loader.Loader, {
197
137
  message: t(selectedCarrier ? "loading.connectCarrierForm" : "loading.carriers")
198
138
  });
199
- if (schemaError) {
139
+ if (schemaError && selectedCarrier && !customExternalCarrierForm.hasCustomExternalCarrierConnectionForm(selectedCarrier)) {
200
140
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
201
141
  children: [jsxRuntime.jsx(giger.InlineNotification, {
202
142
  type: giger.NotificationType.ERROR,
@@ -62,7 +62,31 @@ const Component = _a => {
62
62
  }));
63
63
  // Track if we have a shipment_not_found error to avoid reusing the bad shipment ID
64
64
  const hasShipmentNotFoundError = configureShipmentErrors === null || configureShipmentErrors === void 0 ? void 0 : configureShipmentErrors.some(error => error.message === "shipment_not_found");
65
- const shipmentId = _multiplexedId && "shipmentId" in _multiplexedId ? _multiplexedId.shipmentId : undefined;
65
+ const getMultiplexedIdentifier = React.useCallback(() => {
66
+ if (_multiplexedId && "shipmentId" in _multiplexedId) {
67
+ return {
68
+ shipmentId: _multiplexedId.shipmentId
69
+ };
70
+ } else if (_multiplexedId && "externalShipmentId" in _multiplexedId) {
71
+ return {
72
+ externalShipmentId: _multiplexedId.externalShipmentId
73
+ };
74
+ } else if (_multiplexedId && "salesOrderId" in _multiplexedId) {
75
+ return {
76
+ salesOrderId: _multiplexedId.salesOrderId
77
+ };
78
+ } else if (_multiplexedId && "externalOrderNumber" in _multiplexedId) {
79
+ return {
80
+ externalOrderNumber: _multiplexedId.externalOrderNumber
81
+ };
82
+ } else if (_multiplexedId && "externalOrderId" in _multiplexedId) {
83
+ return {
84
+ externalOrderId: _multiplexedId.externalOrderId
85
+ };
86
+ }
87
+ return {};
88
+ }, [_multiplexedId]);
89
+ const shipmentId = getMultiplexedIdentifier().shipmentId;
66
90
  const {
67
91
  data: insuranceAccount,
68
92
  isInitialLoading: insuranceIsLoading
@@ -180,9 +204,9 @@ const Component = _a => {
180
204
  return jsxRuntime.jsx(suspendPurchase.SuspendPurchase, {
181
205
  data: shipment$1 || salesOrder,
182
206
  errors: errors.length ? errors : undefined,
207
+ identifier: getMultiplexedIdentifier(),
183
208
  isLoading: isLabelsLoading || isConfiguringShipment || insuranceIsLoading,
184
209
  onCreateNewShipment: createNewShipmentForNotFound,
185
- shipmentId: shipmentId,
186
210
  children: element && getElement(element)
187
211
  });
188
212
  };
@@ -12,7 +12,7 @@ const CcProviderLogo = ({
12
12
  height = 36
13
13
  }) => {
14
14
  const providerLogos = {
15
- americanExpress: SvgAmex,
15
+ american_express: SvgAmex,
16
16
  discover: SvgDiscover,
17
17
  mastercard: SvgMastercard,
18
18
  visa: SvgVisa
@@ -23,6 +23,7 @@ const CcProviderLogo = ({
23
23
  size: IconSize.SIZE_LARGE
24
24
  });
25
25
  }
26
+ // TODO: LMNT-1810 - Add missing provider logos
26
27
  const Logo = providerLogos[provider];
27
28
  return jsx(Logo, {
28
29
  height: height,
@@ -75,7 +75,7 @@ const creditCardSchema = z.object({
75
75
  expirationMonth: expirationMonth,
76
76
  expirationYear: expirationYear,
77
77
  name: creditCard.name,
78
- provider: creditCardVendor === "american-express" ? "americanExpress" : creditCardVendor
78
+ provider: creditCardVendor === "american-express" ? "american_express" : creditCardVendor
79
79
  };
80
80
  });
81
81
  const getWalletSchema = (emailRequirement, blackboxRequirement) => {
@@ -5,12 +5,26 @@ import { useTranslation } from 'react-i18next';
5
5
  import { styles } from './shipment-not-found-error.styles.js';
6
6
 
7
7
  const ShipmentNotFoundError = ({
8
- shipmentId,
8
+ identifier,
9
9
  onCreateNewShipment
10
10
  }) => {
11
11
  const {
12
12
  t
13
13
  } = useTranslation(["common", "purchase-label"]);
14
+ const getIdentifierInfo = identifier => {
15
+ // Order should match the actual search priority in useConfigureShipment:
16
+ const identifierKeys = ["shipmentId", "externalShipmentId", "salesOrderId", "externalOrderId", "externalOrderNumber"];
17
+ const foundKey = identifierKeys.find(key => identifier === null || identifier === void 0 ? void 0 : identifier[key]);
18
+ const identifierKey = foundKey || "shipmentId";
19
+ return {
20
+ type: t(`purchase-label:identifierTypes.${identifierKey}`),
21
+ value: identifier === null || identifier === void 0 ? void 0 : identifier[identifierKey]
22
+ };
23
+ };
24
+ const {
25
+ type: identifierType,
26
+ value: identifierNumber
27
+ } = getIdentifierInfo(identifier);
14
28
  return jsxs("div", {
15
29
  css: styles.container,
16
30
  children: [jsx("div", {
@@ -22,7 +36,8 @@ const ShipmentNotFoundError = ({
22
36
  }), jsx("div", {
23
37
  css: styles.message,
24
38
  children: t("common:errorMessages.shipmentNotFound", {
25
- id: shipmentId
39
+ identifierType,
40
+ identifierNumber
26
41
  })
27
42
  }), jsx(Button, {
28
43
  "data-testid": "create-new-shipment",
@@ -9,7 +9,7 @@ const SuspendPurchase = ({
9
9
  isLoading,
10
10
  data,
11
11
  onCreateNewShipment,
12
- shipmentId
12
+ identifier
13
13
  }) => {
14
14
  const {
15
15
  t
@@ -36,8 +36,8 @@ const SuspendPurchase = ({
36
36
  throw new Error(t("common:errorMessages.labelHasBeenPurchased"));
37
37
  case "shipment_not_found":
38
38
  return jsx(ShipmentNotFoundError, {
39
- onCreateNewShipment: onCreateNewShipment,
40
- shipmentId: shipmentId
39
+ identifier: identifier,
40
+ onCreateNewShipment: onCreateNewShipment
41
41
  });
42
42
  }
43
43
  }
@@ -160,7 +160,7 @@ const useAddress = ({
160
160
  if (warning && warning.error) return warning;
161
161
  const value = addressMinusGeolocation[key];
162
162
  if (!value) return warning;
163
- if (/^[0-9\p{Script=Latin}\p{P}\p{S}\s]+$/u.test(value)) return warning;
163
+ 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;
164
164
  if (key === "name" || key === "companyName") {
165
165
  return {
166
166
  error: false,
@@ -90,9 +90,15 @@ const Component = _a => {
90
90
  return jsx(SuspendPurchase, {
91
91
  data: shipment || salesOrder,
92
92
  errors: errors,
93
+ identifier: {
94
+ externalOrderId,
95
+ externalOrderNumber,
96
+ externalShipmentId,
97
+ salesOrderId,
98
+ shipmentId
99
+ },
93
100
  isLoading: isLoading || insuranceIsLoading,
94
101
  onCreateNewShipment: createNewShipmentForNotFound,
95
- shipmentId: shipmentId,
96
102
  children: jsx(ConfigureShipment, Object.assign({
97
103
  currency: currency,
98
104
  features: features,
@@ -20,8 +20,8 @@ const useConfigureShipment = ({
20
20
  warehouseId,
21
21
  useWarehouses = true
22
22
  }) => {
23
- // Track when we've created a replacement shipment for a "not found" case
24
- const [replacementShipmentId, setReplacementShipmentId] = useState();
23
+ // Track when user manually created a shipment for a "not found" case
24
+ const [manuallyCreatedShipmentId, setManuallyCreatedShipmentId] = useState();
25
25
  // Queue of incomplete requirement keys (i.e., Ship From addresses, Warehouses, Carriers)
26
26
  const incompleteRequirementsKeys = useMemo(() => [], []);
27
27
  const {
@@ -45,6 +45,7 @@ const useConfigureShipment = ({
45
45
  // Dont run Sales Order Import unless the Sales order info is present
46
46
  enabled: !!externalOrderNumber || !!orderSourceCode || !!salesOrderId || !!externalOrderId,
47
47
  externalOrderId,
48
+ externalOrderNumber,
48
49
  orderSourceCode,
49
50
  salesOrderId
50
51
  });
@@ -61,24 +62,49 @@ const useConfigureShipment = ({
61
62
  isInitialLoading: isExternalShipmentInitialLoading,
62
63
  isFetching: isExternalShipmentFetching
63
64
  } = useGetShipmentByExternalId({
64
- enabled: !!externalShipmentId && !shipmentId,
65
+ enabled: !!externalShipmentId && !shipmentId && !manuallyCreatedShipmentId,
65
66
  queryFnParams: {
66
67
  externalId: externalShipmentId !== null && externalShipmentId !== void 0 ? externalShipmentId : ""
67
68
  }
69
+ // TODO: weird refetch on focus behavior
68
70
  });
71
+ // #region List Sales Order Shipments
72
+ const externalOrderIds = useMemo(() => {
73
+ return externalOrderId ? [externalOrderId] : undefined;
74
+ }, [externalOrderId]);
75
+ const salesOrderIds = useMemo(() => {
76
+ return salesOrderId ? [salesOrderId] : salesOrder ? [salesOrder.salesOrderId] :
77
+ // TODO: current workaround - revert to being undefined rather than empty list
78
+ [];
79
+ }, [salesOrderId, salesOrder]);
80
+ const shipmentIds = useMemo(() => {
81
+ return manuallyCreatedShipmentId ? [manuallyCreatedShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined;
82
+ }, [manuallyCreatedShipmentId, shipmentId, externalShipment, newV1Shipment]);
83
+ const listSalesOrderShipmentsParams = useMemo(() => {
84
+ // TODO: useListSalesOrderShipments needs to be able to use the enabled prop, this is a workaround
85
+ // Prevent query with stale params during shipment creation or when V1 shipment exists but manuallyCreatedShipmentId not set
86
+ if (creatingV1Shipment && !manuallyCreatedShipmentId || newV1Shipment && !manuallyCreatedShipmentId) {
87
+ return {};
88
+ }
89
+ if (manuallyCreatedShipmentId) {
90
+ return {
91
+ shipmentIds
92
+ };
93
+ }
94
+ return {
95
+ externalOrderIds,
96
+ salesOrderIds,
97
+ shipmentIds
98
+ };
99
+ }, [manuallyCreatedShipmentId, externalOrderIds, salesOrderIds, shipmentIds, creatingV1Shipment, newV1Shipment]);
69
100
  const {
70
101
  data: salesOrderShipments,
71
102
  error: listSalesOrderShipmentsErrors,
72
103
  refetch: refetchSalesOrderShipments,
73
104
  isInitialLoading: listSalesOrderShipmentsInitiallyLoading,
74
105
  isFetching: listSalesOrderShipmentsIsFetching
75
- } = useListSalesOrderShipments({
76
- externalOrderIds: externalOrderId ? [externalOrderId] : undefined,
77
- salesOrderIds: salesOrderId ? [salesOrderId] : salesOrder ? [salesOrder.salesOrderId] :
78
- // TODO: current workaround - revert to being undefined rather than empty list
79
- [],
80
- shipmentIds: replacementShipmentId ? [replacementShipmentId] : shipmentId ? [shipmentId] : externalShipment ? [externalShipment.shipmentId] : newV1Shipment ? [newV1Shipment.shipments[0].shipmentId] : undefined
81
- });
106
+ } = useListSalesOrderShipments(listSalesOrderShipmentsParams);
107
+ // #endregion
82
108
  const {
83
109
  error: createSalesOrderShipmentErrors,
84
110
  mutateAsync: createSalesOrderShipment,
@@ -103,6 +129,7 @@ const useConfigureShipment = ({
103
129
  }
104
130
  return null;
105
131
  }), [createV1Shipment, defaultShipFromAddress, defaultWarehouse, warehouseId, refetchSalesOrderShipments]);
132
+ // #region Create Sales Order Shipment
106
133
  // Handles the creation of new shipments for the sales order flow and one-off flow
107
134
  const handleShipmentCreation = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
108
135
  var _a, _b, _c;
@@ -152,17 +179,23 @@ const useConfigureShipment = ({
152
179
  }
153
180
  // Create a Shipment for one-off flow
154
181
  if (!salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId) {
155
- yield createV1ShipmentWithDefaults();
182
+ const v1Shipment = yield createV1ShipmentWithDefaults();
183
+ // Set manuallyCreatedShipmentId to ensure proper query parameter handling
184
+ if (v1Shipment) {
185
+ setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
186
+ }
156
187
  }
157
188
  }), [createSalesOrderShipment, createV1ShipmentWithDefaults, creatingSalesOrderShipment, creatingV1Shipment, defaultShipFromAddress, defaultWarehouse, externalOrderId, externalOrderNumber, externalShipmentId, incompleteRequirementsKeys, isExternalShipmentFetching, isExternalShipmentInitialLoading, isFetchingWarehouses, isInitialLoadingWarehouses, labelPurchasedSalesOrderShipment, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, orderSourceCode, pendingSalesOrderShipment, salesOrder, salesOrderId, salesOrderShipmentCreated, shipFromAddresses === null || shipFromAddresses === void 0 ? void 0 : shipFromAddresses.length, shipmentId, useWarehouses, v1shipmentCreated, warehouseId, warehouses]);
189
+ // #endregion
158
190
  const createNewShipmentForNotFound = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
159
191
  // Force create a new shipment even if shipmentId exists (for shipment_not_found case)
160
192
  const v1Shipment = yield createV1ShipmentWithDefaults();
161
193
  if (v1Shipment) {
162
- // Store the new shipment ID to override the stale one
163
- setReplacementShipmentId(v1Shipment.shipments[0].shipmentId);
194
+ setManuallyCreatedShipmentId(v1Shipment.shipments[0].shipmentId);
195
+ // Refetch to ensure we have the latest shipment data
196
+ yield refetchSalesOrderShipments();
164
197
  }
165
- }), [createV1ShipmentWithDefaults]);
198
+ }), [createV1ShipmentWithDefaults, refetchSalesOrderShipments]);
166
199
  const refetchPendingSalesOrderShipments = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
167
200
  const {
168
201
  data: shipments
@@ -186,7 +219,83 @@ const useConfigureShipment = ({
186
219
  if (isInitialLoadingCarriers || isFetchingCarriers) return;
187
220
  if ((carriers === null || carriers === void 0 ? void 0 : carriers.length) === 0) incompleteRequirementsKeys.push("no_carriers");
188
221
  }, [carriers, incompleteRequirementsKeys, isFetchingCarriers, isInitialLoadingCarriers]);
189
- 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 CodedError("shipment_cancelled", {
222
+ const isConfigureShipmentLoading = useMemo(() => {
223
+ if (isSalesOrderLoading) return true;
224
+ if (listSalesOrderShipmentsInitiallyLoading) return true;
225
+ if (listSalesOrderShipmentsIsFetching) return true;
226
+ if (creatingSalesOrderShipment) return true;
227
+ if (creatingV1Shipment) return true;
228
+ // Include external shipment loading states to prevent premature error display
229
+ // Only keep loading if we're actually fetching and don't have an error yet
230
+ // Skip this check if we already have an error to avoid infinite loading
231
+ if (externalShipmentId && isExternalShipmentFetching && !getExternalShipmentErrors && !isExternalShipmentInitialLoading) {
232
+ return true;
233
+ }
234
+ // Check if this is a one-off flow (no identifiers provided)
235
+ const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
236
+ // For one-off flow, keep loading until we have shipment data or V1 creation is complete
237
+ if (isOneOffFlow && !pendingSalesOrderShipment && !labelPurchasedSalesOrderShipment) {
238
+ return true;
239
+ }
240
+ // Only consider empty salesOrderShipments array as loading if we're not initially loading and have valid identifiers
241
+ const shouldReturnTrueForEmptyShipments = (salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching;
242
+ if (shouldReturnTrueForEmptyShipments) {
243
+ return true;
244
+ }
245
+ return false;
246
+ }, [isSalesOrderLoading, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, creatingSalesOrderShipment, creatingV1Shipment, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors,
247
+ // This was missing!
248
+ salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, pendingSalesOrderShipment, labelPurchasedSalesOrderShipment, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length]);
249
+ // #region Custom Error Mapping
250
+ const hasGetShipmentErrors = useMemo(() => {
251
+ // Check for explicit API errors
252
+ if (listSalesOrderShipmentsErrors) return true;
253
+ if (getExternalShipmentErrors) return true;
254
+ if (importSalesOrderErrors) return true;
255
+ // Only treat empty results as error if we're not loading and have finished initial fetch
256
+ if ((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && shipmentId && !listSalesOrderShipmentsInitiallyLoading && !listSalesOrderShipmentsIsFetching) {
257
+ return true;
258
+ }
259
+ return false;
260
+ }, [listSalesOrderShipmentsErrors, getExternalShipmentErrors, importSalesOrderErrors, salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length, shipmentId, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching]);
261
+ const hasValidShipmentData = useMemo(() => {
262
+ if (manuallyCreatedShipmentId) return true;
263
+ if (pendingSalesOrderShipment) return true;
264
+ if (labelPurchasedSalesOrderShipment) return true;
265
+ return false;
266
+ }, [labelPurchasedSalesOrderShipment, manuallyCreatedShipmentId, pendingSalesOrderShipment]);
267
+ const showShipmentNotFoundError = useMemo(() => {
268
+ // Don't show error if we have a manually created shipment
269
+ if (manuallyCreatedShipmentId) {
270
+ return false;
271
+ }
272
+ // Don't show error if we're creating a V1 shipment
273
+ if (creatingV1Shipment || newV1Shipment) {
274
+ return false;
275
+ }
276
+ // For external shipment ID, show error if we're not in loading state
277
+ // and we don't have valid shipment data
278
+ if (externalShipmentId && !isConfigureShipmentLoading && !hasValidShipmentData) {
279
+ return true;
280
+ }
281
+ // Don't show error if external shipment is still loading, unless we have explicit errors
282
+ if (externalShipmentId && (isExternalShipmentInitialLoading || isExternalShipmentFetching) && !getExternalShipmentErrors) {
283
+ return false;
284
+ }
285
+ // Show error immediately if we have shipment errors, even if still loading
286
+ if (hasGetShipmentErrors) {
287
+ return true;
288
+ }
289
+ // Check if this is a one-off flow (no identifiers provided)
290
+ const isOneOffFlow = !salesOrderId && !externalOrderId && !externalOrderNumber && !orderSourceCode && !shipmentId && !externalShipmentId;
291
+ // Don't show error for one-off flow until we've attempted shipment creation
292
+ if (isOneOffFlow && !v1shipmentCreated) {
293
+ return false;
294
+ }
295
+ // Otherwise, only show if not loading and no valid shipment data
296
+ return !isConfigureShipmentLoading && !hasValidShipmentData;
297
+ }, [manuallyCreatedShipmentId, creatingV1Shipment, newV1Shipment, hasGetShipmentErrors, isExternalShipmentInitialLoading, isExternalShipmentFetching, getExternalShipmentErrors, listSalesOrderShipmentsErrors, importSalesOrderErrors, salesOrderId, externalOrderId, externalOrderNumber, orderSourceCode, shipmentId, externalShipmentId, v1shipmentCreated, isConfigureShipmentLoading, hasValidShipmentData, pendingSalesOrderShipment, externalShipment]);
298
+ const errors = [...(listWarehouseErrors !== null && listWarehouseErrors !== void 0 ? listWarehouseErrors : []), ...(createSalesOrderShipmentErrors !== null && createSalesOrderShipmentErrors !== void 0 ? createSalesOrderShipmentErrors : []), ...(createV1ShipmentErrors !== null && createV1ShipmentErrors !== void 0 ? createV1ShipmentErrors : []), ...(errorWhenShipmentCancelled && cancelledShipment ? [new CodedError("shipment_cancelled", {
190
299
  errorCode: "invalid_status",
191
300
  errorSource: "elements",
192
301
  errorType: "business_rules"
@@ -198,16 +307,17 @@ const useConfigureShipment = ({
198
307
  errorCode: "unknown",
199
308
  errorSource: "elements",
200
309
  errorType: "business_rules"
201
- })] : []), ...((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) === 0 && shipmentId ? [new CodedError("shipment_not_found", {
310
+ })] : []), ...(showShipmentNotFoundError ? [new CodedError("shipment_not_found", {
202
311
  errorCode: "invalid_status",
203
312
  errorSource: "elements",
204
313
  errorType: "business_rules"
205
314
  })] : [])];
315
+ // #endregion
206
316
  return {
207
317
  carriers,
208
318
  createNewShipmentForNotFound,
209
319
  errors: errors.length > 0 ? errors : undefined,
210
- isLoading: (isSalesOrderLoading || !(salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) || creatingSalesOrderShipment) && errors.length === 0,
320
+ isLoading: isConfigureShipmentLoading && errors.length === 0,
211
321
  refetchPendingSalesOrderShipments,
212
322
  salesOrder,
213
323
  shipment: pendingSalesOrderShipment !== null && pendingSalesOrderShipment !== void 0 ? pendingSalesOrderShipment : labelPurchasedSalesOrderShipment,
@@ -1,28 +1,51 @@
1
1
  import { __awaiter } from '../_virtual/_tslib.js';
2
- import { useGetSalesOrderByExternalOrderId, useGetSalesOrder, useListOrderSources, useRefreshOrderSource } from '@shipengine/react-api';
2
+ import { useListSalesOrders, useGetSalesOrder, useListOrderSources, useRefreshOrderSource } from '@shipengine/react-api';
3
3
  import { useQueryClient } from '@tanstack/react-query';
4
- import { useState, useMemo, useEffect } from 'react';
4
+ import { useState, useMemo, useCallback, useEffect } from 'react';
5
5
 
6
+ /**
7
+ * Imports and retrieves sales orders by either:
8
+ * - Sales order ID lookup
9
+ * - External order ID/number search
10
+ *
11
+ * 1. First attempts to find the sales order using provided identifiers
12
+ * 2. If no order is found and initial fetches have run, automatically refreshes order sources
13
+ * 3. Invalidates relevant queries after successful refresh to refetch updated data
14
+ *
15
+ * @returns Object:
16
+ * - `salesOrder`: The found sales order, or undefined
17
+ * - `isLoading`: Boolean indicating if the hook is currently loading data
18
+ * - `errors`: Array of errors from failed queries, or undefined
19
+ */
6
20
  const useImportSalesOrder = ({
7
21
  enabled,
8
22
  externalOrderId,
23
+ externalOrderNumber,
9
24
  orderSourceCode,
10
25
  salesOrderId
11
26
  }) => {
12
27
  var _a, _b, _c;
13
28
  const queryClient = useQueryClient();
14
29
  const [refreshAttempted, setRefreshAttempted] = useState(false);
15
- // attempt to get sales order through external id means
16
- const orderByExternalIdQuery = useGetSalesOrderByExternalOrderId(externalOrderId, {
17
- enabled: enabled && !!externalOrderId && !salesOrderId
30
+ // Fetch sales order by External Order ID or External Order Number
31
+ const salesOrderByExternalIdQuery = useListSalesOrders({
32
+ externalOrderId,
33
+ externalOrderNumber
18
34
  });
19
35
  // if an order was found through external search disable this query
20
- const orderByIdQuery = useGetSalesOrder(salesOrderId, {
36
+ const salesOrderByIdQuery = useGetSalesOrder(salesOrderId, {
21
37
  enabled: enabled && !!salesOrderId
22
38
  });
23
- const salesOrder = useMemo(() => salesOrderId ? orderByIdQuery.data : orderByExternalIdQuery.data, [salesOrderId, orderByIdQuery.data, orderByExternalIdQuery.data]);
39
+ const salesOrder = useMemo(() => {
40
+ if (salesOrderId) {
41
+ return salesOrderByIdQuery.data;
42
+ } else if (salesOrderByExternalIdQuery.data && salesOrderByExternalIdQuery.data.length > 0) {
43
+ return salesOrderByExternalIdQuery.data[0];
44
+ }
45
+ return undefined;
46
+ }, [salesOrderId, salesOrderByIdQuery.data, salesOrderByExternalIdQuery.data]);
24
47
  // Determine if the initial fetch attempts (if applicable) have settled without finding data
25
- const initialFetchSettled = (salesOrderId ? !orderByIdQuery.isInitialLoading && !orderByIdQuery.isFetching : true) && (externalOrderId && !salesOrderId ? !orderByExternalIdQuery.isLoading && !orderByExternalIdQuery.isFetching : true);
48
+ const initialFetchSettled = (salesOrderId ? !salesOrderByIdQuery.isInitialLoading && !salesOrderByIdQuery.isFetching : true) && ((externalOrderNumber || externalOrderId) && !salesOrderId ? !salesOrderByExternalIdQuery.isLoading && !salesOrderByExternalIdQuery.isFetching : true);
26
49
  const shouldAttemptRefresh = enabled && initialFetchSettled && !salesOrder && !refreshAttempted;
27
50
  const listOrderSourcesQuery = useListOrderSources({
28
51
  enabled: shouldAttemptRefresh
@@ -32,6 +55,17 @@ const useImportSalesOrder = ({
32
55
  isLoading: isRefreshingOrderSource,
33
56
  mutateAsync: refreshOrderSource
34
57
  } = useRefreshOrderSource();
58
+ const invalidateSalesOrderQueries = useCallback(() => {
59
+ if (salesOrderId) {
60
+ void queryClient.invalidateQueries({
61
+ queryKey: ["useGetSalesOrder", salesOrderId]
62
+ });
63
+ } else if (externalOrderId || externalOrderNumber) {
64
+ void queryClient.invalidateQueries({
65
+ queryKey: ["useListSalesOrders", externalOrderId, externalOrderNumber]
66
+ });
67
+ }
68
+ }, [queryClient, salesOrderId, externalOrderId, externalOrderNumber]);
35
69
  useEffect(() => {
36
70
  if (listOrderSourcesQuery.isSuccess && listOrderSourcesQuery.data && shouldAttemptRefresh && !isRefreshingOrderSource) {
37
71
  const orderSourcesToRefresh = orderSourceCode ? listOrderSourcesQuery.data.filter(o => o.orderSourceCode.includes(orderSourceCode) && o.active) : listOrderSourcesQuery.data.filter(o => o.active);
@@ -39,29 +73,20 @@ const useImportSalesOrder = ({
39
73
  setRefreshAttempted(true);
40
74
  void (() => __awaiter(void 0, void 0, void 0, function* () {
41
75
  yield Promise.all(orderSourcesToRefresh.map(o => refreshOrderSource(o.orderSourceId, {
42
- // Invalidate relevant queries on successful refresh
76
+ // Invalidate relevant queries
43
77
  onSuccess: () => {
44
- if (salesOrderId) {
45
- void queryClient.invalidateQueries({
46
- queryKey: ["useGetSalesOrder", salesOrderId]
47
- });
48
- }
49
- if (externalOrderId && !salesOrderId) {
50
- void queryClient.invalidateQueries({
51
- queryKey: ["useGetSalesOrderByExternalOrderId", externalOrderId]
52
- });
53
- }
78
+ invalidateSalesOrderQueries();
54
79
  }
55
80
  })));
56
81
  }))();
57
82
  }
58
83
  }
59
84
  }, [externalOrderId, isRefreshingOrderSource, listOrderSourcesQuery.data, listOrderSourcesQuery.isSuccess, orderSourceCode, queryClient, refreshOrderSource, salesOrderId, shouldAttemptRefresh]);
60
- const isLoading = orderByIdQuery.isInitialLoading || orderByExternalIdQuery.isInitialLoading || listOrderSourcesQuery.isInitialLoading || isRefreshingOrderSource;
61
- 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 : [])];
85
+ const isLoading = salesOrderByIdQuery.isInitialLoading || salesOrderByExternalIdQuery.isInitialLoading || listOrderSourcesQuery.isInitialLoading || isRefreshingOrderSource;
86
+ 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 : [])];
62
87
  return {
63
88
  errors: errors.length > 0 ? errors : undefined,
64
- isLoading,
89
+ isLoading: isLoading && errors.length === 0,
65
90
  salesOrder
66
91
  };
67
92
  };
@@ -166,7 +166,7 @@ var common = {
166
166
  invalidNameOrCompany: "Recipient name and company name (if provided) must have two characters in first and last name.",
167
167
  parsingFailure: "Parsing failed. Please check address and try again.",
168
168
  incompleteLabelPurchaseRequirements: "Please add your {{requirements}} to continue purchasing a label.",
169
- shipmentNotFound: "Cannot find shipment with ID: {{id}}.",
169
+ shipmentNotFound: "Cannot find {{identifierType}}: {{identifierNumber}}",
170
170
  shipmentCancelled: "This shipment is Cancelled in ShipStation. Log into ShipStation to restore the order to Awaiting Shipment status.",
171
171
  unableToLoad: {
172
172
  accountSettings: "Unable to load account settings",
@@ -30,6 +30,13 @@ var purchaseLabel = {
30
30
  saveRateFailedMessage: "Saving DHL Express Worldwide rates is temporarily unavailable. Please try again later.",
31
31
  saveRateFailedTitle: "Unable To Save Rate"
32
32
  },
33
+ identifierTypes: {
34
+ externalOrderId: "External Order ID",
35
+ externalOrderNumber: "External Order Number",
36
+ externalShipmentId: "External Shipment ID",
37
+ salesOrderId: "Sales Order ID",
38
+ shipmentId: "Shipment ID"
39
+ },
33
40
  errorTypes: {
34
41
  results: "No results returned"
35
42
  },
@@ -1,3 +1,3 @@
1
- var version = "2.26.2";
1
+ var version = "2.26.4";
2
2
 
3
3
  export { version };