@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,10 +1,11 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { useSortableQuery } from '../../hooks/use-sortable-query.js';
|
|
3
|
+
import { useRef, useMemo, useEffect, useCallback } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import { TagColor, Next, Typography, Tag, TagVariant, EmptyState, Button } from '@shipengine/giger';
|
|
5
6
|
import { useLabelsGrid } from './hooks/use-labels-grid.js';
|
|
6
7
|
import { styles } from './labels-grid.styles.js';
|
|
7
|
-
import { SortableHeader } from '../../components/grid-controller/sortable-header.js';
|
|
8
|
+
import { SortableHeader } from '../../components/grid-controller/sortable-header/sortable-header.js';
|
|
8
9
|
import { CellFormattedDate } from '../../components/grid-controller/cell-formatted-date.js';
|
|
9
10
|
import { ActionsMenu, Actions } from '../../components/actions-menu/actions-menu.js';
|
|
10
11
|
import { ErrorState } from '../../components/error-state/error-state.js';
|
|
@@ -13,7 +14,6 @@ import { GridFilters } from '../../components/grid-filters/grid-filters.js';
|
|
|
13
14
|
import { GridFooter } from '../../components/grid-controller/grid-footer.js';
|
|
14
15
|
import en from '../../locales/en/index.js';
|
|
15
16
|
import { useElements } from '../../elements-provider/elements-context-provider.js';
|
|
16
|
-
import { Loader } from '../../components/loader/loader.js';
|
|
17
17
|
import { Spacer } from '../../components/spacer/spacer.js';
|
|
18
18
|
import { PoweredByShipEngine } from '../../components/powered-by-shipengine/powered-by-shipengine.js';
|
|
19
19
|
import { createElement } from '../../create-element/create-element.js';
|
|
@@ -31,7 +31,7 @@ const Component = ({
|
|
|
31
31
|
onClickExternalShipmentId,
|
|
32
32
|
onClickShipmentNumber
|
|
33
33
|
}) => {
|
|
34
|
-
var _a, _b
|
|
34
|
+
var _a, _b;
|
|
35
35
|
const {
|
|
36
36
|
t
|
|
37
37
|
} = useTranslation(["common", "list-labels"]);
|
|
@@ -41,7 +41,13 @@ const Component = ({
|
|
|
41
41
|
} = useElements();
|
|
42
42
|
const defaultFeatures = getFeatures("labelsGridFeatures");
|
|
43
43
|
const prevStatus = useRef(labelStatus);
|
|
44
|
-
const
|
|
44
|
+
const {
|
|
45
|
+
toggleSort,
|
|
46
|
+
sortState
|
|
47
|
+
} = useSortableQuery({
|
|
48
|
+
defaultSortBy: "modified_at",
|
|
49
|
+
defaultSortDir: "desc"
|
|
50
|
+
});
|
|
45
51
|
features = Object.assign(Object.assign({}, defaultFeatures), features !== null && features !== void 0 ? features : {});
|
|
46
52
|
const labelIdColumn = useMemo(() => {
|
|
47
53
|
var _a;
|
|
@@ -61,12 +67,14 @@ const Component = ({
|
|
|
61
67
|
}, [features]);
|
|
62
68
|
const showLabelIdFilter = labelIdColumn && ((_a = labelIdColumn.allowFilter) !== null && _a !== void 0 ? _a : true);
|
|
63
69
|
const showShipmentIdFilter = shipmentIdColumn && ((_b = shipmentIdColumn.allowFilter) !== null && _b !== void 0 ? _b : true);
|
|
64
|
-
const showTrackingStatusFilter = trackingStatusColumn &&
|
|
70
|
+
const showTrackingStatusFilter = trackingStatusColumn && !!trackingStatusColumn.allowFilter;
|
|
65
71
|
const {
|
|
66
72
|
labels,
|
|
67
73
|
getGridData,
|
|
68
74
|
isError,
|
|
69
75
|
isLoading,
|
|
76
|
+
isFetchingNextPage,
|
|
77
|
+
hasMoreUnfetchedResults,
|
|
70
78
|
filters,
|
|
71
79
|
setFilters,
|
|
72
80
|
pageConfig,
|
|
@@ -74,12 +82,12 @@ const Component = ({
|
|
|
74
82
|
shouldShowFilters,
|
|
75
83
|
clearAllFilters
|
|
76
84
|
} = useLabelsGrid({
|
|
77
|
-
createdDateSortBy,
|
|
78
85
|
fetchShipments: !!shipmentNumberColumn,
|
|
79
86
|
labelStatus,
|
|
80
87
|
showLabelIdFilter,
|
|
81
88
|
showShipmentIdFilter,
|
|
82
|
-
showTrackingStatusFilter
|
|
89
|
+
showTrackingStatusFilter,
|
|
90
|
+
sortDir: sortState.dir
|
|
83
91
|
});
|
|
84
92
|
useEffect(() => {
|
|
85
93
|
if (prevStatus.current !== labelStatus) {
|
|
@@ -101,8 +109,8 @@ const Component = ({
|
|
|
101
109
|
};
|
|
102
110
|
}, [filters, labelIdColumn, shipmentIdColumn, trackingStatusColumn]);
|
|
103
111
|
const toggleCreatedDateSort = useCallback(() => {
|
|
104
|
-
|
|
105
|
-
}, [
|
|
112
|
+
toggleSort("created_at");
|
|
113
|
+
}, [toggleSort]);
|
|
106
114
|
const columns = useMemo(() => {
|
|
107
115
|
var _a;
|
|
108
116
|
const labelTags = {
|
|
@@ -146,7 +154,7 @@ const Component = ({
|
|
|
146
154
|
headerContent: jsx(SortableHeader, {
|
|
147
155
|
headerText: t("list-labels:headers.created"),
|
|
148
156
|
onToggleSort: toggleCreatedDateSort,
|
|
149
|
-
sortDirection:
|
|
157
|
+
sortDirection: sortState.createdAtDir
|
|
150
158
|
}),
|
|
151
159
|
renderCellContent: label => {
|
|
152
160
|
return jsx(CellFormattedDate, {
|
|
@@ -374,24 +382,13 @@ const Component = ({
|
|
|
374
382
|
});
|
|
375
383
|
}
|
|
376
384
|
return cols;
|
|
377
|
-
}, [t, toggleCreatedDateSort,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return jsx(ErrorState, {
|
|
385
|
-
css: styles.errorState,
|
|
386
|
-
subtitle: [t("list-labels:errorMessages.subtitle"), t("errorMessages.refreshAndTryAgain")],
|
|
387
|
-
title: t("list-labels:errorMessages.title")
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
return jsxs(Fragment, {
|
|
391
|
-
children: [jsx(GridController, {
|
|
392
|
-
columns: columns,
|
|
393
|
-
data: getGridData(),
|
|
394
|
-
emptyContent: isAnyFilterActive ? jsx(EmptyState, Object.assign({
|
|
385
|
+
}, [t, toggleCreatedDateSort, sortState.createdAtDir, features === null || features === void 0 ? void 0 : features.columns, features === null || features === void 0 ? void 0 : features.showActions, labels, onClickExternalOrderId, onClickExternalShipmentId, onClickShipmentNumber, onClickVoidLabel, onClickViewDetails, onClickPrintLabel, onClickPrintForms]);
|
|
386
|
+
const emptyContentComponent = useMemo(() => {
|
|
387
|
+
if (isLoading) {
|
|
388
|
+
return undefined;
|
|
389
|
+
}
|
|
390
|
+
if (isAnyFilterActive) {
|
|
391
|
+
return jsx(EmptyState, Object.assign({
|
|
395
392
|
isElevated: false,
|
|
396
393
|
subtitle: t("list-labels:emptyWithFilters.subtitle"),
|
|
397
394
|
title: t("list-labels:emptyWithFilters.title")
|
|
@@ -401,17 +398,36 @@ const Component = ({
|
|
|
401
398
|
}, {
|
|
402
399
|
children: t("list-labels:emptyWithFilters.button")
|
|
403
400
|
}))
|
|
404
|
-
}))
|
|
401
|
+
}));
|
|
402
|
+
} else {
|
|
403
|
+
return jsx(EmptyState, {
|
|
405
404
|
isElevated: false,
|
|
406
405
|
subtitle: t("list-labels:empty.subtitle"),
|
|
407
406
|
title: t("list-labels:empty.title")
|
|
408
|
-
})
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}, [clearAllFilters, isAnyFilterActive, isLoading, t]);
|
|
410
|
+
if (isError) {
|
|
411
|
+
return jsx(ErrorState, {
|
|
412
|
+
css: styles.errorState,
|
|
413
|
+
subtitle: [t("list-labels:errorMessages.subtitle"), t("errorMessages.refreshAndTryAgain")],
|
|
414
|
+
title: t("list-labels:errorMessages.title")
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
return jsxs(Fragment, {
|
|
418
|
+
children: [jsx(GridController, {
|
|
419
|
+
columns: columns,
|
|
420
|
+
data: getGridData(),
|
|
421
|
+
emptyContent: emptyContentComponent,
|
|
409
422
|
filters: shouldShowFilters && jsx(GridFilters, {
|
|
410
423
|
filters: gridFilters,
|
|
424
|
+
filtersDisabled: isLoading,
|
|
411
425
|
onClearAllFilters: clearAllFilters,
|
|
412
426
|
onFiltersUpdated: setFilters
|
|
413
427
|
}),
|
|
414
428
|
footerContent: jsx(GridFooter, {
|
|
429
|
+
hasMoreUnfetchedResults: hasMoreUnfetchedResults,
|
|
430
|
+
isLoadingMore: isFetchingNextPage,
|
|
415
431
|
onPageChange: pageConfig.pagerProps.onPageSelect,
|
|
416
432
|
page: pageConfig.currentPage,
|
|
417
433
|
pages: pageConfig.pagesAmount,
|
|
@@ -419,6 +435,7 @@ const Component = ({
|
|
|
419
435
|
showPagination: pageConfig.showPagination,
|
|
420
436
|
total: pageConfig.totalElements
|
|
421
437
|
}),
|
|
438
|
+
isLoading: isLoading,
|
|
422
439
|
onRowClick: onRowClick
|
|
423
440
|
}), globalFeatures.poweredByShipEngine && jsxs(Fragment, {
|
|
424
441
|
children: [jsx(Spacer, {}), jsx(PoweredByShipEngine, {})]
|
|
@@ -34,12 +34,12 @@ const FundAndPurchase = ({
|
|
|
34
34
|
currency,
|
|
35
35
|
disabled,
|
|
36
36
|
isFundingEnabled,
|
|
37
|
-
|
|
38
|
-
onSave,
|
|
37
|
+
isInvalidatedByError,
|
|
39
38
|
onPurchase,
|
|
39
|
+
onSave,
|
|
40
40
|
onVatRegistrationComplete,
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
rateData,
|
|
42
|
+
showVatSettings
|
|
43
43
|
}) => {
|
|
44
44
|
var _a, _b, _c;
|
|
45
45
|
const {
|
|
@@ -71,10 +71,18 @@ const FundAndPurchase = ({
|
|
|
71
71
|
const purchaseAmount = getTotalRateAmount(rate);
|
|
72
72
|
const [isSavingRate, setIsSavingRate] = useState(false);
|
|
73
73
|
const [isSavingError, setIsSavingError] = useState(false);
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
const purchaseRequiresAddingFunds = isFundingEnabled && isFundingRequired && (fundingOrigin === null || fundingOrigin === void 0 ? void 0 : fundingOrigin.balance) !== undefined && fundingOrigin.balance < purchaseAmount && !isInvalidatedByError;
|
|
75
|
+
const [isFormManuallyToggled, setIsFormManuallyToggled] = useState(false);
|
|
76
|
+
const isAddFundsFormOpen = purchaseRequiresAddingFunds || isFormManuallyToggled;
|
|
77
|
+
const toggleAddFundsForm = () => {
|
|
78
|
+
if (!purchaseRequiresAddingFunds) {
|
|
79
|
+
// If the label can be purchased without adding funds, allow manual toggling of the form
|
|
80
|
+
setIsFormManuallyToggled(!isFormManuallyToggled);
|
|
81
|
+
} else if (isFormManuallyToggled) {
|
|
82
|
+
// If the form is already open, close it
|
|
83
|
+
setIsFormManuallyToggled(false);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
78
86
|
useEffect(() => {
|
|
79
87
|
resetAddFundsMutationState();
|
|
80
88
|
}, [isAddFundsFormOpen, resetAddFundsMutationState]);
|
|
@@ -82,7 +90,7 @@ const FundAndPurchase = ({
|
|
|
82
90
|
setIsSavingRate(true);
|
|
83
91
|
setIsSavingError(false);
|
|
84
92
|
try {
|
|
85
|
-
yield onSave();
|
|
93
|
+
yield onSave === null || onSave === void 0 ? void 0 : onSave();
|
|
86
94
|
} catch (e) {
|
|
87
95
|
setIsSavingError(true);
|
|
88
96
|
} finally {
|
|
@@ -108,7 +116,7 @@ const FundAndPurchase = ({
|
|
|
108
116
|
breakpoint: "mobileLarge",
|
|
109
117
|
justify: "end"
|
|
110
118
|
}, {
|
|
111
|
-
children: [jsx(Button, Object.assign({
|
|
119
|
+
children: [onSave && jsx(Button, Object.assign({
|
|
112
120
|
bold: false,
|
|
113
121
|
css: styles.saveRateButton,
|
|
114
122
|
disabled: disableSaveButton,
|
|
@@ -139,7 +147,7 @@ const FundAndPurchase = ({
|
|
|
139
147
|
}), isFundingEnabled ? jsx(LinkAction, {
|
|
140
148
|
icon: "add",
|
|
141
149
|
isDisabled: !isFundingRequired || isAddFundsFormOpen || isRateFormSubmitting,
|
|
142
|
-
onClick:
|
|
150
|
+
onClick: toggleAddFundsForm,
|
|
143
151
|
title: t("manage-funding:actions.addFunds")
|
|
144
152
|
}) : null]
|
|
145
153
|
}), jsx(Spacer, {
|
|
@@ -185,7 +193,7 @@ const FundAndPurchase = ({
|
|
|
185
193
|
}), isFundingEnabled && jsx(LinkAction, {
|
|
186
194
|
icon: "add",
|
|
187
195
|
isDisabled: isAddFundsFormOpen || isRateFormSubmitting,
|
|
188
|
-
onClick:
|
|
196
|
+
onClick: toggleAddFundsForm,
|
|
189
197
|
title: t("manage-funding:actions.addFunds")
|
|
190
198
|
})]
|
|
191
199
|
}), jsx(Spacer, {
|
|
@@ -206,7 +214,7 @@ const FundAndPurchase = ({
|
|
|
206
214
|
currency: currency,
|
|
207
215
|
minimumAmount: purchaseAmount - balance,
|
|
208
216
|
onSuccess: () => {
|
|
209
|
-
|
|
217
|
+
setIsFormManuallyToggled(false);
|
|
210
218
|
onPurchase();
|
|
211
219
|
}
|
|
212
220
|
}, {
|
|
@@ -243,7 +251,7 @@ const FundAndPurchase = ({
|
|
|
243
251
|
}, {
|
|
244
252
|
children: jsx(Button, Object.assign({
|
|
245
253
|
disabled: addFundsForm.isSubmitting || isRateFormSubmitting,
|
|
246
|
-
onClick: () =>
|
|
254
|
+
onClick: () => setIsFormManuallyToggled(false),
|
|
247
255
|
variant: ButtonVariant.TEXT
|
|
248
256
|
}, {
|
|
249
257
|
children: t("actions.cancel")
|
|
@@ -215,7 +215,7 @@ const RateForm = ({
|
|
|
215
215
|
isFundingEnabled: !!(features === null || features === void 0 ? void 0 : features.enableFunding),
|
|
216
216
|
isInvalidatedByError: !!(labelErrors === null || labelErrors === void 0 ? void 0 : labelErrors.length),
|
|
217
217
|
onPurchase: handleSubmit,
|
|
218
|
-
onSave: handleSaveRate,
|
|
218
|
+
onSave: (features === null || features === void 0 ? void 0 : features.saveRate) ? handleSaveRate : undefined,
|
|
219
219
|
onVatRegistrationComplete: onVatRegistrationComplete,
|
|
220
220
|
rateData: {
|
|
221
221
|
isPreferredRate,
|
|
@@ -18,7 +18,9 @@ const getInitialFilters = (showShipmentIdFilter, showCreatedDateFilter) => ({
|
|
|
18
18
|
const useShipmentsGrid = ({
|
|
19
19
|
shipmentStatus,
|
|
20
20
|
showShipmentIdFilter: _showShipmentIdFilter = true,
|
|
21
|
-
showCreatedDateFilter: _showCreatedDateFilter = true
|
|
21
|
+
showCreatedDateFilter: _showCreatedDateFilter = true,
|
|
22
|
+
sortBy,
|
|
23
|
+
sortDir
|
|
22
24
|
}) => {
|
|
23
25
|
var _a, _b, _c, _d;
|
|
24
26
|
const initialFilters = getInitialFilters(_showShipmentIdFilter, _showCreatedDateFilter);
|
|
@@ -58,14 +60,13 @@ const useShipmentsGrid = ({
|
|
|
58
60
|
page,
|
|
59
61
|
pageSize,
|
|
60
62
|
shipmentStatus,
|
|
61
|
-
sortBy:
|
|
62
|
-
sortDir:
|
|
63
|
+
sortBy: sortBy,
|
|
64
|
+
sortDir: sortDir
|
|
63
65
|
}, getCreatedDateFilterValue((_b = (_a = filters.createdDate) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.start, (_d = (_c = filters.createdDate) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.end)));
|
|
64
66
|
const shipments = useMemo(() => data === null || data === void 0 ? void 0 : data.shipments.map(shipment => Object.assign(Object.assign({}, shipment), {
|
|
65
67
|
disableOnRowClick: shipment.shipmentStatus === "cancelled",
|
|
66
68
|
serviceName: getServiceName(shipment)
|
|
67
69
|
})), [data === null || data === void 0 ? void 0 : data.shipments, getServiceName]);
|
|
68
|
-
const shouldShowFilters = isAnyFilterEnabled && (isAnyFilterActive || Boolean(shipments === null || shipments === void 0 ? void 0 : shipments.length));
|
|
69
70
|
const {
|
|
70
71
|
data: shipmentById,
|
|
71
72
|
error: shipmentErrors,
|
|
@@ -132,7 +133,7 @@ const useShipmentsGrid = ({
|
|
|
132
133
|
},
|
|
133
134
|
setFilters: onSetFilters,
|
|
134
135
|
shipments,
|
|
135
|
-
shouldShowFilters
|
|
136
|
+
shouldShowFilters: isAnyFilterEnabled
|
|
136
137
|
};
|
|
137
138
|
};
|
|
138
139
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
|
|
2
|
+
import { useSortableQuery } from '../../hooks/use-sortable-query.js';
|
|
3
|
+
import { useMemo } from 'react';
|
|
2
4
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { TagColor, Typography, Tag, TagVariant
|
|
5
|
+
import { EmptyState, Button, TagColor, Typography, Tag, TagVariant } from '@shipengine/giger';
|
|
4
6
|
import { useShipmentsGrid } from './hooks/use-shipments-grid.js';
|
|
5
7
|
import { styles } from './shipments-grid.styles.js';
|
|
6
8
|
import { ActionsMenu, Actions } from '../../components/actions-menu/actions-menu.js';
|
|
7
9
|
import { GridFilters } from '../../components/grid-filters/grid-filters.js';
|
|
8
10
|
import en from '../../locales/en/index.js';
|
|
9
11
|
import { useElements } from '../../elements-provider/elements-context-provider.js';
|
|
10
|
-
import { Loader } from '../../components/loader/loader.js';
|
|
11
12
|
import { ErrorState } from '../../components/error-state/error-state.js';
|
|
13
|
+
import { SortableHeader } from '../../components/grid-controller/sortable-header/sortable-header.js';
|
|
12
14
|
import { CellFormattedDate } from '../../components/grid-controller/cell-formatted-date.js';
|
|
13
15
|
import { GridController } from '../../components/grid-controller/grid-controller.js';
|
|
14
16
|
import { GridFooter } from '../../components/grid-controller/grid-footer.js';
|
|
@@ -51,6 +53,13 @@ const Component = ({
|
|
|
51
53
|
const {
|
|
52
54
|
globalFeatures
|
|
53
55
|
} = useElements();
|
|
56
|
+
const {
|
|
57
|
+
toggleSort,
|
|
58
|
+
sortState
|
|
59
|
+
} = useSortableQuery({
|
|
60
|
+
defaultSortBy: "modified_at",
|
|
61
|
+
defaultSortDir: "desc"
|
|
62
|
+
});
|
|
54
63
|
const {
|
|
55
64
|
isLoading,
|
|
56
65
|
isError,
|
|
@@ -64,13 +73,40 @@ const Component = ({
|
|
|
64
73
|
} = useShipmentsGrid({
|
|
65
74
|
shipmentStatus,
|
|
66
75
|
showCreatedDateFilter: _showCreatedDateFilter,
|
|
67
|
-
showShipmentIdFilter: _showShipmentIdFilter
|
|
76
|
+
showShipmentIdFilter: _showShipmentIdFilter,
|
|
77
|
+
sortBy: sortState.by,
|
|
78
|
+
sortDir: sortState.dir
|
|
68
79
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
const handleCreatedDateSort = () => {
|
|
81
|
+
toggleSort("created_at");
|
|
82
|
+
};
|
|
83
|
+
const handleUpdatedDateSort = () => {
|
|
84
|
+
toggleSort("modified_at");
|
|
85
|
+
};
|
|
86
|
+
const emptyContentComponent = useMemo(() => {
|
|
87
|
+
if (isLoading) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
if (isAnyFilterActive) {
|
|
91
|
+
return jsx(EmptyState, Object.assign({
|
|
92
|
+
isElevated: false,
|
|
93
|
+
subtitle: t("list-shipments:emptyState.filtersSubtitle"),
|
|
94
|
+
title: t("list-shipments:emptyState.filtersTitle")
|
|
95
|
+
}, {
|
|
96
|
+
children: jsx(Button, Object.assign({
|
|
97
|
+
onClick: clearAllFilters
|
|
98
|
+
}, {
|
|
99
|
+
children: t("list-shipments:emptyState.viewAll")
|
|
100
|
+
}))
|
|
101
|
+
}));
|
|
102
|
+
} else {
|
|
103
|
+
return jsx(EmptyState, {
|
|
104
|
+
isElevated: false,
|
|
105
|
+
subtitle: t("list-shipments:emptyState.subtitle"),
|
|
106
|
+
title: t("list-shipments:emptyState.title")
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}, [clearAllFilters, isAnyFilterActive, isLoading, t]);
|
|
74
110
|
if (isError) {
|
|
75
111
|
return jsx(ErrorState, {
|
|
76
112
|
css: styles.errorState,
|
|
@@ -156,7 +192,11 @@ const Component = ({
|
|
|
156
192
|
}));
|
|
157
193
|
}
|
|
158
194
|
}, {
|
|
159
|
-
headerContent:
|
|
195
|
+
headerContent: jsx(SortableHeader, {
|
|
196
|
+
headerText: t("list-shipments:headers.created"),
|
|
197
|
+
onToggleSort: handleCreatedDateSort,
|
|
198
|
+
sortDirection: sortState.createdAtDir
|
|
199
|
+
}),
|
|
160
200
|
renderCellContent: shipment => {
|
|
161
201
|
return jsx(CellFormattedDate, {
|
|
162
202
|
date: shipment.createdAt,
|
|
@@ -164,7 +204,11 @@ const Component = ({
|
|
|
164
204
|
});
|
|
165
205
|
}
|
|
166
206
|
}, {
|
|
167
|
-
headerContent:
|
|
207
|
+
headerContent: jsx(SortableHeader, {
|
|
208
|
+
headerText: t("list-shipments:headers.modified"),
|
|
209
|
+
onToggleSort: handleUpdatedDateSort,
|
|
210
|
+
sortDirection: sortState.modifiedAtDir
|
|
211
|
+
}),
|
|
168
212
|
renderCellContent: shipment => {
|
|
169
213
|
return jsx(CellFormattedDate, {
|
|
170
214
|
date: shipment.modifiedAt,
|
|
@@ -196,23 +240,10 @@ const Component = ({
|
|
|
196
240
|
children: [jsx(GridController, {
|
|
197
241
|
columns: columns,
|
|
198
242
|
data: getGridData(),
|
|
199
|
-
emptyContent:
|
|
200
|
-
isElevated: false,
|
|
201
|
-
subtitle: t("list-shipments:emptyState.filtersSubtitle"),
|
|
202
|
-
title: t("list-shipments:emptyState.filtersTitle")
|
|
203
|
-
}, {
|
|
204
|
-
children: jsx(Button, Object.assign({
|
|
205
|
-
onClick: clearAllFilters
|
|
206
|
-
}, {
|
|
207
|
-
children: t("list-shipments:emptyState.viewAll")
|
|
208
|
-
}))
|
|
209
|
-
})) : jsx(EmptyState, {
|
|
210
|
-
isElevated: false,
|
|
211
|
-
subtitle: t("list-shipments:emptyState.subtitle"),
|
|
212
|
-
title: t("list-shipments:emptyState.title")
|
|
213
|
-
}),
|
|
243
|
+
emptyContent: emptyContentComponent,
|
|
214
244
|
filters: shouldShowFilters && jsx(GridFilters, {
|
|
215
245
|
filters: filters,
|
|
246
|
+
filtersDisabled: isLoading,
|
|
216
247
|
onClearAllFilters: clearAllFilters,
|
|
217
248
|
onFiltersUpdated: setFilters
|
|
218
249
|
}),
|
|
@@ -224,6 +255,7 @@ const Component = ({
|
|
|
224
255
|
showPagination: pageConfig.showPagination,
|
|
225
256
|
total: pageConfig.totalElements
|
|
226
257
|
}),
|
|
258
|
+
isLoading: isLoading,
|
|
227
259
|
onRowClick: onRowClick
|
|
228
260
|
}), globalFeatures.poweredByShipEngine && jsxs(Fragment, {
|
|
229
261
|
children: [jsx(Spacer, {}), jsx(PoweredByShipEngine, {})]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
const useSortableQuery = ({
|
|
4
|
+
defaultSortBy: _defaultSortBy = "modified_at",
|
|
5
|
+
defaultSortDir: _defaultSortDir = "desc"
|
|
6
|
+
}) => {
|
|
7
|
+
const [sortState, setSortState] = useState({
|
|
8
|
+
by: _defaultSortBy,
|
|
9
|
+
createdAtDir: _defaultSortDir,
|
|
10
|
+
dir: _defaultSortDir,
|
|
11
|
+
modifiedAtDir: _defaultSortDir
|
|
12
|
+
});
|
|
13
|
+
const toggleSort = sortQuery => {
|
|
14
|
+
const newSortState = Object.assign({}, sortState);
|
|
15
|
+
if (sortQuery === "created_at") {
|
|
16
|
+
newSortState.createdAtDir = sortState.createdAtDir === "asc" ? "desc" : "asc";
|
|
17
|
+
newSortState.dir = newSortState.createdAtDir;
|
|
18
|
+
newSortState.by = "created_at";
|
|
19
|
+
} else if (sortQuery === "modified_at") {
|
|
20
|
+
newSortState.modifiedAtDir = sortState.modifiedAtDir === "asc" ? "desc" : "asc";
|
|
21
|
+
newSortState.dir = newSortState.modifiedAtDir;
|
|
22
|
+
newSortState.by = "modified_at";
|
|
23
|
+
}
|
|
24
|
+
setSortState(newSortState);
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
sortState,
|
|
28
|
+
toggleSort
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { useSortableQuery };
|
package/esm/locales/en/common.js
CHANGED
|
@@ -212,6 +212,7 @@ var common = {
|
|
|
212
212
|
grid: {
|
|
213
213
|
"row-count_one": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}} item</0>",
|
|
214
214
|
"row-count_other": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}} items</0>",
|
|
215
|
+
"row-count-plus_other": "Showing {{firstIndex}}-{{lastIndex}} of <0>{{count}}+ items</0>",
|
|
215
216
|
rows: "Rows",
|
|
216
217
|
clearAll: "Clear all",
|
|
217
218
|
shipmentId: "Shipment ID",
|
package/esm/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipengine/elements",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"module": "./index.js",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -269,8 +269,8 @@
|
|
|
269
269
|
"@rollup/plugin-node-resolve": "13.3.0",
|
|
270
270
|
"@shipengine/giger": "1.20.18",
|
|
271
271
|
"@shipengine/giger-theme": "1.8.1",
|
|
272
|
-
"@shipengine/js-api": "3.
|
|
273
|
-
"@shipengine/react-api": "3.
|
|
272
|
+
"@shipengine/js-api": "3.8.0",
|
|
273
|
+
"@shipengine/react-api": "3.11.0",
|
|
274
274
|
"@tanstack/react-query": "4.36.1",
|
|
275
275
|
"@testing-library/dom": "8.19.0",
|
|
276
276
|
"axios": "1.8.4",
|
|
@@ -22,6 +22,7 @@ type GridProps<T extends GridDataType> = {
|
|
|
22
22
|
emptyContent?: ReactNode;
|
|
23
23
|
filters?: ReactNode;
|
|
24
24
|
footerContent?: ReactNode;
|
|
25
|
+
isLoading?: boolean;
|
|
25
26
|
onRowClick?: (data: T) => void;
|
|
26
27
|
useCheckboxes?: boolean;
|
|
27
28
|
};
|
|
@@ -34,5 +35,5 @@ type GridProps<T extends GridDataType> = {
|
|
|
34
35
|
*
|
|
35
36
|
* @see {@link GridProps | The props for the `<GridController />` component}
|
|
36
37
|
*/
|
|
37
|
-
export declare const GridController: <T extends GridDataType>({ columns, data, footerContent, onRowClick, useCheckboxes, filters, emptyContent, }: GridProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare const GridController: <T extends GridDataType>({ columns, data, footerContent, onRowClick, isLoading, useCheckboxes, filters, emptyContent, }: GridProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
38
39
|
export {};
|
|
@@ -3,8 +3,12 @@ export declare const styles: {
|
|
|
3
3
|
width: number;
|
|
4
4
|
};
|
|
5
5
|
filters: (theme: import("../../utilities/styles").ScopedGigerTheme) => {
|
|
6
|
+
backgroundColor: string;
|
|
6
7
|
borderBottom: string;
|
|
7
|
-
padding:
|
|
8
|
+
padding: number;
|
|
9
|
+
};
|
|
10
|
+
skeletonTableRow: () => {
|
|
11
|
+
height: string;
|
|
8
12
|
};
|
|
9
13
|
table: {
|
|
10
14
|
tableLayout: "initial";
|
|
@@ -24,5 +28,6 @@ export declare const styles: {
|
|
|
24
28
|
borderRadius?: string | undefined;
|
|
25
29
|
boxShadow?: string | undefined;
|
|
26
30
|
height: string;
|
|
31
|
+
overflow: "hidden";
|
|
27
32
|
};
|
|
28
33
|
};
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
* @see {@link GridFooter | The `<GridFooter />` component}
|
|
8
8
|
*/
|
|
9
9
|
interface GridFooterProps {
|
|
10
|
+
/**
|
|
11
|
+
* If true, indicates there might be more results beyond what's been fetched
|
|
12
|
+
*/
|
|
13
|
+
hasMoreUnfetchedResults?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* If true, displays a loading indicator in the pagination area
|
|
16
|
+
*/
|
|
17
|
+
isLoadingMore?: boolean;
|
|
10
18
|
onPageChange: (nextPage: number) => void;
|
|
11
19
|
page: number;
|
|
12
20
|
pages: number;
|
|
@@ -23,5 +31,5 @@ interface GridFooterProps {
|
|
|
23
31
|
*
|
|
24
32
|
* @see {@link GridFooterProps | The props for the `<GridFooter />` component}
|
|
25
33
|
*/
|
|
26
|
-
export declare const GridFooter: ({ page, pages, pageSize, total, showPagination, onPageChange, }: GridFooterProps) => JSX.Element;
|
|
34
|
+
export declare const GridFooter: ({ page, pages, pageSize, total, showPagination, onPageChange, isLoadingMore, hasMoreUnfetchedResults, }: GridFooterProps) => JSX.Element;
|
|
27
35
|
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const styles: {
|
|
2
|
+
countWrapper: (theme: import("../../utilities/styles").ScopedGigerTheme) => {
|
|
3
|
+
alignItems: "center";
|
|
4
|
+
display: "flex";
|
|
5
|
+
gap: number;
|
|
6
|
+
};
|
|
7
|
+
loader: (theme: import("../../utilities/styles").ScopedGigerTheme) => {
|
|
8
|
+
color: string;
|
|
9
|
+
};
|
|
10
|
+
wrapper: {
|
|
11
|
+
alignItems: "center";
|
|
12
|
+
display: "flex";
|
|
13
|
+
justifyContent: "space-between";
|
|
14
|
+
width: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./sortable-header";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { SE } from "@shipengine/js-api";
|
|
2
2
|
export interface SortableHeaderProps {
|
|
3
3
|
/**
|
|
4
4
|
* The text to display in the header
|
|
@@ -11,7 +11,7 @@ export interface SortableHeaderProps {
|
|
|
11
11
|
/**
|
|
12
12
|
* The current sort direction
|
|
13
13
|
*/
|
|
14
|
-
sortDirection:
|
|
14
|
+
sortDirection: SE.SortableQuery["sortDir"];
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* A reusable component for creating sortable table headers
|
package/types/src/components/grid-filters/components/created-date-filter/created-date-filter.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { IGridFilters } from "../../grid-filters";
|
|
|
7
7
|
* @see {@link CreatedDateFilter | The `<CreatedDateFilter />` component}
|
|
8
8
|
*/
|
|
9
9
|
type CreatedDateFilterProps = {
|
|
10
|
+
disabled?: boolean;
|
|
10
11
|
filters: IGridFilters;
|
|
11
12
|
onFiltersUpdated: (params: IGridFilters) => void;
|
|
12
13
|
};
|
|
@@ -19,5 +20,5 @@ type CreatedDateFilterProps = {
|
|
|
19
20
|
*
|
|
20
21
|
* @see {@link CreatedDateFilterProps | The props for the `<CreatedDateFilter />` component}
|
|
21
22
|
*/
|
|
22
|
-
export declare const CreatedDateFilter: ({ filters, onFiltersUpdated }: CreatedDateFilterProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
23
|
+
export declare const CreatedDateFilter: ({ disabled, filters, onFiltersUpdated, }: CreatedDateFilterProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
23
24
|
export {};
|