@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.
- package/cjs/components/grid-controller/grid-controller.cjs +25 -7
- package/cjs/components/grid-controller/grid-controller.styles.cjs +7 -2
- package/cjs/components/grid-controller/grid-footer.cjs +30 -15
- package/cjs/components/grid-controller/grid-footer.styles.cjs +24 -0
- package/cjs/components/grid-controller/index.cjs +1 -1
- package/cjs/components/grid-controller/sortable-header/index.cjs +9 -0
- package/cjs/components/grid-controller/{sortable-header.cjs → sortable-header/sortable-header.cjs} +3 -5
- package/cjs/components/grid-controller/sortable-header/sortable-header.styles.cjs +18 -0
- package/cjs/components/grid-filters/components/created-date-filter/created-date-filter.cjs +3 -0
- package/cjs/components/grid-filters/components/label-id-filter/label-id-filter.cjs +2 -0
- package/cjs/components/grid-filters/components/shipment-id-filter/shipment-id-filter.cjs +2 -0
- package/cjs/components/grid-filters/components/tracking-status-filter/tracking-status-filter.cjs +2 -0
- package/cjs/components/grid-filters/grid-filters.cjs +6 -0
- package/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +63 -29
- package/cjs/elements/labels-grid/hooks/use-tracking-status-filter.cjs +109 -0
- package/cjs/elements/labels-grid/labels-grid.cjs +47 -30
- package/cjs/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.cjs +22 -14
- package/cjs/elements/purchase-label/components/rate-form/rate-form.cjs +1 -1
- package/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +6 -5
- package/cjs/elements/shipments-grid/shipments-grid.cjs +56 -24
- package/cjs/hooks/use-sortable-query.cjs +36 -0
- package/cjs/locales/en/common.cjs +1 -0
- package/cjs/package.cjs +1 -1
- package/cjs/utilities/feature-flags/feature-flags.cjs +1 -1
- package/esm/components/grid-controller/grid-controller.js +27 -9
- package/esm/components/grid-controller/grid-controller.styles.js +7 -2
- package/esm/components/grid-controller/grid-footer.js +32 -17
- package/esm/components/grid-controller/grid-footer.styles.js +20 -0
- package/esm/components/grid-controller/index.js +1 -1
- package/esm/components/grid-controller/sortable-header/index.js +1 -0
- package/esm/components/grid-controller/{sortable-header.js → sortable-header/sortable-header.js} +3 -5
- package/esm/components/grid-controller/sortable-header/sortable-header.styles.js +14 -0
- package/esm/components/grid-filters/components/created-date-filter/created-date-filter.js +3 -0
- package/esm/components/grid-filters/components/label-id-filter/label-id-filter.js +2 -0
- package/esm/components/grid-filters/components/shipment-id-filter/shipment-id-filter.js +2 -0
- package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js +2 -0
- package/esm/components/grid-filters/grid-filters.js +6 -0
- package/esm/elements/labels-grid/hooks/use-labels-grid.js +64 -30
- package/esm/elements/labels-grid/hooks/use-tracking-status-filter.js +105 -0
- package/esm/elements/labels-grid/labels-grid.js +48 -31
- package/esm/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.js +22 -14
- package/esm/elements/purchase-label/components/rate-form/rate-form.js +1 -1
- package/esm/elements/shipments-grid/hooks/use-shipments-grid.js +6 -5
- package/esm/elements/shipments-grid/shipments-grid.js +57 -25
- package/esm/hooks/use-sortable-query.js +32 -0
- package/esm/locales/en/common.js +1 -0
- package/esm/package.js +1 -1
- package/esm/utilities/feature-flags/feature-flags.js +1 -1
- package/package.json +3 -3
- package/types/src/components/grid-controller/grid-controller.d.ts +2 -1
- package/types/src/components/grid-controller/grid-controller.styles.d.ts +6 -1
- package/types/src/components/grid-controller/grid-footer.d.ts +9 -1
- package/types/src/components/grid-controller/grid-footer.styles.d.ts +16 -0
- package/types/src/components/grid-controller/sortable-header/index.d.ts +1 -0
- package/types/src/components/grid-controller/{sortable-header.d.ts → sortable-header/sortable-header.d.ts} +2 -2
- package/types/src/components/grid-controller/sortable-header/sortable-header.styles.d.ts +10 -0
- package/types/src/components/grid-filters/components/created-date-filter/created-date-filter.d.ts +2 -1
- package/types/src/components/grid-filters/components/label-id-filter/label-id-filter.d.ts +2 -1
- package/types/src/components/grid-filters/components/shipment-id-filter/shipment-id-filter.d.ts +2 -1
- package/types/src/components/grid-filters/components/tracking-status-filter/tracking-status-filter.d.ts +2 -1
- package/types/src/components/grid-filters/grid-filters.d.ts +2 -1
- package/types/src/elements/labels-grid/hooks/use-labels-grid.d.ts +4 -3
- package/types/src/elements/labels-grid/hooks/use-tracking-status-filter.d.ts +25 -0
- package/types/src/elements/labels-grid/labels-grid.d.ts +36 -21
- package/types/src/elements/manage-carriers/manage-carriers.d.ts +1 -0
- package/types/src/elements/manage-external-carriers/manage-external-carriers.d.ts +1 -0
- package/types/src/elements/manage-funding/manage-funding-element.d.ts +1 -0
- package/types/src/elements/manage-warehouses/manage-warehouses.d.ts +1 -0
- package/types/src/elements/payment-method-settings/payment-method-settings-element.d.ts +1 -0
- package/types/src/elements/purchase-label/components/fund-and-purchase/fund-and-purchase.d.ts +2 -2
- package/types/src/elements/purchase-label/purchase-label.d.ts +1 -0
- package/types/src/elements/select-label-layout/select-label-layout-element.d.ts +1 -0
- package/types/src/elements/shipment-summary/shipment-summary.d.ts +1 -0
- package/types/src/elements/shipments-grid/hooks/use-shipments-grid.d.ts +7 -1
- package/types/src/elements/shipments-grid/shipments-grid.d.ts +10 -1
- package/types/src/elements/theme-creator/theme-creator.d.ts +1 -0
- package/types/src/elements/transaction-history/transaction-history-element.d.ts +1 -0
- package/types/src/elements/unit-settings/unit-settings-element.d.ts +1 -0
- package/types/src/elements/vat-settings/vat-settings-element.d.ts +1 -0
- package/types/src/elements/void-label/void-label.d.ts +1 -0
- package/types/src/hooks/use-sortable-query.d.ts +13 -0
- package/types/src/locales/en/index.d.ts +1 -0
- package/types/src/workflows/account-settings/account-settings.d.ts +1 -0
- package/types/src/workflows/carrier-services/carrier-services.d.ts +1 -0
- package/types/src/workflows/connect-external-carrier/connect-external-carrier.d.ts +1 -0
- package/types/src/workflows/label-workflow/label-workflow.d.ts +1 -0
- package/types/src/workflows/onboarding/onboarding.d.ts +1 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { jsxs,
|
|
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(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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';
|
package/esm/components/grid-controller/{sortable-header.js → sortable-header/sortable-header.js}
RENAMED
|
@@ -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
|
|
@@ -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
|
|
@@ -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
|
package/esm/components/grid-filters/components/tracking-status-filter/tracking-status-filter.js
CHANGED
|
@@ -21,6 +21,7 @@ import { Spacer } from '../../../spacer/spacer.js';
|
|
|
21
21
|
* @see {@link TrackingStatusFilterProps | The props for the `<TrackingStatusFilter />` component}
|
|
22
22
|
*/
|
|
23
23
|
const TrackingStatusFilter = ({
|
|
24
|
+
disabled: _disabled = false,
|
|
24
25
|
filters,
|
|
25
26
|
onFiltersUpdated
|
|
26
27
|
}) => {
|
|
@@ -105,6 +106,7 @@ const TrackingStatusFilter = ({
|
|
|
105
106
|
}, [watchedValues]);
|
|
106
107
|
return jsxs(Fragment, {
|
|
107
108
|
children: [jsxs(Button, Object.assign({
|
|
109
|
+
disabled: _disabled,
|
|
108
110
|
onClick: toggleTrackingStatusFilter,
|
|
109
111
|
ref: buttonRef,
|
|
110
112
|
variant: ButtonVariant.TEXT
|
|
@@ -18,6 +18,7 @@ import { TrackingStatusFilter } from './components/tracking-status-filter/tracki
|
|
|
18
18
|
const GridFilters = ({
|
|
19
19
|
filters,
|
|
20
20
|
onFiltersUpdated,
|
|
21
|
+
filtersDisabled: _filtersDisabled = false,
|
|
21
22
|
onClearAllFilters
|
|
22
23
|
}) => {
|
|
23
24
|
var _a, _b, _c;
|
|
@@ -37,18 +38,23 @@ const GridFilters = ({
|
|
|
37
38
|
});
|
|
38
39
|
return jsxs("section", {
|
|
39
40
|
children: [filters.shipmentId.enabled && jsx(ShipmentIdFilter, {
|
|
41
|
+
disabled: _filtersDisabled,
|
|
40
42
|
filters: filters,
|
|
41
43
|
onFiltersUpdated: onFiltersUpdated
|
|
42
44
|
}), ((_a = filters.labelId) === null || _a === void 0 ? void 0 : _a.enabled) && jsx(LabelIdFilter, {
|
|
45
|
+
disabled: _filtersDisabled,
|
|
43
46
|
filters: filters,
|
|
44
47
|
onFiltersUpdated: onFiltersUpdated
|
|
45
48
|
}), ((_b = filters.createdDate) === null || _b === void 0 ? void 0 : _b.enabled) && jsx(CreatedDateFilter, {
|
|
49
|
+
disabled: _filtersDisabled,
|
|
46
50
|
filters: filters,
|
|
47
51
|
onFiltersUpdated: onFiltersUpdated
|
|
48
52
|
}), ((_c = filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.enabled) && jsx(TrackingStatusFilter, {
|
|
53
|
+
disabled: _filtersDisabled,
|
|
49
54
|
filters: filters,
|
|
50
55
|
onFiltersUpdated: onFiltersUpdated
|
|
51
56
|
}), shouldShowClearAll && jsx(Button, Object.assign({
|
|
57
|
+
disabled: _filtersDisabled,
|
|
52
58
|
onClick: () => {
|
|
53
59
|
onClearAllFilters();
|
|
54
60
|
},
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { useTheme } from '@emotion/react';
|
|
2
2
|
import { useGetServiceName } from '../../../hooks/use-get-service-name.js';
|
|
3
|
-
import { useState, useEffect, useMemo } from 'react';
|
|
3
|
+
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
4
4
|
import { useListLabels, useListSalesOrderShipments, useGetLabel } from '@shipengine/react-api';
|
|
5
|
+
import { useTrackingStatusFilter } from './use-tracking-status-filter.js';
|
|
5
6
|
import { usePager } from '../../../components/pager/usePager.js';
|
|
6
7
|
|
|
7
8
|
const PAGE_SIZE = 20;
|
|
8
9
|
const useLabelsGrid = ({
|
|
9
|
-
createdDateSortBy,
|
|
10
10
|
labelStatus,
|
|
11
11
|
showShipmentIdFilter,
|
|
12
12
|
showLabelIdFilter,
|
|
13
13
|
showTrackingStatusFilter,
|
|
14
|
-
fetchShipments
|
|
14
|
+
fetchShipments,
|
|
15
|
+
sortDir
|
|
15
16
|
}) => {
|
|
16
|
-
var _a, _b, _c;
|
|
17
|
+
var _a, _b, _c, _d, _e, _f;
|
|
17
18
|
const initialFilters = {
|
|
18
19
|
labelId: {
|
|
19
20
|
enabled: !!showLabelIdFilter,
|
|
@@ -46,7 +47,7 @@ const useLabelsGrid = ({
|
|
|
46
47
|
pagerProps.onPageSelect(1);
|
|
47
48
|
setFilters(newFilters);
|
|
48
49
|
};
|
|
49
|
-
const hasActiveFilterValue = value => {
|
|
50
|
+
const hasActiveFilterValue = useCallback(value => {
|
|
50
51
|
if (value === null || value === undefined) {
|
|
51
52
|
return false;
|
|
52
53
|
}
|
|
@@ -60,7 +61,7 @@ const useLabelsGrid = ({
|
|
|
60
61
|
return value.trim() !== "";
|
|
61
62
|
}
|
|
62
63
|
return Boolean(value);
|
|
63
|
-
};
|
|
64
|
+
}, []);
|
|
64
65
|
const isAnyFilterActive = Object.keys(filters).some(key => {
|
|
65
66
|
const filter = filters[key];
|
|
66
67
|
return (filter === null || filter === void 0 ? void 0 : filter.enabled) && hasActiveFilterValue(filter === null || filter === void 0 ? void 0 : filter.value);
|
|
@@ -86,38 +87,64 @@ const useLabelsGrid = ({
|
|
|
86
87
|
};
|
|
87
88
|
setFilters(updatedFilters);
|
|
88
89
|
}, [showLabelIdFilter, showShipmentIdFilter, showTrackingStatusFilter]);
|
|
90
|
+
const isTrackingStatusFilterActive = useMemo(() => {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
return !!(((_a = filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.enabled) && hasActiveFilterValue((_b = filters.trackingStatus) === null || _b === void 0 ? void 0 : _b.value));
|
|
93
|
+
}, [(_a = filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.enabled, (_b = filters.trackingStatus) === null || _b === void 0 ? void 0 : _b.value, hasActiveFilterValue]);
|
|
94
|
+
// Use tracking status filter hook when the filter is active
|
|
95
|
+
const {
|
|
96
|
+
labels: trackingFilteredLabels,
|
|
97
|
+
isLoading: isTrackingFilterLoading,
|
|
98
|
+
isFetchingNextPage,
|
|
99
|
+
hasMoreUnfetchedResults,
|
|
100
|
+
paginationInfo: statusFilteredPaginationInfo
|
|
101
|
+
} = useTrackingStatusFilter({
|
|
102
|
+
currentPage: page,
|
|
103
|
+
isActive: isTrackingStatusFilterActive,
|
|
104
|
+
labelStatus,
|
|
105
|
+
pageSize,
|
|
106
|
+
shipmentId: ((_c = filters.shipmentId) === null || _c === void 0 ? void 0 : _c.value) || undefined,
|
|
107
|
+
sortDir: sortDir !== null && sortDir !== void 0 ? sortDir : "desc",
|
|
108
|
+
trackingStatusFilters: ((_d = filters.trackingStatus) === null || _d === void 0 ? void 0 : _d.value) || []
|
|
109
|
+
});
|
|
110
|
+
// Use regular API pagination when tracking status filter is not active
|
|
89
111
|
const {
|
|
90
112
|
data: listLabelsData,
|
|
91
113
|
isLoading: isListLabelsLoading,
|
|
92
114
|
isError: isListLabelsError
|
|
93
115
|
} = useListLabels({
|
|
116
|
+
enabled: !isTrackingStatusFilterActive,
|
|
94
117
|
queryFnParams: {
|
|
95
118
|
labelStatus,
|
|
96
119
|
page,
|
|
97
120
|
pageSize,
|
|
98
121
|
shipmentId: filters.shipmentId.value || undefined,
|
|
99
|
-
sortDir:
|
|
122
|
+
sortDir: sortDir !== null && sortDir !== void 0 ? sortDir : "desc"
|
|
100
123
|
}
|
|
101
124
|
});
|
|
102
125
|
const labels = useMemo(() => {
|
|
126
|
+
// If tracking status filter is active, use the filtered labels from the hook
|
|
127
|
+
if (isTrackingStatusFilterActive) {
|
|
128
|
+
return trackingFilteredLabels.map(label => Object.assign(Object.assign({}, label), {
|
|
129
|
+
bodyCellStyles: {
|
|
130
|
+
color: label.status === "voided" ? theme.palette.gray[400] : undefined
|
|
131
|
+
},
|
|
132
|
+
serviceName: getServiceName(label)
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
// Otherwise, use the regular API pagination
|
|
103
136
|
if (!(listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.labels)) {
|
|
104
137
|
return [];
|
|
105
138
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return !((_b = (_a = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
110
|
-
// Voided labels still have an in_transit tracking status, exclude them if the in_transit filter is selected
|
|
111
|
-
label.status !== "voided" && ((_c = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.value.includes(label.trackingStatus)) ||
|
|
112
|
-
// We show voided labels under tracking status also, include them if the voided filter is selected
|
|
113
|
-
label.status === "voided" && ((_d = filters === null || filters === void 0 ? void 0 : filters.trackingStatus) === null || _d === void 0 ? void 0 : _d.value.includes(label.status));
|
|
114
|
-
}).map(label => Object.assign(Object.assign({}, label), {
|
|
139
|
+
// No need to filter by tracking status here since that's handled by useTrackingStatusFilter
|
|
140
|
+
// when the tracking status filter is active
|
|
141
|
+
return listLabelsData.labels.map(label => Object.assign(Object.assign({}, label), {
|
|
115
142
|
bodyCellStyles: {
|
|
116
143
|
color: label.status === "voided" ? theme.palette.gray[400] : undefined
|
|
117
144
|
},
|
|
118
145
|
serviceName: getServiceName(label)
|
|
119
146
|
}));
|
|
120
|
-
}, [listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.labels,
|
|
147
|
+
}, [isTrackingStatusFilterActive, trackingFilteredLabels, listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.labels, theme.palette.gray, getServiceName]);
|
|
121
148
|
const {
|
|
122
149
|
data: listShipmentsData,
|
|
123
150
|
isFetching: isListShipmentsLoading,
|
|
@@ -126,18 +153,17 @@ const useLabelsGrid = ({
|
|
|
126
153
|
// An empty array here should disable the query
|
|
127
154
|
shipmentIds: fetchShipments ? labels === null || labels === void 0 ? void 0 : labels.map(label => label.shipmentId) : []
|
|
128
155
|
});
|
|
129
|
-
const shouldShowFilters = isAnyFilterEnabled && (isAnyFilterActive || Boolean(labels === null || labels === void 0 ? void 0 : labels.length));
|
|
130
156
|
const {
|
|
131
157
|
data: labelFilterData,
|
|
132
158
|
isError: isLabelFilterError,
|
|
133
159
|
isInitialLoading: isLabelFilterLoading
|
|
134
|
-
} = useGetLabel(((
|
|
135
|
-
const isLabelFilterActive = (
|
|
160
|
+
} = useGetLabel(((_e = filters.labelId) === null || _e === void 0 ? void 0 : _e.value) || undefined);
|
|
161
|
+
const isLabelFilterActive = (_f = filters.labelId) === null || _f === void 0 ? void 0 : _f.value;
|
|
136
162
|
const isStatusFilteredOut = (status, filter) => {
|
|
137
163
|
return (filter === null || filter === void 0 ? void 0 : filter.length) && !filter.includes(status);
|
|
138
164
|
};
|
|
139
165
|
const getLabelById = labelById => {
|
|
140
|
-
var _a, _b;
|
|
166
|
+
var _a, _b, _c, _d;
|
|
141
167
|
// Check if filter by label id is active and there are no errors
|
|
142
168
|
if (isLabelFilterActive && !isLabelFilterError) {
|
|
143
169
|
let labelPassFilters = true;
|
|
@@ -146,14 +172,14 @@ const useLabelsGrid = ({
|
|
|
146
172
|
labelPassFilters = false;
|
|
147
173
|
}
|
|
148
174
|
// Check if shipment filter has the same value if defined
|
|
149
|
-
if ((filters === null || filters === void 0 ? void 0 : filters.shipmentId.value) !== "" && (filters === null || filters === void 0 ? void 0 : filters.shipmentId.value) !== (labelById === null || labelById === void 0 ? void 0 : labelById.shipmentId)) {
|
|
175
|
+
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)) {
|
|
150
176
|
labelPassFilters = false;
|
|
151
177
|
}
|
|
152
178
|
if (
|
|
153
179
|
// If Label status is voided and voided status is filtered out, don't show the label
|
|
154
|
-
(labelById === null || labelById === void 0 ? void 0 : labelById.status) === "voided" && isStatusFilteredOut("voided", (
|
|
180
|
+
(labelById === null || labelById === void 0 ? void 0 : labelById.status) === "voided" && isStatusFilteredOut("voided", (_c = filters.trackingStatus) === null || _c === void 0 ? void 0 : _c.value) ||
|
|
155
181
|
// If Label status is not voided and tracking status is filtered out, don't show the label
|
|
156
|
-
(labelById === null || labelById === void 0 ? void 0 : labelById.status) !== "voided" && (labelById === null || labelById === void 0 ? void 0 : labelById.trackingStatus) && isStatusFilteredOut(labelById.trackingStatus, (
|
|
182
|
+
(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)) {
|
|
157
183
|
labelPassFilters = false;
|
|
158
184
|
}
|
|
159
185
|
return labelPassFilters ? labelById : undefined;
|
|
@@ -188,20 +214,28 @@ const useLabelsGrid = ({
|
|
|
188
214
|
clearAllFilters,
|
|
189
215
|
filters,
|
|
190
216
|
getGridData,
|
|
217
|
+
hasMoreUnfetchedResults: isTrackingStatusFilterActive ? hasMoreUnfetchedResults : false,
|
|
191
218
|
isAnyFilterActive,
|
|
192
219
|
isError: isListLabelsError || isListShipmentsError && fetchShipments,
|
|
193
|
-
|
|
220
|
+
isFetchingNextPage: isTrackingStatusFilterActive ? isFetchingNextPage : false,
|
|
221
|
+
// Calculate isLoading based on which query should be active
|
|
222
|
+
isLoading:
|
|
223
|
+
// Always include label filter loading when label ID filter is active
|
|
224
|
+
isLabelFilterActive && isLabelFilterLoading || (
|
|
225
|
+
// For tracking status filter
|
|
226
|
+
isTrackingStatusFilterActive ? isTrackingFilterLoading // Use tracking filter loading when active
|
|
227
|
+
: isListLabelsLoading || isListShipmentsLoading && fetchShipments),
|
|
194
228
|
labels,
|
|
195
229
|
pageConfig: {
|
|
196
|
-
currentPage: labelFilteredById ? 1 : (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.page) || 0,
|
|
230
|
+
currentPage: labelFilteredById ? 1 : isTrackingStatusFilterActive ? statusFilteredPaginationInfo.currentPage : (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.page) || 0,
|
|
197
231
|
pagerProps,
|
|
198
|
-
pagesAmount: (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.pages) || 0,
|
|
232
|
+
pagesAmount: labelFilteredById ? 1 : isTrackingStatusFilterActive ? (statusFilteredPaginationInfo === null || statusFilteredPaginationInfo === void 0 ? void 0 : statusFilteredPaginationInfo.totalPages) || 1 : (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.pages) || 0,
|
|
199
233
|
pageSize,
|
|
200
|
-
showPagination: labelFilteredById ? false : ((listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.total) || 0) > pageSize,
|
|
201
|
-
totalElements: labelFilteredById ? 1 : (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.total) || 0
|
|
234
|
+
showPagination: labelFilteredById ? false : isTrackingStatusFilterActive ? ((statusFilteredPaginationInfo === null || statusFilteredPaginationInfo === void 0 ? void 0 : statusFilteredPaginationInfo.totalCount) || 0) > pageSize : ((listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.total) || 0) > pageSize,
|
|
235
|
+
totalElements: labelFilteredById ? 1 : isTrackingStatusFilterActive ? (statusFilteredPaginationInfo === null || statusFilteredPaginationInfo === void 0 ? void 0 : statusFilteredPaginationInfo.totalCount) || 0 : (listLabelsData === null || listLabelsData === void 0 ? void 0 : listLabelsData.total) || 0
|
|
202
236
|
},
|
|
203
237
|
setFilters: onSetFilters,
|
|
204
|
-
shouldShowFilters
|
|
238
|
+
shouldShowFilters: isAnyFilterEnabled
|
|
205
239
|
};
|
|
206
240
|
};
|
|
207
241
|
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
|
+
import { useListLabelsInfinite } from '@shipengine/react-api';
|
|
3
|
+
|
|
4
|
+
const MIN_RESULTS = 20; // Minimum number of filtered results needed to stop fetching
|
|
5
|
+
const MAX_PAGES = 5; // Maximum number of pages to fetch if we have enough results
|
|
6
|
+
const useTrackingStatusFilter = ({
|
|
7
|
+
isActive,
|
|
8
|
+
labelStatus,
|
|
9
|
+
shipmentId,
|
|
10
|
+
trackingStatusFilters,
|
|
11
|
+
sortDir,
|
|
12
|
+
currentPage,
|
|
13
|
+
pageSize
|
|
14
|
+
}) => {
|
|
15
|
+
const [allLabels, setAllLabels] = useState([]);
|
|
16
|
+
const {
|
|
17
|
+
data: infiniteData,
|
|
18
|
+
fetchNextPage,
|
|
19
|
+
hasNextPage,
|
|
20
|
+
isLoading,
|
|
21
|
+
isFetchingNextPage
|
|
22
|
+
} = useListLabelsInfinite({
|
|
23
|
+
enabled: isActive,
|
|
24
|
+
queryFnParams: {
|
|
25
|
+
labelStatus,
|
|
26
|
+
pageSize: 100,
|
|
27
|
+
shipmentId,
|
|
28
|
+
sortDir
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (isActive && (infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages)) {
|
|
33
|
+
const allLabelsFromPages = infiniteData.pages.flatMap(page => page.labels || []);
|
|
34
|
+
setAllLabels(allLabelsFromPages);
|
|
35
|
+
}
|
|
36
|
+
}, [isActive, infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages]);
|
|
37
|
+
const filteredLabels = useMemo(() => {
|
|
38
|
+
if (!isActive || !trackingStatusFilters.length) {
|
|
39
|
+
return allLabels;
|
|
40
|
+
}
|
|
41
|
+
return allLabels.filter(label => {
|
|
42
|
+
if (label.status === "voided") {
|
|
43
|
+
return trackingStatusFilters.includes("voided");
|
|
44
|
+
}
|
|
45
|
+
return trackingStatusFilters.includes(label.trackingStatus);
|
|
46
|
+
});
|
|
47
|
+
}, [isActive, allLabels, trackingStatusFilters]);
|
|
48
|
+
const totalCount = filteredLabels.length;
|
|
49
|
+
const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
|
|
50
|
+
const paginatedLabels = useMemo(() => {
|
|
51
|
+
const startIndex = (currentPage - 1) * pageSize;
|
|
52
|
+
const endIndex = Math.min(startIndex + pageSize, filteredLabels.length);
|
|
53
|
+
return filteredLabels.slice(startIndex, endIndex);
|
|
54
|
+
}, [filteredLabels, currentPage, pageSize]);
|
|
55
|
+
// Check if we have enough data for the next page
|
|
56
|
+
const hasDataForNextPage = useMemo(() => {
|
|
57
|
+
const nextPageStart = currentPage * pageSize;
|
|
58
|
+
return nextPageStart < filteredLabels.length;
|
|
59
|
+
}, [currentPage, pageSize, filteredLabels.length]);
|
|
60
|
+
// Check if we have more unfetched results
|
|
61
|
+
const hasMoreUnfetchedResults = useMemo(() => {
|
|
62
|
+
return hasNextPage && (infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages) && infiniteData.pages.length >= MAX_PAGES && filteredLabels.length >= MIN_RESULTS;
|
|
63
|
+
}, [hasNextPage, infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages, filteredLabels.length]);
|
|
64
|
+
// Trigger fetchNextPage
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
// Don't fetch if not active or already fetching
|
|
67
|
+
if (!isActive || isFetchingNextPage) return;
|
|
68
|
+
// Continue fetching if we don't have minimum results yet
|
|
69
|
+
if (filteredLabels.length < MIN_RESULTS && hasNextPage) {
|
|
70
|
+
fetchNextPage();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Continue fetching if we don't have data for the next page
|
|
74
|
+
if (!hasDataForNextPage && hasNextPage) {
|
|
75
|
+
fetchNextPage();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Stop fetching if we've reached max pages and have enough results
|
|
79
|
+
if ((infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages) && infiniteData.pages.length >= MAX_PAGES && filteredLabels.length >= MIN_RESULTS && hasDataForNextPage) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Otherwise, fetch next page if available
|
|
83
|
+
if (hasNextPage) {
|
|
84
|
+
fetchNextPage();
|
|
85
|
+
}
|
|
86
|
+
}, [isActive, currentPage, pageSize, filteredLabels.length, hasNextPage, isFetchingNextPage, fetchNextPage, hasDataForNextPage, infiniteData === null || infiniteData === void 0 ? void 0 : infiniteData.pages]);
|
|
87
|
+
return {
|
|
88
|
+
allLabelsCount: totalCount,
|
|
89
|
+
fetchNextPage,
|
|
90
|
+
filteredLabelsCount: totalCount,
|
|
91
|
+
hasMorePages: hasNextPage,
|
|
92
|
+
hasMoreUnfetchedResults,
|
|
93
|
+
isFetchingNextPage,
|
|
94
|
+
isLoading: isLoading || filteredLabels.length === 0 && isFetchingNextPage,
|
|
95
|
+
labels: paginatedLabels,
|
|
96
|
+
paginationInfo: {
|
|
97
|
+
currentPage,
|
|
98
|
+
pageSize,
|
|
99
|
+
totalCount,
|
|
100
|
+
totalPages
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export { useTrackingStatusFilter };
|