Skip to content

Commit 291120f

Browse files
authored
Merge pull request #2 from vuestorefront-community/dev
Release v1.2.6
2 parents f18ad8a + 3c045ce commit 291120f

File tree

11 files changed

+748
-521
lines changed

11 files changed

+748
-521
lines changed

components/CartSidebar.vue

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
data-cy="collected-product-cart-sidebar"
2323
v-for="product in products"
2424
:key="cartGetters.getItemSku(product)"
25-
:image="cartGetters.getItemImage(product)"
25+
:image="$image(cartGetters.getItemImage(product))"
2626
:title="cartGetters.getItemName(product)"
2727
:regular-price="
2828
$n(cartGetters.getItemPrice(product).regular, 'currency')
@@ -92,15 +92,15 @@
9292
class="sf-button--full-width color-secondary"
9393
@click="toggleCartSidebar"
9494
>
95-
{{ $t("Go to checkout") }}
95+
{{ $t('Go to checkout') }}
9696
</SfButton>
9797
</nuxt-link>
9898
</div>
9999
<div v-else>
100100
<SfButton
101101
class="sf-button--full-width color-primary"
102102
@click="toggleCartSidebar"
103-
>{{ $t("Go back shopping") }}</SfButton
103+
>{{ $t('Go back shopping') }}</SfButton
104104
>
105105
</div>
106106
</transition>
@@ -118,14 +118,14 @@ import {
118118
SfPrice,
119119
SfCollectedProduct,
120120
SfImage
121-
} from "@storefront-ui/vue";
122-
import { computed } from "@nuxtjs/composition-api";
123-
import { useCart, useUser, cartGetters } from "@vue-storefront/odoo";
124-
import { useUiState } from "~/composables";
125-
import { onSSR } from "@vue-storefront/core";
121+
} from '@storefront-ui/vue';
122+
import { computed } from '@nuxtjs/composition-api';
123+
import { useCart, useUser, cartGetters } from '@vue-storefront/odoo';
124+
import { useUiState } from '~/composables';
125+
import { onSSR } from '@vue-storefront/core';
126126
127127
export default {
128-
name: "Cart",
128+
name: 'Cart',
129129
components: {
130130
SfSidebar,
131131
SfButton,

components/Category/FilterSideBar.vue

+336
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
<template>
2+
<SfSidebar
3+
:visible="isFilterSidebarOpen"
4+
title="Filters"
5+
class="sidebar-filters"
6+
@close="toggleFilterSidebar"
7+
>
8+
<div class="filters desktop-only">
9+
<div v-for="(facet, i) in facets" :key="i">
10+
<template v-if="isFacetPrice(facet)">
11+
<SfHeading
12+
:level="4"
13+
:title="facet.label"
14+
class="filters__title sf-heading--left"
15+
/>
16+
17+
<SfRange
18+
:value="[20, 600]"
19+
:disabled="false"
20+
:config="config"
21+
v-model="price"
22+
@change="selectPrice"
23+
/>
24+
</template>
25+
26+
<template v-if="facetHasMoreThanOneOption(facet)">
27+
<SfHeading
28+
:level="4"
29+
:title="facet.label"
30+
class="filters__title sf-heading--left"
31+
:key="`filter-title-${facet.value}`"
32+
/>
33+
<div
34+
v-if="isFacetColor(facet, facet.options)"
35+
class="filters__colors"
36+
:key="`${facet.value}-colors`"
37+
>
38+
<SfColor
39+
v-for="option in facet.options"
40+
:key="`${facet.id}-${option.value}`"
41+
:data-cy="`category-filter_color_${option.value}`"
42+
:color="option.htmlColor"
43+
:selected="isFilterSelected(facet, option)"
44+
class="filters__color tw-mr-3"
45+
@click="() => selectFilter(facet, option)"
46+
/>
47+
</div>
48+
<div v-else>
49+
<SfFilter
50+
v-for="option in facet.options"
51+
:key="`${facet.id}-${option.value}`"
52+
:data-cy="`category-filter_${facet.id}_${option.value}`"
53+
:label="
54+
option.label + `${option.count ? ` (${option.count})` : ''}`
55+
"
56+
:selected="isFilterSelected(facet, option)"
57+
class="filters__item"
58+
@change="() => selectFilter(facet, option)"
59+
/>
60+
</div>
61+
</template>
62+
</div>
63+
</div>
64+
<SfAccordion class="filters smartphone-only">
65+
<div v-for="(facet, i) in facets" :key="i">
66+
<SfAccordionItem
67+
:key="`filter-title-${facet.id}`"
68+
:header="facet.label"
69+
class="filters__accordion-item"
70+
>
71+
<SfFilter
72+
v-for="option in facet.options"
73+
:key="`${facet.id}-${option.id}`"
74+
:label="option.label"
75+
:selected="isFilterSelected(facet, option)"
76+
class="filters__item"
77+
@change="() => selectFilter(facet, option)"
78+
/>
79+
</SfAccordionItem>
80+
</div>
81+
</SfAccordion>
82+
83+
<template #content-bottom>
84+
<div class="filters__buttons">
85+
<SfButton class="sf-button--full-width" @click="applyFilters">{{
86+
$t('Done')
87+
}}</SfButton>
88+
<SfButton
89+
class="sf-button--full-width filters__button-clear"
90+
@click="clearFilters"
91+
>{{ $t('Clear all') }}</SfButton
92+
>
93+
</div>
94+
</template>
95+
</SfSidebar>
96+
</template>
97+
<script >
98+
import {
99+
SfSidebar,
100+
SfHeading,
101+
SfFilter,
102+
SfSelect,
103+
SfCheckbox,
104+
SfLoader,
105+
SfColor,
106+
SfButton,
107+
SfProperty,
108+
SfImage,
109+
SfRange,
110+
SfAccordion
111+
} from '@storefront-ui/vue';
112+
import { facetGetters } from '@vue-storefront/odoo';
113+
import {
114+
defineComponent,
115+
ref,
116+
onMounted,
117+
reactive,
118+
computed
119+
} from '@nuxtjs/composition-api';
120+
import { useUiState, useUiHelpers } from '~/composables';
121+
122+
export default defineComponent({
123+
components: {
124+
SfSidebar,
125+
SfHeading,
126+
SfFilter,
127+
SfSelect,
128+
SfCheckbox,
129+
SfButton,
130+
SfLoader,
131+
SfColor,
132+
SfProperty,
133+
SfAccordion,
134+
SfImage,
135+
SfRange
136+
},
137+
props: {
138+
facetsList: {
139+
type: Object,
140+
default: () => []
141+
}
142+
},
143+
setup(props) {
144+
const selectedFilters = ref([]);
145+
const price = ref([]);
146+
const config = reactive({
147+
start: [40, 700],
148+
range: { min: 20, max: 2000 },
149+
step: 10,
150+
connect: true,
151+
direction: 'ltr',
152+
orientation: 'horizontal',
153+
behaviour: 'tap-drag',
154+
tooltips: true,
155+
keyboardSupport: true
156+
});
157+
158+
const { changeFilters, isFacetColor, isFacetPrice, facetsFromUrlToFilter } =
159+
useUiHelpers();
160+
const { toggleFilterSidebar, isFilterSidebarOpen } = useUiState();
161+
162+
const clearFilters = () => {
163+
toggleFilterSidebar();
164+
selectedFilters.value = [];
165+
changeFilters(selectedFilters.value);
166+
};
167+
168+
const applyFilters = () => {
169+
toggleFilterSidebar();
170+
changeFilters(selectedFilters.value);
171+
};
172+
173+
const isFilterSelected = (facet, option) => {
174+
return selectedFilters.value.some(
175+
(filter) => String(filter.id) === String(option.value)
176+
);
177+
};
178+
179+
const facetHasMoreThanOneOption = (facet) =>
180+
facet?.options?.length > 1 || false;
181+
182+
const selectPrice = (values) => {
183+
const newValue = `${values[0]}-${values[1]}`;
184+
price.value = values;
185+
const selectedValue = selectedFilters.value.find(
186+
(item) => item?.filterName === 'price'
187+
);
188+
189+
if (selectedValue) {
190+
selectedValue.id = newValue;
191+
return;
192+
}
193+
194+
selectedFilters.value.push({
195+
label: 'Price',
196+
filterName: 'price',
197+
id: newValue
198+
});
199+
};
200+
201+
const selectFilter = (facet, option) => {
202+
const alreadySelectedIndex = selectedFilters.value.findIndex(
203+
(filter) => String(filter.id) === String(option.value)
204+
);
205+
206+
if (alreadySelectedIndex === -1) {
207+
selectedFilters.value.push({
208+
filterName: facet.label,
209+
label: option.label,
210+
id: option.value
211+
});
212+
213+
return;
214+
}
215+
216+
selectedFilters.value.splice(alreadySelectedIndex, 1);
217+
};
218+
219+
const facets = computed(() => [
220+
{
221+
id: null,
222+
label: 'Price',
223+
type: 'price'
224+
},
225+
...facetGetters.getGrouped(props.facetsList, ['color', 'size'])
226+
]);
227+
228+
const setPrice = () => {
229+
const selectedValue = selectedFilters.value.find(
230+
(item) => item?.filterName === 'price'
231+
);
232+
233+
if (selectedValue) {
234+
const splitedPriceFromUrl = selectedValue?.id?.split('-');
235+
236+
price.value = [splitedPriceFromUrl];
237+
config.start = splitedPriceFromUrl.map((item) => parseInt(item));
238+
}
239+
};
240+
241+
onMounted(() => {
242+
selectedFilters.value = facetsFromUrlToFilter();
243+
setPrice();
244+
});
245+
246+
return {
247+
price,
248+
selectPrice,
249+
facetHasMoreThanOneOption,
250+
isFilterSidebarOpen,
251+
facets,
252+
config,
253+
toggleFilterSidebar,
254+
isFacetColor,
255+
selectedFilters,
256+
isFacetPrice,
257+
selectFilter,
258+
isFilterSelected,
259+
clearFilters,
260+
applyFilters
261+
};
262+
}
263+
});
264+
</script>
265+
<style scoped lang="scss">
266+
.sidebar-filters {
267+
--sidebar-title-display: none;
268+
--sidebar-top-padding: 0;
269+
@include for-desktop {
270+
--sidebar-content-padding: 0 var(--spacer-xl);
271+
--sidebar-bottom-padding: 0 var(--spacer-xl);
272+
}
273+
}
274+
275+
.sf-range {
276+
width: 80%;
277+
}
278+
279+
.filters {
280+
&__title {
281+
--heading-title-font-size: var(--font-size--xl);
282+
margin: var(--spacer-xl) 0 var(--spacer-base) 0;
283+
&:first-child {
284+
margin: calc(var(--spacer-xl) + var(--spacer-base)) 0 var(--spacer-xs) 0;
285+
}
286+
}
287+
&__colors {
288+
display: flex;
289+
}
290+
&__color {
291+
margin: var(--spacer-xs) var(--spacer-xs) var(--spacer-xs) 0;
292+
}
293+
&__chosen {
294+
color: var(--c-text-muted);
295+
font-weight: var(--font-weight--normal);
296+
font-family: var(--font-family--secondary);
297+
position: absolute;
298+
right: var(--spacer-xl);
299+
}
300+
&__item {
301+
--radio-container-padding: 0 var(--spacer-sm) 0 var(--spacer-xl);
302+
--radio-background: transparent;
303+
--filter-label-color: var(--c-secondary-variant);
304+
--filter-count-color: var(--c-secondary-variant);
305+
--checkbox-padding: 0 var(--spacer-sm) 0 var(--spacer-xl);
306+
padding: var(--spacer-sm) 0;
307+
border-bottom: 1px solid var(--c-light);
308+
&:last-child {
309+
border-bottom: 0;
310+
}
311+
@include for-desktop {
312+
--checkbox-padding: 0;
313+
margin: var(--spacer-sm) 0;
314+
border: 0;
315+
padding: 0;
316+
}
317+
}
318+
&__accordion-item {
319+
--accordion-item-content-padding: 0;
320+
position: relative;
321+
left: 50%;
322+
right: 50%;
323+
margin-left: -50vw;
324+
margin-right: -50vw;
325+
width: 100vw;
326+
}
327+
&__buttons {
328+
margin: var(--spacer-sm) 0;
329+
}
330+
&__button-clear {
331+
--button-background: var(--c-light);
332+
--button-color: var(--c-dark-variant);
333+
margin: var(--spacer-xs) 0 0 0;
334+
}
335+
}
336+
</style>

0 commit comments

Comments
 (0)