@shipengine/elements 2.22.0 → 2.23.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.
Files changed (86) hide show
  1. package/cjs/components/grid-controller/grid-controller.cjs +29 -15
  2. package/cjs/components/grid-filters/components/index.cjs +2 -0
  3. package/cjs/components/grid-filters/components/label-status-filter/index.cjs +9 -0
  4. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter-schema.cjs +12 -0
  5. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.cjs +174 -0
  6. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.styles.cjs +21 -0
  7. package/cjs/components/grid-filters/components/tracking-status-filter/tracking-status-filter.cjs +21 -12
  8. package/cjs/components/grid-filters/grid-filters.cjs +6 -1
  9. package/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +25 -12
  10. package/cjs/elements/labels-grid/labels-grid.cjs +11 -2
  11. package/cjs/elements/purchase-label/components/customs-forms/customs-forms.cjs +10 -3
  12. package/cjs/elements/purchase-label/components/rate-form/rate-view.cjs +4 -9
  13. package/cjs/elements/purchase-label/components/shipment-form/shipment-form.cjs +11 -5
  14. package/cjs/elements/purchase-label/configure-shipment.cjs +3 -1
  15. package/cjs/elements/purchase-label/hooks/use-rates-form.cjs +38 -16
  16. package/cjs/elements/purchase-label/purchase-label.cjs +0 -1
  17. package/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +5 -1
  18. package/cjs/elements/shipments-grid/shipments-grid.cjs +12 -5
  19. package/cjs/hooks/index.cjs +3 -0
  20. package/cjs/hooks/use-configure-shipment.cjs +1 -34
  21. package/cjs/index.cjs +5 -0
  22. package/cjs/locales/en/common.cjs +2 -1
  23. package/cjs/locales/en/purchase-label.cjs +2 -1
  24. package/cjs/package.cjs +1 -1
  25. package/cjs/workflows/label-workflow/label-workflow.cjs +0 -1
  26. package/esm/components/grid-controller/grid-controller.js +29 -15
  27. package/esm/components/grid-filters/components/index.js +1 -0
  28. package/esm/components/grid-filters/components/label-status-filter/index.js +1 -0
  29. package/esm/components/grid-filters/components/label-status-filter/label-status-filter-schema.js +8 -0
  30. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.js +170 -0
  31. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.styles.js +17 -0
  32. package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js +21 -12
  33. package/esm/components/grid-filters/grid-filters.js +6 -1
  34. package/esm/elements/labels-grid/hooks/use-labels-grid.js +25 -12
  35. package/esm/elements/labels-grid/labels-grid.js +11 -2
  36. package/esm/elements/purchase-label/components/customs-forms/customs-forms.js +10 -3
  37. package/esm/elements/purchase-label/components/rate-form/rate-view.js +4 -9
  38. package/esm/elements/purchase-label/components/shipment-form/shipment-form.js +11 -5
  39. package/esm/elements/purchase-label/configure-shipment.js +3 -1
  40. package/esm/elements/purchase-label/hooks/use-rates-form.js +38 -16
  41. package/esm/elements/purchase-label/purchase-label.js +0 -1
  42. package/esm/elements/shipments-grid/hooks/use-shipments-grid.js +5 -1
  43. package/esm/elements/shipments-grid/shipments-grid.js +12 -5
  44. package/esm/hooks/index.js +1 -0
  45. package/esm/hooks/use-configure-shipment.js +3 -36
  46. package/esm/index.js +2 -0
  47. package/esm/locales/en/common.js +2 -1
  48. package/esm/locales/en/purchase-label.js +2 -1
  49. package/esm/package.js +1 -1
  50. package/esm/workflows/label-workflow/label-workflow.js +0 -1
  51. package/package.json +13 -2
  52. package/types/src/components/grid-controller/grid-controller.d.ts +2 -0
  53. package/types/src/components/grid-filters/components/index.d.ts +1 -0
  54. package/types/src/components/grid-filters/components/label-status-filter/index.d.ts +1 -0
  55. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter-schema.d.ts +12 -0
  56. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.d.ts +24 -0
  57. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.styles.d.ts +13 -0
  58. package/types/src/components/grid-filters/grid-filters.d.ts +2 -0
  59. package/types/src/elements/labels-grid/hooks/use-labels-grid.d.ts +2 -1
  60. package/types/src/elements/labels-grid/labels-grid.d.ts +3 -4
  61. package/types/src/elements/manage-carriers/manage-carriers.d.ts +2 -0
  62. package/types/src/elements/manage-external-carriers/manage-external-carriers.d.ts +2 -0
  63. package/types/src/elements/manage-funding/manage-funding-element.d.ts +2 -0
  64. package/types/src/elements/manage-warehouses/manage-warehouses.d.ts +2 -0
  65. package/types/src/elements/payment-method-settings/payment-method-settings-element.d.ts +2 -0
  66. package/types/src/elements/purchase-label/hooks/use-rates-form.d.ts +1 -0
  67. package/types/src/elements/purchase-label/purchase-label.d.ts +11 -9
  68. package/types/src/elements/select-label-layout/select-label-layout-element.d.ts +2 -0
  69. package/types/src/elements/shipment-summary/shipment-summary.d.ts +2 -0
  70. package/types/src/elements/shipments-grid/hooks/use-shipments-grid.d.ts +11 -6
  71. package/types/src/elements/shipments-grid/shipments-grid.d.ts +31 -5
  72. package/types/src/elements/theme-creator/theme-creator.d.ts +2 -0
  73. package/types/src/elements/transaction-history/transaction-history-element.d.ts +2 -0
  74. package/types/src/elements/unit-settings/unit-settings-element.d.ts +2 -0
  75. package/types/src/elements/vat-settings/vat-settings-element.d.ts +2 -0
  76. package/types/src/elements/void-label/void-label.d.ts +33 -0
  77. package/types/src/hooks/index.d.ts +1 -0
  78. package/types/src/hooks/use-configure-shipment.d.ts +1 -2
  79. package/types/src/index.d.ts +5 -0
  80. package/types/src/locales/en/index.d.ts +2 -0
  81. package/types/src/utilities/feature-flags/types.d.ts +5 -1
  82. package/types/src/workflows/account-settings/account-settings.d.ts +2 -0
  83. package/types/src/workflows/carrier-services/carrier-services.d.ts +2 -0
  84. package/types/src/workflows/connect-external-carrier/connect-external-carrier.d.ts +2 -0
  85. package/types/src/workflows/label-workflow/label-workflow.d.ts +10 -1
  86. package/types/src/workflows/onboarding/onboarding.d.ts +2 -0
@@ -146,7 +146,9 @@ const ConfigureShipment = _a => {
146
146
  }
147
147
  });
148
148
  // Capture ship from address schema validation error to toggle form and display error message
149
- const hasShipFromAddressErrors = React.useMemo(() => !!(shipmentFormErrors === null || shipmentFormErrors === void 0 ? void 0 : shipmentFormErrors.filter(error => error.errorCode === "invalid_address")), [shipmentFormErrors]);
149
+ const hasShipFromAddressErrors = React.useMemo(() => {
150
+ return (shipmentFormErrors === null || shipmentFormErrors === void 0 ? void 0 : shipmentFormErrors.some(error => error.errorCode === "invalid_address")) || false;
151
+ }, [shipmentFormErrors]);
150
152
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
151
153
  children: [jsxRuntime.jsx(shipmentForm.ShipmentForm, Object.assign({}, shipmentFormProps, props, ((_c = features === null || features === void 0 ? void 0 : features.shipmentForm) === null || _c === void 0 ? void 0 : _c.useWarehouses) && {
152
154
  warehouses
@@ -61,7 +61,7 @@ const useRatesForm = ({
61
61
  mutateAsync: updateShipment
62
62
  } = reactApi.useUpdateSalesOrderShipment();
63
63
  const {
64
- error: labelErrors,
64
+ error: createLabelErrors,
65
65
  reset: resetLabel,
66
66
  mutateAsync: createLabel
67
67
  } = reactApi.useCreateLabel();
@@ -184,7 +184,7 @@ const useRatesForm = ({
184
184
  }
185
185
  }), [onBeforeRateSaved, onUpdatedShipment, resetRates, shipment, updateShipment]);
186
186
  const handleSubmit = React.useCallback((rateId, servicePoint) => tslib.__awaiter(void 0, void 0, void 0, function* () {
187
- var _g, _h, _j;
187
+ var _g, _h, _j, _k;
188
188
  setBeforeCreateError(undefined);
189
189
  if (!shipment) return;
190
190
  const preferredRates = preferredRatesResponse === null || preferredRatesResponse === void 0 ? void 0 : preferredRatesResponse.map(r => r.rate);
@@ -192,17 +192,35 @@ const useRatesForm = ({
192
192
  if (rate) {
193
193
  try {
194
194
  const beforePurchaseResponse = yield onBeforeLabelCreate === null || onBeforeLabelCreate === void 0 ? void 0 : onBeforeLabelCreate(rate, shipment);
195
- if (!beforePurchaseResponse || Object.keys(beforePurchaseResponse).length === 0) {
196
- yield purchaseLabel(rateId, shipment, rate, servicePoint);
197
- return;
198
- }
199
- // The user has selected a house rate that requires some type of set up to happen before purchase.
200
- // For white label this would be a user has selected a house account UPS ground saver rate and needs to register and
201
- // re-rate their shipment to get a real rate. If its successful, we'll purchase a label with the new rate.
202
- if (beforePurchaseResponse.error) {
195
+ // If the callback has returned an error, abort label purchase
196
+ if (beforePurchaseResponse === null || beforePurchaseResponse === void 0 ? void 0 : beforePurchaseResponse.error) {
203
197
  resetRates();
204
198
  throw new Error(beforePurchaseResponse.error.message);
205
- } else if (beforePurchaseResponse.rate && !beforePurchaseResponse.error) {
199
+ }
200
+ let updatedShipment;
201
+ if (beforePurchaseResponse === null || beforePurchaseResponse === void 0 ? void 0 : beforePurchaseResponse.labelMessages) {
202
+ // The callback has returned custom label messages to be added to the shipment.
203
+ // Merge those messages in with the shipment
204
+ updatedShipment = Object.assign(Object.assign({}, shipment), {
205
+ packages: (_h = shipment.packages) === null || _h === void 0 ? void 0 : _h.map(pkg => Object.assign(Object.assign({}, pkg), {
206
+ labelMessages: beforePurchaseResponse.labelMessages
207
+ }))
208
+ });
209
+ }
210
+ if (updatedShipment) {
211
+ // The shipment needs to be updated before purchase
212
+ try {
213
+ yield updateShipment(Object.assign(Object.assign({}, updatedShipment), {
214
+ shipDate: date.isNowOrInTheFuture(updatedShipment.shipDate) ? updatedShipment.shipDate : undefined
215
+ }));
216
+ } catch (_l) {
217
+ throw new Error("Unable to update shipment before creating label.");
218
+ }
219
+ }
220
+ if (beforePurchaseResponse === null || beforePurchaseResponse === void 0 ? void 0 : beforePurchaseResponse.rate) {
221
+ // The user has selected a house rate that requires some type of set up to happen before purchase.
222
+ // For white label this would be a user has selected a house account UPS ground saver rate and needs to register and
223
+ // re-rate their shipment to get a real rate. If its successful, we'll purchase a label with the new rate.
206
224
  const _rate = beforePurchaseResponse.rate;
207
225
  const totalRateAmount = rates.getTotalRateAmount(_rate);
208
226
  if (!fundingOrigin) throw new Error("Unable to find balance");
@@ -213,24 +231,27 @@ const useRatesForm = ({
213
231
  });
214
232
  throw new Error("Insufficient funds. Please add funds before purchasing and try again.");
215
233
  } else {
216
- yield purchaseLabel(_rate.rateId, shipment, _rate, servicePoint);
234
+ yield purchaseLabel(_rate.rateId, updatedShipment !== null && updatedShipment !== void 0 ? updatedShipment : shipment, _rate, servicePoint);
217
235
  return;
218
236
  }
219
237
  }
238
+ // The user has selected a standard rate and no further action is required before purchase
239
+ yield purchaseLabel(rateId, shipment, rate, servicePoint);
240
+ return;
220
241
  } catch (e) {
221
242
  if (Array.isArray(e)) {
222
243
  if (e[0] instanceof reactApi.SE.CodedError) setBeforeCreateError(e[0]);else setBeforeCreateError({
223
244
  errorCode: "unknown",
224
245
  errorSource: "client",
225
246
  errorType: "unknown",
226
- message: (_h = e[0].message) !== null && _h !== void 0 ? _h : "An unknown error occurred"
247
+ message: (_j = e[0].message) !== null && _j !== void 0 ? _j : "An unknown error occurred"
227
248
  });
228
249
  } else {
229
250
  if (e instanceof reactApi.SE.CodedError) setBeforeCreateError(e);else setBeforeCreateError({
230
251
  errorCode: "unknown",
231
252
  errorSource: "client",
232
253
  errorType: "unknown",
233
- message: (_j = e.message) !== null && _j !== void 0 ? _j : "An unknown error occurred"
254
+ message: (_k = e.message) !== null && _k !== void 0 ? _k : "An unknown error occurred"
234
255
  });
235
256
  }
236
257
  return;
@@ -238,7 +259,8 @@ const useRatesForm = ({
238
259
  }
239
260
  }), [fundingOrigin, handleSave, onBeforeLabelCreate, preferredRatesResponse, purchaseLabel, ratesResponse === null || ratesResponse === void 0 ? void 0 : ratesResponse.rates, resetRates, shipment]);
240
261
  let errors = [...(ratesErrors !== null && ratesErrors !== void 0 ? ratesErrors : []), ...((_b = ratesResponse === null || ratesResponse === void 0 ? void 0 : ratesResponse.errors) !== null && _b !== void 0 ? _b : [])];
241
- if (beforeCreateError) errors = [...errors, beforeCreateError];
262
+ let labelErrors = createLabelErrors !== null && createLabelErrors !== void 0 ? createLabelErrors : [];
263
+ if (beforeCreateError) labelErrors = [...labelErrors, beforeCreateError];
242
264
  if (beforeSaveError) errors = [...errors, beforeSaveError];
243
265
  // Sometimes no rates are returned and no top-level errors are returned
244
266
  // but there are invalid rates with errors. This will filter out duplicate error messages and expose those to the user
@@ -259,7 +281,7 @@ const useRatesForm = ({
259
281
  scrubber: React.useCallback(() => "common:errorMessages.noRatesAvailable", [])
260
282
  });
261
283
  const displayableLabelErrors = useScrubErrors.useScrubErrors({
262
- errors: labelErrors !== null && labelErrors !== void 0 ? labelErrors : undefined,
284
+ errors: labelErrors,
263
285
  scrubber: React.useCallback(e => {
264
286
  if (e.message.includes("The ship from email is required") || e.message.includes("The ship to email is required")) return "common:errorMessages.emailIsRequired";
265
287
  return e.message.replace(/Exception with code \w+; module \d+, category \d+, item \d+/g, "");
@@ -74,7 +74,6 @@ const Component = _a => {
74
74
  externalOrderNumber,
75
75
  externalShipmentId,
76
76
  onLoad,
77
- onShipmentUpdated,
78
77
  orderSourceCode,
79
78
  salesOrderId,
80
79
  shipFromAddresses,
@@ -36,6 +36,7 @@ const useShipmentsGrid = ({
36
36
  pageSize,
37
37
  pagerProps
38
38
  } = usePager.usePager(PAGE_SIZE);
39
+ const [activeShipmentId, setActiveShipmentId] = React.useState();
39
40
  const [filters, setFilters] = React.useState(initialFilters);
40
41
  const clearAllFilters = () => {
41
42
  setFilters(initialFilters);
@@ -69,8 +70,9 @@ const useShipmentsGrid = ({
69
70
  }, createdDateValue.getCreatedDateFilterValue((_b = (_a = filters.createdDate) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.start, (_d = (_c = filters.createdDate) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.end)));
70
71
  const shipments = React.useMemo(() => data === null || data === void 0 ? void 0 : data.shipments.map(shipment => Object.assign(Object.assign({}, shipment), {
71
72
  disableOnRowClick: shipment.shipmentStatus === "cancelled",
73
+ isLoading: activeShipmentId === shipment.shipmentId,
72
74
  serviceName: getServiceName(shipment)
73
- })), [data === null || data === void 0 ? void 0 : data.shipments, getServiceName]);
75
+ })), [activeShipmentId, data === null || data === void 0 ? void 0 : data.shipments, getServiceName]);
74
76
  const {
75
77
  data: shipmentById,
76
78
  error: shipmentErrors,
@@ -111,6 +113,7 @@ const useShipmentsGrid = ({
111
113
  if (shipmentFilteredById) {
112
114
  return [Object.assign(Object.assign({}, shipmentFilteredById), {
113
115
  disableOnRowClick: shipmentFilteredById.shipmentStatus === "cancelled",
116
+ isLoading: activeShipmentId === shipmentFilteredById.shipmentId,
114
117
  serviceName: getServiceName(shipmentFilteredById)
115
118
  })];
116
119
  } else if (shipmentFilteredByIdHasErrors) {
@@ -135,6 +138,7 @@ const useShipmentsGrid = ({
135
138
  showPagination: shipmentFilteredById ? false : ((data === null || data === void 0 ? void 0 : data.total) || 0) > pageSize,
136
139
  totalElements: shipmentFilteredById ? 1 : (data === null || data === void 0 ? void 0 : data.total) || 0
137
140
  },
141
+ setActiveShipmentId,
138
142
  setFilters: onSetFilters,
139
143
  shipments,
140
144
  shouldShowFilters: isAnyFilterEnabled
@@ -2,6 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var tslib = require('tslib');
5
6
  var jsxRuntime = require('@emotion/react/jsx-runtime');
6
7
  var useSortableQuery = require('../../hooks/use-sortable-query.cjs');
7
8
  var React = require('react');
@@ -45,18 +46,18 @@ var errorFallback = require('../../components/error-fallback/error-fallback.cjs'
45
46
  * @see {@link ShipmentsGrid.Element | The **Element** created to render `<ShipmentsGrid />`}
46
47
  */
47
48
  const Component = ({
48
- onRowClick,
49
+ onRowClick: onRowClickProp,
49
50
  onClickCancelShipment,
50
51
  shipmentStatus,
51
52
  showShipmentIdFilter: _showShipmentIdFilter = true,
52
53
  showCreatedDateFilter: _showCreatedDateFilter = true
53
54
  }) => {
54
- const {
55
- t
56
- } = reactI18next.useTranslation(["common", "list-shipments"]);
57
55
  const {
58
56
  globalFeatures
59
57
  } = elementsContextProvider.useElements();
58
+ const {
59
+ t
60
+ } = reactI18next.useTranslation(["common", "list-shipments"]);
60
61
  const {
61
62
  toggleSort,
62
63
  sortState
@@ -73,7 +74,8 @@ const Component = ({
73
74
  getGridData,
74
75
  isAnyFilterActive,
75
76
  shouldShowFilters,
76
- clearAllFilters
77
+ clearAllFilters,
78
+ setActiveShipmentId
77
79
  } = useShipmentsGrid.useShipmentsGrid({
78
80
  shipmentStatus,
79
81
  showCreatedDateFilter: _showCreatedDateFilter,
@@ -81,6 +83,11 @@ const Component = ({
81
83
  sortBy: sortState.by,
82
84
  sortDir: sortState.dir
83
85
  });
86
+ const onRowClick = shipment => tslib.__awaiter(void 0, void 0, void 0, function* () {
87
+ setActiveShipmentId(shipment.shipmentId);
88
+ yield onRowClickProp === null || onRowClickProp === void 0 ? void 0 : onRowClickProp(shipment);
89
+ setActiveShipmentId(undefined);
90
+ });
84
91
  const handleCreatedDateSort = () => {
85
92
  toggleSort("created_at");
86
93
  };
@@ -7,6 +7,7 @@ var useHelpers = require('./use-helpers.cjs');
7
7
  var useConfigureShipment = require('./use-configure-shipment.cjs');
8
8
  var useImportSalesOrder = require('./use-import-sales-order.cjs');
9
9
  var useBalanceServices = require('./use-balance-services.cjs');
10
+ var useRootPortal = require('./use-root-portal.cjs');
10
11
 
11
12
 
12
13
 
@@ -15,3 +16,5 @@ exports.useHelpers = useHelpers.useHelpers;
15
16
  exports.useConfigureShipment = useConfigureShipment.useConfigureShipment;
16
17
  exports.useImportSalesOrder = useImportSalesOrder.useImportSalesOrder;
17
18
  exports.useBalanceServices = useBalanceServices.useBalanceServices;
19
+ exports.RootPortalProvider = useRootPortal.RootPortalProvider;
20
+ exports.useRootPortal = useRootPortal.useRootPortal;
@@ -3,7 +3,6 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tslib = require('tslib');
6
- var reactQuery = require('@tanstack/react-query');
7
6
  var address = require('../utilities/shipengine/address.cjs');
8
7
  var salesOrder = require('../utilities/shipengine/sales-order.cjs');
9
8
  var shipment = require('../utilities/shipengine/shipment.cjs');
@@ -13,7 +12,6 @@ var reactApi = require('@shipengine/react-api');
13
12
  var useImportSalesOrder = require('./use-import-sales-order.cjs');
14
13
 
15
14
  const useConfigureShipment = ({
16
- onShipmentUpdated,
17
15
  onLoad,
18
16
  errorWhenShipmentCancelled: _errorWhenShipmentCancelled = false,
19
17
  externalOrderId,
@@ -26,7 +24,6 @@ const useConfigureShipment = ({
26
24
  warehouseId,
27
25
  useWarehouses: _useWarehouses = true
28
26
  }) => {
29
- const queryClient = reactQuery.useQueryClient();
30
27
  // Queue of incomplete requirement keys (i.e., Ship From addresses, Warehouses, Carriers)
31
28
  const incompleteRequirementsKeys = React.useMemo(() => [], []);
32
29
  const {
@@ -54,10 +51,6 @@ const useConfigureShipment = ({
54
51
  orderSourceCode,
55
52
  salesOrderId
56
53
  });
57
- const {
58
- error: updateShipmentErrors,
59
- mutate: updateShipment
60
- } = reactApi.useUpdateSalesOrderShipment();
61
54
  const {
62
55
  data: newV1Shipment,
63
56
  mutateAsync: createV1Shipment,
@@ -161,25 +154,6 @@ const useConfigureShipment = ({
161
154
  }
162
155
  }
163
156
  }), [createSalesOrderShipment, createV1Shipment, creatingSalesOrderShipment, creatingV1Shipment, defaultShipFromAddress, defaultWarehouse, externalOrderId, externalOrderNumber, externalShipmentId, incompleteRequirementsKeys, isExternalShipmentFetching, isExternalShipmentInitialLoading, isFetchingWarehouses, isInitialLoadingWarehouses, labelPurchasedSalesOrderShipment, listSalesOrderShipmentsInitiallyLoading, listSalesOrderShipmentsIsFetching, orderSourceCode, pendingSalesOrderShipment, refetchSalesOrderShipments, salesOrder$1, salesOrderId, salesOrderShipmentCreated, shipFromAddresses === null || shipFromAddresses === void 0 ? void 0 : shipFromAddresses.length, shipmentId, _useWarehouses, v1shipmentCreated, warehouseId, warehouses$1]);
164
- /**
165
- * Update a shipment with deprecated customs items. Move items to the products array on the Shipment's packages array
166
- *
167
- * Invalidate useGetShipment's cache
168
- */
169
- const formatCustoms = React.useCallback(shipment$1 => {
170
- const formattedShipment = shipment.moveCustomsItemsToProducts(shipment$1);
171
- updateShipment(formattedShipment, {
172
- onSuccess(data) {
173
- void (onShipmentUpdated === null || onShipmentUpdated === void 0 ? void 0 : onShipmentUpdated(data));
174
- void queryClient.invalidateQueries(["useListSalesOrderShipments", {
175
- shipmentId: data.shipmentId
176
- }], {
177
- exact: false
178
- } // Invalidate queries with similar keys
179
- );
180
- }
181
- });
182
- }, [onShipmentUpdated, queryClient, updateShipment]);
183
157
  const refetchPendingSalesOrderShipments = React.useCallback(() => tslib.__awaiter(void 0, void 0, void 0, function* () {
184
158
  const {
185
159
  data: shipments
@@ -192,13 +166,6 @@ const useConfigureShipment = ({
192
166
  yield handleShipmentCreation();
193
167
  }))();
194
168
  }, [shipmentId, externalShipmentId, salesOrderId, salesOrder$1, warehouses$1, warehouseId, handleShipmentCreation]);
195
- // useEffect to handle formating customs
196
- React.useEffect(() => {
197
- var _a, _b;
198
- if ((_b = (_a = pendingSalesOrderShipment === null || pendingSalesOrderShipment === void 0 ? void 0 : pendingSalesOrderShipment.customs) === null || _a === void 0 ? void 0 : _a.customsItems) === null || _b === void 0 ? void 0 : _b.length) {
199
- formatCustoms(pendingSalesOrderShipment);
200
- }
201
- }, [formatCustoms, pendingSalesOrderShipment]);
202
169
  // useEffect to check and run the onLoad prop
203
170
  React.useEffect(() => {
204
171
  if ((salesOrderShipments === null || salesOrderShipments === void 0 ? void 0 : salesOrderShipments.length) && salesOrderShipments.every(s => s.shipmentStatus === "label_purchased")) {
@@ -210,7 +177,7 @@ const useConfigureShipment = ({
210
177
  if (isInitialLoadingCarriers || isFetchingCarriers) return;
211
178
  if ((carriers === null || carriers === void 0 ? void 0 : carriers.length) === 0) incompleteRequirementsKeys.push("no_carriers");
212
179
  }, [carriers, incompleteRequirementsKeys, isFetchingCarriers, isInitialLoadingCarriers]);
213
- 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 : []), ...(updateShipmentErrors !== null && updateShipmentErrors !== void 0 ? updateShipmentErrors : []), ...(_errorWhenShipmentCancelled && cancelledShipment ? [new reactApi.CodedError("shipment_cancelled", {
180
+ 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", {
214
181
  errorCode: "invalid_status",
215
182
  errorSource: "elements",
216
183
  errorType: "business_rules"
package/cjs/index.cjs CHANGED
@@ -28,6 +28,7 @@ var useHelpers = require('./hooks/use-helpers.cjs');
28
28
  var useConfigureShipment = require('./hooks/use-configure-shipment.cjs');
29
29
  var useImportSalesOrder = require('./hooks/use-import-sales-order.cjs');
30
30
  var useBalanceServices = require('./hooks/use-balance-services.cjs');
31
+ var useRootPortal = require('./hooks/use-root-portal.cjs');
31
32
  var canadaDdp = require('./types/canada-ddp.cjs');
32
33
  var pudo = require('./types/pudo.cjs');
33
34
  var onboarding = require('./workflows/onboarding/onboarding.cjs');
@@ -37,6 +38,7 @@ var connectExternalCarrier = require('./workflows/connect-external-carrier/conne
37
38
  var elementsContextProvider = require('./elements-provider/elements-context-provider.cjs');
38
39
  var elementsProvider = require('./elements-provider/elements-provider.cjs');
39
40
  var elementsTestProvider = require('./elements-provider/elements-test-provider.cjs');
41
+ var createElement = require('./create-element/create-element.cjs');
40
42
 
41
43
 
42
44
 
@@ -79,6 +81,8 @@ exports.useHelpers = useHelpers.useHelpers;
79
81
  exports.useConfigureShipment = useConfigureShipment.useConfigureShipment;
80
82
  exports.useImportSalesOrder = useImportSalesOrder.useImportSalesOrder;
81
83
  exports.useBalanceServices = useBalanceServices.useBalanceServices;
84
+ exports.RootPortalProvider = useRootPortal.RootPortalProvider;
85
+ exports.useRootPortal = useRootPortal.useRootPortal;
82
86
  Object.defineProperty(exports, 'CanadaDeliveredDutyOptions', {
83
87
  enumerable: true,
84
88
  get: function () { return canadaDdp.CanadaDeliveredDutyOptions; }
@@ -96,6 +100,7 @@ exports.ElementsContextProvider = elementsContextProvider.ElementsContextProvide
96
100
  exports.useElements = elementsContextProvider.useElements;
97
101
  exports.ElementsProvider = elementsProvider.ElementsProvider;
98
102
  exports.ElementsTestProvider = elementsTestProvider.ElementsTestProvider;
103
+ exports.createElement = createElement.createElement;
99
104
  Object.keys(reactApi).forEach(function (k) {
100
105
  if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
101
106
  enumerable: true,
@@ -222,7 +222,8 @@ var common = {
222
222
  shipmentId: "Shipment ID",
223
223
  labelId: "Label ID",
224
224
  labelIdFilter: "{{name}}: {{labelId}}",
225
- filteredTrackingStatus: "Delivery Status: {{filter}}",
225
+ filteredStatus: "{{name}}: {{filter}}",
226
+ filteredTrackingStatus: "{{name}}: {{filter}}",
226
227
  more: ", +{{count}} more",
227
228
  createdDate: "Created Date",
228
229
  shipmentIdFilter: "{{name}}: {{shipmentId}}",
@@ -35,7 +35,8 @@ var purchaseLabel = {
35
35
  results: "No results returned"
36
36
  },
37
37
  fields: {
38
- "requires-additional-handling": "This package requires <Link>additional handling</Link>",
38
+ "requires-additional-handling-link": "This package requires <Link>additional handling</Link>",
39
+ "requires-additional-handling": "This package requires additional handling",
39
40
  addOns: "Add-Ons",
40
41
  contentDescription: "Contents Description",
41
42
  confirmation: "Delivery Confirmation",
package/cjs/package.cjs CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = "2.22.0";
5
+ var version = "2.23.0";
6
6
 
7
7
  exports.version = version;
@@ -56,7 +56,6 @@ const Component = _a => {
56
56
  carriers
57
57
  } = useConfigureShipment.useConfigureShipment(Object.assign(Object.assign({}, _multiplexedId), {
58
58
  onLoad: onLoad,
59
- onShipmentUpdated: onShipmentUpdated,
60
59
  shipFromAddresses,
61
60
  useWarehouses: (_b = propFeatures === null || propFeatures === void 0 ? void 0 : propFeatures.shipmentForm) === null || _b === void 0 ? void 0 : _b.useWarehouses,
62
61
  warehouseId
@@ -69,7 +69,7 @@ const GridController = ({
69
69
  children: filters
70
70
  })), data.length === 0 && emptyContent ? emptyContent : jsx(Table, Object.assign({
71
71
  "data-testid": "grid",
72
- footer: footerContent && jsx(TableFooter, Object.assign({
72
+ footer: footerContent && !_isLoading && jsx(TableFooter, Object.assign({
73
73
  css: styles.tableFooter
74
74
  }, {
75
75
  children: footerContent
@@ -94,29 +94,43 @@ const GridController = ({
94
94
  outerWrapperStyles: styles.tableWrapper,
95
95
  tableStyles: styles.table
96
96
  }, {
97
- children: jsxs(TableBody, {
98
- children: [_isLoading && loadingRows, data.map((row, index) => {
97
+ children: jsx(TableBody, {
98
+ children: _isLoading ? loadingRows : data.map((row, rowIndex) => {
99
99
  var _a;
100
- const allowOnClick = !!onRowClick && !(row === null || row === void 0 ? void 0 : row.disableOnRowClick);
100
+ const allowOnClick = !!onRowClick && !(row === null || row === void 0 ? void 0 : row.disableOnRowClick) || !row.isLoading;
101
101
  return jsxs(TableRow, Object.assign({
102
+ css: row.isLoading && styles.skeletonTableRow,
102
103
  "data-testid": "grid-row",
103
- onClick: allowOnClick ? () => onRowClick(row) : undefined,
104
- withHover: !(row === null || row === void 0 ? void 0 : row.disableOnRowClick)
104
+ onClick: allowOnClick ? () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row) : undefined,
105
+ withHover: allowOnClick
105
106
  }, {
106
107
  children: [_useCheckboxes && jsx(TableBodyCell, Object.assign({
107
108
  css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
108
109
  }, {
109
110
  children: jsx(Checkbox, {
110
- checked: (_a = isChecked[index]) !== null && _a !== void 0 ? _a : false,
111
- onChange: () => toggleCheckbox(index)
111
+ checked: (_a = isChecked[rowIndex]) !== null && _a !== void 0 ? _a : false,
112
+ onChange: () => toggleCheckbox(rowIndex)
112
113
  })
113
- })), columns.filter(column => column.renderCellContent).map((column, index) => jsx(TableBodyCell, Object.assign({
114
- css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
115
- }, {
116
- children: column.renderCellContent(row)
117
- }), index))]
118
- }), index);
119
- })]
114
+ })), columns.filter(column => column.renderCellContent).map((column, index) => {
115
+ if (row.isLoading) {
116
+ return jsx(TableBodyCell, Object.assign({
117
+ css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
118
+ }, {
119
+ children: jsx(Skeleton, {
120
+ animation: SkeletonAnimation.WAVE,
121
+ height: 24,
122
+ variant: SkeletonVariant.RECT
123
+ })
124
+ }), index);
125
+ }
126
+ return jsx(TableBodyCell, Object.assign({
127
+ css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
128
+ }, {
129
+ children: column.renderCellContent(row)
130
+ }), index);
131
+ })]
132
+ }), rowIndex);
133
+ })
120
134
  })
121
135
  }))]
122
136
  }));
@@ -1,4 +1,5 @@
1
1
  export { ShipmentIdFilter } from './shipment-id-filter/shipment-id-filter.js';
2
2
  export { CreatedDateFilter } from './created-date-filter/created-date-filter.js';
3
3
  export { LabelIdFilter } from './label-id-filter/label-id-filter.js';
4
+ export { LabelStatusFilter } from './label-status-filter/label-status-filter.js';
4
5
  export { TrackingStatusFilter } from './tracking-status-filter/tracking-status-filter.js';
@@ -0,0 +1 @@
1
+ export { LabelStatusFilter } from './label-status-filter.js';
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+
3
+ const labelStatusFormSchema = z.object({
4
+ labelStatus: z.union([z.literal("completed"), z.literal("error"), z.literal("processing"), z.literal("voided"), z.literal("") // Empty string for no selection
5
+ ])
6
+ });
7
+
8
+ export { labelStatusFormSchema };
@@ -0,0 +1,170 @@
1
+ import { jsxs, Fragment, jsx } from '@emotion/react/jsx-runtime';
2
+ import { validationResolver } from '../../../../utilities/validation.js';
3
+ import { useState, useRef, useCallback, useEffect } from 'react';
4
+ import { useForm } from 'react-hook-form';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { useToggle } from 'react-use';
7
+ import { Button, ButtonVariant, Icon, IconSize, Popover, RadioGroup, Radio } from '@shipengine/giger';
8
+ import { IconNames } from '@shipengine/giger-theme';
9
+ import { labelStatusFormSchema } from './label-status-filter-schema.js';
10
+ import { styles } from './label-status-filter.styles.js';
11
+
12
+ /**
13
+ * @internal
14
+ *
15
+ * # StatusFilter
16
+ *
17
+ * - The `<StatusFilter />` component handles the label status filter used in Labels Grid.
18
+ *
19
+ * @see {@link StatusFilterProps | The props for the `<StatusFilter />` component}
20
+ */
21
+ const LabelStatusFilter = ({
22
+ disabled: _disabled = false,
23
+ filters,
24
+ onFiltersUpdated
25
+ }) => {
26
+ var _a, _b, _c, _d, _e;
27
+ const {
28
+ t
29
+ } = useTranslation();
30
+ const [showLabelStatusFilter, toggleLabelStatusFilter] = useToggle(false);
31
+ const [buttonText, setButtonText] = useState(((_a = filters === null || filters === void 0 ? void 0 : filters.status) === null || _a === void 0 ? void 0 : _a.nickname) || t("list-labels:headers.status"));
32
+ const buttonRef = useRef(null);
33
+ const form = useForm({
34
+ defaultValues: {
35
+ labelStatus: ""
36
+ },
37
+ resolver: validationResolver(labelStatusFormSchema)
38
+ });
39
+ const determineButtonText = useCallback(status => {
40
+ var _a, _b;
41
+ if (!status) {
42
+ return ((_a = filters === null || filters === void 0 ? void 0 : filters.status) === null || _a === void 0 ? void 0 : _a.nickname) || t("list-labels:headers.status");
43
+ }
44
+ return t("common:grid.filteredStatus", {
45
+ filter: t(`list-labels:status.${status}`),
46
+ name: ((_b = filters === null || filters === void 0 ? void 0 : filters.status) === null || _b === void 0 ? void 0 : _b.nickname) || t("list-labels:headers.status")
47
+ });
48
+ }, [t, (_b = filters === null || filters === void 0 ? void 0 : filters.status) === null || _b === void 0 ? void 0 : _b.nickname]);
49
+ useEffect(() => {
50
+ var _a;
51
+ // keep form in sync with filters
52
+ if ((_a = filters.status) === null || _a === void 0 ? void 0 : _a.value) {
53
+ form.reset({
54
+ labelStatus: filters.status.value
55
+ });
56
+ setButtonText(determineButtonText(filters.status.value));
57
+ } else {
58
+ // Reset to default when filter value is empty
59
+ form.reset({
60
+ labelStatus: ""
61
+ });
62
+ }
63
+ }, [determineButtonText, (_c = filters.status) === null || _c === void 0 ? void 0 : _c.value, form]);
64
+ const onClearFilters = useCallback(() => {
65
+ onFiltersUpdated(Object.assign(Object.assign({}, filters), {
66
+ status: Object.assign(Object.assign({}, filters.status), {
67
+ enabled: true,
68
+ value: ""
69
+ })
70
+ }));
71
+ // Reset the form
72
+ form.reset({
73
+ labelStatus: ""
74
+ });
75
+ showLabelStatusFilter && toggleLabelStatusFilter();
76
+ }, [filters, onFiltersUpdated, showLabelStatusFilter, toggleLabelStatusFilter, form]);
77
+ const handleRadioChange = e => {
78
+ const value = e.target.value;
79
+ form.setValue("labelStatus", value);
80
+ onFiltersUpdated(Object.assign(Object.assign({}, filters), {
81
+ status: Object.assign(Object.assign({}, filters.status), {
82
+ enabled: true,
83
+ value
84
+ })
85
+ }));
86
+ };
87
+ const watchedValue = form.watch("labelStatus");
88
+ const isRadioSelected = watchedValue !== undefined && watchedValue !== "";
89
+ return jsxs(Fragment, {
90
+ children: [jsxs(Button, Object.assign({
91
+ disabled: _disabled,
92
+ onClick: toggleLabelStatusFilter,
93
+ ref: buttonRef,
94
+ variant: ButtonVariant.TEXT
95
+ }, {
96
+ children: [isRadioSelected ? jsx("span", {
97
+ children: buttonText
98
+ }) : jsx("span", {
99
+ children: (_e = (_d = filters === null || filters === void 0 ? void 0 : filters.status) === null || _d === void 0 ? void 0 : _d.nickname) !== null && _e !== void 0 ? _e : t("list-labels:headers.status")
100
+ }), isRadioSelected ?
101
+ // Show Close Icon
102
+ jsx(Icon, {
103
+ "aria-label": t("common:grid.clear"),
104
+ name: IconNames.CLOSE,
105
+ onClick: e => {
106
+ e.stopPropagation();
107
+ onClearFilters();
108
+ },
109
+ onKeyDown: e => {
110
+ if (e.key === "Enter" || e.key === " ") {
111
+ e.stopPropagation();
112
+ onClearFilters();
113
+ }
114
+ },
115
+ role: "button",
116
+ size: IconSize.SIZE_SMALL,
117
+ tabIndex: 0
118
+ }) : showLabelStatusFilter ? jsx(Icon, {
119
+ name: IconNames.CARET_TOP,
120
+ size: IconSize.SIZE_SMALL
121
+ }) : jsx(Icon, {
122
+ name: IconNames.CARET_BOTTOM,
123
+ size: IconSize.SIZE_SMALL
124
+ })]
125
+ })), jsx(Popover, Object.assign({
126
+ isOpen: showLabelStatusFilter,
127
+ onClickAway: toggleLabelStatusFilter,
128
+ reference: buttonRef.current
129
+ }, {
130
+ children: jsxs("form", {
131
+ children: [jsxs(RadioGroup, Object.assign({
132
+ css: styles.radioGroup,
133
+ name: "status",
134
+ onChange: handleRadioChange,
135
+ value: watchedValue
136
+ }, {
137
+ children: [jsx(Radio, Object.assign({
138
+ value: "completed"
139
+ }, {
140
+ children: t("list-labels:status.completed")
141
+ })), jsx(Radio, Object.assign({
142
+ value: "error"
143
+ }, {
144
+ children: t("list-labels:status.error")
145
+ })), jsx(Radio, Object.assign({
146
+ value: "processing"
147
+ }, {
148
+ children: t("list-labels:status.processing")
149
+ })), jsx(Radio, Object.assign({
150
+ value: "voided"
151
+ }, {
152
+ children: t("list-labels:status.voided")
153
+ }))]
154
+ })), isRadioSelected && jsx("div", Object.assign({
155
+ css: styles.buttons
156
+ }, {
157
+ children: jsx(Button, Object.assign({
158
+ disabled: !isRadioSelected,
159
+ onClick: onClearFilters,
160
+ variant: ButtonVariant.OUTLINED
161
+ }, {
162
+ children: t("common:grid.clear")
163
+ }))
164
+ }))]
165
+ })
166
+ }))]
167
+ });
168
+ };
169
+
170
+ export { LabelStatusFilter };