@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
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,
@@ -216,12 +216,14 @@ 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",
222
223
  labelId: "Label ID",
223
224
  labelIdFilter: "{{name}}: {{labelId}}",
224
- filteredTrackingStatus: "Delivery Status: {{filter}}",
225
+ filteredStatus: "{{name}}: {{filter}}",
226
+ filteredTrackingStatus: "{{name}}: {{filter}}",
225
227
  more: ", +{{count}} more",
226
228
  createdDate: "Created Date",
227
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.21.0";
5
+ var version = "2.23.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"
@@ -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
@@ -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 => {
@@ -51,7 +69,7 @@ const GridController = ({
51
69
  children: filters
52
70
  })), data.length === 0 && emptyContent ? emptyContent : jsx(Table, Object.assign({
53
71
  "data-testid": "grid",
54
- footer: footerContent && jsx(TableFooter, Object.assign({
72
+ footer: footerContent && !_isLoading && jsx(TableFooter, Object.assign({
55
73
  css: styles.tableFooter
56
74
  }, {
57
75
  children: footerContent
@@ -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
@@ -77,27 +95,41 @@ const GridController = ({
77
95
  tableStyles: styles.table
78
96
  }, {
79
97
  children: jsx(TableBody, {
80
- children: data.map((row, index) => {
98
+ children: _isLoading ? loadingRows : data.map((row, rowIndex) => {
81
99
  var _a;
82
- 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;
83
101
  return jsxs(TableRow, Object.assign({
102
+ css: row.isLoading && styles.skeletonTableRow,
84
103
  "data-testid": "grid-row",
85
- onClick: allowOnClick ? () => onRowClick(row) : undefined,
86
- 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
87
106
  }, {
88
107
  children: [_useCheckboxes && jsx(TableBodyCell, Object.assign({
89
108
  css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
90
109
  }, {
91
110
  children: jsx(Checkbox, {
92
- checked: (_a = isChecked[index]) !== null && _a !== void 0 ? _a : false,
93
- onChange: () => toggleCheckbox(index)
111
+ checked: (_a = isChecked[rowIndex]) !== null && _a !== void 0 ? _a : false,
112
+ onChange: () => toggleCheckbox(rowIndex)
94
113
  })
95
- })), columns.filter(column => column.renderCellContent).map((column, index) => jsx(TableBodyCell, Object.assign({
96
- css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
97
- }, {
98
- children: column.renderCellContent(row)
99
- }), index))]
100
- }), index);
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);
101
133
  })
102
134
  })
103
135
  }))]
@@ -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
 
@@ -1,6 +1,8 @@
1
- import { jsxs, Fragment, jsx } from '@emotion/react/jsx-runtime';
1
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
2
  import { Trans } from 'react-i18next';
3
- import { Typography, Pagination } from '@shipengine/giger';
3
+ import { Typography, SpinnerSize, Pagination } from '@shipengine/giger';
4
+ import { styles } from './grid-footer.styles.js';
5
+ import { Loader } from '../loader/loader.js';
4
6
 
5
7
  /**
6
8
  * @internal
@@ -17,30 +19,43 @@ const GridFooter = ({
17
19
  pageSize,
18
20
  total,
19
21
  showPagination,
20
- onPageChange
22
+ onPageChange,
23
+ isLoadingMore,
24
+ hasMoreUnfetchedResults
21
25
  }) => {
22
26
  const firstElementInPage = (page - 1) * pageSize + 1;
23
27
  const lastElementInPage = Math.min(page * pageSize, total);
24
- return jsxs(Fragment, {
25
- children: [jsx(Typography, Object.assign({
26
- component: "span",
27
- variant: "body2"
28
+ return jsxs("div", Object.assign({
29
+ css: styles.wrapper
30
+ }, {
31
+ children: [jsxs("div", Object.assign({
32
+ css: styles.countWrapper
28
33
  }, {
29
- children: jsx(Trans, {
30
- components: [jsx("b", {})],
31
- count: total,
32
- i18nKey: "common:grid.row-count",
33
- values: {
34
- firstIndex: firstElementInPage,
35
- lastIndex: lastElementInPage
36
- }
37
- })
34
+ children: [firstElementInPage > 0 && jsx(Typography, Object.assign({
35
+ component: "span",
36
+ variant: "body2"
37
+ }, {
38
+ children: jsx(Trans, {
39
+ components: [jsx("b", {})],
40
+ count: total,
41
+ i18nKey: hasMoreUnfetchedResults && total > 1 ? "common:grid.row-count-plus_other" : "common:grid.row-count",
42
+ values: {
43
+ firstIndex: firstElementInPage,
44
+ lastIndex: lastElementInPage
45
+ }
46
+ })
47
+ })), isLoadingMore && jsx("div", {
48
+ children: jsx(Loader, {
49
+ css: styles.loader,
50
+ size: SpinnerSize.SIZE_SMALL
51
+ })
52
+ })]
38
53
  })), showPagination && jsx(Pagination, {
39
54
  currentPage: page,
40
55
  onPageChange: onPageChange,
41
56
  totalPages: pages
42
57
  })]
43
- });
58
+ }));
44
59
  };
45
60
 
46
61
  export { GridFooter };
@@ -0,0 +1,20 @@
1
+ import { createStyles, scopeTheme } from '../../utilities/styles.js';
2
+
3
+ const styles = createStyles({
4
+ countWrapper: theme => ({
5
+ alignItems: "center",
6
+ display: "flex",
7
+ gap: scopeTheme(theme).spacing(1)
8
+ }),
9
+ loader: theme => ({
10
+ color: scopeTheme(theme).palette.gray.main
11
+ }),
12
+ wrapper: {
13
+ alignItems: "center",
14
+ display: "flex",
15
+ justifyContent: "space-between",
16
+ width: "100%"
17
+ }
18
+ });
19
+
20
+ export { styles };
@@ -1,4 +1,4 @@
1
1
  export { GridController } from './grid-controller.js';
2
2
  export { CellFormattedDate } from './cell-formatted-date.js';
3
3
  export { GridFooter } from './grid-footer.js';
4
- export { SortableHeader } from './sortable-header.js';
4
+ export { SortableHeader } from './sortable-header/sortable-header.js';
@@ -0,0 +1 @@
1
+ export { SortableHeader } from './sortable-header.js';
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
2
  import { Icon, IconSize } from '@shipengine/giger';
3
3
  import { IconNames } from '@shipengine/giger-theme';
4
+ import { styles } from './sortable-header.styles.js';
4
5
 
5
6
  /**
6
7
  * A reusable component for creating sortable table headers
@@ -19,17 +20,14 @@ const SortableHeader = ({
19
20
  };
20
21
  return jsxs("span", Object.assign({
21
22
  "aria-label": headerText,
22
- css: {
23
- alignItems: "center",
24
- cursor: "pointer",
25
- display: "flex"
26
- },
23
+ css: styles.span,
27
24
  onClick: onToggleSort,
28
25
  onKeyDown: handleKeyDown,
29
26
  role: "button",
30
27
  tabIndex: 0
31
28
  }, {
32
29
  children: [headerText, jsx(Icon, {
30
+ css: styles.icon,
33
31
  name: sortDirection === "desc" ? IconNames.SORT_BOTTOM : IconNames.SORT_TOP,
34
32
  size: IconSize.SIZE_SMALL
35
33
  })]
@@ -0,0 +1,14 @@
1
+ import { createStyles, scopeTheme } from '../../../utilities/styles.js';
2
+
3
+ const styles = createStyles({
4
+ icon: theme => ({
5
+ paddingLeft: scopeTheme(theme).spacing()
6
+ }),
7
+ span: () => ({
8
+ alignItems: "center",
9
+ cursor: "pointer",
10
+ display: "flex"
11
+ })
12
+ });
13
+
14
+ export { styles };
@@ -20,6 +20,7 @@ import { useElements } from '../../../../elements-provider/elements-context-prov
20
20
  * @see {@link CreatedDateFilterProps | The props for the `<CreatedDateFilter />` component}
21
21
  */
22
22
  const CreatedDateFilter = ({
23
+ disabled: _disabled = false,
23
24
  filters,
24
25
  onFiltersUpdated
25
26
  }) => {
@@ -101,6 +102,7 @@ const CreatedDateFilter = ({
101
102
  }, [filters.createdDate]);
102
103
  return ((_a = filters.createdDate) === null || _a === void 0 ? void 0 : _a.value) ? jsxs(Button, Object.assign({
103
104
  css: styles.mainButton,
105
+ disabled: _disabled,
104
106
  onClick: onFilterClear,
105
107
  variant: ButtonVariant.TEXT
106
108
  }, {
@@ -119,6 +121,7 @@ const CreatedDateFilter = ({
119
121
  })) : jsxs(Fragment, {
120
122
  children: [jsxs(Button, Object.assign({
121
123
  css: styles.mainButton,
124
+ disabled: _disabled,
122
125
  onClick: onToggleCreatedDateFilter,
123
126
  ref: buttonRef,
124
127
  variant: ButtonVariant.TEXT
@@ -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';
@@ -23,6 +23,7 @@ import { SubmitButton } from '../../../field/submit-button/submit-button.js';
23
23
  * @see {@link LabelIdFilterProps | The props for the `<LabelIdFilter />` component}
24
24
  */
25
25
  const LabelIdFilter = ({
26
+ disabled: _disabled = false,
26
27
  filters,
27
28
  onFiltersUpdated
28
29
  }) => {
@@ -58,6 +59,7 @@ const LabelIdFilter = ({
58
59
  jsx(Fragment, {
59
60
  children: jsxs(Fragment, {
60
61
  children: [jsx(Button, Object.assign({
62
+ disabled: _disabled,
61
63
  onClick: toggleLabelIdFilter,
62
64
  ref: buttonRef,
63
65
  variant: ButtonVariant.TEXT
@@ -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 };
@@ -0,0 +1,17 @@
1
+ import { createStyles, scopeTheme } from '../../../../utilities/styles.js';
2
+
3
+ const styles = createStyles({
4
+ buttons: theme => ({
5
+ display: "flex",
6
+ gap: scopeTheme(theme).spacing(),
7
+ justifyContent: "end",
8
+ paddingTop: scopeTheme(theme).spacing(2)
9
+ }),
10
+ radioGroup: theme => ({
11
+ display: "flex",
12
+ flexDirection: "column",
13
+ gap: scopeTheme(theme).spacing(0.5)
14
+ })
15
+ });
16
+
17
+ export { styles };
@@ -23,6 +23,7 @@ import { SubmitButton } from '../../../field/submit-button/submit-button.js';
23
23
  * @see {@link ShipmentIdFilterProps | The props for the `<ShipmentIdFilter />` component}
24
24
  */
25
25
  const ShipmentIdFilter = ({
26
+ disabled: _disabled = false,
26
27
  filters,
27
28
  onFiltersUpdated
28
29
  }) => {
@@ -57,6 +58,7 @@ const ShipmentIdFilter = ({
57
58
  children: jsxs(Fragment, {
58
59
  children: [jsx(Button, Object.assign({
59
60
  css: styles.mainButton,
61
+ disabled: _disabled,
60
62
  onClick: toggleShipmentIdFilter,
61
63
  ref: buttonRef,
62
64
  variant: ButtonVariant.TEXT