From 3b42e4cfd0a45432e89a21a32d976473f728837d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Thu, 7 Jan 2021 16:08:36 +0100 Subject: [PATCH 1/8] add ui notification --- .../theme/components/CartSidebar.vue | 30 ++++++--- .../theme/components/Notification.vue | 62 +++++++++++++++++++ .../theme/composables/index.ts | 4 +- .../composables/useUiNotification/index.ts | 43 +++++++++++++ .../theme/layouts/default.vue | 5 +- 5 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 packages/core/nuxt-theme-module/theme/components/Notification.vue create mode 100644 packages/core/nuxt-theme-module/theme/composables/useUiNotification/index.ts diff --git a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue index 19be02bd895..f3236ba6b48 100644 --- a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue +++ b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue @@ -75,9 +75,9 @@ - {{ $t('Go to checkout') }} @@ -87,7 +87,7 @@ {{ $t('Go back shopping') }}{{ $t('Go back shopping') }} @@ -106,9 +106,9 @@ import { SfCollectedProduct, SfImage } from '@storefront-ui/vue'; -import { computed } from '@vue/composition-api'; +import { computed, watch } from '@vue/composition-api'; import { useCart, useUser, cartGetters } from '<%= options.generate.replace.composables %>'; -import { useUiState } from '~/composables'; +import { useUiState, useUiNotification } from '~/composables'; import { onSSR } from '@vue-storefront/core'; export default { @@ -123,10 +123,11 @@ export default { SfCollectedProduct, SfImage }, - setup() { + setup(_, { root }) { const { isCartSidebarOpen, toggleCartSidebar } = useUiState(); const { cart, removeItem, updateItemQty, load: loadCart } = useCart(); const { isAuthenticated } = useUser(); + const { send } = useUiNotification(); const products = computed(() => cartGetters.getItems(cart.value)); const totals = computed(() => cartGetters.getTotals(cart.value)); const totalItems = computed(() => cartGetters.getTotalItems(cart.value)); @@ -135,6 +136,21 @@ export default { await loadCart(); }); + watch(totalItems, () => { + send({ + type: 'info', + message: `Total items: ${totalItems.value}`, + action: { + text: 'Go to checkout', + onClick: () => { + root.$router.push('/checkout/personal-details'); + } + }, + persist: true, + icon: 'heart' + }); + }); + return { isAuthenticated, products, diff --git a/packages/core/nuxt-theme-module/theme/components/Notification.vue b/packages/core/nuxt-theme-module/theme/components/Notification.vue new file mode 100644 index 00000000000..2a22aac458a --- /dev/null +++ b/packages/core/nuxt-theme-module/theme/components/Notification.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/packages/core/nuxt-theme-module/theme/composables/index.ts b/packages/core/nuxt-theme-module/theme/composables/index.ts index 74bd181c0c9..1d414b562dd 100644 --- a/packages/core/nuxt-theme-module/theme/composables/index.ts +++ b/packages/core/nuxt-theme-module/theme/composables/index.ts @@ -1,7 +1,9 @@ import useUiHelpers from './useUiHelpers'; import useUiState from './useUiState'; +import useUiNotification from './useUiNotification'; export { useUiHelpers, - useUiState + useUiState, + useUiNotification }; diff --git a/packages/core/nuxt-theme-module/theme/composables/useUiNotification/index.ts b/packages/core/nuxt-theme-module/theme/composables/useUiNotification/index.ts new file mode 100644 index 00000000000..633bdd63c33 --- /dev/null +++ b/packages/core/nuxt-theme-module/theme/composables/useUiNotification/index.ts @@ -0,0 +1,43 @@ +import { computed, reactive } from '@vue/composition-api'; + +interface UiNotification { + message: string; + action: { text: string; onCLick: Function }; + type: 'danger' | 'success' | 'info'; + icon: string; + persist: boolean; +} + +const state = reactive({ + notifications: [] +}); + +const useUiNotification = () => { + const remove = (id: symbol) => { + const index = state.notifications.findIndex(notification => notification.id === id); + + if (index !== -1) state.notifications.splice(index, 1); + }; + + const send = (notification: UiNotification) => { + const id = Symbol(); + const newNotification = { id, ...notification }; + + state.notifications.push(newNotification); + if (state.notifications.length > 3) state.notifications.shift(); + + if (!notification.persist) { + setTimeout(() => { + remove(id); + }, 3000); + } + }; + + return { + send, + remove, + notifications: computed(() => state.notifications) + }; +}; + +export default useUiNotification; diff --git a/packages/core/nuxt-theme-module/theme/layouts/default.vue b/packages/core/nuxt-theme-module/theme/layouts/default.vue index 0c352a57f6b..592197550a3 100644 --- a/packages/core/nuxt-theme-module/theme/layouts/default.vue +++ b/packages/core/nuxt-theme-module/theme/layouts/default.vue @@ -22,6 +22,7 @@ + @@ -35,6 +36,7 @@ import CartSidebar from '~/components/CartSidebar.vue'; import WishlistSidebar from '~/components/WishlistSidebar.vue'; import LoginModal from '~/components/LoginModal.vue'; import LazyHydrate from 'vue-lazy-hydration'; +import Notification from '~/components/Notification'; export default { components: { @@ -45,7 +47,8 @@ export default { AppFooter, CartSidebar, WishlistSidebar, - LoginModal + LoginModal, + Notification } }; From 1d68a409bc76ac3154153186f91075b1fec0b717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Thu, 7 Jan 2021 16:21:17 +0100 Subject: [PATCH 2/8] chore: changed example usage in error handling doc --- packages/core/docs/general/error-handling.md | 5 +++-- .../theme/components/CartSidebar.vue | 12 ++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/core/docs/general/error-handling.md b/packages/core/docs/general/error-handling.md index 4751157799a..4fdd31d9c7c 100644 --- a/packages/core/docs/general/error-handling.md +++ b/packages/core/docs/general/error-handling.md @@ -79,9 +79,10 @@ Let's imagine you have some global components for error notifications. You want ```ts const { cart, error } = useCart() +const { send } = useUiNotification(); watch(error, (error, prevError) => { - if (error.value.addItem && error.value.addItem !== prevError.value.addItem) sendInAppNotification('error', error.value.addItem.message) - if (error.value.removeItem && error.value.removeItem !== prevError.value.removeItem) sendInAppNotification('error', error.value.removeItem.message) + if (error.value.addItem && error.value.addItem !== prevError.value.addItem) send({ type: 'danger', message: error.value.addItem.message }) + if (error.value.removeItem && error.value.removeItem !== prevError.value.removeItem) send({ type: 'danger', message: error.value.removeItem.message }) }) ``` diff --git a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue index f3236ba6b48..88e37af5d59 100644 --- a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue +++ b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue @@ -123,7 +123,7 @@ export default { SfCollectedProduct, SfImage }, - setup(_, { root }) { + setup() { const { isCartSidebarOpen, toggleCartSidebar } = useUiState(); const { cart, removeItem, updateItemQty, load: loadCart } = useCart(); const { isAuthenticated } = useUser(); @@ -139,15 +139,7 @@ export default { watch(totalItems, () => { send({ type: 'info', - message: `Total items: ${totalItems.value}`, - action: { - text: 'Go to checkout', - onClick: () => { - root.$router.push('/checkout/personal-details'); - } - }, - persist: true, - icon: 'heart' + message: `Total items: ${totalItems.value}` }); }); From e98b95a7f11ffa335ff3e99c538cfe3555c9cf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Thu, 7 Jan 2021 16:22:22 +0100 Subject: [PATCH 3/8] chore: removed example usage --- .../theme/components/CartSidebar.vue | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue index 88e37af5d59..f7fc7a5e020 100644 --- a/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue +++ b/packages/core/nuxt-theme-module/theme/components/CartSidebar.vue @@ -106,9 +106,9 @@ import { SfCollectedProduct, SfImage } from '@storefront-ui/vue'; -import { computed, watch } from '@vue/composition-api'; +import { computed } from '@vue/composition-api'; import { useCart, useUser, cartGetters } from '<%= options.generate.replace.composables %>'; -import { useUiState, useUiNotification } from '~/composables'; +import { useUiState } from '~/composables'; import { onSSR } from '@vue-storefront/core'; export default { @@ -127,7 +127,6 @@ export default { const { isCartSidebarOpen, toggleCartSidebar } = useUiState(); const { cart, removeItem, updateItemQty, load: loadCart } = useCart(); const { isAuthenticated } = useUser(); - const { send } = useUiNotification(); const products = computed(() => cartGetters.getItems(cart.value)); const totals = computed(() => cartGetters.getTotals(cart.value)); const totalItems = computed(() => cartGetters.getTotalItems(cart.value)); @@ -136,13 +135,6 @@ export default { await loadCart(); }); - watch(totalItems, () => { - send({ - type: 'info', - message: `Total items: ${totalItems.value}` - }); - }); - return { isAuthenticated, products, From 51731f2b47c2b08713894a59d9a0d2f33611ba4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Fri, 8 Jan 2021 10:14:54 +0100 Subject: [PATCH 4/8] chore: removed unused title --- .../core/nuxt-theme-module/theme/components/Notification.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/nuxt-theme-module/theme/components/Notification.vue b/packages/core/nuxt-theme-module/theme/components/Notification.vue index 2a22aac458a..63e3b7f9cc2 100644 --- a/packages/core/nuxt-theme-module/theme/components/Notification.vue +++ b/packages/core/nuxt-theme-module/theme/components/Notification.vue @@ -4,7 +4,6 @@ v-for="notification in notifications" :key="notification.id" :visible="!!notification.id" - :title="notification.title" :message="notification.message" :action="notification.action && notification.action.text" :type="notification.type" From f95c3d214ec7f96d9ebc12dccd7ed4fcf82410c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Fri, 8 Jan 2021 13:26:09 +0100 Subject: [PATCH 5/8] chore: add mising transition-group --- .../theme/components/Notification.vue | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/core/nuxt-theme-module/theme/components/Notification.vue b/packages/core/nuxt-theme-module/theme/components/Notification.vue index 63e3b7f9cc2..c83fc8484a4 100644 --- a/packages/core/nuxt-theme-module/theme/components/Notification.vue +++ b/packages/core/nuxt-theme-module/theme/components/Notification.vue @@ -1,5 +1,5 @@ - +