Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
23 changes: 22 additions & 1 deletion packages/composables/src/useSyncWishlist/useSyncWishlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,26 @@ export type UseSyncWishlistReturn = {
* Current page number
*/
currentPage: ComputedRef<number>;
/**
* Limit number of products per page
*/
limit: ComputedRef<number>;
/**
* Wishlist products
*/
products: ComputedRef<Schemas["Product"][]>;
/**
* Indicates if the wishlist is loading
*/
isLoading: Ref<boolean>;
};

const _wishlistItems: Ref<string[]> = ref([]);
const _wishlistProducts: Ref<Schemas["Product"][]> = ref([]);
const _currentPage: Ref<number> = ref(1);
const _limit: Ref<number> = ref(15);
const totalWishlistItemsCount: Ref<number> = ref(0);

const isLoading: Ref<boolean> = ref(false);
/**
* Composable to manage wishlist via API
* @public
Expand Down Expand Up @@ -81,8 +95,10 @@ export function useSyncWishlist(): UseSyncWishlistReturn {
_wishlistItems.value = [
...response.data.products.elements.map((element) => element.id),
];
_wishlistProducts.value = response.data.products.elements;
totalWishlistItemsCount.value = response.data.products.total ?? 0;
_currentPage.value = response.data.products.page ?? 1;
_limit.value = response.data.products.limit ?? 15;
} catch (e) {
if (e instanceof ApiClientError) {
// If 404 ignore printing error and reset wishlist
Expand All @@ -104,14 +120,19 @@ export function useSyncWishlist(): UseSyncWishlistReturn {
const items = computed(() => _wishlistItems.value);
const count = computed(() => totalWishlistItemsCount.value);
const currentPage = computed(() => _currentPage.value);
const products = computed(() => _wishlistProducts.value);
const limit = computed(() => _limit.value);

return {
getWishlistProducts,
addToWishlistSync,
removeFromWishlistSync,
mergeWishlistProducts,
products,
items,
count,
currentPage,
isLoading,
limit,
};
}
9 changes: 9 additions & 0 deletions packages/composables/src/useWishlist/useWishlist.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ describe("useWishlist - not logged in user", () => {
removeFromWishlistSync: () => undefined,
count: computed(() => 17),
currentPage: computed(() => 2),
limit: computed(() => 15),
products: computed((): Schemas["Product"][] => []),
isLoading: computed(() => false),
});
const { vm } = useSetup(() => useWishlist());

Expand All @@ -77,6 +80,9 @@ describe("useWishlist - not logged in user", () => {
removeFromWishlistSync: () => undefined,
count: computed(() => 15),
currentPage: computed(() => 2),
limit: computed(() => 15),
products: computed((): Schemas["Product"][] => []),
isLoading: computed(() => false),
});
const { vm } = useSetup(() => useWishlist());

Expand Down Expand Up @@ -141,6 +147,9 @@ describe("useWishlist - logged in user", () => {
removeFromWishlistSync: () => undefined,
count: computed(() => 15),
currentPage: computed(() => 1),
limit: computed(() => 15),
products: computed((): Schemas["Product"][] => []),
isLoading: computed(() => false),
});
const { vm } = useSetup(() => useWishlist());

Expand Down
24 changes: 19 additions & 5 deletions packages/composables/src/useWishlist/useWishlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ export type UseWishlistReturn = {
* Indicates if the wishlist can be synced
*/
canSyncWishlist: ComputedRef<boolean>;
/**
* Wishlist products
*/
productsSync: ComputedRef<Schemas["Product"][]>;
/**
* Limit number of products per page
*/
limit: ComputedRef<number>;
};

/**
Expand All @@ -65,21 +73,25 @@ export function useWishlist(): UseWishlistReturn {
removeFromWishlistSync,
count: countSync,
currentPage,
products: productsSync,
limit: limitSync,
} = useSyncWishlist();

const limit = ref<number>(15);

const getWishlistProducts = async (query?: Schemas["Criteria"]) => {
const wishlistQuery = {} as Schemas["Criteria"];
if (query) {
defu(wishlistQuery, query);
}
let wishlistQuery = {
limit: limit.value,
} as Schemas["Criteria"];

wishlistQuery = defu(query, wishlistQuery);

if (query?.limit) {
limit.value = query.limit;
}

if (canSyncWishlist.value) {
await getWishlistProductsSync(query);
await getWishlistProductsSync(wishlistQuery);
} else {
getWishlistProductsLocal();
}
Expand Down Expand Up @@ -124,5 +136,7 @@ export function useWishlist(): UseWishlistReturn {
totalPagesCount,
count,
canSyncWishlist,
productsSync,
limit: limitSync,
};
}
1 change: 1 addition & 0 deletions templates/vue-demo-store/app/pages/wishlist.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const {
totalPagesCount,
canSyncWishlist,
} = useWishlist();

defineOptions({
name: "WishlistPage",
});
Expand Down
7 changes: 6 additions & 1 deletion templates/vue-starter-template/app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ useSessionContext(sessionContextData.value);
const { locale, availableLocales, defaultLocale, localeProperties, messages } =
useI18n();
const router = useRouter();
const route = useRoute();

const { languageIdChain, refreshSessionContext } = useSessionContext();

Expand Down Expand Up @@ -94,7 +95,11 @@ if (languages && router.currentRoute.value.name) {

onMounted(() => {
refreshCart();
getWishlistProducts();
const isWishlistPage =
route.name === "wishlist" || route.path.includes("/wishlist");
if (!isWishlistPage) {
getWishlistProducts();
}
});
</script>

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ function handleMyAccountClick() {
<FormIconButton type="ghost" @click="handleMyAccountClick"
><LayoutHeaderMyAccountIcon
/></FormIconButton>
<LayoutHeaderWishlistIcon :counter="wishlistCount" />
<NuxtLink :to="formatLink('/wishlist')">
<LayoutHeaderWishlistIcon :counter="wishlistCount" />
</NuxtLink>

<LayoutHeaderCartIcon :counter="cartCount" />
<LayoutHeaderMobileMenuIcon
class="hidden max-lg:block"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
const { isSelected } = defineProps<{
isSelected: boolean;
}>();
</script>
<template>
<FormIconButton type="ghost" class="justify-center">
<div
class="h-10 w-10 bg-brand-secondary rounded-full flex items-center justify-center"
>
<Icon
size="1.2rem"
:name="isSelected ? 'shopware:solid-heart' : 'shopware:heart'"
class="color-brand-primary"
/>
</div>
</FormIconButton>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup lang="ts">
type BaseProps = {
pages: number;
currentPage: number;
};

type WithPerPageSelector = BaseProps & {
showPageSizeSelector: true;
pageSize: number;
};

type WithoutPerPageSelector = BaseProps & {
showPageSizeSelector: false;
pageSize?: number;
};

const props = defineProps<WithPerPageSelector | WithoutPerPageSelector>();

const emit = defineEmits<{
changePage: [page: number];
changeSize: [size: number];
}>();

function handleChangePage(page: number) {
emit("changePage", page);
}

function handleChangeSize(size: number) {
emit("changeSize", size);
}
</script>
<template>
<div class="flex items-center gap-2 justify-between">
<SharedPagination
@change-page="handleChangePage"
:total="pages"
:current="currentPage"
/>
<SharedSizeSelector @change="handleChangeSize" :value="pageSize ?? 15" />
</div>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script setup lang="ts">
defineProps<{
total: number;
current: number;
}>();

defineEmits<{
changePage: [page: number];
}>();
</script>
<template>
<nav
class="relative z-0 inline-flex rounded-md shadow-sm space-x-px"
aria-label="Pagination"
>
<button
v-if="current - 1 >= 2"
class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-outline-outline-variant bg-white text-sm outline outline-1 outline-offset-[-1px] outline-outline-outline-variant"
@click="$emit('changePage', current - 1)"
>
<SwChevronIcon direction="left" :size="20" />
</button>
<button
v-if="current > 2"
class="bg-white border-outline-outline-variant relative inline-flex items-center px-4 py-2 border text-sm outline outline-1 outline-offset-[-1px] outline-outline-outline-variant"
@click="$emit('changePage', 1)"
>
1
</button>
<span
v-if="current - 1 > 2"
class="relative inline-flex items-center px-4 py-2 border border-outline-outline-variant bg-white text-sm outline outline-1 outline-offset-[-1px] outline-outline-outline-variant"
>
...
</span>
<button
v-if="current > 1"
class="bg-white border-outline-outline-variant relative inline-flex items-center px-4 py-2 border text-sm outline outline-1 outline-offset-[-1px] outline-outline-outline-variant"
:class="[
current == 2
? 'rounded-l-md border border-outline-outline-variant'
: '',
]"
@click="$emit('changePage', current - 1)"
>
{{ current - 1 }}
</button>
<button
aria-current="page"
class="bg-brand-primary text-brand-on-primary relative inline-flex items-center px-4 py-2 border text-sm "
:class="[
current - 1 >= 1
? ''
: 'rounded-l-md border border-outline-outline-variant',
total == current
? 'rounded-r-md border border-outline-outline-variant'
: '',
]"
>
{{ current }}
</button>
<button
v-if="current < total"
class="bg-white border-outline-outline-variant relative inline-flex items-center px-4 py-2 border text-sm "
:class="[
total == current + 1
? 'rounded-r-md border border-outline-outline-variant'
: '',
]"
@click="$emit('changePage', current + 1)"
>
{{ current + 1 }}
</button>
<span
v-if="total - current > 2"
class="relative inline-flex items-center px-4 py-2 border border-outline-outline-variant bg-white text-sm "
>
...
</span>
<button
v-if="total - current > 1"
class="bg-white border-outline-outline-variant relative inline-flex items-center px-4 py-2 border text-sm "
@click="$emit('changePage', total)"
>
{{ total }}
</button>
<button
v-if="total > current + 1"
class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-outline-outline-variant bg-white text-sm "
@click="$emit('changePage', current + 1)"
>
<SwChevronIcon direction="right" :size="20" />
</button>
</nav>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
const props = defineProps<{
value: number;
}>();

const emit = defineEmits<{
change: [size: number];
}>();

const state = ref(props.value.toString());

const options = [
{ value: "1", label: "1" },
{ value: "15", label: "15" },
{ value: "30", label: "30" },
{ value: "45", label: "45" },
];

function handleChange() {
emit("change", Number(state.value));
}
</script>
<template>
<FormDropdownField
id="page-size"
v-model="state"
:options
@change="handleChange"
/>
</template>
Loading
Loading