@shipengine/elements 2.21.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 (129) hide show
  1. package/cjs/components/grid-controller/grid-controller.cjs +49 -17
  2. package/cjs/components/grid-controller/grid-controller.styles.cjs +7 -2
  3. package/cjs/components/grid-controller/grid-footer.cjs +30 -15
  4. package/cjs/components/grid-controller/grid-footer.styles.cjs +24 -0
  5. package/cjs/components/grid-controller/index.cjs +1 -1
  6. package/cjs/components/grid-controller/sortable-header/index.cjs +9 -0
  7. package/cjs/components/grid-controller/{sortable-header.cjs → sortable-header/sortable-header.cjs} +3 -5
  8. package/cjs/components/grid-controller/sortable-header/sortable-header.styles.cjs +18 -0
  9. package/cjs/components/grid-filters/components/created-date-filter/created-date-filter.cjs +3 -0
  10. package/cjs/components/grid-filters/components/index.cjs +2 -0
  11. package/cjs/components/grid-filters/components/label-id-filter/label-id-filter.cjs +2 -0
  12. package/cjs/components/grid-filters/components/label-status-filter/index.cjs +9 -0
  13. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter-schema.cjs +12 -0
  14. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.cjs +174 -0
  15. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.styles.cjs +21 -0
  16. package/cjs/components/grid-filters/components/shipment-id-filter/shipment-id-filter.cjs +2 -0
  17. package/cjs/components/grid-filters/components/tracking-status-filter/tracking-status-filter.cjs +23 -12
  18. package/cjs/components/grid-filters/grid-filters.cjs +12 -1
  19. package/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +78 -31
  20. package/cjs/elements/labels-grid/hooks/use-tracking-status-filter.cjs +109 -0
  21. package/cjs/elements/labels-grid/labels-grid.cjs +56 -30
  22. package/cjs/elements/purchase-label/components/customs-forms/customs-forms.cjs +10 -3
  23. package/cjs/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.cjs +22 -14
  24. package/cjs/elements/purchase-label/components/rate-form/rate-form.cjs +1 -1
  25. package/cjs/elements/purchase-label/components/rate-form/rate-view.cjs +4 -9
  26. package/cjs/elements/purchase-label/components/shipment-form/shipment-form.cjs +11 -5
  27. package/cjs/elements/purchase-label/configure-shipment.cjs +3 -1
  28. package/cjs/elements/purchase-label/hooks/use-rates-form.cjs +38 -16
  29. package/cjs/elements/purchase-label/purchase-label.cjs +0 -1
  30. package/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +11 -6
  31. package/cjs/elements/shipments-grid/shipments-grid.cjs +67 -28
  32. package/cjs/hooks/index.cjs +3 -0
  33. package/cjs/hooks/use-configure-shipment.cjs +1 -34
  34. package/cjs/hooks/use-sortable-query.cjs +36 -0
  35. package/cjs/index.cjs +5 -0
  36. package/cjs/locales/en/common.cjs +3 -1
  37. package/cjs/locales/en/purchase-label.cjs +2 -1
  38. package/cjs/package.cjs +1 -1
  39. package/cjs/utilities/feature-flags/feature-flags.cjs +1 -1
  40. package/cjs/workflows/label-workflow/label-workflow.cjs +0 -1
  41. package/esm/components/grid-controller/grid-controller.js +51 -19
  42. package/esm/components/grid-controller/grid-controller.styles.js +7 -2
  43. package/esm/components/grid-controller/grid-footer.js +32 -17
  44. package/esm/components/grid-controller/grid-footer.styles.js +20 -0
  45. package/esm/components/grid-controller/index.js +1 -1
  46. package/esm/components/grid-controller/sortable-header/index.js +1 -0
  47. package/esm/components/grid-controller/{sortable-header.js → sortable-header/sortable-header.js} +3 -5
  48. package/esm/components/grid-controller/sortable-header/sortable-header.styles.js +14 -0
  49. package/esm/components/grid-filters/components/created-date-filter/created-date-filter.js +3 -0
  50. package/esm/components/grid-filters/components/index.js +1 -0
  51. package/esm/components/grid-filters/components/label-id-filter/label-id-filter.js +2 -0
  52. package/esm/components/grid-filters/components/label-status-filter/index.js +1 -0
  53. package/esm/components/grid-filters/components/label-status-filter/label-status-filter-schema.js +8 -0
  54. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.js +170 -0
  55. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.styles.js +17 -0
  56. package/esm/components/grid-filters/components/shipment-id-filter/shipment-id-filter.js +2 -0
  57. package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js +23 -12
  58. package/esm/components/grid-filters/grid-filters.js +12 -1
  59. package/esm/elements/labels-grid/hooks/use-labels-grid.js +79 -32
  60. package/esm/elements/labels-grid/hooks/use-tracking-status-filter.js +105 -0
  61. package/esm/elements/labels-grid/labels-grid.js +57 -31
  62. package/esm/elements/purchase-label/components/customs-forms/customs-forms.js +10 -3
  63. package/esm/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.js +22 -14
  64. package/esm/elements/purchase-label/components/rate-form/rate-form.js +1 -1
  65. package/esm/elements/purchase-label/components/rate-form/rate-view.js +4 -9
  66. package/esm/elements/purchase-label/components/shipment-form/shipment-form.js +11 -5
  67. package/esm/elements/purchase-label/configure-shipment.js +3 -1
  68. package/esm/elements/purchase-label/hooks/use-rates-form.js +38 -16
  69. package/esm/elements/purchase-label/purchase-label.js +0 -1
  70. package/esm/elements/shipments-grid/hooks/use-shipments-grid.js +11 -6
  71. package/esm/elements/shipments-grid/shipments-grid.js +68 -29
  72. package/esm/hooks/index.js +1 -0
  73. package/esm/hooks/use-configure-shipment.js +3 -36
  74. package/esm/hooks/use-sortable-query.js +32 -0
  75. package/esm/index.js +2 -0
  76. package/esm/locales/en/common.js +3 -1
  77. package/esm/locales/en/purchase-label.js +2 -1
  78. package/esm/package.js +1 -1
  79. package/esm/utilities/feature-flags/feature-flags.js +1 -1
  80. package/esm/workflows/label-workflow/label-workflow.js +0 -1
  81. package/package.json +15 -4
  82. package/types/src/components/grid-controller/grid-controller.d.ts +4 -1
  83. package/types/src/components/grid-controller/grid-controller.styles.d.ts +6 -1
  84. package/types/src/components/grid-controller/grid-footer.d.ts +9 -1
  85. package/types/src/components/grid-controller/grid-footer.styles.d.ts +16 -0
  86. package/types/src/components/grid-controller/sortable-header/index.d.ts +1 -0
  87. package/types/src/components/grid-controller/{sortable-header.d.ts → sortable-header/sortable-header.d.ts} +2 -2
  88. package/types/src/components/grid-controller/sortable-header/sortable-header.styles.d.ts +10 -0
  89. package/types/src/components/grid-filters/components/created-date-filter/created-date-filter.d.ts +2 -1
  90. package/types/src/components/grid-filters/components/index.d.ts +1 -0
  91. package/types/src/components/grid-filters/components/label-id-filter/label-id-filter.d.ts +2 -1
  92. package/types/src/components/grid-filters/components/label-status-filter/index.d.ts +1 -0
  93. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter-schema.d.ts +12 -0
  94. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.d.ts +24 -0
  95. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.styles.d.ts +13 -0
  96. package/types/src/components/grid-filters/components/shipment-id-filter/shipment-id-filter.d.ts +2 -1
  97. package/types/src/components/grid-filters/components/tracking-status-filter/tracking-status-filter.d.ts +2 -1
  98. package/types/src/components/grid-filters/grid-filters.d.ts +4 -1
  99. package/types/src/elements/labels-grid/hooks/use-labels-grid.d.ts +5 -3
  100. package/types/src/elements/labels-grid/hooks/use-tracking-status-filter.d.ts +25 -0
  101. package/types/src/elements/labels-grid/labels-grid.d.ts +34 -20
  102. package/types/src/elements/manage-carriers/manage-carriers.d.ts +3 -0
  103. package/types/src/elements/manage-external-carriers/manage-external-carriers.d.ts +3 -0
  104. package/types/src/elements/manage-funding/manage-funding-element.d.ts +3 -0
  105. package/types/src/elements/manage-warehouses/manage-warehouses.d.ts +3 -0
  106. package/types/src/elements/payment-method-settings/payment-method-settings-element.d.ts +3 -0
  107. package/types/src/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.d.ts +2 -2
  108. package/types/src/elements/purchase-label/hooks/use-rates-form.d.ts +1 -0
  109. package/types/src/elements/purchase-label/purchase-label.d.ts +12 -9
  110. package/types/src/elements/select-label-layout/select-label-layout-element.d.ts +3 -0
  111. package/types/src/elements/shipment-summary/shipment-summary.d.ts +3 -0
  112. package/types/src/elements/shipments-grid/hooks/use-shipments-grid.d.ts +13 -2
  113. package/types/src/elements/shipments-grid/shipments-grid.d.ts +41 -6
  114. package/types/src/elements/theme-creator/theme-creator.d.ts +3 -0
  115. package/types/src/elements/transaction-history/transaction-history-element.d.ts +3 -0
  116. package/types/src/elements/unit-settings/unit-settings-element.d.ts +3 -0
  117. package/types/src/elements/vat-settings/vat-settings-element.d.ts +3 -0
  118. package/types/src/elements/void-label/void-label.d.ts +34 -0
  119. package/types/src/hooks/index.d.ts +1 -0
  120. package/types/src/hooks/use-configure-shipment.d.ts +1 -2
  121. package/types/src/hooks/use-sortable-query.d.ts +13 -0
  122. package/types/src/index.d.ts +5 -0
  123. package/types/src/locales/en/index.d.ts +3 -0
  124. package/types/src/utilities/feature-flags/types.d.ts +5 -1
  125. package/types/src/workflows/account-settings/account-settings.d.ts +3 -0
  126. package/types/src/workflows/carrier-services/carrier-services.d.ts +3 -0
  127. package/types/src/workflows/connect-external-carrier/connect-external-carrier.d.ts +3 -0
  128. package/types/src/workflows/label-workflow/label-workflow.d.ts +11 -1
  129. package/types/src/workflows/onboarding/onboarding.d.ts +3 -0
@@ -38,12 +38,12 @@ const FundAndPurchase = ({
38
38
  currency,
39
39
  disabled,
40
40
  isFundingEnabled,
41
- showVatSettings,
42
- onSave,
41
+ isInvalidatedByError,
43
42
  onPurchase,
43
+ onSave,
44
44
  onVatRegistrationComplete,
45
- isInvalidatedByError,
46
- rateData
45
+ rateData,
46
+ showVatSettings
47
47
  }) => {
48
48
  var _a, _b, _c;
49
49
  const {
@@ -75,10 +75,18 @@ const FundAndPurchase = ({
75
75
  const purchaseAmount = rates.getTotalRateAmount(rate);
76
76
  const [isSavingRate, setIsSavingRate] = React.useState(false);
77
77
  const [isSavingError, setIsSavingError] = React.useState(false);
78
- const [isAddFundsFormOpen, setIsAddFundsFormOpen] = React.useState(() => {
79
- var _a;
80
- return (_a = isFundingEnabled && isFundingRequired && (fundingOrigin === null || fundingOrigin === void 0 ? void 0 : fundingOrigin.balance) !== undefined && fundingOrigin.balance < purchaseAmount && !isInvalidatedByError) !== null && _a !== void 0 ? _a : false;
81
- });
78
+ const purchaseRequiresAddingFunds = isFundingEnabled && isFundingRequired && (fundingOrigin === null || fundingOrigin === void 0 ? void 0 : fundingOrigin.balance) !== undefined && fundingOrigin.balance < purchaseAmount && !isInvalidatedByError;
79
+ const [isFormManuallyToggled, setIsFormManuallyToggled] = React.useState(false);
80
+ const isAddFundsFormOpen = purchaseRequiresAddingFunds || isFormManuallyToggled;
81
+ const toggleAddFundsForm = () => {
82
+ if (!purchaseRequiresAddingFunds) {
83
+ // If the label can be purchased without adding funds, allow manual toggling of the form
84
+ setIsFormManuallyToggled(!isFormManuallyToggled);
85
+ } else if (isFormManuallyToggled) {
86
+ // If the form is already open, close it
87
+ setIsFormManuallyToggled(false);
88
+ }
89
+ };
82
90
  React.useEffect(() => {
83
91
  resetAddFundsMutationState();
84
92
  }, [isAddFundsFormOpen, resetAddFundsMutationState]);
@@ -86,7 +94,7 @@ const FundAndPurchase = ({
86
94
  setIsSavingRate(true);
87
95
  setIsSavingError(false);
88
96
  try {
89
- yield onSave();
97
+ yield onSave === null || onSave === void 0 ? void 0 : onSave();
90
98
  } catch (e) {
91
99
  setIsSavingError(true);
92
100
  } finally {
@@ -112,7 +120,7 @@ const FundAndPurchase = ({
112
120
  breakpoint: "mobileLarge",
113
121
  justify: "end"
114
122
  }, {
115
- children: [jsxRuntime.jsx(giger.Button, Object.assign({
123
+ children: [onSave && jsxRuntime.jsx(giger.Button, Object.assign({
116
124
  bold: false,
117
125
  css: fundAndPurchase_styles.styles.saveRateButton,
118
126
  disabled: disableSaveButton,
@@ -143,7 +151,7 @@ const FundAndPurchase = ({
143
151
  }), isFundingEnabled ? jsxRuntime.jsx(linkAction.LinkAction, {
144
152
  icon: "add",
145
153
  isDisabled: !isFundingRequired || isAddFundsFormOpen || isRateFormSubmitting,
146
- onClick: () => setIsAddFundsFormOpen(!isAddFundsFormOpen),
154
+ onClick: toggleAddFundsForm,
147
155
  title: t("manage-funding:actions.addFunds")
148
156
  }) : null]
149
157
  }), jsxRuntime.jsx(spacer.Spacer, {
@@ -189,7 +197,7 @@ const FundAndPurchase = ({
189
197
  }), isFundingEnabled && jsxRuntime.jsx(linkAction.LinkAction, {
190
198
  icon: "add",
191
199
  isDisabled: isAddFundsFormOpen || isRateFormSubmitting,
192
- onClick: () => setIsAddFundsFormOpen(!isAddFundsFormOpen),
200
+ onClick: toggleAddFundsForm,
193
201
  title: t("manage-funding:actions.addFunds")
194
202
  })]
195
203
  }), jsxRuntime.jsx(spacer.Spacer, {
@@ -210,7 +218,7 @@ const FundAndPurchase = ({
210
218
  currency: currency,
211
219
  minimumAmount: purchaseAmount - balance,
212
220
  onSuccess: () => {
213
- setIsAddFundsFormOpen(false);
221
+ setIsFormManuallyToggled(false);
214
222
  onPurchase();
215
223
  }
216
224
  }, {
@@ -247,7 +255,7 @@ const FundAndPurchase = ({
247
255
  }, {
248
256
  children: jsxRuntime.jsx(giger.Button, Object.assign({
249
257
  disabled: addFundsForm.isSubmitting || isRateFormSubmitting,
250
- onClick: () => setIsAddFundsFormOpen(false),
258
+ onClick: () => setIsFormManuallyToggled(false),
251
259
  variant: giger.ButtonVariant.TEXT
252
260
  }, {
253
261
  children: t("actions.cancel")
@@ -219,7 +219,7 @@ const RateForm = ({
219
219
  isFundingEnabled: !!(features === null || features === void 0 ? void 0 : features.enableFunding),
220
220
  isInvalidatedByError: !!(labelErrors === null || labelErrors === void 0 ? void 0 : labelErrors.length),
221
221
  onPurchase: handleSubmit,
222
- onSave: handleSaveRate,
222
+ onSave: (features === null || features === void 0 ? void 0 : features.saveRate) ? handleSaveRate : undefined,
223
223
  onVatRegistrationComplete: onVatRegistrationComplete,
224
224
  rateData: {
225
225
  isPreferredRate,
@@ -223,16 +223,11 @@ const RateView = ({
223
223
  }))]
224
224
  })]
225
225
  });
226
- if (errors) return jsxRuntime.jsx("article", Object.assign({
227
- css: rateForm_styles.styles.ratesInterstitial,
228
- role: "presentation"
226
+ if (errors) return jsxRuntime.jsx(giger.InlineNotification, Object.assign({
227
+ title: t(errors.title),
228
+ type: giger.NotificationType.ERROR
229
229
  }, {
230
- children: jsxRuntime.jsx(giger.InlineNotification, Object.assign({
231
- title: t(errors.title),
232
- type: giger.NotificationType.ERROR
233
- }, {
234
- children: errors === null || errors === void 0 ? void 0 : errors.messages
235
- }))
230
+ children: errors === null || errors === void 0 ? void 0 : errors.messages
236
231
  }));
237
232
  return jsxRuntime.jsxs("article", Object.assign({
238
233
  css: rateForm_styles.styles.ratesInterstitial,
@@ -875,7 +875,13 @@ const ShipmentForm = ({
875
875
  label: t("purchase-label:fields.packageCode"),
876
876
  name: "packages.0.type",
877
877
  onCategoryChange: value => {
878
- form.setValue("carrierId", value);
878
+ // Set carrierId to value if:
879
+ // 1. value exists (carrier-specific package) - set to that carrier
880
+ // 2. in browse_rates mode (even for custom packages) - could be set to undefined
881
+ // Otherwise (custom package in select_service mode) - keep existing carrierId
882
+ if (value || form.getValues("__mode") === "browse_rates") {
883
+ form.setValue("carrierId", value);
884
+ }
879
885
  // we have deviated from preset so we need to clear it in order to keep required dims and weight fields in sync
880
886
  setSelectedPreset(undefined);
881
887
  },
@@ -962,17 +968,17 @@ const ShipmentForm = ({
962
968
  })
963
969
  })), hasUpsOptions && jsxRuntime.jsx(_switch.Switch, {
964
970
  defaultChecked: ((_k = shipment$1 === null || shipment$1 === void 0 ? void 0 : shipment$1.advancedOptions) === null || _k === void 0 ? void 0 : _k.additionalHandling) || false,
965
- label: jsxRuntime.jsx(reactI18next.Trans, {
971
+ label: (features === null || features === void 0 ? void 0 : features.additionalHandlingHref) ? jsxRuntime.jsx(reactI18next.Trans, {
966
972
  components: {
967
973
  Link: jsxRuntime.jsx(giger.Link, {
968
- href: "https://help.paypal.shipstation.com/hc/en-us/articles/13823149193755-UPS-Additional-Handling",
974
+ href: features === null || features === void 0 ? void 0 : features.additionalHandlingHref,
969
975
  rel: "noopener noreferrer",
970
976
  target: "_blank"
971
977
  })
972
978
  },
973
- i18nKey: "purchase-label:fields.requires-additional-handling",
979
+ i18nKey: "purchase-label:fields.requires-additional-handling-link",
974
980
  t: t
975
- }),
981
+ }) : t("purchase-label:fields.requires-additional-handling"),
976
982
  name: "advancedOptions.additionalHandling",
977
983
  onChange: e => form.setValue("advancedOptions.additionalHandling", e.target.checked, {
978
984
  shouldDirty: true
@@ -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,
@@ -22,7 +22,9 @@ const getInitialFilters = (showShipmentIdFilter, showCreatedDateFilter) => ({
22
22
  const useShipmentsGrid = ({
23
23
  shipmentStatus,
24
24
  showShipmentIdFilter: _showShipmentIdFilter = true,
25
- showCreatedDateFilter: _showCreatedDateFilter = true
25
+ showCreatedDateFilter: _showCreatedDateFilter = true,
26
+ sortBy,
27
+ sortDir
26
28
  }) => {
27
29
  var _a, _b, _c, _d;
28
30
  const initialFilters = getInitialFilters(_showShipmentIdFilter, _showCreatedDateFilter);
@@ -34,6 +36,7 @@ const useShipmentsGrid = ({
34
36
  pageSize,
35
37
  pagerProps
36
38
  } = usePager.usePager(PAGE_SIZE);
39
+ const [activeShipmentId, setActiveShipmentId] = React.useState();
37
40
  const [filters, setFilters] = React.useState(initialFilters);
38
41
  const clearAllFilters = () => {
39
42
  setFilters(initialFilters);
@@ -62,14 +65,14 @@ const useShipmentsGrid = ({
62
65
  page,
63
66
  pageSize,
64
67
  shipmentStatus,
65
- sortBy: "modified_at",
66
- sortDir: "desc"
68
+ sortBy: sortBy,
69
+ sortDir: sortDir
67
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)));
68
71
  const shipments = React.useMemo(() => data === null || data === void 0 ? void 0 : data.shipments.map(shipment => Object.assign(Object.assign({}, shipment), {
69
72
  disableOnRowClick: shipment.shipmentStatus === "cancelled",
73
+ isLoading: activeShipmentId === shipment.shipmentId,
70
74
  serviceName: getServiceName(shipment)
71
- })), [data === null || data === void 0 ? void 0 : data.shipments, getServiceName]);
72
- const shouldShowFilters = isAnyFilterEnabled && (isAnyFilterActive || Boolean(shipments === null || shipments === void 0 ? void 0 : shipments.length));
75
+ })), [activeShipmentId, data === null || data === void 0 ? void 0 : data.shipments, getServiceName]);
73
76
  const {
74
77
  data: shipmentById,
75
78
  error: shipmentErrors,
@@ -110,6 +113,7 @@ const useShipmentsGrid = ({
110
113
  if (shipmentFilteredById) {
111
114
  return [Object.assign(Object.assign({}, shipmentFilteredById), {
112
115
  disableOnRowClick: shipmentFilteredById.shipmentStatus === "cancelled",
116
+ isLoading: activeShipmentId === shipmentFilteredById.shipmentId,
113
117
  serviceName: getServiceName(shipmentFilteredById)
114
118
  })];
115
119
  } else if (shipmentFilteredByIdHasErrors) {
@@ -134,9 +138,10 @@ const useShipmentsGrid = ({
134
138
  showPagination: shipmentFilteredById ? false : ((data === null || data === void 0 ? void 0 : data.total) || 0) > pageSize,
135
139
  totalElements: shipmentFilteredById ? 1 : (data === null || data === void 0 ? void 0 : data.total) || 0
136
140
  },
141
+ setActiveShipmentId,
137
142
  setFilters: onSetFilters,
138
143
  shipments,
139
- shouldShowFilters
144
+ shouldShowFilters: isAnyFilterEnabled
140
145
  };
141
146
  };
142
147
 
@@ -2,7 +2,10 @@
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');
7
+ var useSortableQuery = require('../../hooks/use-sortable-query.cjs');
8
+ var React = require('react');
6
9
  var reactI18next = require('react-i18next');
7
10
  var giger = require('@shipengine/giger');
8
11
  var useShipmentsGrid = require('./hooks/use-shipments-grid.cjs');
@@ -11,8 +14,8 @@ var actionsMenu = require('../../components/actions-menu/actions-menu.cjs');
11
14
  var gridFilters = require('../../components/grid-filters/grid-filters.cjs');
12
15
  var index = require('../../locales/en/index.cjs');
13
16
  var elementsContextProvider = require('../../elements-provider/elements-context-provider.cjs');
14
- var loader = require('../../components/loader/loader.cjs');
15
17
  var errorState = require('../../components/error-state/error-state.cjs');
18
+ var sortableHeader = require('../../components/grid-controller/sortable-header/sortable-header.cjs');
16
19
  var cellFormattedDate = require('../../components/grid-controller/cell-formatted-date.cjs');
17
20
  var gridController = require('../../components/grid-controller/grid-controller.cjs');
18
21
  var gridFooter = require('../../components/grid-controller/grid-footer.cjs');
@@ -43,18 +46,25 @@ var errorFallback = require('../../components/error-fallback/error-fallback.cjs'
43
46
  * @see {@link ShipmentsGrid.Element | The **Element** created to render `<ShipmentsGrid />`}
44
47
  */
45
48
  const Component = ({
46
- onRowClick,
49
+ onRowClick: onRowClickProp,
47
50
  onClickCancelShipment,
48
51
  shipmentStatus,
49
52
  showShipmentIdFilter: _showShipmentIdFilter = true,
50
53
  showCreatedDateFilter: _showCreatedDateFilter = true
51
54
  }) => {
55
+ const {
56
+ globalFeatures
57
+ } = elementsContextProvider.useElements();
52
58
  const {
53
59
  t
54
60
  } = reactI18next.useTranslation(["common", "list-shipments"]);
55
61
  const {
56
- globalFeatures
57
- } = elementsContextProvider.useElements();
62
+ toggleSort,
63
+ sortState
64
+ } = useSortableQuery.useSortableQuery({
65
+ defaultSortBy: "modified_at",
66
+ defaultSortDir: "desc"
67
+ });
58
68
  const {
59
69
  isLoading,
60
70
  isError,
@@ -64,17 +74,50 @@ const Component = ({
64
74
  getGridData,
65
75
  isAnyFilterActive,
66
76
  shouldShowFilters,
67
- clearAllFilters
77
+ clearAllFilters,
78
+ setActiveShipmentId
68
79
  } = useShipmentsGrid.useShipmentsGrid({
69
80
  shipmentStatus,
70
81
  showCreatedDateFilter: _showCreatedDateFilter,
71
- showShipmentIdFilter: _showShipmentIdFilter
82
+ showShipmentIdFilter: _showShipmentIdFilter,
83
+ sortBy: sortState.by,
84
+ sortDir: sortState.dir
72
85
  });
73
- if (isLoading) {
74
- return jsxRuntime.jsx(loader.Loader, {
75
- message: t("loading.shipments")
76
- });
77
- }
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
+ });
91
+ const handleCreatedDateSort = () => {
92
+ toggleSort("created_at");
93
+ };
94
+ const handleUpdatedDateSort = () => {
95
+ toggleSort("modified_at");
96
+ };
97
+ const emptyContentComponent = React.useMemo(() => {
98
+ if (isLoading) {
99
+ return undefined;
100
+ }
101
+ if (isAnyFilterActive) {
102
+ return jsxRuntime.jsx(giger.EmptyState, Object.assign({
103
+ isElevated: false,
104
+ subtitle: t("list-shipments:emptyState.filtersSubtitle"),
105
+ title: t("list-shipments:emptyState.filtersTitle")
106
+ }, {
107
+ children: jsxRuntime.jsx(giger.Button, Object.assign({
108
+ onClick: clearAllFilters
109
+ }, {
110
+ children: t("list-shipments:emptyState.viewAll")
111
+ }))
112
+ }));
113
+ } else {
114
+ return jsxRuntime.jsx(giger.EmptyState, {
115
+ isElevated: false,
116
+ subtitle: t("list-shipments:emptyState.subtitle"),
117
+ title: t("list-shipments:emptyState.title")
118
+ });
119
+ }
120
+ }, [clearAllFilters, isAnyFilterActive, isLoading, t]);
78
121
  if (isError) {
79
122
  return jsxRuntime.jsx(errorState.ErrorState, {
80
123
  css: shipmentsGrid_styles.styles.errorState,
@@ -160,7 +203,11 @@ const Component = ({
160
203
  }));
161
204
  }
162
205
  }, {
163
- headerContent: t("list-shipments:headers.created"),
206
+ headerContent: jsxRuntime.jsx(sortableHeader.SortableHeader, {
207
+ headerText: t("list-shipments:headers.created"),
208
+ onToggleSort: handleCreatedDateSort,
209
+ sortDirection: sortState.createdAtDir
210
+ }),
164
211
  renderCellContent: shipment => {
165
212
  return jsxRuntime.jsx(cellFormattedDate.CellFormattedDate, {
166
213
  date: shipment.createdAt,
@@ -168,7 +215,11 @@ const Component = ({
168
215
  });
169
216
  }
170
217
  }, {
171
- headerContent: t("list-shipments:headers.modified"),
218
+ headerContent: jsxRuntime.jsx(sortableHeader.SortableHeader, {
219
+ headerText: t("list-shipments:headers.modified"),
220
+ onToggleSort: handleUpdatedDateSort,
221
+ sortDirection: sortState.modifiedAtDir
222
+ }),
172
223
  renderCellContent: shipment => {
173
224
  return jsxRuntime.jsx(cellFormattedDate.CellFormattedDate, {
174
225
  date: shipment.modifiedAt,
@@ -200,23 +251,10 @@ const Component = ({
200
251
  children: [jsxRuntime.jsx(gridController.GridController, {
201
252
  columns: columns,
202
253
  data: getGridData(),
203
- emptyContent: isAnyFilterActive ? jsxRuntime.jsx(giger.EmptyState, Object.assign({
204
- isElevated: false,
205
- subtitle: t("list-shipments:emptyState.filtersSubtitle"),
206
- title: t("list-shipments:emptyState.filtersTitle")
207
- }, {
208
- children: jsxRuntime.jsx(giger.Button, Object.assign({
209
- onClick: clearAllFilters
210
- }, {
211
- children: t("list-shipments:emptyState.viewAll")
212
- }))
213
- })) : jsxRuntime.jsx(giger.EmptyState, {
214
- isElevated: false,
215
- subtitle: t("list-shipments:emptyState.subtitle"),
216
- title: t("list-shipments:emptyState.title")
217
- }),
254
+ emptyContent: emptyContentComponent,
218
255
  filters: shouldShowFilters && jsxRuntime.jsx(gridFilters.GridFilters, {
219
256
  filters: filters,
257
+ filtersDisabled: isLoading,
220
258
  onClearAllFilters: clearAllFilters,
221
259
  onFiltersUpdated: setFilters
222
260
  }),
@@ -228,6 +266,7 @@ const Component = ({
228
266
  showPagination: pageConfig.showPagination,
229
267
  total: pageConfig.totalElements
230
268
  }),
269
+ isLoading: isLoading,
231
270
  onRowClick: onRowClick
232
271
  }), globalFeatures.poweredByShipEngine && jsxRuntime.jsxs(jsxRuntime.Fragment, {
233
272
  children: [jsxRuntime.jsx(spacer.Spacer, {}), jsxRuntime.jsx(poweredByShipengine.PoweredByShipEngine, {})]
@@ -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"
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+
7
+ const useSortableQuery = ({
8
+ defaultSortBy: _defaultSortBy = "modified_at",
9
+ defaultSortDir: _defaultSortDir = "desc"
10
+ }) => {
11
+ const [sortState, setSortState] = React.useState({
12
+ by: _defaultSortBy,
13
+ createdAtDir: _defaultSortDir,
14
+ dir: _defaultSortDir,
15
+ modifiedAtDir: _defaultSortDir
16
+ });
17
+ const toggleSort = sortQuery => {
18
+ const newSortState = Object.assign({}, sortState);
19
+ if (sortQuery === "created_at") {
20
+ newSortState.createdAtDir = sortState.createdAtDir === "asc" ? "desc" : "asc";
21
+ newSortState.dir = newSortState.createdAtDir;
22
+ newSortState.by = "created_at";
23
+ } else if (sortQuery === "modified_at") {
24
+ newSortState.modifiedAtDir = sortState.modifiedAtDir === "asc" ? "desc" : "asc";
25
+ newSortState.dir = newSortState.modifiedAtDir;
26
+ newSortState.by = "modified_at";
27
+ }
28
+ setSortState(newSortState);
29
+ };
30
+ return {
31
+ sortState,
32
+ toggleSort
33
+ };
34
+ };
35
+
36
+ exports.useSortableQuery = useSortableQuery;