Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 123 additions & 92 deletions client-app/shared/catalog/components/category.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/>

<VcLayout sticky-sidebar>
<template v-if="!hideSidebar && !isMobile && !isHorizontalFilters" #sidebar>
<template v-if="isSidebarVisible" #sidebar>
<CategorySelector
v-if="categoryId || isRoot"
:category="currentCategory"
Expand All @@ -39,7 +39,11 @@
</template>

<VcTypography tag="h1" class="category__title">
<i18n-t v-if="!categoryId && !isRoot && searchParams.keyword" keypath="pages.search.header" tag="span">
<i18n-t
v-if="!categoryId && !isRoot && searchParams.keyword"
:keypath="emptyViewSearchOnly ? 'pages.search.header_empty' : 'pages.search.header'"
tag="span"
>
<template #keyword>
<strong>{{ searchParams.keyword }}</strong>
</template>
Expand All @@ -60,7 +64,7 @@
{{ currentCategory?.name }}
</span>

<sup v-if="!fetchingProducts && !hideTotal && !fixedProductsCount" class="category__products-count">
<sup v-if="showProductsCount" class="category__products-count">
<b class="me-1">{{ $n(totalProductsCount, "decimal") }}</b>

<template v-if="currentCategory && searchQueryParam">
Expand All @@ -75,99 +79,108 @@

<div ref="stickyMobileHeaderAnchor" class="category__header-anchor"></div>

<div
:class="[
'category__filters',
{
'category__filters--sticky': stickyMobileHeaderIsVisible,
},
]"
>
<!-- Popup sidebar filters toggler -->
<VcButton
v-if="!hideSidebar"
class="category__facets-button"
icon="filter"
size="sm"
:aria-label="$t('common.accessibility.open_filters')"
@click="showFiltersSidebar"
/>

<!-- Sorting -->
<div v-if="!hideSorting && !isHorizontalFilters" class="category__sort">
<VcLabel class="category__sort-label">
{{ $t("pages.catalog.sort_by_label") }}
</VcLabel>

<VcSelect
v-model="sortQueryParam"
text-field="name"
value-field="id"
:disabled="fetchingProducts"
:items="translatedProductSortingList"
class="category__sort-dropdown"
<template v-if="!hideAllControls">
<div
:class="[
'category__filters',
{
'category__filters--sticky': stickyMobileHeaderIsVisible,
},
]"
>
<!-- Popup sidebar filters toggler -->
<VcButton
v-if="!hideSidebar"
class="category__facets-button"
icon="filter"
size="sm"
@change="resetCurrentPage"
:aria-label="$t('common.accessibility.open_filters')"
@click="showFiltersSidebar"
/>
</div>

<!-- View options - horizontal view -->
<ViewMode
v-if="!hideViewModeSelector"
v-model:mode="savedViewMode"
class="category__view-mode"
data-test-id="category-page.view-switcher"
/>
<!-- Sorting -->
<div v-if="!hideSorting && !isHorizontalFilters" class="category__sort">
<VcLabel class="category__sort-label">
{{ $t("pages.catalog.sort_by_label") }}
</VcLabel>

<VcSelect
v-model="sortQueryParam"
text-field="name"
value-field="id"
:disabled="fetchingProducts"
:items="translatedProductSortingList"
class="category__sort-dropdown"
size="sm"
@change="resetCurrentPage"
/>
</div>

<!-- View options - horizontal view -->
<ViewMode
v-if="!hideViewModeSelector"
v-model:mode="savedViewMode"
class="category__view-mode"
data-test-id="category-page.view-switcher"
/>

<!-- In stock and branches -->
<CategoryControls
v-if="!hideControls && !isMobile && !isHorizontalFilters"
v-model="localStorageInStock"
v-model:purchased-before="localStoragePurchasedBefore"
:loading="fetchingProducts"
:saved-branches="localStorageBranches"
class="category__controls"
@open-branches-modal="openBranchesModal"
@apply-in-stock="resetCurrentPage"
@apply-purchased-before="resetCurrentPage"
<!-- In stock and branches -->
<CategoryControls
v-if="!hideControls && !isMobile && !isHorizontalFilters"
v-model="localStorageInStock"
v-model:purchased-before="localStoragePurchasedBefore"
:loading="fetchingProducts"
:saved-branches="localStorageBranches"
class="category__controls"
@open-branches-modal="openBranchesModal"
@apply-in-stock="resetCurrentPage"
@apply-purchased-before="resetCurrentPage"
/>
</div>

<!-- Horizontal filters -->
<CategoryHorizontalFilters
v-if="isHorizontalFilters && !isMobile"
:facets-loading="fetchingFacets"
:keyword-query-param="keywordQueryParam"
:sort-query-param="sortQueryParam"
:loading="fetchingProducts || fetchingFacets"
:filters="filtersToShow"
:hide-sorting="hideSorting"
:hide-all-filters="hideSidebar"
@reset-facet-filters="resetFacetFilters"
@change:filters="applyFiltersOnly($event)"
@show-popup-sidebar="showFiltersSidebar"
@apply-sort="resetCurrentPage"
/>
</div>

<!-- Horizontal filters -->
<CategoryHorizontalFilters
v-if="isHorizontalFilters && !isMobile"
:facets-loading="fetchingFacets"
:keyword-query-param="keywordQueryParam"
:sort-query-param="sortQueryParam"
:loading="fetchingProducts || fetchingFacets"
:filters="filtersToShow"
:hide-sorting="hideSorting"
:hide-all-filters="hideSidebar"
@reset-facet-filters="resetFacetFilters"
@change:filters="applyFiltersOnly($event)"
@show-popup-sidebar="showFiltersSidebar"
@apply-sort="resetCurrentPage"
/>
<ActiveFilterChips
v-if="hasSelectedFacets || isResetPageButtonShown"
:filters="productsFilters.filters"
:facets-to-hide="normalizedFacetsToHide"
@apply-filters="applyFiltersOnly"
>
<template #actions>
<VcChip v-if="hasSelectedFacets" color="secondary" variant="outline" clickable @click="resetFacetFilters">
<span>{{ $t("common.buttons.reset_filters") }}</span>

<VcIcon name="reset" />
</VcChip>

<VcChip v-if="isResetPageButtonShown" color="secondary" variant="outline" clickable @click="resetPage">
<span>{{ $t("common.buttons.reset_page") }}</span>

<VcIcon name="reset" />
</VcChip>
</template>
</ActiveFilterChips>
<ActiveFilterChips
v-if="hasSelectedFilters || isResetPageButtonShown"
:filters="productsFilters.filters"
:facets-to-hide="normalizedFacetsToHide"
@apply-filters="applyFiltersOnly"
>
<template #actions>
<VcChip
v-if="hasSelectedFilters"
color="secondary"
variant="outline"
clickable
@click="resetFacetFilters"
>
<span>{{ $t("common.buttons.reset_filters") }}</span>

<VcIcon name="reset" />
</VcChip>

<VcChip v-if="isResetPageButtonShown" color="secondary" variant="outline" clickable @click="resetPage">
<span>{{ $t("common.buttons.reset_page") }}</span>

<VcIcon name="reset" />
</VcChip>
</template>
</ActiveFilterChips>
</template>

<div ref="categoryProductsAnchor" class="category__products-anchor"></div>

Expand All @@ -179,9 +192,9 @@
:fetching-products="fetchingProducts"
:fixed-products-count="fixedProductsCount"
:has-active-filters="
hasSelectedFacets || localStorageInStock || localStoragePurchasedBefore || !!localStorageBranches.length
hasSelectedFilters || localStorageInStock || localStoragePurchasedBefore || !!localStorageBranches.length
"
:has-selected-facets="hasSelectedFacets"
:has-selected-facets="hasSelectedFilters"
:items-per-page="itemsPerPage"
:pages-count="pagesCount"
:page-number="currentPage"
Expand Down Expand Up @@ -334,6 +347,7 @@ const {
fetchingProducts,
fetchingFacets,
hasSelectedFacets,
hasSelectedFilters,
isFiltersSidebarVisible,
keywordQueryParam,
localStorageBranches,
Expand Down Expand Up @@ -395,6 +409,23 @@ const categoryListProperties = computed(() => ({
related_type: "category",
}));

const filteredOnlyBySearch = computed(() => {
return !hasSelectedFilters.value && !!searchQueryParam.value;
});
const emptyViewSearchOnly = computed(() => {
return filteredOnlyBySearch.value && products.value.length === 0 && !fetchingProducts.value;
});
const hideAllControls = computed(() => {
return emptyViewSearchOnly.value;
});

const isSidebarVisible = computed(() => {
return !props.hideSidebar && !isMobile.value && !isHorizontalFilters.value && !emptyViewSearchOnly.value;
});
const showProductsCount = computed(() => {
return !fetchingProducts.value && !props.hideTotal && !props.fixedProductsCount && !emptyViewSearchOnly.value;
});

const categoryComponentAnchor = shallowRef<HTMLElement | null>(null);
const categoryComponentAnchorIsVisible = useElementVisibility(categoryComponentAnchor);

Expand Down
5 changes: 5 additions & 0 deletions client-app/shared/catalog/composables/useProducts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ export function useProducts(
return !!filteredFacets.length && !!filteredFilters.length;
}

function hasSelectedFilters(): boolean {
return !!productsFilters.value.filters.length;
}

function setFacets({ termFacets = [], rangeFacets = [] }: { termFacets?: TermFacet[]; rangeFacets?: RangeFacet[] }) {
if (themeContext.value?.settings?.product_filters_sorting) {
const ascDirection = themeContext.value?.settings?.product_filters_sorting_direction === SortDirection.Ascending;
Expand Down Expand Up @@ -506,6 +510,7 @@ export function useProducts(
fetchingMoreProducts: readonly(fetchingMoreProducts),
fetchingProducts: readonly(fetchingProducts),
hasSelectedFacets: computed(() => hasSelectedFacets()),
hasSelectedFilters: computed(() => hasSelectedFilters()),
isFiltersDirty: computed(() => !isEqual(prevProductsFilters.value, productsFilters.value)),
isFiltersSidebarVisible: readonly(isFiltersSidebarVisible),
/** @deprecated use `searchQueryParam` instead */
Expand Down
1 change: 1 addition & 0 deletions locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Suche",
"header": "Ihre Suche nach {keyword} ergab Folgendes",
"header_empty": "Ihre Suche nach „{keyword}“ ergab leider keine Ergebnisse",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Ihre <strong>{0}</strong>-Abfrage ergab keine Ergebnisse",
Expand Down
1 change: 1 addition & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Search",
"header": "Your search for {keyword} returned the following",
"header_empty": "Sorry, your search for \"{keyword}\" didn't return any results",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Your <strong>{0}</strong> query did not return any results",
Expand Down
1 change: 1 addition & 0 deletions locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Buscar",
"header": "Tu búsqueda de {keyword} devolvió lo siguiente",
"header_empty": "Lo sentimos, su búsqueda de \"{keyword}\" no produjo ningún resultado",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Tu consulta <strong>{0}</strong> no devolvió ningún resultado",
Expand Down
1 change: 1 addition & 0 deletions locales/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Haku",
"header": "Hakusi {keyword} tuotti seuraavat tulokset",
"header_empty": "Hakusanasi, hakusi \"{keyword}\" -haulla ei löytynyt yhtään tulosta",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Hakusi <strong>{0}</strong> ei tuottanut tuloksia",
Expand Down
1 change: 1 addition & 0 deletions locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Rechercher",
"header": "Votre recherche pour {keyword} a donné les résultats suivants",
"header_empty": "Désolé, votre recherche pour « {keyword} » n’a renvoyé aucun résultat",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Votre requête <strong>{0}</strong> n'a donné aucun résultat",
Expand Down
1 change: 1 addition & 0 deletions locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Cerca",
"header": "La tua ricerca per {keyword} ha restituito i seguenti risultati",
"header_empty": "Siamo spiacenti, la ricerca di \"{keyword}\" non ha prodotto risultati",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "La tua ricerca <strong>{0}</strong> non ha prodotto risultati",
Expand Down
1 change: 1 addition & 0 deletions locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "検索",
"header": "「{keyword}」の検索結果",
"header_empty": "申し訳ありません。「{keyword}」の検索では、何も結果がありませんでした",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "「<strong>{0}</strong>」に一致する結果が見つかりませんでした",
Expand Down
1 change: 1 addition & 0 deletions locales/no.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Søk",
"header": "Søket ditt etter {keyword} ga følgende resultater",
"header_empty": "Beklager, søket ditt etter «{keyword}» ga ingen resultater",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Søket ditt etter <strong>{0}</strong> ga ingen resultater",
Expand Down
1 change: 1 addition & 0 deletions locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Szukaj",
"header": "Twoje wyszukiwanie {keyword} zwróciło następujące wyniki",
"header_empty": "Przepraszamy, wyszukiwanie frazy „{keyword}” nie przyniosło żadnych wyników",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Twoje zapytanie <strong>{0}</strong> nie zwróciło żadnych wyników",
Expand Down
1 change: 1 addition & 0 deletions locales/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Pesquisar",
"header": "Sua pesquisa por {keyword} retornou o seguinte",
"header_empty": "Desculpe, sua busca por \"{keyword}\" não retornou nenhum resultado",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Sua consulta <strong>{0}</strong> não retornou nenhum resultado",
Expand Down
1 change: 1 addition & 0 deletions locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Поиск",
"header": "Ваш поиск {keyword} вернул следующее",
"header_empty": "К сожалению, поиск по запросу «{keyword}» не дал результатов",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Ваш запрос <strong>{0}</strong> не дал результатов",
Expand Down
1 change: 1 addition & 0 deletions locales/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "Sök",
"header": "Din sökning efter {keyword} gav följande resultat",
"header_empty": "Tyvärr, din sökning efter \"{keyword}\" gav inga resultat",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "Din sökning efter <strong>{0}</strong> gav inga resultat",
Expand Down
1 change: 1 addition & 0 deletions locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@
},
"title": "搜索",
"header": "您搜索的 {keyword} 返回了以下结果",
"header_empty": "抱歉,您搜索“{keyword}”未找到任何结果",
"sort_by_label": "@:common.labels.sort_by",
"choose_button": "@:common.buttons.choose",
"no_results_message": "您的 <strong>{0}</strong> 查询未返回任何结果",
Expand Down