@evenicanpm/storefront-core 1.6.0 → 1.8.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/__mocks__/next-image.tsx +3 -1
- package/package.json +3 -3
- package/src/api-manager/datasources/d365/d365-product.datasource.ts +1 -1
- package/src/api-manager/datasources/d365/utils/product-inventory-utils.ts +1 -3
- package/src/api-manager/datasources/e4/cart/e4-cart.remaps.ts +7 -5
- package/src/api-manager/datasources/e4/product/e4-product.datasource.ts +1 -4
- package/src/api-manager/datasources/e4/product/e4-product.translator.ts +13 -19
- package/src/api-manager/datasources/e4/utils/unwrap-e4-variants.ts +10 -13
- package/src/auth/auth-options.ts +34 -1
- package/src/auth/providers/entra-external-id-provider.ts +50 -0
- package/src/auth/providers/index.ts +8 -1
- package/src/auth/refresh-token.ts +1 -1
- package/src/cms/blocks/interfaces.ts +2 -0
- package/src/components-v2/BazaarMenu.stories.tsx +1 -1
- package/src/components-v2/BazaarMenu.tsx +4 -3
- package/src/components-v2/T/__tests__/T.test.tsx +91 -0
- package/src/components-v2/accordion/__tests__/accordion-header.test.tsx +28 -0
- package/src/components-v2/carousel/__tests__/carousel.test.tsx +208 -0
- package/src/components-v2/carousel-cards/carousel-card-1/__tests__/carousel-card-1.test.tsx +81 -0
- package/src/components-v2/categories/__tests__/category-menu.test.tsx +115 -0
- package/src/components-v2/categories/category-list/category-list.tsx +5 -1
- package/src/components-v2/categories/category-menu.tsx +11 -5
- package/src/components-v2/flex-box/__tests__/flex-box.test.tsx +88 -0
- package/src/components-v2/header/__tests__/header.test.tsx +122 -0
- package/src/components-v2/icons/__tests__/icons.test.tsx +53 -0
- package/src/components-v2/mobile-navigation/__tests__/mobile-navigation-bar.test.tsx +94 -0
- package/src/components-v2/nav-link/__tests__/nav-link.test.tsx +75 -0
- package/src/components-v2/navbar/__tests__/navbar.test.tsx +96 -0
- package/src/components-v2/product-cards/__tests__/product-cards.test.tsx +91 -0
- package/src/components-v2/product-dialog/__tests__/product-dialog.test.tsx +129 -0
- package/src/components-v2/product-dimensions/__tests__/product-dimensions.test.tsx +130 -0
- package/src/components-v2/product-dimensions/compound/dimensions-group-list-chip.tsx +36 -37
- package/src/components-v2/product-quantity-buttons/__tests__/product-quantity-buttons.test.tsx +77 -0
- package/src/components-v2/product-quantity-variants/__tests__/product-quantity-variants.test.tsx +109 -0
- package/src/components-v2/products-view/__tests__/products-view.test.tsx +147 -0
- package/src/components-v2/progress/__tests__/progress.test.tsx +62 -0
- package/src/components-v2/scrollbar/Scrollbar.stories.tsx +2 -2
- package/src/components-v2/scrollbar/__tests__/scrollbar.test.tsx +93 -0
- package/src/components-v2/search-bar/__tests__/search-bar.test.tsx +142 -0
- package/src/components-v2/search-bar/compound/results.tsx +1 -1
- package/src/components-v2/section/__tests__/section.test.tsx +100 -0
- package/src/components-v2/side-nav/__tests__/side-nav.test.tsx +156 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/add-to-wishlist-button.tsx +14 -15
- package/src/components-v2/wishlist-dialogs/styles.ts +8 -10
- package/src/pages-v2/account/addresses/address-item.tsx +2 -1
- package/src/pages-v2/checkout/checkout-alt-form/checkout-form.tsx +6 -1
- package/src/pages-v2/checkout/checkout-alt-form/steps/address/new-address-form.tsx +9 -8
- package/src/pages-v2/product-details/bopis/find-in-store-modal.tsx +1 -1
- package/src/pages-v2/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +1 -0
- package/src/pages-v2/product-list/product-list-context.tsx +123 -44
- package/src/pages-v2/product-list/range-filter.tsx +36 -25
- package/src/pages-v2/product-list/selected-facets.tsx +15 -8
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "@msdyn365-commerce/retail-proxy";
|
|
16
16
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
17
17
|
import { parseAsInteger, parseAsString, useQueryState } from "nuqs";
|
|
18
|
-
import React, { createContext, useCallback, useMemo } from "react";
|
|
18
|
+
import React, { createContext, useCallback, useMemo, useRef } from "react";
|
|
19
19
|
import {
|
|
20
20
|
buildInitialState,
|
|
21
21
|
calculatePage,
|
|
@@ -52,6 +52,7 @@ export const ProductListContext = createContext<
|
|
|
52
52
|
const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
53
53
|
const pathname = usePathname();
|
|
54
54
|
const searchParams = useSearchParams();
|
|
55
|
+
const isUserInitiated = useRef(false);
|
|
55
56
|
const [topParameter, setTopParameter] = useQueryState(
|
|
56
57
|
PageKey.TOP,
|
|
57
58
|
parseAsInteger
|
|
@@ -96,16 +97,57 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
96
97
|
.withOptions({ clearOnDefault: true }),
|
|
97
98
|
);
|
|
98
99
|
|
|
99
|
-
const initialState =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
const initialState = React.useMemo(
|
|
101
|
+
() =>
|
|
102
|
+
buildInitialState(
|
|
103
|
+
pathname.split("/"),
|
|
104
|
+
topParameter,
|
|
105
|
+
pageParameter,
|
|
106
|
+
sortParameter,
|
|
107
|
+
refinerParameter,
|
|
108
|
+
searchParameter,
|
|
109
|
+
),
|
|
110
|
+
[
|
|
111
|
+
pathname,
|
|
112
|
+
topParameter,
|
|
113
|
+
pageParameter,
|
|
114
|
+
sortParameter,
|
|
115
|
+
refinerParameter,
|
|
116
|
+
searchParameter,
|
|
117
|
+
],
|
|
106
118
|
);
|
|
107
119
|
const [inputParams, setInputParams] =
|
|
108
120
|
React.useState<SearchByCriteriaInput>(initialState);
|
|
121
|
+
React.useEffect(() => {
|
|
122
|
+
if (isUserInitiated.current) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
setInputParams((prev) => {
|
|
127
|
+
const prevRefiners = prev.searchState.refinement
|
|
128
|
+
.map((r) => convertRefinerToParameter(r))
|
|
129
|
+
.join("||");
|
|
130
|
+
if (prevRefiners === refinerParameter) {
|
|
131
|
+
return prev;
|
|
132
|
+
}
|
|
133
|
+
const newState = buildInitialState(
|
|
134
|
+
pathname.split("/"),
|
|
135
|
+
topParameter,
|
|
136
|
+
pageParameter,
|
|
137
|
+
sortParameter,
|
|
138
|
+
refinerParameter,
|
|
139
|
+
searchParameter,
|
|
140
|
+
);
|
|
141
|
+
return newState;
|
|
142
|
+
});
|
|
143
|
+
}, [
|
|
144
|
+
refinerParameter,
|
|
145
|
+
searchParameter,
|
|
146
|
+
sortParameter,
|
|
147
|
+
topParameter,
|
|
148
|
+
pageParameter,
|
|
149
|
+
pathname,
|
|
150
|
+
]);
|
|
109
151
|
|
|
110
152
|
const { data, isLoading } = getProductList.useData(inputParams);
|
|
111
153
|
const { data: productPrices } = getProductPrices.useSuspenseData({
|
|
@@ -113,45 +155,57 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
113
155
|
});
|
|
114
156
|
const handleRefinerChange = useCallback(
|
|
115
157
|
(refiner: ProductRefinerValue) => {
|
|
116
|
-
|
|
117
|
-
const refiners =
|
|
158
|
+
isUserInitiated.current = true;
|
|
159
|
+
const refiners = inputParams.searchState.refinement;
|
|
118
160
|
const priceIndex = ProductRefinerSource.Price;
|
|
119
|
-
|
|
161
|
+
|
|
162
|
+
let newRefiners: ProductRefinerValue[];
|
|
120
163
|
|
|
121
164
|
if (refiner.RefinerSourceValue === priceIndex) {
|
|
122
|
-
const
|
|
165
|
+
const priceRefinerIndex = refiners.findIndex(
|
|
166
|
+
(r) => r.RefinerSourceValue === priceIndex,
|
|
167
|
+
);
|
|
123
168
|
|
|
124
|
-
if (
|
|
169
|
+
if (priceRefinerIndex > -1) {
|
|
170
|
+
const existingPriceRefiner = refiners[priceRefinerIndex];
|
|
125
171
|
if (
|
|
126
|
-
|
|
172
|
+
existingPriceRefiner.LeftValueBoundString ===
|
|
127
173
|
refiner.LeftValueBoundString &&
|
|
128
|
-
|
|
174
|
+
existingPriceRefiner.RightValueBoundString ===
|
|
175
|
+
refiner.RightValueBoundString
|
|
129
176
|
) {
|
|
130
|
-
refiners.
|
|
177
|
+
newRefiners = refiners.filter((_, i) => i !== priceRefinerIndex);
|
|
131
178
|
} else {
|
|
132
|
-
|
|
133
|
-
|
|
179
|
+
newRefiners = refiners.map((r, i) =>
|
|
180
|
+
i === priceRefinerIndex ? refiner : r,
|
|
181
|
+
);
|
|
134
182
|
}
|
|
135
183
|
} else {
|
|
136
|
-
refiners
|
|
184
|
+
newRefiners = [...refiners, refiner];
|
|
137
185
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (refiner.RefinerSourceValue !== priceIndex) {
|
|
186
|
+
} else {
|
|
187
|
+
const idx = refiners.findIndex((r) => areRefinersEqual(r, refiner));
|
|
141
188
|
if (idx > -1) {
|
|
142
|
-
refiners.
|
|
189
|
+
newRefiners = refiners.filter((_, i) => i !== idx);
|
|
143
190
|
} else {
|
|
144
|
-
refiners
|
|
191
|
+
newRefiners = [...refiners, refiner];
|
|
145
192
|
}
|
|
146
193
|
}
|
|
147
194
|
|
|
148
|
-
setInputParams(
|
|
195
|
+
setInputParams({
|
|
196
|
+
...inputParams,
|
|
197
|
+
searchState: {
|
|
198
|
+
...inputParams.searchState,
|
|
199
|
+
refinement: newRefiners,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
149
202
|
},
|
|
150
|
-
[inputParams
|
|
203
|
+
[inputParams],
|
|
151
204
|
);
|
|
152
205
|
|
|
153
206
|
const handlePageChange = useCallback(
|
|
154
207
|
(page: number) => {
|
|
208
|
+
isUserInitiated.current = true;
|
|
155
209
|
const updatedInputParams = { ...inputParams };
|
|
156
210
|
const calculationSkip = calculateSkip(page, topParameter);
|
|
157
211
|
let paging = updatedInputParams.searchState.queryResultSettings.Paging;
|
|
@@ -159,18 +213,19 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
159
213
|
paging.Skip = calculationSkip;
|
|
160
214
|
setInputParams(updatedInputParams);
|
|
161
215
|
},
|
|
162
|
-
[inputParams, topParameter
|
|
216
|
+
[inputParams, topParameter],
|
|
163
217
|
);
|
|
164
218
|
|
|
165
219
|
const handlePerPageChange = useCallback(
|
|
166
220
|
(newValue: number) => {
|
|
221
|
+
isUserInitiated.current = true;
|
|
167
222
|
const updatedInputParams = { ...inputParams };
|
|
168
223
|
let paging = updatedInputParams.searchState.queryResultSettings.Paging;
|
|
169
224
|
paging = paging || {};
|
|
170
225
|
paging.Top = newValue;
|
|
171
226
|
setInputParams(updatedInputParams);
|
|
172
227
|
},
|
|
173
|
-
[inputParams
|
|
228
|
+
[inputParams],
|
|
174
229
|
);
|
|
175
230
|
|
|
176
231
|
const handleViewChange = useCallback(
|
|
@@ -182,6 +237,7 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
182
237
|
|
|
183
238
|
const handleSortChange = useCallback(
|
|
184
239
|
(sort: SortOption) => {
|
|
240
|
+
isUserInitiated.current = true;
|
|
185
241
|
const updatedInputParams = { ...inputParams };
|
|
186
242
|
const sortOption = getSortOptions().find((s) => s.code === sort.code);
|
|
187
243
|
if (!sortOption) {
|
|
@@ -194,23 +250,25 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
194
250
|
];
|
|
195
251
|
setInputParams(updatedInputParams);
|
|
196
252
|
},
|
|
197
|
-
[inputParams
|
|
253
|
+
[inputParams],
|
|
198
254
|
);
|
|
199
255
|
|
|
200
256
|
const handleSearchChange = useCallback(
|
|
201
257
|
(searchTerm: string) => {
|
|
258
|
+
isUserInitiated.current = true;
|
|
202
259
|
const updatedInputParams = { ...inputParams };
|
|
203
260
|
updatedInputParams.searchState.searchTerm = searchTerm;
|
|
204
261
|
setInputParams(updatedInputParams);
|
|
205
262
|
},
|
|
206
|
-
[inputParams
|
|
263
|
+
[inputParams],
|
|
207
264
|
);
|
|
208
265
|
|
|
209
266
|
const handleRefinersClear = useCallback(() => {
|
|
267
|
+
isUserInitiated.current = true;
|
|
210
268
|
const updatedInputParams = { ...inputParams };
|
|
211
269
|
updatedInputParams.searchState.refinement = [];
|
|
212
270
|
setInputParams(updatedInputParams);
|
|
213
|
-
}, [inputParams
|
|
271
|
+
}, [inputParams]);
|
|
214
272
|
|
|
215
273
|
const paramHandlers = useMemo(
|
|
216
274
|
() => ({
|
|
@@ -234,6 +292,10 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
234
292
|
);
|
|
235
293
|
|
|
236
294
|
React.useEffect(() => {
|
|
295
|
+
if (!isUserInitiated.current) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
237
299
|
const sortObj =
|
|
238
300
|
inputParams.searchState.queryResultSettings.Sorting?.Columns?.[0];
|
|
239
301
|
let sortCode = "";
|
|
@@ -246,21 +308,38 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
246
308
|
)?.code || "";
|
|
247
309
|
}
|
|
248
310
|
|
|
249
|
-
|
|
250
|
-
inputParams.searchState.queryResultSettings.Paging?.Top || 20
|
|
251
|
-
);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
311
|
+
const newTop =
|
|
312
|
+
inputParams.searchState.queryResultSettings.Paging?.Top || 20;
|
|
313
|
+
const newPage = calculatePage(inputParams.searchState.queryResultSettings);
|
|
314
|
+
const newRefiners = inputParams.searchState.refinement
|
|
315
|
+
.map((r) => convertRefinerToParameter(r))
|
|
316
|
+
.join("||");
|
|
317
|
+
const newSearch = inputParams.searchState.searchTerm || "";
|
|
318
|
+
|
|
319
|
+
if (topParameter !== newTop) {
|
|
320
|
+
setTopParameter(newTop);
|
|
321
|
+
}
|
|
322
|
+
if (pageParameter !== newPage) {
|
|
323
|
+
setPageParameter(newPage);
|
|
324
|
+
}
|
|
325
|
+
if (refinerParameter !== newRefiners) {
|
|
326
|
+
setRefinerParameter(newRefiners);
|
|
327
|
+
}
|
|
328
|
+
if (sortParameter !== sortCode) {
|
|
329
|
+
setSortParameter(sortCode);
|
|
330
|
+
}
|
|
331
|
+
if (searchParameter !== newSearch) {
|
|
332
|
+
setSearchParameter(newSearch);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
isUserInitiated.current = false;
|
|
262
336
|
}, [
|
|
263
337
|
inputParams,
|
|
338
|
+
topParameter,
|
|
339
|
+
pageParameter,
|
|
340
|
+
refinerParameter,
|
|
341
|
+
sortParameter,
|
|
342
|
+
searchParameter,
|
|
264
343
|
setPageParameter,
|
|
265
344
|
setRefinerParameter,
|
|
266
345
|
setSearchParameter,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "@msdyn365-commerce/retail-proxy";
|
|
7
7
|
import { Box, Slider, TextField, Typography } from "@mui/material";
|
|
8
8
|
import type React from "react";
|
|
9
|
-
import { useEffect, useState } from "react";
|
|
9
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
10
10
|
import type { RenderedFacetProps } from "./facet-group";
|
|
11
11
|
|
|
12
12
|
type Props = RenderedFacetProps & {
|
|
@@ -17,6 +17,7 @@ export default function RangeFilter({
|
|
|
17
17
|
handleRefinerSelect,
|
|
18
18
|
selectedValues,
|
|
19
19
|
}: Props) {
|
|
20
|
+
const isUserInteraction = useRef(false);
|
|
20
21
|
const getMinValForSlider = () => {
|
|
21
22
|
const item = facet.Values?.[0];
|
|
22
23
|
if (item) {
|
|
@@ -36,58 +37,68 @@ export default function RangeFilter({
|
|
|
36
37
|
const [maxVal, setMaxVal] = useState<number>(getMaxValForSlider());
|
|
37
38
|
const [textMin, setTextMin] = useState<number>(getMinValForSlider());
|
|
38
39
|
const [textMax, setTextMax] = useState<number>(getMaxValForSlider());
|
|
39
|
-
const [selected, setSelected] = useState<boolean>(false);
|
|
40
40
|
|
|
41
|
+
// Sync slider position when selectedValues changes from URL
|
|
41
42
|
useEffect(() => {
|
|
42
43
|
if (selectedValues) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const newMin = Number(selectedValues.LeftValueBoundString);
|
|
45
|
+
const newMax = Number(selectedValues.RightValueBoundString);
|
|
46
|
+
// Only sync from URL if not from user interaction
|
|
47
|
+
if (
|
|
48
|
+
!isUserInteraction.current &&
|
|
49
|
+
(minVal !== newMin || maxVal !== newMax)
|
|
50
|
+
) {
|
|
51
|
+
setMinVal(newMin);
|
|
52
|
+
setMaxVal(newMax);
|
|
53
|
+
setTextMin(newMin);
|
|
54
|
+
setTextMax(newMax);
|
|
55
|
+
}
|
|
47
56
|
}
|
|
48
|
-
}, [selectedValues]);
|
|
57
|
+
}, [selectedValues, minVal, maxVal]);
|
|
58
|
+
|
|
59
|
+
const pushPriceFilter = useCallback(() => {
|
|
60
|
+
const refiner: ProductRefinerValue = {
|
|
61
|
+
RefinerRecordId: 0,
|
|
62
|
+
RefinerSourceValue: ProductRefinerSource.Price,
|
|
63
|
+
LeftValueBoundString: minVal.toString(),
|
|
64
|
+
RightValueBoundString: maxVal.toString(),
|
|
65
|
+
DataTypeValue: 1,
|
|
66
|
+
};
|
|
67
|
+
handleRefinerSelect(refiner);
|
|
68
|
+
// Reset flag after pushing
|
|
69
|
+
isUserInteraction.current = false;
|
|
70
|
+
}, [minVal, maxVal, handleRefinerSelect]);
|
|
49
71
|
|
|
50
72
|
useEffect(() => {
|
|
51
|
-
|
|
73
|
+
if (!isUserInteraction.current) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
52
76
|
const request = setTimeout(pushPriceFilter, 600);
|
|
53
77
|
return () => clearTimeout(request);
|
|
54
|
-
});
|
|
78
|
+
}, [pushPriceFilter]);
|
|
55
79
|
|
|
56
80
|
const handleSliderChange = (_: Event, newValue: number | number[]) => {
|
|
81
|
+
isUserInteraction.current = true;
|
|
57
82
|
if (Array.isArray(newValue)) {
|
|
58
83
|
setMinVal(Number(newValue[0]));
|
|
59
84
|
setTextMin(Number(newValue[0]));
|
|
60
85
|
setMaxVal(Number(newValue[1]));
|
|
61
86
|
setTextMax(Number(newValue[1]));
|
|
62
|
-
setSelected(true);
|
|
63
87
|
}
|
|
64
88
|
};
|
|
65
89
|
|
|
66
90
|
const handleTextMin = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
|
91
|
+
isUserInteraction.current = true;
|
|
67
92
|
const val = Number(evt.target.value);
|
|
68
93
|
setTextMin(val);
|
|
69
94
|
setMinVal(val);
|
|
70
|
-
setSelected(true);
|
|
71
95
|
};
|
|
72
96
|
|
|
73
97
|
const handleTextMax = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
|
98
|
+
isUserInteraction.current = true;
|
|
74
99
|
const val = Number(evt.target.value);
|
|
75
100
|
setTextMax(val);
|
|
76
101
|
setMaxVal(val);
|
|
77
|
-
setSelected(true);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const pushPriceFilter = () => {
|
|
81
|
-
if (selected) {
|
|
82
|
-
const refiner: ProductRefinerValue = {
|
|
83
|
-
RefinerRecordId: 0,
|
|
84
|
-
RefinerSourceValue: ProductRefinerSource.Price,
|
|
85
|
-
LeftValueBoundString: minVal.toString(),
|
|
86
|
-
RightValueBoundString: maxVal.toString(),
|
|
87
|
-
DataTypeValue: 1,
|
|
88
|
-
};
|
|
89
|
-
handleRefinerSelect(refiner);
|
|
90
|
-
}
|
|
91
102
|
};
|
|
92
103
|
|
|
93
104
|
return (
|
|
@@ -62,14 +62,21 @@ export default function SelectedFacets() {
|
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
64
|
<Stack direction={"row"} spacing={2}>
|
|
65
|
-
{selectedRefiners.map((refiner) =>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
{selectedRefiners.map((refiner, _) => {
|
|
66
|
+
// For price refiners (RefinerRecordId is always 0), use index + source value for unique key
|
|
67
|
+
const key =
|
|
68
|
+
refiner.RefinerSourceValue === ProductRefinerSource.Price
|
|
69
|
+
? `price-${refiner.LeftValueBoundString}-${refiner.RightValueBoundString}`
|
|
70
|
+
: `${refiner.RefinerRecordId}-${refiner.LeftValueBoundString}`;
|
|
71
|
+
return (
|
|
72
|
+
<Chip
|
|
73
|
+
key={key}
|
|
74
|
+
title={refiner.LeftValueBoundString}
|
|
75
|
+
label={`${getRefinerLabel(refiner)}: ${getRefinerValue(refiner)}`}
|
|
76
|
+
onDelete={() => handleRefinerChange(refiner)}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
})}
|
|
73
80
|
{selectedRefiners.length > 0 ? (
|
|
74
81
|
<Button variant={"text"} sx={{ ml: 2 }} onClick={handleRefinersClear}>
|
|
75
82
|
<Paragraph>{t("clearAll")}</Paragraph>
|