@shipengine/elements 2.22.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/cjs/components/grid-controller/grid-controller.cjs +29 -15
  2. package/cjs/components/grid-filters/components/index.cjs +2 -0
  3. package/cjs/components/grid-filters/components/label-status-filter/index.cjs +9 -0
  4. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter-schema.cjs +12 -0
  5. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.cjs +174 -0
  6. package/cjs/components/grid-filters/components/label-status-filter/label-status-filter.styles.cjs +21 -0
  7. package/cjs/components/grid-filters/components/tracking-status-filter/tracking-status-filter.cjs +21 -12
  8. package/cjs/components/grid-filters/grid-filters.cjs +6 -1
  9. package/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +25 -12
  10. package/cjs/elements/labels-grid/labels-grid.cjs +11 -2
  11. package/cjs/elements/purchase-label/components/customs-forms/customs-forms.cjs +10 -3
  12. package/cjs/elements/purchase-label/components/rate-form/rate-view.cjs +4 -9
  13. package/cjs/elements/purchase-label/components/shipment-form/shipment-form.cjs +11 -5
  14. package/cjs/elements/purchase-label/configure-shipment.cjs +3 -1
  15. package/cjs/elements/purchase-label/hooks/use-rates-form.cjs +38 -16
  16. package/cjs/elements/purchase-label/purchase-label.cjs +0 -1
  17. package/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +5 -1
  18. package/cjs/elements/shipments-grid/shipments-grid.cjs +12 -5
  19. package/cjs/hooks/index.cjs +3 -0
  20. package/cjs/hooks/use-configure-shipment.cjs +1 -34
  21. package/cjs/index.cjs +5 -0
  22. package/cjs/locales/en/common.cjs +2 -1
  23. package/cjs/locales/en/purchase-label.cjs +2 -1
  24. package/cjs/package.cjs +1 -1
  25. package/cjs/workflows/label-workflow/label-workflow.cjs +0 -1
  26. package/esm/components/grid-controller/grid-controller.js +29 -15
  27. package/esm/components/grid-filters/components/index.js +1 -0
  28. package/esm/components/grid-filters/components/label-status-filter/index.js +1 -0
  29. package/esm/components/grid-filters/components/label-status-filter/label-status-filter-schema.js +8 -0
  30. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.js +170 -0
  31. package/esm/components/grid-filters/components/label-status-filter/label-status-filter.styles.js +17 -0
  32. package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js +21 -12
  33. package/esm/components/grid-filters/grid-filters.js +6 -1
  34. package/esm/elements/labels-grid/hooks/use-labels-grid.js +25 -12
  35. package/esm/elements/labels-grid/labels-grid.js +11 -2
  36. package/esm/elements/purchase-label/components/customs-forms/customs-forms.js +10 -3
  37. package/esm/elements/purchase-label/components/rate-form/rate-view.js +4 -9
  38. package/esm/elements/purchase-label/components/shipment-form/shipment-form.js +11 -5
  39. package/esm/elements/purchase-label/configure-shipment.js +3 -1
  40. package/esm/elements/purchase-label/hooks/use-rates-form.js +38 -16
  41. package/esm/elements/purchase-label/purchase-label.js +0 -1
  42. package/esm/elements/shipments-grid/hooks/use-shipments-grid.js +5 -1
  43. package/esm/elements/shipments-grid/shipments-grid.js +12 -5
  44. package/esm/hooks/index.js +1 -0
  45. package/esm/hooks/use-configure-shipment.js +3 -36
  46. package/esm/index.js +2 -0
  47. package/esm/locales/en/common.js +2 -1
  48. package/esm/locales/en/purchase-label.js +2 -1
  49. package/esm/package.js +1 -1
  50. package/esm/workflows/label-workflow/label-workflow.js +0 -1
  51. package/package.json +13 -2
  52. package/types/src/components/grid-controller/grid-controller.d.ts +2 -0
  53. package/types/src/components/grid-filters/components/index.d.ts +1 -0
  54. package/types/src/components/grid-filters/components/label-status-filter/index.d.ts +1 -0
  55. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter-schema.d.ts +12 -0
  56. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.d.ts +24 -0
  57. package/types/src/components/grid-filters/components/label-status-filter/label-status-filter.styles.d.ts +13 -0
  58. package/types/src/components/grid-filters/grid-filters.d.ts +2 -0
  59. package/types/src/elements/labels-grid/hooks/use-labels-grid.d.ts +2 -1
  60. package/types/src/elements/labels-grid/labels-grid.d.ts +3 -4
  61. package/types/src/elements/manage-carriers/manage-carriers.d.ts +2 -0
  62. package/types/src/elements/manage-external-carriers/manage-external-carriers.d.ts +2 -0
  63. package/types/src/elements/manage-funding/manage-funding-element.d.ts +2 -0
  64. package/types/src/elements/manage-warehouses/manage-warehouses.d.ts +2 -0
  65. package/types/src/elements/payment-method-settings/payment-method-settings-element.d.ts +2 -0
  66. package/types/src/elements/purchase-label/hooks/use-rates-form.d.ts +1 -0
  67. package/types/src/elements/purchase-label/purchase-label.d.ts +11 -9
  68. package/types/src/elements/select-label-layout/select-label-layout-element.d.ts +2 -0
  69. package/types/src/elements/shipment-summary/shipment-summary.d.ts +2 -0
  70. package/types/src/elements/shipments-grid/hooks/use-shipments-grid.d.ts +11 -6
  71. package/types/src/elements/shipments-grid/shipments-grid.d.ts +31 -5
  72. package/types/src/elements/theme-creator/theme-creator.d.ts +2 -0
  73. package/types/src/elements/transaction-history/transaction-history-element.d.ts +2 -0
  74. package/types/src/elements/unit-settings/unit-settings-element.d.ts +2 -0
  75. package/types/src/elements/vat-settings/vat-settings-element.d.ts +2 -0
  76. package/types/src/elements/void-label/void-label.d.ts +33 -0
  77. package/types/src/hooks/index.d.ts +1 -0
  78. package/types/src/hooks/use-configure-shipment.d.ts +1 -2
  79. package/types/src/index.d.ts +5 -0
  80. package/types/src/locales/en/index.d.ts +2 -0
  81. package/types/src/utilities/feature-flags/types.d.ts +5 -1
  82. package/types/src/workflows/account-settings/account-settings.d.ts +2 -0
  83. package/types/src/workflows/carrier-services/carrier-services.d.ts +2 -0
  84. package/types/src/workflows/connect-external-carrier/connect-external-carrier.d.ts +2 -0
  85. package/types/src/workflows/label-workflow/label-workflow.d.ts +10 -1
  86. package/types/src/workflows/onboarding/onboarding.d.ts +2 -0
@@ -73,7 +73,7 @@ const GridController = ({
73
73
  children: filters
74
74
  })), data.length === 0 && emptyContent ? emptyContent : jsxRuntime.jsx(giger.Table, Object.assign({
75
75
  "data-testid": "grid",
76
- footer: footerContent && jsxRuntime.jsx(giger.TableFooter, Object.assign({
76
+ footer: footerContent && !_isLoading && jsxRuntime.jsx(giger.TableFooter, Object.assign({
77
77
  css: gridController_styles.styles.tableFooter
78
78
  }, {
79
79
  children: footerContent
@@ -98,29 +98,43 @@ const GridController = ({
98
98
  outerWrapperStyles: gridController_styles.styles.tableWrapper,
99
99
  tableStyles: gridController_styles.styles.table
100
100
  }, {
101
- children: jsxRuntime.jsxs(giger.TableBody, {
102
- children: [_isLoading && loadingRows, data.map((row, index) => {
101
+ children: jsxRuntime.jsx(giger.TableBody, {
102
+ children: _isLoading ? loadingRows : data.map((row, rowIndex) => {
103
103
  var _a;
104
- const allowOnClick = !!onRowClick && !(row === null || row === void 0 ? void 0 : row.disableOnRowClick);
104
+ const allowOnClick = !!onRowClick && !(row === null || row === void 0 ? void 0 : row.disableOnRowClick) || !row.isLoading;
105
105
  return jsxRuntime.jsxs(giger.TableRow, Object.assign({
106
+ css: row.isLoading && gridController_styles.styles.skeletonTableRow,
106
107
  "data-testid": "grid-row",
107
- onClick: allowOnClick ? () => onRowClick(row) : undefined,
108
- withHover: !(row === null || row === void 0 ? void 0 : row.disableOnRowClick)
108
+ onClick: allowOnClick ? () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row) : undefined,
109
+ withHover: allowOnClick
109
110
  }, {
110
111
  children: [_useCheckboxes && jsxRuntime.jsx(giger.TableBodyCell, Object.assign({
111
112
  css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
112
113
  }, {
113
114
  children: jsxRuntime.jsx(giger.Checkbox, {
114
- checked: (_a = isChecked[index]) !== null && _a !== void 0 ? _a : false,
115
- onChange: () => toggleCheckbox(index)
115
+ checked: (_a = isChecked[rowIndex]) !== null && _a !== void 0 ? _a : false,
116
+ onChange: () => toggleCheckbox(rowIndex)
116
117
  })
117
- })), columns.filter(column => column.renderCellContent).map((column, index) => jsxRuntime.jsx(giger.TableBodyCell, Object.assign({
118
- css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
119
- }, {
120
- children: column.renderCellContent(row)
121
- }), index))]
122
- }), index);
123
- })]
118
+ })), columns.filter(column => column.renderCellContent).map((column, index) => {
119
+ if (row.isLoading) {
120
+ return jsxRuntime.jsx(giger.TableBodyCell, Object.assign({
121
+ css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
122
+ }, {
123
+ children: jsxRuntime.jsx(giger.Skeleton, {
124
+ animation: giger.SkeletonAnimation.WAVE,
125
+ height: 24,
126
+ variant: giger.SkeletonVariant.RECT
127
+ })
128
+ }), index);
129
+ }
130
+ return jsxRuntime.jsx(giger.TableBodyCell, Object.assign({
131
+ css: row === null || row === void 0 ? void 0 : row.bodyCellStyles
132
+ }, {
133
+ children: column.renderCellContent(row)
134
+ }), index);
135
+ })]
136
+ }), rowIndex);
137
+ })
124
138
  })
125
139
  }))]
126
140
  }));
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var shipmentIdFilter = require('./shipment-id-filter/shipment-id-filter.cjs');
6
6
  var createdDateFilter = require('./created-date-filter/created-date-filter.cjs');
7
7
  var labelIdFilter = require('./label-id-filter/label-id-filter.cjs');
8
+ var labelStatusFilter = require('./label-status-filter/label-status-filter.cjs');
8
9
  var trackingStatusFilter = require('./tracking-status-filter/tracking-status-filter.cjs');
9
10
 
10
11
 
@@ -12,4 +13,5 @@ var trackingStatusFilter = require('./tracking-status-filter/tracking-status-fil
12
13
  exports.ShipmentIdFilter = shipmentIdFilter.ShipmentIdFilter;
13
14
  exports.CreatedDateFilter = createdDateFilter.CreatedDateFilter;
14
15
  exports.LabelIdFilter = labelIdFilter.LabelIdFilter;
16
+ exports.LabelStatusFilter = labelStatusFilter.LabelStatusFilter;
15
17
  exports.TrackingStatusFilter = trackingStatusFilter.TrackingStatusFilter;
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var labelStatusFilter = require('./label-status-filter.cjs');
6
+
7
+
8
+
9
+ exports.LabelStatusFilter = labelStatusFilter.LabelStatusFilter;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var zod = require('zod');
6
+
7
+ const labelStatusFormSchema = zod.z.object({
8
+ labelStatus: zod.z.union([zod.z.literal("completed"), zod.z.literal("error"), zod.z.literal("processing"), zod.z.literal("voided"), zod.z.literal("") // Empty string for no selection
9
+ ])
10
+ });
11
+
12
+ exports.labelStatusFormSchema = labelStatusFormSchema;
@@ -0,0 +1,174 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('@emotion/react/jsx-runtime');
6
+ var validation = require('../../../../utilities/validation.cjs');
7
+ var React = require('react');
8
+ var reactHookForm = require('react-hook-form');
9
+ var reactI18next = require('react-i18next');
10
+ var reactUse = require('react-use');
11
+ var giger = require('@shipengine/giger');
12
+ var gigerTheme = require('@shipengine/giger-theme');
13
+ var labelStatusFilterSchema = require('./label-status-filter-schema.cjs');
14
+ var labelStatusFilter_styles = require('./label-status-filter.styles.cjs');
15
+
16
+ /**
17
+ * @internal
18
+ *
19
+ * # StatusFilter
20
+ *
21
+ * - The `<StatusFilter />` component handles the label status filter used in Labels Grid.
22
+ *
23
+ * @see {@link StatusFilterProps | The props for the `<StatusFilter />` component}
24
+ */
25
+ const LabelStatusFilter = ({
26
+ disabled: _disabled = false,
27
+ filters,
28
+ onFiltersUpdated
29
+ }) => {
30
+ var _a, _b, _c, _d, _e;
31
+ const {
32
+ t
33
+ } = reactI18next.useTranslation();
34
+ const [showLabelStatusFilter, toggleLabelStatusFilter] = reactUse.useToggle(false);
35
+ const [buttonText, setButtonText] = React.useState(((_a = filters === null || filters === void 0 ? void 0 : filters.status) === null || _a === void 0 ? void 0 : _a.nickname) || t("list-labels:headers.status"));
36
+ const buttonRef = React.useRef(null);
37
+ const form = reactHookForm.useForm({
38
+ defaultValues: {
39
+ labelStatus: ""
40
+ },
41
+ resolver: validation.validationResolver(labelStatusFilterSchema.labelStatusFormSchema)
42
+ });
43
+ const determineButtonText = React.useCallback(status => {
44
+ var _a, _b;
45
+ if (!status) {
46
+ return ((_a = filters === null || filters === void 0 ? void 0 : filters.status) === null || _a === void 0 ? void 0 : _a.nickname) || t("list-labels:headers.status");
47
+ }
48
+ return t("common:grid.filteredStatus", {
49
+ filter: t(`list-labels:status.${status}`),
50
+ name: ((_b = filters === null || filters === void 0 ? void 0 : filters.status) === null || _b === void 0 ? void 0 : _b.nickname) || t("list-labels:headers.status")
51
+ });
52
+ }, [t, (_b = filters === null || filters === void 0 ? void 0 : filters.status) === null || _b === void 0 ? void 0 : _b.nickname]);
53
+ React.useEffect(() => {
54
+ var _a;
55
+ // keep form in sync with filters
56
+ if ((_a = filters.status) === null || _a === void 0 ? void 0 : _a.value) {
57
+ form.reset({
58
+ labelStatus: filters.status.value
59
+ });
60
+ setButtonText(determineButtonText(filters.status.value));
61
+ } else {
62
+ // Reset to default when filter value is empty
63
+ form.reset({
64
+ labelStatus: ""
65
+ });
66
+ }
67
+ }, [determineButtonText, (_c = filters.status) === null || _c === void 0 ? void 0 : _c.value, form]);
68
+ const onClearFilters = React.useCallback(() => {
69
+ onFiltersUpdated(Object.assign(Object.assign({}, filters), {
70
+ status: Object.assign(Object.assign({}, filters.status), {
71
+ enabled: true,
72
+ value: ""
73
+ })
74
+ }));
75
+ // Reset the form
76
+ form.reset({
77
+ labelStatus: ""
78
+ });
79
+ showLabelStatusFilter && toggleLabelStatusFilter();
80
+ }, [filters, onFiltersUpdated, showLabelStatusFilter, toggleLabelStatusFilter, form]);
81
+ const handleRadioChange = e => {
82
+ const value = e.target.value;
83
+ form.setValue("labelStatus", value);
84
+ onFiltersUpdated(Object.assign(Object.assign({}, filters), {
85
+ status: Object.assign(Object.assign({}, filters.status), {
86
+ enabled: true,
87
+ value
88
+ })
89
+ }));
90
+ };
91
+ const watchedValue = form.watch("labelStatus");
92
+ const isRadioSelected = watchedValue !== undefined && watchedValue !== "";
93
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
94
+ children: [jsxRuntime.jsxs(giger.Button, Object.assign({
95
+ disabled: _disabled,
96
+ onClick: toggleLabelStatusFilter,
97
+ ref: buttonRef,
98
+ variant: giger.ButtonVariant.TEXT
99
+ }, {
100
+ children: [isRadioSelected ? jsxRuntime.jsx("span", {
101
+ children: buttonText
102
+ }) : jsxRuntime.jsx("span", {
103
+ 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")
104
+ }), isRadioSelected ?
105
+ // Show Close Icon
106
+ jsxRuntime.jsx(giger.Icon, {
107
+ "aria-label": t("common:grid.clear"),
108
+ name: gigerTheme.IconNames.CLOSE,
109
+ onClick: e => {
110
+ e.stopPropagation();
111
+ onClearFilters();
112
+ },
113
+ onKeyDown: e => {
114
+ if (e.key === "Enter" || e.key === " ") {
115
+ e.stopPropagation();
116
+ onClearFilters();
117
+ }
118
+ },
119
+ role: "button",
120
+ size: giger.IconSize.SIZE_SMALL,
121
+ tabIndex: 0
122
+ }) : showLabelStatusFilter ? jsxRuntime.jsx(giger.Icon, {
123
+ name: gigerTheme.IconNames.CARET_TOP,
124
+ size: giger.IconSize.SIZE_SMALL
125
+ }) : jsxRuntime.jsx(giger.Icon, {
126
+ name: gigerTheme.IconNames.CARET_BOTTOM,
127
+ size: giger.IconSize.SIZE_SMALL
128
+ })]
129
+ })), jsxRuntime.jsx(giger.Popover, Object.assign({
130
+ isOpen: showLabelStatusFilter,
131
+ onClickAway: toggleLabelStatusFilter,
132
+ reference: buttonRef.current
133
+ }, {
134
+ children: jsxRuntime.jsxs("form", {
135
+ children: [jsxRuntime.jsxs(giger.RadioGroup, Object.assign({
136
+ css: labelStatusFilter_styles.styles.radioGroup,
137
+ name: "status",
138
+ onChange: handleRadioChange,
139
+ value: watchedValue
140
+ }, {
141
+ children: [jsxRuntime.jsx(giger.Radio, Object.assign({
142
+ value: "completed"
143
+ }, {
144
+ children: t("list-labels:status.completed")
145
+ })), jsxRuntime.jsx(giger.Radio, Object.assign({
146
+ value: "error"
147
+ }, {
148
+ children: t("list-labels:status.error")
149
+ })), jsxRuntime.jsx(giger.Radio, Object.assign({
150
+ value: "processing"
151
+ }, {
152
+ children: t("list-labels:status.processing")
153
+ })), jsxRuntime.jsx(giger.Radio, Object.assign({
154
+ value: "voided"
155
+ }, {
156
+ children: t("list-labels:status.voided")
157
+ }))]
158
+ })), isRadioSelected && jsxRuntime.jsx("div", Object.assign({
159
+ css: labelStatusFilter_styles.styles.buttons
160
+ }, {
161
+ children: jsxRuntime.jsx(giger.Button, Object.assign({
162
+ disabled: !isRadioSelected,
163
+ onClick: onClearFilters,
164
+ variant: giger.ButtonVariant.OUTLINED
165
+ }, {
166
+ children: t("common:grid.clear")
167
+ }))
168
+ }))]
169
+ })
170
+ }))]
171
+ });
172
+ };
173
+
174
+ exports.LabelStatusFilter = LabelStatusFilter;
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var styles$1 = require('../../../../utilities/styles.cjs');
6
+
7
+ const styles = styles$1.createStyles({
8
+ buttons: theme => ({
9
+ display: "flex",
10
+ gap: styles$1.scopeTheme(theme).spacing(),
11
+ justifyContent: "end",
12
+ paddingTop: styles$1.scopeTheme(theme).spacing(2)
13
+ }),
14
+ radioGroup: theme => ({
15
+ display: "flex",
16
+ flexDirection: "column",
17
+ gap: styles$1.scopeTheme(theme).spacing(0.5)
18
+ })
19
+ });
20
+
21
+ exports.styles = styles;
@@ -29,7 +29,7 @@ const TrackingStatusFilter = ({
29
29
  filters,
30
30
  onFiltersUpdated
31
31
  }) => {
32
- var _a;
32
+ var _a, _b, _c, _d;
33
33
  const {
34
34
  t
35
35
  } = reactI18next.useTranslation();
@@ -46,21 +46,24 @@ const TrackingStatusFilter = ({
46
46
  },
47
47
  resolver: validation.validationResolver(trackingStatusFilterSchema.trackingStatusFormSchema)
48
48
  });
49
- const determineButtonText = React.useCallback(filters => {
50
- if (filters.length === 0) {
51
- return t("list-labels:headers.trackingStatus");
52
- } else if (filters.length === 1) {
49
+ const determineButtonText = React.useCallback(statuses => {
50
+ var _a, _b, _c;
51
+ if (statuses.length === 0) {
52
+ return ((_a = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.nickname) || t("list-labels:headers.trackingStatus");
53
+ } else if (statuses.length === 1) {
53
54
  return t("common:grid.filteredTrackingStatus", {
54
- filter: t(`list-labels:trackingStatus.${filters[0]}`)
55
+ filter: t(`list-labels:trackingStatus.${statuses[0]}`),
56
+ name: ((_b = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _b === void 0 ? void 0 : _b.nickname) || t("list-labels:headers.trackingStatus")
55
57
  });
56
58
  } else {
57
59
  return t("common:grid.filteredTrackingStatus", {
58
- filter: t(`list-labels:trackingStatus.${filters[0]}`)
60
+ filter: t(`list-labels:trackingStatus.${statuses[0]}`),
61
+ name: ((_c = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.nickname) || t("list-labels:headers.trackingStatus")
59
62
  }) + t("common:grid.more", {
60
- count: filters.length - 1
63
+ count: statuses.length - 1
61
64
  });
62
65
  }
63
- }, [t]);
66
+ }, [t, (_a = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.nickname]);
64
67
  const getUpdatedKeys = React.useCallback(updatedFields => {
65
68
  return Object.keys(updatedFields).filter(key => updatedFields[key]);
66
69
  }, []);
@@ -80,9 +83,13 @@ const TrackingStatusFilter = ({
80
83
  unknown: filters.trackingStatus.value.includes("unknown")
81
84
  };
82
85
  form.reset(updatedFields);
83
- setButtonText(determineButtonText(getUpdatedKeys(updatedFields)));
86
+ // Only set buttonText when filters are applied
87
+ const updatedKeys = getUpdatedKeys(updatedFields);
88
+ if (updatedKeys.length > 0) {
89
+ setButtonText(determineButtonText(updatedKeys));
90
+ }
84
91
  }
85
- }, [determineButtonText, (_a = filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.value, form, getUpdatedKeys, t]);
92
+ }, [determineButtonText, (_b = filters.trackingStatus) === null || _b === void 0 ? void 0 : _b.value, form, getUpdatedKeys]);
86
93
  const onClearFilters = React.useCallback(() => {
87
94
  onFiltersUpdated(Object.assign(Object.assign({}, filters), {
88
95
  trackingStatus: Object.assign(Object.assign({}, filters.trackingStatus), {
@@ -115,8 +122,10 @@ const TrackingStatusFilter = ({
115
122
  ref: buttonRef,
116
123
  variant: giger.ButtonVariant.TEXT
117
124
  }, {
118
- children: [jsxRuntime.jsx("span", {
125
+ children: [isAnyCheckboxChecked ? jsxRuntime.jsx("span", {
119
126
  children: buttonText
127
+ }) : jsxRuntime.jsx("span", {
128
+ children: (_d = (_c = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.nickname) !== null && _d !== void 0 ? _d : t("list-labels:headers.trackingStatus")
120
129
  }), isAnyCheckboxChecked ?
121
130
  // Show Close Icon
122
131
  jsxRuntime.jsx(giger.Icon, {
@@ -9,6 +9,7 @@ var shipmentIdFilter = require('./components/shipment-id-filter/shipment-id-filt
9
9
  var labelIdFilter = require('./components/label-id-filter/label-id-filter.cjs');
10
10
  var createdDateFilter = require('./components/created-date-filter/created-date-filter.cjs');
11
11
  var trackingStatusFilter = require('./components/tracking-status-filter/tracking-status-filter.cjs');
12
+ var labelStatusFilter = require('./components/label-status-filter/label-status-filter.cjs');
12
13
 
13
14
  /**
14
15
  * @internal
@@ -25,7 +26,7 @@ const GridFilters = ({
25
26
  filtersDisabled: _filtersDisabled = false,
26
27
  onClearAllFilters
27
28
  }) => {
28
- var _a, _b, _c;
29
+ var _a, _b, _c, _d;
29
30
  const {
30
31
  t
31
32
  } = reactI18next.useTranslation(["common"]);
@@ -57,6 +58,10 @@ const GridFilters = ({
57
58
  disabled: _filtersDisabled,
58
59
  filters: filters,
59
60
  onFiltersUpdated: onFiltersUpdated
61
+ }), ((_d = filters.status) === null || _d === void 0 ? void 0 : _d.enabled) && jsxRuntime.jsx(labelStatusFilter.LabelStatusFilter, {
62
+ disabled: _filtersDisabled,
63
+ filters: filters,
64
+ onFiltersUpdated: onFiltersUpdated
60
65
  }), shouldShowClearAll && jsxRuntime.jsx(giger.Button, Object.assign({
61
66
  disabled: _filtersDisabled,
62
67
  onClick: () => {
@@ -14,11 +14,12 @@ const useLabelsGrid = ({
14
14
  labelStatus,
15
15
  showShipmentIdFilter,
16
16
  showLabelIdFilter,
17
+ showStatusFilter,
17
18
  showTrackingStatusFilter,
18
19
  fetchShipments,
19
20
  sortDir
20
21
  }) => {
21
- var _a, _b, _c, _d, _e, _f;
22
+ var _a, _b, _c, _d, _e, _f, _g, _h;
22
23
  const initialFilters = {
23
24
  labelId: {
24
25
  enabled: !!showLabelIdFilter,
@@ -28,6 +29,10 @@ const useLabelsGrid = ({
28
29
  enabled: !!showShipmentIdFilter,
29
30
  value: ""
30
31
  },
32
+ status: {
33
+ enabled: !!showStatusFilter,
34
+ value: ""
35
+ },
31
36
  trackingStatus: {
32
37
  enabled: !!showTrackingStatusFilter,
33
38
  value: []
@@ -84,13 +89,17 @@ const useLabelsGrid = ({
84
89
  enabled: !!showShipmentIdFilter,
85
90
  value: ""
86
91
  },
92
+ status: {
93
+ enabled: !!showStatusFilter,
94
+ value: ""
95
+ },
87
96
  trackingStatus: {
88
97
  enabled: !!showTrackingStatusFilter,
89
98
  value: []
90
99
  }
91
100
  };
92
101
  setFilters(updatedFilters);
93
- }, [showLabelIdFilter, showShipmentIdFilter, showTrackingStatusFilter]);
102
+ }, [showLabelIdFilter, showShipmentIdFilter, showStatusFilter, showTrackingStatusFilter]);
94
103
  const isTrackingStatusFilterActive = React.useMemo(() => {
95
104
  var _a, _b;
96
105
  return !!(((_a = filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.enabled) && hasActiveFilterValue((_b = filters.trackingStatus) === null || _b === void 0 ? void 0 : _b.value));
@@ -105,11 +114,11 @@ const useLabelsGrid = ({
105
114
  } = useTrackingStatusFilter.useTrackingStatusFilter({
106
115
  currentPage: page,
107
116
  isActive: isTrackingStatusFilterActive,
108
- labelStatus,
117
+ labelStatus: ((_c = filters.status) === null || _c === void 0 ? void 0 : _c.value) || labelStatus,
109
118
  pageSize,
110
- shipmentId: ((_c = filters.shipmentId) === null || _c === void 0 ? void 0 : _c.value) || undefined,
119
+ shipmentId: ((_d = filters.shipmentId) === null || _d === void 0 ? void 0 : _d.value) || undefined,
111
120
  sortDir: sortDir !== null && sortDir !== void 0 ? sortDir : "desc",
112
- trackingStatusFilters: ((_d = filters.trackingStatus) === null || _d === void 0 ? void 0 : _d.value) || []
121
+ trackingStatusFilters: ((_e = filters.trackingStatus) === null || _e === void 0 ? void 0 : _e.value) || []
113
122
  });
114
123
  // Use regular API pagination when tracking status filter is not active
115
124
  const {
@@ -119,7 +128,7 @@ const useLabelsGrid = ({
119
128
  } = reactApi.useListLabels({
120
129
  enabled: !isTrackingStatusFilterActive,
121
130
  queryFnParams: {
122
- labelStatus,
131
+ labelStatus: ((_f = filters.status) === null || _f === void 0 ? void 0 : _f.value) || labelStatus,
123
132
  page,
124
133
  pageSize,
125
134
  shipmentId: filters.shipmentId.value || undefined,
@@ -161,13 +170,13 @@ const useLabelsGrid = ({
161
170
  data: labelFilterData,
162
171
  isError: isLabelFilterError,
163
172
  isInitialLoading: isLabelFilterLoading
164
- } = reactApi.useGetLabel(((_e = filters.labelId) === null || _e === void 0 ? void 0 : _e.value) || undefined);
165
- const isLabelFilterActive = (_f = filters.labelId) === null || _f === void 0 ? void 0 : _f.value;
173
+ } = reactApi.useGetLabel(((_g = filters.labelId) === null || _g === void 0 ? void 0 : _g.value) || undefined);
174
+ const isLabelFilterActive = (_h = filters.labelId) === null || _h === void 0 ? void 0 : _h.value;
166
175
  const isStatusFilteredOut = (status, filter) => {
167
176
  return (filter === null || filter === void 0 ? void 0 : filter.length) && !filter.includes(status);
168
177
  };
169
178
  const getLabelById = labelById => {
170
- var _a, _b, _c, _d;
179
+ var _a, _b, _c, _d, _e, _f, _g;
171
180
  // Check if filter by label id is active and there are no errors
172
181
  if (isLabelFilterActive && !isLabelFilterError) {
173
182
  let labelPassFilters = true;
@@ -175,15 +184,19 @@ const useLabelsGrid = ({
175
184
  if (labelStatus && labelStatus !== (labelById === null || labelById === void 0 ? void 0 : labelById.status)) {
176
185
  labelPassFilters = false;
177
186
  }
187
+ // Check if status filter is active and if the label has the same status
188
+ if (((_a = filters === null || filters === void 0 ? void 0 : filters.status) === null || _a === void 0 ? void 0 : _a.enabled) && ((_b = filters === null || filters === void 0 ? void 0 : filters.status) === null || _b === void 0 ? void 0 : _b.value) && ((_c = filters === null || filters === void 0 ? void 0 : filters.status) === null || _c === void 0 ? void 0 : _c.value) !== (labelById === null || labelById === void 0 ? void 0 : labelById.status)) {
189
+ labelPassFilters = false;
190
+ }
178
191
  // Check if shipment filter has the same value if defined
179
- if (((_a = filters === null || filters === void 0 ? void 0 : filters.shipmentId) === null || _a === void 0 ? void 0 : _a.value) !== "" && ((_b = filters === null || filters === void 0 ? void 0 : filters.shipmentId) === null || _b === void 0 ? void 0 : _b.value) !== (labelById === null || labelById === void 0 ? void 0 : labelById.shipmentId)) {
192
+ if (((_d = filters === null || filters === void 0 ? void 0 : filters.shipmentId) === null || _d === void 0 ? void 0 : _d.value) !== "" && ((_e = filters === null || filters === void 0 ? void 0 : filters.shipmentId) === null || _e === void 0 ? void 0 : _e.value) !== (labelById === null || labelById === void 0 ? void 0 : labelById.shipmentId)) {
180
193
  labelPassFilters = false;
181
194
  }
182
195
  if (
183
196
  // If Label status is voided and voided status is filtered out, don't show the label
184
- (labelById === null || labelById === void 0 ? void 0 : labelById.status) === "voided" && isStatusFilteredOut("voided", (_c = filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.value) ||
197
+ (labelById === null || labelById === void 0 ? void 0 : labelById.status) === "voided" && isStatusFilteredOut("voided", (_f = filters.trackingStatus) === null || _f === void 0 ? void 0 : _f.value) ||
185
198
  // If Label status is not voided and tracking status is filtered out, don't show the label
186
- (labelById === null || labelById === void 0 ? void 0 : labelById.status) !== "voided" && (labelById === null || labelById === void 0 ? void 0 : labelById.trackingStatus) && isStatusFilteredOut(labelById.trackingStatus, (_d = filters.trackingStatus) === null || _d === void 0 ? void 0 : _d.value)) {
199
+ (labelById === null || labelById === void 0 ? void 0 : labelById.status) !== "voided" && (labelById === null || labelById === void 0 ? void 0 : labelById.trackingStatus) && isStatusFilteredOut(labelById.trackingStatus, (_g = filters.trackingStatus) === null || _g === void 0 ? void 0 : _g.value)) {
187
200
  labelPassFilters = false;
188
201
  }
189
202
  return labelPassFilters ? labelById : undefined;
@@ -35,7 +35,7 @@ const Component = ({
35
35
  onClickExternalShipmentId,
36
36
  onClickShipmentNumber
37
37
  }) => {
38
- var _a, _b;
38
+ var _a, _b, _c;
39
39
  const {
40
40
  t
41
41
  } = reactI18next.useTranslation(["common", "list-labels"]);
@@ -69,8 +69,13 @@ const Component = ({
69
69
  var _a;
70
70
  return (_a = features === null || features === void 0 ? void 0 : features.columns) === null || _a === void 0 ? void 0 : _a.find(c => c.name === "shipmentNumber");
71
71
  }, [features]);
72
+ const statusColumn = React.useMemo(() => {
73
+ var _a;
74
+ return (_a = features === null || features === void 0 ? void 0 : features.columns) === null || _a === void 0 ? void 0 : _a.find(c => c.name === "status");
75
+ }, [features]);
72
76
  const showLabelIdFilter = labelIdColumn && ((_a = labelIdColumn.allowFilter) !== null && _a !== void 0 ? _a : true);
73
77
  const showShipmentIdFilter = shipmentIdColumn && ((_b = shipmentIdColumn.allowFilter) !== null && _b !== void 0 ? _b : true);
78
+ const showStatusFilter = statusColumn && ((_c = statusColumn.allowFilter) !== null && _c !== void 0 ? _c : true);
74
79
  const showTrackingStatusFilter = trackingStatusColumn && !!trackingStatusColumn.allowFilter;
75
80
  const {
76
81
  labels,
@@ -90,6 +95,7 @@ const Component = ({
90
95
  labelStatus,
91
96
  showLabelIdFilter,
92
97
  showShipmentIdFilter,
98
+ showStatusFilter,
93
99
  showTrackingStatusFilter,
94
100
  sortDir: sortState.dir
95
101
  });
@@ -107,11 +113,14 @@ const Component = ({
107
113
  shipmentId: Object.assign(Object.assign({}, filters.shipmentId), {
108
114
  nickname: shipmentIdColumn === null || shipmentIdColumn === void 0 ? void 0 : shipmentIdColumn.nickname
109
115
  }),
116
+ status: Object.assign(Object.assign({}, filters.status), {
117
+ nickname: statusColumn === null || statusColumn === void 0 ? void 0 : statusColumn.nickname
118
+ }),
110
119
  trackingStatus: Object.assign(Object.assign({}, filters.trackingStatus), {
111
120
  nickname: trackingStatusColumn === null || trackingStatusColumn === void 0 ? void 0 : trackingStatusColumn.nickname
112
121
  })
113
122
  };
114
- }, [filters, labelIdColumn, shipmentIdColumn, trackingStatusColumn]);
123
+ }, [filters, labelIdColumn, shipmentIdColumn, statusColumn, trackingStatusColumn]);
115
124
  const toggleCreatedDateSort = React.useCallback(() => {
116
125
  toggleSort("created_at");
117
126
  }, [toggleSort]);
@@ -9,6 +9,7 @@ var React = require('react');
9
9
  var reactI18next = require('react-i18next');
10
10
  var giger = require('@shipengine/giger');
11
11
  var windsorFramework = require('./windsor-framework/windsor-framework.cjs');
12
+ var shipment = require('../../../../utilities/shipengine/shipment.cjs');
12
13
  var useCustomsContentsOptions = require('../../hooks/use-customs-contents-options.cjs');
13
14
  var useCustomsNonDeliveryOptions = require('../../hooks/use-customs-non-delivery-options.cjs');
14
15
  var productsDisplay = require('./products-display/products-display.cjs');
@@ -28,7 +29,7 @@ const CustomsForms = ({
28
29
  onUpdateCustoms,
29
30
  onUpdateTaxableIds,
30
31
  isCanadaDeliveredDutyEligible,
31
- shipment,
32
+ shipment: shipment$1,
32
33
  onDirty,
33
34
  requiresWindsorFramework: _requiresWindsorFramework = false,
34
35
  harmonizedTariffCodes
@@ -37,6 +38,12 @@ const CustomsForms = ({
37
38
  const {
38
39
  t
39
40
  } = reactI18next.useTranslation(["purchase-label", "common"]);
41
+ // Convert deprecated customs items to the products format
42
+ const formattedShipment = React.useMemo(() => {
43
+ var _a, _b, _c, _d;
44
+ const hasDeprecatedCustomsItems = !!((_b = (_a = shipment$1.customs) === null || _a === void 0 ? void 0 : _a.customsItems) === null || _b === void 0 ? void 0 : _b.length) && !((_d = (_c = shipment$1.packages) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.products);
45
+ return hasDeprecatedCustomsItems ? shipment.moveCustomsItemsToProducts(shipment$1) : shipment$1;
46
+ }, [shipment$1]);
40
47
  const {
41
48
  errors: {
42
49
  packages: packageErrors
@@ -139,11 +146,11 @@ const CustomsForms = ({
139
146
  currency: currency,
140
147
  harmonizedTariffCodes: harmonizedTariffCodes,
141
148
  onUpdate: handleUpdateProducts,
142
- shipment: shipment
149
+ shipment: formattedShipment
143
150
  }), jsxRuntime.jsx(taxIds.TaxIds, {
144
151
  onDirty: onDirty,
145
152
  onUpdateTaxableIds: onUpdateTaxableIds,
146
- shipment: shipment
153
+ shipment: formattedShipment
147
154
  })]
148
155
  }));
149
156
  };
@@ -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