@shipengine/elements 2.21.0 → 2.22.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 (87) hide show
  1. package/cjs/components/grid-controller/grid-controller.cjs +25 -7
  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/label-id-filter/label-id-filter.cjs +2 -0
  11. package/cjs/components/grid-filters/components/shipment-id-filter/shipment-id-filter.cjs +2 -0
  12. package/cjs/components/grid-filters/components/tracking-status-filter/tracking-status-filter.cjs +2 -0
  13. package/cjs/components/grid-filters/grid-filters.cjs +6 -0
  14. package/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +63 -29
  15. package/cjs/elements/labels-grid/hooks/use-tracking-status-filter.cjs +109 -0
  16. package/cjs/elements/labels-grid/labels-grid.cjs +47 -30
  17. package/cjs/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.cjs +22 -14
  18. package/cjs/elements/purchase-label/components/rate-form/rate-form.cjs +1 -1
  19. package/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +6 -5
  20. package/cjs/elements/shipments-grid/shipments-grid.cjs +56 -24
  21. package/cjs/hooks/use-sortable-query.cjs +36 -0
  22. package/cjs/locales/en/common.cjs +1 -0
  23. package/cjs/package.cjs +1 -1
  24. package/cjs/utilities/feature-flags/feature-flags.cjs +1 -1
  25. package/esm/components/grid-controller/grid-controller.js +27 -9
  26. package/esm/components/grid-controller/grid-controller.styles.js +7 -2
  27. package/esm/components/grid-controller/grid-footer.js +32 -17
  28. package/esm/components/grid-controller/grid-footer.styles.js +20 -0
  29. package/esm/components/grid-controller/index.js +1 -1
  30. package/esm/components/grid-controller/sortable-header/index.js +1 -0
  31. package/esm/components/grid-controller/{sortable-header.js → sortable-header/sortable-header.js} +3 -5
  32. package/esm/components/grid-controller/sortable-header/sortable-header.styles.js +14 -0
  33. package/esm/components/grid-filters/components/created-date-filter/created-date-filter.js +3 -0
  34. package/esm/components/grid-filters/components/label-id-filter/label-id-filter.js +2 -0
  35. package/esm/components/grid-filters/components/shipment-id-filter/shipment-id-filter.js +2 -0
  36. package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js +2 -0
  37. package/esm/components/grid-filters/grid-filters.js +6 -0
  38. package/esm/elements/labels-grid/hooks/use-labels-grid.js +64 -30
  39. package/esm/elements/labels-grid/hooks/use-tracking-status-filter.js +105 -0
  40. package/esm/elements/labels-grid/labels-grid.js +48 -31
  41. package/esm/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.js +22 -14
  42. package/esm/elements/purchase-label/components/rate-form/rate-form.js +1 -1
  43. package/esm/elements/shipments-grid/hooks/use-shipments-grid.js +6 -5
  44. package/esm/elements/shipments-grid/shipments-grid.js +57 -25
  45. package/esm/hooks/use-sortable-query.js +32 -0
  46. package/esm/locales/en/common.js +1 -0
  47. package/esm/package.js +1 -1
  48. package/esm/utilities/feature-flags/feature-flags.js +1 -1
  49. package/package.json +3 -3
  50. package/types/src/components/grid-controller/grid-controller.d.ts +2 -1
  51. package/types/src/components/grid-controller/grid-controller.styles.d.ts +6 -1
  52. package/types/src/components/grid-controller/grid-footer.d.ts +9 -1
  53. package/types/src/components/grid-controller/grid-footer.styles.d.ts +16 -0
  54. package/types/src/components/grid-controller/sortable-header/index.d.ts +1 -0
  55. package/types/src/components/grid-controller/{sortable-header.d.ts → sortable-header/sortable-header.d.ts} +2 -2
  56. package/types/src/components/grid-controller/sortable-header/sortable-header.styles.d.ts +10 -0
  57. package/types/src/components/grid-filters/components/created-date-filter/created-date-filter.d.ts +2 -1
  58. package/types/src/components/grid-filters/components/label-id-filter/label-id-filter.d.ts +2 -1
  59. package/types/src/components/grid-filters/components/shipment-id-filter/shipment-id-filter.d.ts +2 -1
  60. package/types/src/components/grid-filters/components/tracking-status-filter/tracking-status-filter.d.ts +2 -1
  61. package/types/src/components/grid-filters/grid-filters.d.ts +2 -1
  62. package/types/src/elements/labels-grid/hooks/use-labels-grid.d.ts +4 -3
  63. package/types/src/elements/labels-grid/hooks/use-tracking-status-filter.d.ts +25 -0
  64. package/types/src/elements/labels-grid/labels-grid.d.ts +36 -21
  65. package/types/src/elements/manage-carriers/manage-carriers.d.ts +1 -0
  66. package/types/src/elements/manage-external-carriers/manage-external-carriers.d.ts +1 -0
  67. package/types/src/elements/manage-funding/manage-funding-element.d.ts +1 -0
  68. package/types/src/elements/manage-warehouses/manage-warehouses.d.ts +1 -0
  69. package/types/src/elements/payment-method-settings/payment-method-settings-element.d.ts +1 -0
  70. package/types/src/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.d.ts +2 -2
  71. package/types/src/elements/purchase-label/purchase-label.d.ts +1 -0
  72. package/types/src/elements/select-label-layout/select-label-layout-element.d.ts +1 -0
  73. package/types/src/elements/shipment-summary/shipment-summary.d.ts +1 -0
  74. package/types/src/elements/shipments-grid/hooks/use-shipments-grid.d.ts +7 -1
  75. package/types/src/elements/shipments-grid/shipments-grid.d.ts +10 -1
  76. package/types/src/elements/theme-creator/theme-creator.d.ts +1 -0
  77. package/types/src/elements/transaction-history/transaction-history-element.d.ts +1 -0
  78. package/types/src/elements/unit-settings/unit-settings-element.d.ts +1 -0
  79. package/types/src/elements/vat-settings/vat-settings-element.d.ts +1 -0
  80. package/types/src/elements/void-label/void-label.d.ts +1 -0
  81. package/types/src/hooks/use-sortable-query.d.ts +13 -0
  82. package/types/src/locales/en/index.d.ts +1 -0
  83. package/types/src/workflows/account-settings/account-settings.d.ts +1 -0
  84. package/types/src/workflows/carrier-services/carrier-services.d.ts +1 -0
  85. package/types/src/workflows/connect-external-carrier/connect-external-carrier.d.ts +1 -0
  86. package/types/src/workflows/label-workflow/label-workflow.d.ts +1 -0
  87. package/types/src/workflows/onboarding/onboarding.d.ts +1 -0
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('@emotion/react/jsx-runtime');
6
+ var useSortableQuery = require('../../hooks/use-sortable-query.cjs');
6
7
  var React = require('react');
7
8
  var reactI18next = require('react-i18next');
8
9
  var giger = require('@shipengine/giger');
9
10
  var useLabelsGrid = require('./hooks/use-labels-grid.cjs');
10
11
  var labelsGrid_styles = require('./labels-grid.styles.cjs');
11
- var sortableHeader = require('../../components/grid-controller/sortable-header.cjs');
12
+ var sortableHeader = require('../../components/grid-controller/sortable-header/sortable-header.cjs');
12
13
  var cellFormattedDate = require('../../components/grid-controller/cell-formatted-date.cjs');
13
14
  var actionsMenu = require('../../components/actions-menu/actions-menu.cjs');
14
15
  var errorState = require('../../components/error-state/error-state.cjs');
@@ -17,7 +18,6 @@ var gridFilters = require('../../components/grid-filters/grid-filters.cjs');
17
18
  var gridFooter = require('../../components/grid-controller/grid-footer.cjs');
18
19
  var index = require('../../locales/en/index.cjs');
19
20
  var elementsContextProvider = require('../../elements-provider/elements-context-provider.cjs');
20
- var loader = require('../../components/loader/loader.cjs');
21
21
  var spacer = require('../../components/spacer/spacer.cjs');
22
22
  var poweredByShipengine = require('../../components/powered-by-shipengine/powered-by-shipengine.cjs');
23
23
  var createElement = require('../../create-element/create-element.cjs');
@@ -35,7 +35,7 @@ const Component = ({
35
35
  onClickExternalShipmentId,
36
36
  onClickShipmentNumber
37
37
  }) => {
38
- var _a, _b, _c;
38
+ var _a, _b;
39
39
  const {
40
40
  t
41
41
  } = reactI18next.useTranslation(["common", "list-labels"]);
@@ -45,7 +45,13 @@ const Component = ({
45
45
  } = elementsContextProvider.useElements();
46
46
  const defaultFeatures = getFeatures("labelsGridFeatures");
47
47
  const prevStatus = React.useRef(labelStatus);
48
- const [createdDateSortBy, setCreatedDateSortBy] = React.useState("desc");
48
+ const {
49
+ toggleSort,
50
+ sortState
51
+ } = useSortableQuery.useSortableQuery({
52
+ defaultSortBy: "modified_at",
53
+ defaultSortDir: "desc"
54
+ });
49
55
  features = Object.assign(Object.assign({}, defaultFeatures), features !== null && features !== void 0 ? features : {});
50
56
  const labelIdColumn = React.useMemo(() => {
51
57
  var _a;
@@ -65,12 +71,14 @@ const Component = ({
65
71
  }, [features]);
66
72
  const showLabelIdFilter = labelIdColumn && ((_a = labelIdColumn.allowFilter) !== null && _a !== void 0 ? _a : true);
67
73
  const showShipmentIdFilter = shipmentIdColumn && ((_b = shipmentIdColumn.allowFilter) !== null && _b !== void 0 ? _b : true);
68
- const showTrackingStatusFilter = trackingStatusColumn && ((_c = trackingStatusColumn.allowFilter) !== null && _c !== void 0 ? _c : true);
74
+ const showTrackingStatusFilter = trackingStatusColumn && !!trackingStatusColumn.allowFilter;
69
75
  const {
70
76
  labels,
71
77
  getGridData,
72
78
  isError,
73
79
  isLoading,
80
+ isFetchingNextPage,
81
+ hasMoreUnfetchedResults,
74
82
  filters,
75
83
  setFilters,
76
84
  pageConfig,
@@ -78,12 +86,12 @@ const Component = ({
78
86
  shouldShowFilters,
79
87
  clearAllFilters
80
88
  } = useLabelsGrid.useLabelsGrid({
81
- createdDateSortBy,
82
89
  fetchShipments: !!shipmentNumberColumn,
83
90
  labelStatus,
84
91
  showLabelIdFilter,
85
92
  showShipmentIdFilter,
86
- showTrackingStatusFilter
93
+ showTrackingStatusFilter,
94
+ sortDir: sortState.dir
87
95
  });
88
96
  React.useEffect(() => {
89
97
  if (prevStatus.current !== labelStatus) {
@@ -105,8 +113,8 @@ const Component = ({
105
113
  };
106
114
  }, [filters, labelIdColumn, shipmentIdColumn, trackingStatusColumn]);
107
115
  const toggleCreatedDateSort = React.useCallback(() => {
108
- setCreatedDateSortBy(createdDateSortBy === "desc" ? "asc" : "desc");
109
- }, [createdDateSortBy]);
116
+ toggleSort("created_at");
117
+ }, [toggleSort]);
110
118
  const columns = React.useMemo(() => {
111
119
  var _a;
112
120
  const labelTags = {
@@ -150,7 +158,7 @@ const Component = ({
150
158
  headerContent: jsxRuntime.jsx(sortableHeader.SortableHeader, {
151
159
  headerText: t("list-labels:headers.created"),
152
160
  onToggleSort: toggleCreatedDateSort,
153
- sortDirection: createdDateSortBy
161
+ sortDirection: sortState.createdAtDir
154
162
  }),
155
163
  renderCellContent: label => {
156
164
  return jsxRuntime.jsx(cellFormattedDate.CellFormattedDate, {
@@ -378,24 +386,13 @@ const Component = ({
378
386
  });
379
387
  }
380
388
  return cols;
381
- }, [t, toggleCreatedDateSort, createdDateSortBy, features === null || features === void 0 ? void 0 : features.columns, features === null || features === void 0 ? void 0 : features.showActions, labels, onClickExternalOrderId, onClickExternalShipmentId, onClickViewDetails, onClickVoidLabel, onClickPrintLabel, onClickPrintForms, onClickShipmentNumber]);
382
- if (isLoading) {
383
- return jsxRuntime.jsx(loader.Loader, {
384
- message: t("loading.labels")
385
- });
386
- }
387
- if (isError) {
388
- return jsxRuntime.jsx(errorState.ErrorState, {
389
- css: labelsGrid_styles.styles.errorState,
390
- subtitle: [t("list-labels:errorMessages.subtitle"), t("errorMessages.refreshAndTryAgain")],
391
- title: t("list-labels:errorMessages.title")
392
- });
393
- }
394
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
395
- children: [jsxRuntime.jsx(gridController.GridController, {
396
- columns: columns,
397
- data: getGridData(),
398
- emptyContent: isAnyFilterActive ? jsxRuntime.jsx(giger.EmptyState, Object.assign({
389
+ }, [t, toggleCreatedDateSort, sortState.createdAtDir, features === null || features === void 0 ? void 0 : features.columns, features === null || features === void 0 ? void 0 : features.showActions, labels, onClickExternalOrderId, onClickExternalShipmentId, onClickShipmentNumber, onClickVoidLabel, onClickViewDetails, onClickPrintLabel, onClickPrintForms]);
390
+ const emptyContentComponent = React.useMemo(() => {
391
+ if (isLoading) {
392
+ return undefined;
393
+ }
394
+ if (isAnyFilterActive) {
395
+ return jsxRuntime.jsx(giger.EmptyState, Object.assign({
399
396
  isElevated: false,
400
397
  subtitle: t("list-labels:emptyWithFilters.subtitle"),
401
398
  title: t("list-labels:emptyWithFilters.title")
@@ -405,17 +402,36 @@ const Component = ({
405
402
  }, {
406
403
  children: t("list-labels:emptyWithFilters.button")
407
404
  }))
408
- })) : jsxRuntime.jsx(giger.EmptyState, {
405
+ }));
406
+ } else {
407
+ return jsxRuntime.jsx(giger.EmptyState, {
409
408
  isElevated: false,
410
409
  subtitle: t("list-labels:empty.subtitle"),
411
410
  title: t("list-labels:empty.title")
412
- }),
411
+ });
412
+ }
413
+ }, [clearAllFilters, isAnyFilterActive, isLoading, t]);
414
+ if (isError) {
415
+ return jsxRuntime.jsx(errorState.ErrorState, {
416
+ css: labelsGrid_styles.styles.errorState,
417
+ subtitle: [t("list-labels:errorMessages.subtitle"), t("errorMessages.refreshAndTryAgain")],
418
+ title: t("list-labels:errorMessages.title")
419
+ });
420
+ }
421
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
422
+ children: [jsxRuntime.jsx(gridController.GridController, {
423
+ columns: columns,
424
+ data: getGridData(),
425
+ emptyContent: emptyContentComponent,
413
426
  filters: shouldShowFilters && jsxRuntime.jsx(gridFilters.GridFilters, {
414
427
  filters: gridFilters$1,
428
+ filtersDisabled: isLoading,
415
429
  onClearAllFilters: clearAllFilters,
416
430
  onFiltersUpdated: setFilters
417
431
  }),
418
432
  footerContent: jsxRuntime.jsx(gridFooter.GridFooter, {
433
+ hasMoreUnfetchedResults: hasMoreUnfetchedResults,
434
+ isLoadingMore: isFetchingNextPage,
419
435
  onPageChange: pageConfig.pagerProps.onPageSelect,
420
436
  page: pageConfig.currentPage,
421
437
  pages: pageConfig.pagesAmount,
@@ -423,6 +439,7 @@ const Component = ({
423
439
  showPagination: pageConfig.showPagination,
424
440
  total: pageConfig.totalElements
425
441
  }),
442
+ isLoading: isLoading,
426
443
  onRowClick: onRowClick
427
444
  }), globalFeatures.poweredByShipEngine && jsxRuntime.jsxs(jsxRuntime.Fragment, {
428
445
  children: [jsxRuntime.jsx(spacer.Spacer, {}), jsxRuntime.jsx(poweredByShipengine.PoweredByShipEngine, {})]
@@ -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,
@@ -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);
@@ -62,14 +64,13 @@ const useShipmentsGrid = ({
62
64
  page,
63
65
  pageSize,
64
66
  shipmentStatus,
65
- sortBy: "modified_at",
66
- sortDir: "desc"
67
+ sortBy: sortBy,
68
+ sortDir: sortDir
67
69
  }, 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
70
  const shipments = React.useMemo(() => data === null || data === void 0 ? void 0 : data.shipments.map(shipment => Object.assign(Object.assign({}, shipment), {
69
71
  disableOnRowClick: shipment.shipmentStatus === "cancelled",
70
72
  serviceName: getServiceName(shipment)
71
73
  })), [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));
73
74
  const {
74
75
  data: shipmentById,
75
76
  error: shipmentErrors,
@@ -136,7 +137,7 @@ const useShipmentsGrid = ({
136
137
  },
137
138
  setFilters: onSetFilters,
138
139
  shipments,
139
- shouldShowFilters
140
+ shouldShowFilters: isAnyFilterEnabled
140
141
  };
141
142
  };
142
143
 
@@ -3,6 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('@emotion/react/jsx-runtime');
6
+ var useSortableQuery = require('../../hooks/use-sortable-query.cjs');
7
+ var React = require('react');
6
8
  var reactI18next = require('react-i18next');
7
9
  var giger = require('@shipengine/giger');
8
10
  var useShipmentsGrid = require('./hooks/use-shipments-grid.cjs');
@@ -11,8 +13,8 @@ var actionsMenu = require('../../components/actions-menu/actions-menu.cjs');
11
13
  var gridFilters = require('../../components/grid-filters/grid-filters.cjs');
12
14
  var index = require('../../locales/en/index.cjs');
13
15
  var elementsContextProvider = require('../../elements-provider/elements-context-provider.cjs');
14
- var loader = require('../../components/loader/loader.cjs');
15
16
  var errorState = require('../../components/error-state/error-state.cjs');
17
+ var sortableHeader = require('../../components/grid-controller/sortable-header/sortable-header.cjs');
16
18
  var cellFormattedDate = require('../../components/grid-controller/cell-formatted-date.cjs');
17
19
  var gridController = require('../../components/grid-controller/grid-controller.cjs');
18
20
  var gridFooter = require('../../components/grid-controller/grid-footer.cjs');
@@ -55,6 +57,13 @@ const Component = ({
55
57
  const {
56
58
  globalFeatures
57
59
  } = elementsContextProvider.useElements();
60
+ const {
61
+ toggleSort,
62
+ sortState
63
+ } = useSortableQuery.useSortableQuery({
64
+ defaultSortBy: "modified_at",
65
+ defaultSortDir: "desc"
66
+ });
58
67
  const {
59
68
  isLoading,
60
69
  isError,
@@ -68,13 +77,40 @@ const Component = ({
68
77
  } = useShipmentsGrid.useShipmentsGrid({
69
78
  shipmentStatus,
70
79
  showCreatedDateFilter: _showCreatedDateFilter,
71
- showShipmentIdFilter: _showShipmentIdFilter
80
+ showShipmentIdFilter: _showShipmentIdFilter,
81
+ sortBy: sortState.by,
82
+ sortDir: sortState.dir
72
83
  });
73
- if (isLoading) {
74
- return jsxRuntime.jsx(loader.Loader, {
75
- message: t("loading.shipments")
76
- });
77
- }
84
+ const handleCreatedDateSort = () => {
85
+ toggleSort("created_at");
86
+ };
87
+ const handleUpdatedDateSort = () => {
88
+ toggleSort("modified_at");
89
+ };
90
+ const emptyContentComponent = React.useMemo(() => {
91
+ if (isLoading) {
92
+ return undefined;
93
+ }
94
+ if (isAnyFilterActive) {
95
+ return jsxRuntime.jsx(giger.EmptyState, Object.assign({
96
+ isElevated: false,
97
+ subtitle: t("list-shipments:emptyState.filtersSubtitle"),
98
+ title: t("list-shipments:emptyState.filtersTitle")
99
+ }, {
100
+ children: jsxRuntime.jsx(giger.Button, Object.assign({
101
+ onClick: clearAllFilters
102
+ }, {
103
+ children: t("list-shipments:emptyState.viewAll")
104
+ }))
105
+ }));
106
+ } else {
107
+ return jsxRuntime.jsx(giger.EmptyState, {
108
+ isElevated: false,
109
+ subtitle: t("list-shipments:emptyState.subtitle"),
110
+ title: t("list-shipments:emptyState.title")
111
+ });
112
+ }
113
+ }, [clearAllFilters, isAnyFilterActive, isLoading, t]);
78
114
  if (isError) {
79
115
  return jsxRuntime.jsx(errorState.ErrorState, {
80
116
  css: shipmentsGrid_styles.styles.errorState,
@@ -160,7 +196,11 @@ const Component = ({
160
196
  }));
161
197
  }
162
198
  }, {
163
- headerContent: t("list-shipments:headers.created"),
199
+ headerContent: jsxRuntime.jsx(sortableHeader.SortableHeader, {
200
+ headerText: t("list-shipments:headers.created"),
201
+ onToggleSort: handleCreatedDateSort,
202
+ sortDirection: sortState.createdAtDir
203
+ }),
164
204
  renderCellContent: shipment => {
165
205
  return jsxRuntime.jsx(cellFormattedDate.CellFormattedDate, {
166
206
  date: shipment.createdAt,
@@ -168,7 +208,11 @@ const Component = ({
168
208
  });
169
209
  }
170
210
  }, {
171
- headerContent: t("list-shipments:headers.modified"),
211
+ headerContent: jsxRuntime.jsx(sortableHeader.SortableHeader, {
212
+ headerText: t("list-shipments:headers.modified"),
213
+ onToggleSort: handleUpdatedDateSort,
214
+ sortDirection: sortState.modifiedAtDir
215
+ }),
172
216
  renderCellContent: shipment => {
173
217
  return jsxRuntime.jsx(cellFormattedDate.CellFormattedDate, {
174
218
  date: shipment.modifiedAt,
@@ -200,23 +244,10 @@ const Component = ({
200
244
  children: [jsxRuntime.jsx(gridController.GridController, {
201
245
  columns: columns,
202
246
  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
- }),
247
+ emptyContent: emptyContentComponent,
218
248
  filters: shouldShowFilters && jsxRuntime.jsx(gridFilters.GridFilters, {
219
249
  filters: filters,
250
+ filtersDisabled: isLoading,
220
251
  onClearAllFilters: clearAllFilters,
221
252
  onFiltersUpdated: setFilters
222
253
  }),
@@ -228,6 +259,7 @@ const Component = ({
228
259
  showPagination: pageConfig.showPagination,
229
260
  total: pageConfig.totalElements
230
261
  }),
262
+ isLoading: isLoading,
231
263
  onRowClick: onRowClick
232
264
  }), globalFeatures.poweredByShipEngine && jsxRuntime.jsxs(jsxRuntime.Fragment, {
233
265
  children: [jsxRuntime.jsx(spacer.Spacer, {}), jsxRuntime.jsx(poweredByShipengine.PoweredByShipEngine, {})]
@@ -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;
@@ -216,6 +216,7 @@ var common = {
216
216
  grid: {
217
217
  "row-count_one": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}} item</0>",
218
218
  "row-count_other": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}} items</0>",
219
+ "row-count-plus_other": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}}+ items</0>",
219
220
  rows: "Rows",
220
221
  clearAll: "Clear all",
221
222
  shipmentId: "Shipment ID",
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.21.0";
5
+ var version = "2.22.0";
6
6
 
7
7
  exports.version = version;
@@ -12,7 +12,7 @@ const defaultLabelsGridColumns = [{
12
12
  allowFilter: true,
13
13
  name: "labelId"
14
14
  }, {
15
- allowFilter: true,
15
+ allowFilter: false,
16
16
  name: "trackingStatus"
17
17
  }, {
18
18
  name: "recipient"
@@ -1,6 +1,6 @@
1
- import { jsxs, jsx } from '@emotion/react/jsx-runtime';
1
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
2
2
  import { useState, useMemo, useCallback } from 'react';
3
- import { Table, TableFooter, TableHeader, TableHeaderRow, TableHeaderCell, Checkbox, TableBody, TableRow, TableBodyCell } from '@shipengine/giger';
3
+ import { TableRow, TableBodyCell, Skeleton, SkeletonAnimation, SkeletonVariant, Table, TableFooter, TableHeader, TableHeaderRow, TableHeaderCell, Checkbox, TableBody } from '@shipengine/giger';
4
4
  import { styles } from './grid-controller.styles.js';
5
5
 
6
6
  /**
@@ -17,15 +17,33 @@ const GridController = ({
17
17
  data,
18
18
  footerContent,
19
19
  onRowClick,
20
+ isLoading: _isLoading = false,
20
21
  useCheckboxes: _useCheckboxes = false,
21
22
  filters,
22
23
  emptyContent
23
24
  }) => {
24
25
  var _a, _b, _c;
25
26
  const [isChecked, setIsChecked] = useState((_a = data === null || data === void 0 ? void 0 : data.map(() => false)) !== null && _a !== void 0 ? _a : []);
26
- const getColumnHeaderContents = () => {
27
- return columns.map(column => column.headerContent);
28
- };
27
+ const columnHeaderContents = useMemo(() => columns.map(column => column.headerContent), [columns]);
28
+ const loadingRows = useMemo(() => {
29
+ const items = [];
30
+ for (let index = 0; index < 5; index++) {
31
+ items.push(jsx(TableRow, Object.assign({
32
+ css: styles.skeletonTableRow,
33
+ withHover: false
34
+ }, {
35
+ children: columnHeaderContents.map((item, index) => jsx(TableBodyCell, {
36
+ children: item && jsx(Skeleton, {
37
+ animation: SkeletonAnimation.WAVE,
38
+ height: 16,
39
+ variant: SkeletonVariant.RECT,
40
+ width: 72
41
+ })
42
+ }, index))
43
+ }), `loading-row-${index}`));
44
+ }
45
+ return items;
46
+ }, [columnHeaderContents]);
29
47
  const isAllChecked = useMemo(() => isChecked.length > 0 && isChecked.every(check => check), [isChecked]);
30
48
  const isIndeterminate = useMemo(() => isChecked.some(check => check), [isChecked]);
31
49
  const toggleCheckbox = useCallback(index => {
@@ -66,7 +84,7 @@ const GridController = ({
66
84
  indeterminate: (_c = !isAllChecked && isIndeterminate) !== null && _c !== void 0 ? _c : false,
67
85
  onChange: event => toggleAllCheckboxes(event.target.checked)
68
86
  })
69
- })), getColumnHeaderContents().map((header, index) => jsx(TableHeaderCell, Object.assign({
87
+ })), columnHeaderContents.map((header, index) => jsx(TableHeaderCell, Object.assign({
70
88
  css: styles.tableHeader
71
89
  }, {
72
90
  children: header
@@ -76,8 +94,8 @@ const GridController = ({
76
94
  outerWrapperStyles: styles.tableWrapper,
77
95
  tableStyles: styles.table
78
96
  }, {
79
- children: jsx(TableBody, {
80
- children: data.map((row, index) => {
97
+ children: jsxs(TableBody, {
98
+ children: [_isLoading && loadingRows, data.map((row, index) => {
81
99
  var _a;
82
100
  const allowOnClick = !!onRowClick && !(row === null || row === void 0 ? void 0 : row.disableOnRowClick);
83
101
  return jsxs(TableRow, Object.assign({
@@ -98,7 +116,7 @@ const GridController = ({
98
116
  children: column.renderCellContent(row)
99
117
  }), index))]
100
118
  }), index);
101
- })
119
+ })]
102
120
  })
103
121
  }))]
104
122
  }));
@@ -5,8 +5,12 @@ const styles = createStyles({
5
5
  width: scopeTheme(theme).spacing(6)
6
6
  }),
7
7
  filters: theme => ({
8
+ backgroundColor: scopeTheme(theme).palette.white,
8
9
  borderBottom: `1px solid ${scopeTheme(theme).palette.gray[200]}`,
9
- padding: `${scopeTheme(theme).spacing()}px ${scopeTheme(theme).spacing(2)}px`
10
+ padding: scopeTheme(theme).spacing()
11
+ }),
12
+ skeletonTableRow: () => ({
13
+ height: "68px"
10
14
  }),
11
15
  table: {
12
16
  tableLayout: "initial"
@@ -22,7 +26,8 @@ const styles = createStyles({
22
26
  border: "none"
23
27
  },
24
28
  wrapper: theme => Object.assign({
25
- height: "auto"
29
+ height: "auto",
30
+ overflow: "hidden"
26
31
  }, scopeTheme(theme).getComponentOverride("Table"))
27
32
  });
28
33