diff --git a/CHANGELOG.md b/CHANGELOG.md index 24310e956..51534c5ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- Shipping filter on filters section + +### Fixed + +- Updated English, Spanish and Portuguese translations. +- Added new strings to remaining languages. + ## [3.134.1] - 2024-11-07 ### Fixed diff --git a/manifest.json b/manifest.json index 5ab505f31..74992827b 100644 --- a/manifest.json +++ b/manifest.json @@ -5,9 +5,7 @@ "title": "VTEX Search Result", "description": "A search result wrapper component", "mustUpdateAt": "2019-04-25", - "registries": [ - "smartcheckout" - ], + "registries": ["smartcheckout"], "scripts": { "postreleasy": "vtex publish --verbose" }, diff --git a/messages/ar.json b/messages/ar.json index b9ad437cb..36f6143d0 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "العلامات التجارية", "store/search.filter.title.price-ranges": "نطاقات السعر", "store/search.text": "عرض {from}-{to} من {recordsFiltered} نتائج", + "store/search.filter.title.shipping": "الشحن", + "store/search.filter.shipping.name.delivery": "توصيل الى", + "store/search.filter.shipping.name.pickup-in-point": "الاستلام في", + "store/search.filter.shipping.name.pickup-nearby": "استلام بقرب", + "store/search.filter.shipping.name.pickup-all": "الإستلام", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "تصفية حسب:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {منتج} other {منتجات}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {منتج} other {منتجات}}", @@ -104,4 +111,3 @@ "admin/editor.search-result.fetch-button.button-behavior.button": "الزر", "admin/editor.search-result.fetch-button.button-behavior.link-to-page": "الرابط إلى الصفحة - تحسين SEO، قد يغير تصميم الزر" } - diff --git a/messages/bg.json b/messages/bg.json index 8c6d755d7..86c88f250 100644 --- a/messages/bg.json +++ b/messages/bg.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Брандове", "store/search.filter.title.price-ranges": "Ценови диапазони", "store/search.text": "Показване на {from}–{to} от {recordsFiltered} резултата", + "store/search.filter.title.shipping": "Доставка", + "store/search.filter.shipping.name.delivery": "Доставка до", + "store/search.filter.shipping.name.pickup-in-point": "Вземане от", + "store/search.filter.shipping.name.pickup-nearby": "Вземане наблизо", + "store/search.filter.shipping.name.pickup-all": "Вземане", + "store/search.filter.shipping.action-button.delivery": "Въвеждане на местоположение", + "store/search.filter.shipping.action-button.pickup-in-point": "Въвеждане на магазин", "store/search.selected-filters": "Филтрирани по:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {продукт} other {продукта}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {продукт} other {продукта}}", diff --git a/messages/ca.json b/messages/ca.json index d348327ce..4eaef63a2 100644 --- a/messages/ca.json +++ b/messages/ca.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Marques", "store/search.filter.title.price-ranges": "Intervals de preus", "store/search.text": "S'estan mostrant de {from} a {to} de {recordsFiltered} resultats", + "store/search.filter.title.shipping": "Enviament", + "store/search.filter.shipping.name.delivery": "Lliura a", + "store/search.filter.shipping.name.pickup-in-point": "Recollida a", + "store/search.filter.shipping.name.pickup-nearby": "Recollida a prop", + "store/search.filter.shipping.name.pickup-all": "Recollida", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrat per:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", diff --git a/messages/context.json b/messages/context.json index a10ab84b7..138b660d4 100644 --- a/messages/context.json +++ b/messages/context.json @@ -65,6 +65,13 @@ "store/search.filter.placeholder": "Search by {filterName}", "store/search.filter.title.brands": "Brands", "store/search.filter.title.price-ranges": "Price Ranges", + "store/search.filter.title.shipping": "Shipping", + "store/search.filter.shipping.name.delivery": "Deliver to", + "store/search.filter.shipping.name.pickup-in-point": "Pickup at", + "store/search.filter.shipping.name.pickup-nearby": "Pickup nearby", + "store/search.filter.shipping.name.pickup-all": "Pickup", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.text": "Showing {from}-{to} from {recordsFiltered} records", "store/search.selected-filters": "Filtered by:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {Product} other {Products}}", diff --git a/messages/da.json b/messages/da.json index ea6d6f7e7..fd72e4b67 100644 --- a/messages/da.json +++ b/messages/da.json @@ -65,6 +65,13 @@ "store/search.filter.placeholder": "Søg efter {filterName}", "store/search.filter.title.brands": "Brands", "store/search.filter.title.price-ranges": "Prisintervaller", + "store/search.filter.title.shipping": "Forsendelse", + "store/search.filter.shipping.name.delivery": "Lever til", + "store/search.filter.shipping.name.pickup-in-point": "Afhentning ved", + "store/search.filter.shipping.name.pickup-nearby": "Afhentning i nærheden", + "store/search.filter.shipping.name.pickup-all": "Afhentning", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.text": "Viser {from}-{to} fra {recordsFiltered} optegnelser", "store/search.selected-filters": "Filtreret efter:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", diff --git a/messages/de.json b/messages/de.json index c50ffa9d0..f242b9dea 100644 --- a/messages/de.json +++ b/messages/de.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Marken", "store/search.filter.title.price-ranges": "Preisspannen", "store/search.text": "Anzeigen {from}-{to} aus {recordsFiltered}-Ergebnissen", + "store/search.filter.title.shipping": "Versand", + "store/search.filter.shipping.name.delivery": "Liefern an", + "store/search.filter.shipping.name.pickup-in-point": "Abholung bei", + "store/search.filter.shipping.name.pickup-nearby": "Abholung in der Nähe", + "store/search.filter.shipping.name.pickup-all": "Abholung", + "store/search.filter.shipping.action-button.delivery": "Ort eingeben", + "store/search.filter.shipping.action-button.pickup-in-point": "Geschäft eingeben", "store/search.selected-filters": "Gefiltert nach:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {Produkt} other {Produkte}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {Produkt} other {Produkte}}", diff --git a/messages/el.json b/messages/el.json index 60fdcf95e..d641c3061 100644 --- a/messages/el.json +++ b/messages/el.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Εμπορικές επωνυμίες", "store/search.filter.title.price-ranges": "Εύρος τιμών", "store/search.text": "Γίνεται εμφάνιση {from}–{to} από {recordsFiltered} αποτελέσματα", + "store/search.filter.title.shipping": "Μεταφορά", + "store/search.filter.shipping.name.delivery": "Παράδοση προς", + "store/search.filter.shipping.name.pickup-in-point": "Παραλαβή σε", + "store/search.filter.shipping.name.pickup-nearby": "Παραλαβή πλησίον", + "store/search.filter.shipping.name.pickup-all": "Παραλαβή", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Φιλτράρισμα ανά:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", diff --git a/messages/en.json b/messages/en.json index bd7a11e1c..197088321 100644 --- a/messages/en.json +++ b/messages/en.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Brands", "store/search.filter.title.price-ranges": "Price ranges", "store/search.text": "Showing {from}–{to} of {recordsFiltered} results", + "store/search.filter.title.shipping": "Shipping", + "store/search.filter.shipping.name.delivery": "Deliver to", + "store/search.filter.shipping.name.pickup-in-point": "Pickup at", + "store/search.filter.shipping.name.pickup-nearby": "Pickup nearby", + "store/search.filter.shipping.name.pickup-all": "Pickup", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtered by:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {product} other {products}}", diff --git a/messages/es.json b/messages/es.json index b1e9c69bd..a4c1e4bbb 100644 --- a/messages/es.json +++ b/messages/es.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Marcas", "store/search.filter.title.price-ranges": "Rangos de precio", "store/search.text": "Mostrando {from}-{to} de {recordsFiltered} resultados", + "store/search.filter.title.shipping": "Envío", + "store/search.filter.shipping.name.delivery": "Entregar a", + "store/search.filter.shipping.name.pickup-in-point": "Recogida en", + "store/search.filter.shipping.name.pickup-nearby": "Recogida en tiendas cercanas", + "store/search.filter.shipping.name.pickup-all": "Recogida", + "store/search.filter.shipping.action-button.delivery": "Ingresa tu ubicación", + "store/search.filter.shipping.action-button.pickup-in-point": "Ingresa la tienda", "store/search.selected-filters": "Filtrado por:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {producto} other {productos}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {producto} other {productos}}", diff --git a/messages/fi.json b/messages/fi.json index c38c84499..9f17a7ed9 100644 --- a/messages/fi.json +++ b/messages/fi.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Brändit", "store/search.filter.title.price-ranges": "Hintaluokat", "store/search.text": "Näytetään {from}–{to} {recordsFiltered} tuloksesta", + "store/search.filter.title.shipping": "Toimitus", + "store/search.filter.shipping.name.delivery": "Toimitus osoitteeseen", + "store/search.filter.shipping.name.pickup-in-point": "Nouto myymälästä", + "store/search.filter.shipping.name.pickup-nearby": "Nouto läheltä", + "store/search.filter.shipping.name.pickup-all": "Nouto", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Suodatus:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {tuote} other {tuotetta}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {tuote} other {tuotetta}}", diff --git a/messages/fr.json b/messages/fr.json index a97e7f0a6..e9ee9a8c0 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Marques", "store/search.filter.title.price-ranges": "Gammes de prix", "store/search.text": "Afficher les {from}-{to} des {recordsFiltered} résultats", + "store/search.filter.title.shipping": "Expédition", + "store/search.filter.shipping.name.delivery": "Livrer à", + "store/search.filter.shipping.name.pickup-in-point": "Retrait à", + "store/search.filter.shipping.name.pickup-nearby": "Retrait à proximité", + "store/search.filter.shipping.name.pickup-all": "Point de retrait", + "store/search.filter.shipping.action-button.delivery": "Saisir la localisation", + "store/search.filter.shipping.action-button.pickup-in-point": "Saisir le magasin", "store/search.selected-filters": "Filtré par :", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produit} other {produits}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {produit} other {produits}}", diff --git a/messages/hu.json b/messages/hu.json index 59eeaec20..925ce25ff 100644 --- a/messages/hu.json +++ b/messages/hu.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Márkák", "store/search.filter.title.price-ranges": "Ártartományok", "store/search.text": "{from}-{to} eredmény megjelenítése a(z) {recordsFiltered} eredményből", + "store/search.filter.title.shipping": "Shipping", + "store/search.filter.shipping.name.delivery": "Deliver to", + "store/search.filter.shipping.name.pickup-in-point": "Pickup at", + "store/search.filter.shipping.name.pickup-nearby": "Pickup nearby", + "store/search.filter.shipping.name.pickup-all": "Pickup", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Szűrés:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {termék} other {termék}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {termék} other {termék}}", @@ -104,4 +111,3 @@ "admin/editor.search-result.fetch-button.button-behavior.button": "Gomb", "admin/editor.search-result.fetch-button.button-behavior.link-to-page": "Link az oldalra – Javítja a SEO-t, megváltoztathatja a gomb megjelenését" } - \ No newline at end of file diff --git a/messages/id.json b/messages/id.json index 5dd73b883..af34d2387 100644 --- a/messages/id.json +++ b/messages/id.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Merek", "store/search.filter.title.price-ranges": "Rentang harga", "store/search.text": "Menampilka {from}–{to} dari {recordsFiltered} hasil", + "store/search.filter.title.shipping": "Pengiriman", + "store/search.filter.shipping.name.delivery": "Kirim ke", + "store/search.filter.shipping.name.pickup-in-point": "Ambil di", + "store/search.filter.shipping.name.pickup-nearby": "Pengambilan terdekat", + "store/search.filter.shipping.name.pickup-all": "Pengambilan", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Difilter menurut:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, other {produk}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, other {produk}}", diff --git a/messages/it.json b/messages/it.json index 52fd0731a..8f5f84edf 100644 --- a/messages/it.json +++ b/messages/it.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Brand", "store/search.filter.title.price-ranges": "Fasce di prezzo", "store/search.text": "Mostra {from}–{to} di {recordsFiltered} risultati", + "store/search.filter.title.shipping": "Spedizione", + "store/search.filter.shipping.name.delivery": "Consegna a", + "store/search.filter.shipping.name.pickup-in-point": "Ritiro presso", + "store/search.filter.shipping.name.pickup-nearby": "Ritiro nelle vicinanze", + "store/search.filter.shipping.name.pickup-all": "Ritiro", + "store/search.filter.shipping.action-button.delivery": "Inserisci località", + "store/search.filter.shipping.action-button.pickup-in-point": "Inserisci negozio", "store/search.selected-filters": "Filtrato per:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {prodotto} other {prodotti}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {prodotto} other {prodotti}}", diff --git a/messages/ja.json b/messages/ja.json new file mode 100644 index 000000000..ecdd7e7db --- /dev/null +++ b/messages/ja.json @@ -0,0 +1,113 @@ +{ + "admin/editor.search-result.title": "検索結果", + "admin/editor.search-result.query": "カスタムクエリ", + "admin/editor.search-result.query.description": "コンテキストがない場合に作成されるクエリ", + "admin/editor.search-result.query.enableCustomQuery": "カスタムクエリを有効にする", + "admin/editor.search-result.query.maxItemsPerPage": "検索結果1ページあたりに表示される最大項目数", + "admin/editor.search-result.query.hideUnavailableItems": "利用できない項目を非表示にする", + "admin/editor.search-result.query.skusFilter": "SKU フィルタ", + "admin/editor.search-result.query.skusFilter.description": "最初に利用できるフィルタを設定しておくと、クエリが早くなります!", + "admin/editor.search-result.query.skusFilter.none": "なし", + "admin/editor.search-result.query.skusFilter.first-available": "最初に利用できる", + "admin/editor.search-result.query.skusFilter.all-available": "すべて利用できる", + "admin/editor.search-result.query.simulationBehavior": "シミュレーション動作", + "admin/editor.search-result.query.simulationBehavior.description": "クエリを高速化したい場合、スキップに設定してください。ただし、SKU の価格と在庫は最新のものに更新されないことがあります", + "admin/editor.search-result.query.simulationBehavior.default": "デフォルト", + "admin/editor.search-result.query.simulationBehavior.skip": "シミュレーションをスキップ", + "admin/editor.search-result.query.installmentCriteria.title": "表示する分割払い", + "admin/editor.search-result.query.installmentCriteria.description": "表示する分割払いのタイプを選びます(例:金利込みの最大金額、金利を別にした最大金額)。", + "admin/editor.search-result.query.installmentCriteria.max-without-interest": "金利を別にした最大金額", + "admin/editor.search-result.query.installmentCriteria.max-with-interest": "金利込みの最大金額", + "admin/editor.search-result.pagination.title": "ページネーションのタイプ", + "admin/editor.search-result.pagination.show-more": "もっと見る", + "admin/editor.search-result.pagination.infinite-scroll": "無限スクロール", + "admin/editor.search-result.description": "検索結果のラッパー", + "admin/editor.search-result.maxItemsPerLine.title": "1行あたりに表示される最大項目数", + "admin/editor.search-result.mobileLayout": "モバイルレイアウトの切り替え", + "admin/editor.search-result.mobileLayout.mode1": "レイアウトモード1", + "admin/editor.search-result.mobileLayout.mode2": "レイアウトモード2", + "admin/editor.search-result.hiddenFacets": "非表示のフィルタ", + "admin/editor.search-result.hiddenFacets.brands": "ブランドフィルタを非表示にする", + "admin/editor.search-result.hiddenFacets.categories": "カテゴリフィルタを非表示にする", + "admin/editor.search-result.hiddenFacets.priceRange": "価格フィルタを非表示にする", + "admin/editor.search-result.hiddenFacets.specificationFilters": "仕様フィルタを非表示にする", + "admin/editor.search-result.hiddenFacets.specificationFilters.hideAll": "仕様フィルタをすべて非表示にする", + "admin/editor.search-result.hiddenFacets.specificationFilters.hiddenFilter": "非表示の仕様フィルタ", + "admin/editor.search-result.hiddenFacets.specificationFilters.hiddenFilter.name": "非表示の仕様フィルタ名", + "admin/editor.search-result.showTitle": "カテゴリタイトルを表示するか、またはギャラリーの上にある語句を検索する", + "admin/editor.search-result.gap.title": "ギャラリー項目間のギャップ", + "admin/editor.search-result.facet-quantity": "フィルタ項目数を表示する", + "admin/editor.search-result.advanced-settings.title": "高度な設定", + "admin/editor.search-result.advanced-settings.trackingId.title": "GTM 検索結果の名前", + "admin/editor.search-result.advanced-settings.trackingId.description": "Google Analytics で表示される名前。設定しない場合は「検索結果」となります", + "admin/editor.search-result.ordination.sort-by": "並べ替え", + "admin/editor.search-result.total-products": "製品の合計", + "store/search-result.show-more-button": "次を表示", + "store/search-result.show-previous-button": "前を表示", + "store/search-result.showing-products": "{value} 個を表示中", + "store/search-result.showing-products-count": "{productsLoaded, number} / {total, number}", + "store/search-result.showing-all-products": "全 {value} 個の製品を表示しました", + "store/search-result.showing-all-products-count": "{total, number}", + "store/search-result.filter-button.title": "フィルタ", + "store/search-result.filter-breadcrumbs.primary": "フィルタ", + "store/search-result.filter-button.apply": "適用", + "store/search-result.filter-button.clear": "クリア", + "store/search-result.filter-button.clearAll": "すべてクリア", + "store/search-result.orderby.title": "並べ替え", + "store/search-result.clear-filters.title": "クリア", + "store/search-result.filter-action.title": "フィルタ", + "store/search.filter.title.categories": "部門", + "store/search.filter.title.color": "色", + "store/filter.more-departments": "さらに {quantity} 個の部門を表示", + "store/filter.more-categories": "さらに {quantity} 個のカテゴリを表示", + "store/filter.more-items": "さらに {quantity} 個を表示", + "store/filter.less-items": "一部を表示", + "store/search.filter.placeholder": "{filterName} で検索", + "store/search.filter.title.brands": "ブランド", + "store/search.filter.title.price-ranges": "価格帯", + "store/search.filter.title.shipping": "発送方法", + "store/search.filter.shipping.name.delivery": "宛先", + "store/search.filter.shipping.name.pickup-in-point": "集荷場所", + "store/search.filter.shipping.name.pickup-nearby": "近くの集荷場所", + "store/search.filter.shipping.name.pickup-all": "集荷", + "store/search.filter.shipping.action-button.delivery": "場所を入力", + "store/search.filter.shipping.action-button.pickup-in-point": "ストアを入力", + "store/search.text": "{from}-{to} に該当する {recordsFiltered} の記録を表示中", + "store/search.selected-filters": "検索条件:", + "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, other {製品}}", + "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, other {製品}}", + "store/search.empty-products": "「{term}」に関連した結果は見つかりませんでした", + "store/search.what-do-i-do": "以下を試してください", + "store/search.what-to-do.1": "入力した語句を確認してください。", + "store/search.what-to-do.2": "単語を1つにしてみてください。", + "store/search.what-to-do.3": "一般的な語句で検索してください。", + "store/search.what-to-do.4": "探している語句の類義語で検索してみてください。", + "store/search.no-products": "製品が見つかりません", + "store/ordenation.button": "並べ替え", + "store/ordenation.sort-by": "並べ替えの順番", + "store/ordenation.relevance": "関連度", + "store/ordenation.sales": "売上高", + "store/ordenation.release.date": "発売日", + "store/ordenation.discount": "割引率", + "store/ordenation.price.descending": "価格:高い順", + "store/ordenation.price.ascending": "価格:低い順", + "store/ordenation.name.ascending": "名前(昇順)", + "store/ordenation.name.descending": "名前(降順)", + "store/layoutModeSwitcher.inline": "行", + "store/layoutModeSwitcher.small": "小", + "store/layoutModeSwitcher.normal": "普通", + "store/gallery.gapType.none": "なし", + "store/gallery.gapType.small": "小", + "store/gallery.gapType.medium": "中", + "store/gallery.gapType.large": "大", + "admin/editor.search-result-layout-custom.title": "検索結果カスタム・フレキシブルレイアウト", + "admin/editor.search-result-layout.title": "検索結果フレキシブルレイアウト", + "admin/editor.search-result-mobile.title": "検索結果フレキシブルレイアウト・モバイル", + "admin/editor.search-result-desktop.title": "検索結果フレキシブルレイアウト・デスクトップ", + "store/search-result.price-ranges.submit": "進む", + "admin/editor.search-result.fetch-more": "さらに取得", + "admin/editor.search-result.fetch-previous": "前のを取得", + "admin/editor.search-result.fetch-button.button-behavior": "ボタンの動作", + "admin/editor.search-result.fetch-button.button-behavior.button": "ボタン", + "admin/editor.search-result.fetch-button.button-behavior.link-to-page": "ページへのリンク - SEO を改善します。ボタンの見た目が変わることがあります。" +} diff --git a/messages/ko.json b/messages/ko.json index b2d1748fb..72222b573 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "브랜드", "store/search.filter.title.price-ranges": "가격 범위", "store/search.text": "{recordsFiltered} 결과 중 {from}–{to} 표시", + "store/search.filter.title.shipping": "배송", + "store/search.filter.shipping.name.delivery": "배송 대상", + "store/search.filter.shipping.name.pickup-in-point": "픽업 장소", + "store/search.filter.shipping.name.pickup-nearby": "근처 픽업", + "store/search.filter.shipping.name.pickup-all": "픽업", + "store/search.filter.shipping.action-button.delivery": "위치 입력", + "store/search.filter.shipping.action-button.pickup-in-point": "스토어 입력", "store/search.selected-filters": "필터링 기준:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {제품} other {제품}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {제품} other {제품}}", diff --git a/messages/nl.json b/messages/nl.json index d6a446545..4f7b6e5d2 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -70,6 +70,13 @@ "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {product} other {producten}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {product} other {producten}}", "store/search.empty-products": "We hebben geen resultaten gevonden die gerelateerd zijn aan \"{term}\"", + "store/search.filter.title.shipping": "Verzending", + "store/search.filter.shipping.name.delivery": "Leveren aan", + "store/search.filter.shipping.name.pickup-in-point": "Afhalen op", + "store/search.filter.shipping.name.pickup-nearby": "Afhalen in de buurt van", + "store/search.filter.shipping.name.pickup-all": "Afhalen", + "store/search.filter.shipping.action-button.delivery": "Voer locatie in", + "store/search.filter.shipping.action-button.pickup-in-point": "Winkel invoeren", "store/search.what-do-i-do": "Wat moet ik doen?", "store/search.what-to-do.1": "Controleer de termen die u hebt getypt.", "store/search.what-to-do.2": "Probeer een enkel woord te gebruiken.", diff --git a/messages/nn.json b/messages/nn.json index c38d2e09b..57564abfa 100644 --- a/messages/nn.json +++ b/messages/nn.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Merker", "store/search.filter.title.price-ranges": "Prisklasser", "store/search.text": "Viser {from}–{to} av {recordsFiltered} resultater", + "store/search.filter.title.shipping": "Forsendelse", + "store/search.filter.shipping.name.delivery": "Leveres til", + "store/search.filter.shipping.name.pickup-in-point": "Hent hos", + "store/search.filter.shipping.name.pickup-nearby": "Henting i nærheten", + "store/search.filter.shipping.name.pickup-all": "Hent", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrert etter:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", diff --git a/messages/no.json b/messages/no.json index c38d2e09b..57564abfa 100644 --- a/messages/no.json +++ b/messages/no.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Merker", "store/search.filter.title.price-ranges": "Prisklasser", "store/search.text": "Viser {from}–{to} av {recordsFiltered} resultater", + "store/search.filter.title.shipping": "Forsendelse", + "store/search.filter.shipping.name.delivery": "Leveres til", + "store/search.filter.shipping.name.pickup-in-point": "Hent hos", + "store/search.filter.shipping.name.pickup-nearby": "Henting i nærheten", + "store/search.filter.shipping.name.pickup-all": "Hent", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrert etter:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", diff --git a/messages/pl.json b/messages/pl.json index bb13cb389..a71d05f06 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -65,6 +65,13 @@ "store/search.filter.placeholder": "Wyszukaj według {filterName}", "store/search.filter.title.brands": "Marki", "store/search.filter.title.price-ranges": "Zakresy cenowe", + "store/search.filter.title.shipping": "Wysyłka", + "store/search.filter.shipping.name.delivery": "Dostarcz do", + "store/search.filter.shipping.name.pickup-in-point": "Odbiór w", + "store/search.filter.shipping.name.pickup-nearby": "Odbiór w pobliżu", + "store/search.filter.shipping.name.pickup-all": "Odbiór", + "store/search.filter.shipping.action-button.delivery": "Wprowadź lokalizację", + "store/search.filter.shipping.action-button.pickup-in-point": "Wprowadź sklep", "store/search.text": "Pokazuję {from}-{to} od {recordsFiltered} wpisów", "store/search.selected-filters": "Filtrowane według:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produkt} few {produkty} many {produkty} other {produkty}}", diff --git a/messages/pt.json b/messages/pt.json index 36a67d303..40722ab97 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Marcas", "store/search.filter.title.price-ranges": "Faixas de preço", "store/search.text": "Exibindo {from}–{to} de {recordsFiltered} resultados", + "store/search.filter.title.shipping": "Entrega", + "store/search.filter.shipping.name.delivery": "Entregar em", + "store/search.filter.shipping.name.pickup-in-point": "Retirada em", + "store/search.filter.shipping.name.pickup-nearby": "Retirada em lojas próximas", + "store/search.filter.shipping.name.pickup-all": "Retirada", + "store/search.filter.shipping.action-button.delivery": "Insira seu código postal", + "store/search.filter.shipping.action-button.pickup-in-point": "Insira a loja", "store/search.selected-filters": "Filtrado por:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {Produto} other {Produtos}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {Produto} other {Produtos}}", diff --git a/messages/ro.json b/messages/ro.json index dda41ce2c..0b921a59a 100644 --- a/messages/ro.json +++ b/messages/ro.json @@ -65,6 +65,13 @@ "store/search.filter.placeholder": "Caută după {filterName}", "store/search.filter.title.brands": "Branduri", "store/search.filter.title.price-ranges": "Intervale de prețuri", + "store/search.filter.title.shipping": "Transport", + "store/search.filter.shipping.name.delivery": "Livrează la", + "store/search.filter.shipping.name.pickup-in-point": "Ridicare la", + "store/search.filter.shipping.name.pickup-nearby": "Ridicare în apropiere", + "store/search.filter.shipping.name.pickup-all": "Ridicare", + "store/search.filter.shipping.action-button.delivery": "Introdu locația", + "store/search.filter.shipping.action-button.pickup-in-point": "Introdu magazinul", "store/search.text": "Afișează {from}-{to} de la {recordsFiltered} înregistrări", "store/search.selected-filters": "Filtru după:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produs} few {produse} other {de produse}}", diff --git a/messages/ru.json b/messages/ru.json index 0beccfc3d..6ad53ac9e 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -75,6 +75,13 @@ "store/search.what-to-do.2": "Попробуйте ввести одно слово.", "store/search.what-to-do.3": "Ищите по общим терминам.", "store/search.what-to-do.4": "Попробуйте ввести синонимы.", + "store/search.filter.title.shipping": "Отправка", + "store/search.filter.shipping.name.delivery": "Место доставки", + "store/search.filter.shipping.name.pickup-in-point": "Место самовывоза", + "store/search.filter.shipping.name.pickup-nearby": "Самовывоз поблизости", + "store/search.filter.shipping.name.pickup-all": "Самовывоз", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.no-products": "Ничего не найдено", "store/ordenation.button": "Сортировать", "store/ordenation.sort-by": "Критерий сортировки", diff --git a/messages/sk.json b/messages/sk.json index 405faf8eb..b8a185a59 100644 --- a/messages/sk.json +++ b/messages/sk.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Značky", "store/search.filter.title.price-ranges": "Rozsahy cien", "store/search.text": "Zobrazuje sa {from} – {to} z/zo {recordsFiltered} záznamov", + "store/search.filter.title.shipping": "Doprava", + "store/search.filter.shipping.name.delivery": "Doručiť na", + "store/search.filter.shipping.name.pickup-in-point": "Vyzdvihnúť na", + "store/search.filter.shipping.name.pickup-nearby": "Vyzdvihnúť v blízosti", + "store/search.filter.shipping.name.pickup-all": "Vyzdvihnúť", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrované podľa:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {product} few {products} many {products} other {products}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {product} few {products} many {products} other {products}}", diff --git a/messages/sl.json b/messages/sl.json index c96685277..fa732c9f8 100644 --- a/messages/sl.json +++ b/messages/sl.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Znamke", "store/search.filter.title.price-ranges": "Cenovni razponi", "store/search.text": "Kažem {from}-{to} od {recordsFiltered} rezultatov", + "store/search.filter.title.shipping": "Odpošiljanje", + "store/search.filter.shipping.name.delivery": "Dostavi v", + "store/search.filter.shipping.name.pickup-in-point": "Prevzemi pri", + "store/search.filter.shipping.name.pickup-nearby": "Prevzemite blizu", + "store/search.filter.shipping.name.pickup-all": "Prevzemi", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrirano po:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {izdelek} two {izdelka} few {izdelkov} other {izdelki}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {izdelek} two {izdelka} few {izdelkov} other {izdelki}}", diff --git a/messages/sv.json b/messages/sv.json index 069fc3f7c..8fe6e6fbc 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "Varumärken", "store/search.filter.title.price-ranges": "Prisklasser", "store/search.text": "Visar {from}–{to} av {recordsFiltered} resultat", + "store/search.filter.title.shipping": "Frakt", + "store/search.filter.shipping.name.delivery": "Leverera till", + "store/search.filter.shipping.name.pickup-in-point": "Hämta vid", + "store/search.filter.shipping.name.pickup-nearby": "Hämtning i närheten", + "store/search.filter.shipping.name.pickup-all": "Hämta", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/search.selected-filters": "Filtrerad enligt:", "store/search.total-products": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", "store/search.total-products-2": "{recordsFiltered} {recordsFiltered, plural, one {produkt} other {produkter}}", diff --git a/messages/th.json b/messages/th.json index 6d326e951..4f4e93837 100644 --- a/messages/th.json +++ b/messages/th.json @@ -66,6 +66,13 @@ "store/search.filter.title.brands": "แบรนด์", "store/search.filter.title.price-ranges": "ช่วงราคา", "store/search.text": "กำลังแสดงผล {from}–{to} ของ {recordsFiltered}", + "store/search.filter.title.shipping": "การส่ง", + "store/search.filter.shipping.name.delivery": "จัดส่งไปยัง", + "store/search.filter.shipping.name.pickup-in-point": "จุดรับสินค้าเอง", + "store/search.filter.shipping.name.pickup-nearby": "จุดรับสินค้าบริเวณใกล้เคียง", + "store/search.filter.shipping.name.pickup-all": "การรับสินค้าเอง", + "store/search.filter.shipping.action-button.delivery": "ใส่ตำแหน่งที่ตั้ง", + "store/search.filter.shipping.action-button.pickup-in-point": "ใส่ร้านค้า", "store/search.selected-filters": "กรองตาม:", "store/search.total-products": "ผลิตภัณฑ์ {recordsFiltered} {recordsFiltered, plural, other {รายการ}}", "store/search.total-products-2": "ผลิตภัณฑ์ {recordsFiltered} {recordsFiltered, plural, other {รายการ}}", diff --git a/messages/uk.json b/messages/uk.json index 6f7aa71fc..bf13f7376 100644 --- a/messages/uk.json +++ b/messages/uk.json @@ -76,6 +76,13 @@ "store/search.what-to-do.3": "Пошукайте за узагальненою назвою.", "store/search.what-to-do.4": "Спробуйте ввести синоніми.", "store/search.no-products": "Товарів не знайдено", + "store/search.filter.title.shipping": "Відправлення", + "store/search.filter.shipping.name.delivery": "Місце доставки", + "store/search.filter.shipping.name.pickup-in-point": "Місце самовивозу", + "store/search.filter.shipping.name.pickup-nearby": "Самовивіз поблизу", + "store/search.filter.shipping.name.pickup-all": "Самовивіз", + "store/search.filter.shipping.action-button.delivery": "Enter location", + "store/search.filter.shipping.action-button.pickup-in-point": "Enter store", "store/ordenation.button": "Сортувати", "store/ordenation.sort-by": "Критерій сортування", "store/ordenation.relevance": "Релевантність", diff --git a/react/FilterNavigator.js b/react/FilterNavigator.js index 6186c1783..861871eea 100644 --- a/react/FilterNavigator.js +++ b/react/FilterNavigator.js @@ -8,7 +8,7 @@ import { useCssHandles, applyModifiers } from 'vtex.css-handles' import { useSearchPage } from 'vtex.search-page-context/SearchPageContext' // eslint-disable-next-line no-restricted-imports import { flatten } from 'ramda' -import { FormattedMessage } from 'react-intl' +import { FormattedMessage, useIntl } from 'react-intl' import { Button } from 'vtex.styleguide' import FilterSidebar from './components/FilterSidebar' @@ -23,7 +23,7 @@ import { import useFacetNavigation from './hooks/useFacetNavigation' import FilterNavigatorTitleTag from './components/FilterNavigatorTitleTag' import styles from './searchResult.css' -import { CATEGORIES_TITLE } from './utils/getFilters' +import { CATEGORIES_TITLE, shippingOptions } from './utils/getFilters' import { newFacetPathName } from './utils/slug' import { FACETS_RENDER_THRESHOLD } from './constants/filterConstants' @@ -73,6 +73,7 @@ const FilterNavigator = ({ priceRange, tree = [], specificationFilters = [], + deliveries = [], priceRanges = [], brands = [], loading = false, @@ -101,6 +102,7 @@ const FilterNavigator = ({ priceRangeLayout = 'slider', showQuantityBadgeOnMobile = false, }) => { + const intl = useIntl() const { isMobile } = useDevice() const handles = useCssHandles(CSS_HANDLES) const [truncatedFacetsFetched, setTruncatedFacetsFetched] = useState(false) @@ -158,9 +160,17 @@ const FilterNavigator = ({ } }, [filters, filtersFetchMore, truncatedFacetsFetched, loading]) + const shipping = deliveries.map(delivery => ({ + ...delivery, + facets: delivery.facets.map(facet => ({ + ...facet, + name: intl.formatMessage({ id: shippingOptions[facet.name] }), + })), + })) + const selectedFilters = useMemo(() => { const options = [ - ...specificationFilters.map(filter => { + ...specificationFilters.concat(shipping).map(filter => { return filter.facets.map(facet => { return { ...newNamedFacet({ ...facet, title: filter.name }), @@ -173,7 +183,7 @@ const FilterNavigator = ({ ] return flatten(options) - }, [brands, priceRanges, specificationFilters]).filter( + }, [brands, priceRanges, specificationFilters, shipping]).filter( facet => facet.selected ) diff --git a/react/FilterNavigatorFlexible.js b/react/FilterNavigatorFlexible.js index becb16071..475f68efd 100644 --- a/react/FilterNavigatorFlexible.js +++ b/react/FilterNavigatorFlexible.js @@ -63,6 +63,7 @@ const withSearchPageContextProps = specificationFilters, categoriesTrees, queryArgs, + deliveries, } = facets const sortedFilters = useMemo( @@ -113,6 +114,7 @@ const withSearchPageContextProps = priceRangeLayout={priceRangeLayout} drawerDirectionMobile={drawerDirectionMobile} showQuantityBadgeOnMobile={showQuantityBadgeOnMobile} + deliveries={deliveries} /> diff --git a/react/SearchResultFlexible.js b/react/SearchResultFlexible.js index 9d59ccb43..49b6526bc 100644 --- a/react/SearchResultFlexible.js +++ b/react/SearchResultFlexible.js @@ -50,6 +50,7 @@ const SearchResultFlexible = ({ preventRouteChange = false, showFacetQuantity = false, showFacetTitle = false, + showShippingFacet = false, // Below are set by SearchContext searchQuery, maxItemsPerPage, @@ -82,6 +83,7 @@ const SearchResultFlexible = ({ priceRanges, specificationFilters, categoriesTrees, + deliveries, } = facets const filters = useMemo( @@ -92,8 +94,18 @@ const SearchResultFlexible = ({ brands, brandsQuantity, hiddenFacets, + deliveries, + showShippingFacet, }), - [brands, hiddenFacets, priceRanges, specificationFilters, brandsQuantity] + [ + brands, + hiddenFacets, + priceRanges, + specificationFilters, + brandsQuantity, + deliveries, + showShippingFacet, + ] ) const handles = useCssHandles(CSS_HANDLES) diff --git a/react/__mocks__/vtex.pixel-manager.js b/react/__mocks__/vtex.pixel-manager.js index 1355be386..ff3042bb3 100644 --- a/react/__mocks__/vtex.pixel-manager.js +++ b/react/__mocks__/vtex.pixel-manager.js @@ -5,3 +5,5 @@ const PixelContext = createContext({ push: () => undefined }) export const usePixel = () => { return useContext(PixelContext) } + +export const usePixelEventCallback = () => {} diff --git a/react/__mocks__/vtex.render-runtime/react/components/NoSSR.js b/react/__mocks__/vtex.render-runtime/react/components/NoSSR.js new file mode 100644 index 000000000..9d1c4e77d --- /dev/null +++ b/react/__mocks__/vtex.render-runtime/react/components/NoSSR.js @@ -0,0 +1 @@ +export const useSSR = () => jest.fn() diff --git a/react/components/AccordionFilterContainer.js b/react/components/AccordionFilterContainer.js index 879d2e63f..cfcf585a5 100644 --- a/react/components/AccordionFilterContainer.js +++ b/react/components/AccordionFilterContainer.js @@ -214,7 +214,7 @@ const AccordionFilterContainer = ({ style={{ background: 'rgba(3, 4, 78, 0.4)' }} className={classNames( handles.filterLoadingOverlay, - 'fixed dim top-0 w-100 vh-100 left-0 z-9999 justify-center items-center justify-center items-center flex' + 'fixed dim top-0 w-100 vh-100 left-0 z-999 justify-center items-center justify-center items-center flex' )} > diff --git a/react/components/FacetCheckboxList.js b/react/components/FacetCheckboxList.js index 57ff8aba0..183dbff0d 100644 --- a/react/components/FacetCheckboxList.js +++ b/react/components/FacetCheckboxList.js @@ -1,17 +1,12 @@ -import classNames from 'classnames' import React, { useContext, useState, useMemo } from 'react' -import { Checkbox } from 'vtex.styleguide' -import { applyModifiers } from 'vtex.css-handles' import { useRuntime } from 'vtex.render-runtime' -import { usePixel } from 'vtex.pixel-manager' import { useSearchPage } from 'vtex.search-page-context/SearchPageContext' -import { pushFilterManipulationPixelEvent } from '../utils/filterManipulationPixelEvents' -import styles from '../searchResult.css' import SettingsContext from './SettingsContext' import { SearchFilterBar } from './SearchFilterBar' import { FACETS_RENDER_THRESHOLD } from '../constants/filterConstants' import ShowMoreFilterButton from './ShowMoreFilterButton' +import FacetCheckboxListItem from './FacetCheckboxListItem' const useSettings = () => useContext(SettingsContext) @@ -25,7 +20,6 @@ const FacetCheckboxList = ({ truncatedFacetsFetched, setTruncatedFacetsFetched, }) => { - const { push } = usePixel() const { searchQuery } = useSearchPage() const { showFacetQuantity } = useContext(SettingsContext) const { getSettings } = useRuntime() @@ -76,40 +70,16 @@ const FacetCheckboxList = ({ ) : null} {filteredFacets.slice(0, endSlice).map(facet => { - const { name, value: slugifiedName } = facet - return ( -
- { - pushFilterManipulationPixelEvent({ - name: facetTitle, - value: name, - products: searchQuery?.products ?? [], - push, - }) - - onFilterCheck({ ...facet, title: facetTitle }) - }} - value={name} - /> -
+ ) })} {shouldTruncate && ( diff --git a/react/components/FacetCheckboxListItem.js b/react/components/FacetCheckboxListItem.js new file mode 100644 index 000000000..27c839874 --- /dev/null +++ b/react/components/FacetCheckboxListItem.js @@ -0,0 +1,94 @@ +import classNames from 'classnames' +import React, { useMemo } from 'react' +import { applyModifiers } from 'vtex.css-handles' +import { Checkbox } from 'vtex.styleguide' +import { usePixel } from 'vtex.pixel-manager' +import { useIntl } from 'react-intl' + +import styles from '../searchResult.css' +import { pushFilterManipulationPixelEvent } from '../utils/filterManipulationPixelEvents' +import useShippingActions from '../hooks/useShippingActions' +import ShippingActionButton from './ShippingActionButton' + +const FacetCheckboxListItem = ({ + facet, + showFacetQuantity, + sampling, + facetTitle, + searchQuery, + onFilterCheck, +}) => { + const intl = useIntl() + + const { push } = usePixel() + + const { actionLabel, actionType, openDrawer, shouldDisable } = + useShippingActions(facet) + + const showActionButton = !!actionType + + const { name, value: slugifiedName } = facet + + const facetLabel = useMemo(() => { + let labelElement = facet.name + + if (showFacetQuantity && !sampling) { + labelElement = `${labelElement} (${facet.quantity})` + } + + if (showActionButton) { + labelElement = ( +
+ {labelElement} + +
+ ) + } + + return labelElement + }, [ + showFacetQuantity, + sampling, + facet.name, + facet.quantity, + showActionButton, + actionLabel, + openDrawer, + intl, + ]) + + return ( +
+ { + pushFilterManipulationPixelEvent({ + name: facetTitle, + value: name, + products: searchQuery?.products ?? [], + push, + }) + + onFilterCheck({ ...facet, title: facetTitle }) + }} + value={name} + /> +
+ ) +} + +export default FacetCheckboxListItem diff --git a/react/components/FacetItem.js b/react/components/FacetItem.js index 7dcdf25f3..046a40c4a 100644 --- a/react/components/FacetItem.js +++ b/react/components/FacetItem.js @@ -4,10 +4,12 @@ import { useCssHandles, applyModifiers } from 'vtex.css-handles' import classNames from 'classnames' import { useSearchPage } from 'vtex.search-page-context/SearchPageContext' import { usePixel } from 'vtex.pixel-manager' +import { useIntl } from 'react-intl' import { pushFilterManipulationPixelEvent } from '../utils/filterManipulationPixelEvents' import SettingsContext from './SettingsContext' -import useShouldDisableFacet from '../hooks/useShouldDisableFacet' +import ShippingActionButton from './ShippingActionButton' +import useShippingActions from '../hooks/useShippingActions' const CSS_HANDLES = ['filterItem', 'productCount', 'filterItemTitle'] @@ -30,10 +32,17 @@ const FacetItem = ({ preventRouteChange, showTitle = false, }) => { + const intl = useIntl() + const { push } = usePixel() + + const { actionLabel, actionType, openDrawer, shouldDisable } = + useShippingActions(facet) + + const showActionButton = !!actionType + const { showFacetQuantity } = useContext(SettingsContext) const [selected, setSelected] = useState(facet.selected) - const { push } = usePixel() const handles = useCssHandles(CSS_HANDLES) const classes = classNames( applyModifiers(handles.filterItem, facet.value), @@ -61,13 +70,13 @@ const FacetItem = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [facet.selected]) - const shouldDisable = useShouldDisableFacet(facet) - const facetLabel = useMemo(() => { - const labelElement = - showFacetQuantity && !sampling ? ( + let labelElement = facet.name + + if (showFacetQuantity && !sampling) { + labelElement = ( <> - {facet.name}{' '} + {labelElement}{' '} - ) : ( - facet.name ) + } + + if (showActionButton) { + labelElement = ( +
+
{labelElement}
+ +
+ ) + } if (showTitle) { - return ( + labelElement = ( <> {facetTitle}:{' '} {labelElement} @@ -90,19 +110,25 @@ const FacetItem = ({ return labelElement }, [ - facet, + showFacetQuantity, + sampling, + facet.name, + facet.value, + facet.quantity, handles.productCount, handles.filterItemTitle, - facetTitle, + showActionButton, + actionLabel, + openDrawer, showTitle, - showFacetQuantity, - sampling, + facetTitle, + intl, ]) return (
diff --git a/react/components/FilterNavigator/legacy/FilterSidebar.js b/react/components/FilterNavigator/legacy/FilterSidebar.js index 1393332e6..a38d51d90 100644 --- a/react/components/FilterNavigator/legacy/FilterSidebar.js +++ b/react/components/FilterNavigator/legacy/FilterSidebar.js @@ -13,6 +13,7 @@ import { facetOptionShape } from '../../../constants/propTypes' import useSelectedFilters from './hooks/useSelectedFilters' import searchResult from './searchResult.css' import QueryContext from '../../QueryContext' +import isShippingOptionsComponent from '../../../utils/isShippingOptionsComponent' const FilterSidebar = ({ filters, preventRouteChange = false }) => { const { navigate, setQuery } = useRuntime() @@ -49,7 +50,11 @@ const FilterSidebar = ({ filters, preventRouteChange = false }) => { } } - const handleClose = () => { + const handleClose = e => { + if (isShippingOptionsComponent(e)) { + return + } + setOpen(false) } diff --git a/react/components/FilterSidebar.js b/react/components/FilterSidebar.js index 8a4ffeb20..52fc13931 100644 --- a/react/components/FilterSidebar.js +++ b/react/components/FilterSidebar.js @@ -23,6 +23,7 @@ import { filterCategoryDepartmentCollectionAndFT, } from '../utils/queryAndMapUtils' import { pushFilterManipulationPixelEvent } from '../utils/filterManipulationPixelEvents' +import isShippingOptionsComponent from '../utils/isShippingOptionsComponent' const CSS_HANDLES = [ 'filterPopupButton', @@ -110,7 +111,11 @@ const FilterSidebar = ({ } } - const handleClose = () => { + const handleClose = e => { + if (isShippingOptionsComponent(e)) { + return + } + setOpen(false) } diff --git a/react/components/SearchFilter.js b/react/components/SearchFilter.js index f39138dcd..a8700203f 100644 --- a/react/components/SearchFilter.js +++ b/react/components/SearchFilter.js @@ -93,6 +93,7 @@ SearchFilter.propTypes = { /** Whether an overview of the applied filters should be displayed (`"show"`) or not (`"hide"`). */ appliedFiltersOverview: PropTypes.string, showClearByFilter: PropTypes.bool, + type: PropTypes.string, } export default SearchFilter diff --git a/react/components/SearchQuery.js b/react/components/SearchQuery.js index 5a8a0d291..bf383ff88 100644 --- a/react/components/SearchQuery.js +++ b/react/components/SearchQuery.js @@ -248,6 +248,7 @@ const useQueries = (variables, facetsArgs, price) => { specificationFilters: [], categoriesTrees: [], priceRanges: [], + deliveries: [], } const selectedFacetsOutput = diff --git a/react/components/ShippingActionButton.tsx b/react/components/ShippingActionButton.tsx new file mode 100644 index 000000000..b300dd99d --- /dev/null +++ b/react/components/ShippingActionButton.tsx @@ -0,0 +1,24 @@ +import React from 'react' +import { useCssHandles } from 'vtex.css-handles' + +const CSS_HANDLES = ['shippingActionButton'] + +interface Props { + label: string + openDrawer: () => void +} + +const ShippingActionButton = ({ label, openDrawer }: Props) => { + const handles = useCssHandles(CSS_HANDLES) + + return ( + + ) +} + +export default ShippingActionButton diff --git a/react/components/SideBar.js b/react/components/SideBar.js index 005ca787d..76eddca84 100644 --- a/react/components/SideBar.js +++ b/react/components/SideBar.js @@ -42,14 +42,14 @@ class Sidebar extends Component { } const scrimClasses = classNames( - 'fixed dim bg-base--inverted top-0 z-9999 w-100 vh-100 o-40 left-0', + `${searchResult.scrim} fixed dim bg-base--inverted top-0 w-100 vh-100 o-40 left-0`, { dn: !isOpen, } ) const sidebarClasses = classNames( - `${searchResult.sidebar} w-auto-ns h-100 fixed top-0 z-9999 bg-base shadow-2 flex flex-column`, + `${searchResult.sidebar} w-auto-ns h-100 fixed top-0 bg-base shadow-2 flex flex-column`, this.props.fullWidth ? 'w-100' : 'w-80', filtersDrawerDirectionMobile === 'drawerLeft' ? 'right-0' : 'left-0' ) diff --git a/react/hooks/useShippingActions.js b/react/hooks/useShippingActions.js new file mode 100644 index 000000000..f868d47e6 --- /dev/null +++ b/react/hooks/useShippingActions.js @@ -0,0 +1,132 @@ +import { useCallback, useEffect, useState } from 'react' +import { usePixel, usePixelEventCallback } from 'vtex.pixel-manager' +import { useSSR } from 'vtex.render-runtime/react/components/NoSSR' + +import useShouldDisableFacet from './useShouldDisableFacet' + +const shippingActionTypes = { + delivery: 'DELIVERY', + 'pickup-nearby': 'DELIVERY', + pickup: 'DELIVERY', + 'pickup-in-point': 'PICKUP_POINT', +} + +const eventIdentifiers = { + DELIVERY: 'addressLabel', + PICKUP_POINT: 'pickupPointLabel', +} + +const placeHolders = { + DELIVERY: 'store/search.filter.shipping.action-button.delivery', + PICKUP_POINT: 'store/search.filter.shipping.action-button.pickup-in-point', +} + +const drawerEvent = { + DELIVERY: 'shipping-option-deliver-to', + PICKUP_POINT: 'shipping-option-store', +} + +const addressDependentValues = [ + 'delivery', + 'pickup-in-point', + 'pickup-nearby', + 'pickup', +] + +const useShippingActions = facet => { + const actionType = shippingActionTypes[facet.value] + const eventIdentifier = actionType ? eventIdentifiers[actionType] : null + + const [actionLabel, setActionLabel] = useState(placeHolders[actionType]) + const [isAddressSet, setIsAddressSet] = useState(false) + const [isPickupSet, setIsPickupSet] = useState(false) + + const isAddressDependent = + addressDependentValues.findIndex(value => facet.value === value) > -1 + + const isSSR = useSSR() + const { push } = usePixel() + + usePixelEventCallback({ + eventId: `shipping-option-${eventIdentifier}`, + handler: e => { + if (e?.data?.label) { + setActionLabel(e.data.label) + + if (isAddressDependent) { + setIsAddressSet(true) + } + + if (eventIdentifier === 'pickupPointLabel') { + setIsPickupSet(true) + } + } else { + setActionLabel(placeHolders[actionType]) + + if (isAddressDependent) { + setIsAddressSet(false) + } + + if (eventIdentifier === 'pickupPointLabel') { + setIsPickupSet(false) + } + } + }, + }) + + useEffect(() => { + if (!isSSR) { + return + } + + const windowLabel = window[eventIdentifier] + + if (windowLabel) { + setActionLabel(windowLabel) + + if (isAddressDependent) { + setIsAddressSet(true) + } + + if (eventIdentifier === 'pickupPointLabel') { + setIsPickupSet(true) + } + } else { + setActionLabel(placeHolders[actionType]) + + if (isAddressDependent) { + setIsAddressSet(false) + } + + if (eventIdentifier === 'pickupPointLabel') { + setIsPickupSet(false) + } + } + }, [actionType, eventIdentifier, isSSR, isAddressDependent]) + + const openDrawer = useCallback(() => { + push({ + id: drawerEvent[actionType], + }) + }, [actionType, push]) + + const shouldDisable = useShouldDisableFacet(facet, isAddressSet, isPickupSet) + + if (facet.value === 'pickup-nearby' || facet.value === 'pickup') { + return { + actionLabel: null, + actionType: null, + openDrawer: null, + shouldDisable, + } + } + + return { + actionType, + actionLabel, + openDrawer, + shouldDisable, + } +} + +export default useShippingActions diff --git a/react/hooks/useShouldDisableFacet.js b/react/hooks/useShouldDisableFacet.js index 759d53e42..489515b4c 100644 --- a/react/hooks/useShouldDisableFacet.js +++ b/react/hooks/useShouldDisableFacet.js @@ -2,9 +2,30 @@ import { useSearchPage } from 'vtex.search-page-context/SearchPageContext' import { MAP_VALUES_SEP } from '../constants' -export default function useShouldDisableFacet(facet) { +export default function useShouldDisableFacet( + facet, + isAddressSet, + isPickupSet +) { const { map } = useSearchPage() + if ( + (facet.value === 'delivery' || + facet.value === 'pickup-nearby' || + facet.value === 'pickup') && + !isAddressSet + ) { + return true + } + + if (facet.value === 'pickup-in-point' && !isPickupSet) { + return true + } + + if (facet.quantity === 0) { + return true + } + if (!facet.selected || !map) { return false } diff --git a/react/searchResult.css b/react/searchResult.css index 63948a915..c2026798c 100644 --- a/react/searchResult.css +++ b/react/searchResult.css @@ -258,3 +258,18 @@ .notFound--layout { } + +.shippingActionButton { + border: 0; + padding: 0; + font-size: 14px; + background: unset; + cursor: pointer; + text-align: left; + font-weight: 500; + color: #134CD8; +} + +.scrim, .sidebar { + z-index: 999; +} diff --git a/react/typings/vtex.styleguide.d.ts b/react/typings/vtex.styleguide.d.ts index e2c82da55..e2c402bc6 100644 --- a/react/typings/vtex.styleguide.d.ts +++ b/react/typings/vtex.styleguide.d.ts @@ -2,4 +2,5 @@ declare module 'vtex.styleguide' { import type { ComponentType } from 'react' export const Spinner: ComponentType> + export const RadioGroup: ComponentType> } diff --git a/react/utils/compatibilityLayer.js b/react/utils/compatibilityLayer.js index 583bff626..85cd92a78 100644 --- a/react/utils/compatibilityLayer.js +++ b/react/utils/compatibilityLayer.js @@ -2,6 +2,23 @@ import { groupBy, pathOr, zipObj } from 'ramda' import { PATH_SEPARATOR, MAP_VALUES_SEP } from '../constants' +import { shippingOptions, SHIPPING_KEY } from './getFilters' + +const shippingFacetDefault = { + name: SHIPPING_KEY, + type: 'DELIVERY', + hidden: false, + quantity: 0, + facets: Object.keys(shippingOptions).map(option => ({ + id: null, + quantity: 0, + name: option, + key: SHIPPING_KEY, + selected: false, + map: SHIPPING_KEY, + value: option, + })), +} export const getMainSearches = (query, map) => { const querySegments = (query && query.split(PATH_SEPARATOR)) || [] @@ -79,6 +96,8 @@ export const detachFiltersByType = facets => { groupedFilters.TEXT || [] ) + const deliveries = getFormattedDeliveries(groupedFilters.DELIVERY || []) + const categoriesTrees = pathOr( [], ['CATEGORYTREE', 0, 'facets'], @@ -102,6 +121,7 @@ export const detachFiltersByType = facets => { specificationFilters, categoriesTrees, priceRanges, + deliveries, } } @@ -116,3 +136,21 @@ export const buildQueryArgsFromSelectedFacets = selectedFacets => { { query: '', map: '' } ) } + +const getFormattedDeliveries = deliveries => { + const shippingFacet = deliveries.find(d => d.name === SHIPPING_KEY) + + if (!shippingFacet) { + return [...deliveries, shippingFacetDefault] + } + + const facetsNotIncluded = shippingFacetDefault.facets.filter(facet => + shippingFacet.facets.every(f => f.value !== facet.value) + ) + + shippingFacet.facets = [...shippingFacet.facets, ...facetsNotIncluded] + + return deliveries.map(facet => + facet.name === SHIPPING_KEY ? shippingFacet : facet + ) +} diff --git a/react/utils/getFilters.js b/react/utils/getFilters.js index 1a25feb3a..8f4208668 100644 --- a/react/utils/getFilters.js +++ b/react/utils/getFilters.js @@ -1,9 +1,20 @@ import { path, contains, isEmpty } from 'ramda' +import { useIntl } from 'react-intl' +export const SHIPPING_TITLE = 'store/search.filter.title.shipping' export const CATEGORIES_TITLE = 'store/search.filter.title.categories' export const BRANDS_TITLE = 'store/search.filter.title.brands' export const PRICE_RANGES_TITLE = 'store/search.filter.title.price-ranges' +export const shippingOptions = { + delivery: 'store/search.filter.shipping.name.delivery', + 'pickup-in-point': 'store/search.filter.shipping.name.pickup-in-point', + 'pickup-nearby': 'store/search.filter.shipping.name.pickup-nearby', + 'pickup-all': 'store/search.filter.shipping.name.pickup-all', +} + +export const SHIPPING_KEY = 'shipping' + const BRANDS_TYPE = 'Brands' const PRICE_RANGES_TYPE = 'PriceRanges' const SPECIFICATION_FILTERS_TYPE = 'SpecificationFilters' @@ -12,9 +23,39 @@ const getFilters = ({ specificationFilters = [], priceRanges = [], brands = [], + deliveries = [], brandsQuantity = 0, hiddenFacets = {}, + showShippingFacet = false, }) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const intl = useIntl() + + let deliveriesFormatted = deliveries + + const shipping = deliveries.find(d => d.name === SHIPPING_KEY) + + if (shipping) { + const shippingFacet = { + ...shipping, + title: SHIPPING_TITLE, + facets: shipping.facets.map(facet => ({ + ...facet, + name: intl.formatMessage({ id: shippingOptions[facet.name] }), + })), + } + + deliveriesFormatted = deliveries.map(facet => + facet.name === SHIPPING_KEY ? shippingFacet : facet + ) + } + + if (!showShippingFacet) { + deliveriesFormatted = deliveriesFormatted.filter( + d => d.name !== SHIPPING_KEY + ) + } + const hiddenFacetsNames = ( path(['specificationFilters', 'hiddenFilters'], hiddenFacets) || [] ).map(filter => filter.name) @@ -35,6 +76,7 @@ const getFilters = ({ : [] return [ + ...deliveriesFormatted, ...mappedSpecificationFilters, !hiddenFacets.brands && !isEmpty(brands) && { diff --git a/react/utils/isShippingOptionsComponent.js b/react/utils/isShippingOptionsComponent.js new file mode 100644 index 000000000..4f004fdf4 --- /dev/null +++ b/react/utils/isShippingOptionsComponent.js @@ -0,0 +1,23 @@ +const SHIPPING_OPTION_COMPONENT_DRAWER_CLASS = + 'vtex-shipping-option-components-0-x-drawer' + +const SHIPPING_OPTION_COMPONENT_OVERLAY_CLASS = + 'vtex-shipping-option-components-0-x-overlay' + +const isShippingOptionsComponent = e => { + if (!e.target) { + return false + } + + const shippingOptionsDawerElement = e.target.closest( + `.${SHIPPING_OPTION_COMPONENT_DRAWER_CLASS}` + ) + + const isShippingOptionsOverlayElement = e.target.classList.contains( + SHIPPING_OPTION_COMPONENT_OVERLAY_CLASS + ) + + return shippingOptionsDawerElement || isShippingOptionsOverlayElement +} + +export default isShippingOptionsComponent