From fa42391bf29065bc52ec7eb48eef811304ea07ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=BB=C4=85d=C5=82owski?= Date: Wed, 10 Jul 2019 09:50:42 +0200 Subject: [PATCH 01/27] Issue-3152. Modules rewrite to match new design. Issue-3152. Modules rewrite to match new design. --- core/modules/catalog-next/index.ts | 13 +- .../catalog-next/store/category/index.ts | 2 +- .../compare/hooks/afterRegistration.ts | 2 - .../compare/hooks/beforeRegistration.ts | 15 --- core/modules/compare/index.ts | 21 ++- core/modules/compare/store/index.ts | 2 +- core/modules/mailer/index.ts | 13 +- core/modules/mailer/store/index.ts | 2 +- core/modules/newsletter/index.ts | 12 +- core/modules/newsletter/store/index.ts | 2 +- core/modules/notification/index.ts | 13 +- core/modules/notification/store/index.ts | 2 +- .../hooks/afterRegistration.ts | 4 - core/modules/recently-viewed/index.ts | 19 +-- core/modules/recently-viewed/store/index.ts | 2 +- core/modules/review/index.ts | 13 +- core/modules/review/store/index.ts | 2 +- core/modules/url/index.ts | 18 +-- core/modules/url/router/beforeEach.ts | 2 +- core/modules/url/store/index.ts | 2 +- .../wishlist/components/AddToWishlist.ts | 5 +- .../wishlist/components/IsOnWishlist.ts | 5 +- .../wishlist/components/RemoveFromWishlist.ts | 5 +- core/modules/wishlist/components/Wishlist.ts | 5 +- core/modules/wishlist/index.ts | 13 +- core/modules/wishlist/store/index.ts | 2 +- src/modules/amp-renderer/index.ts | 14 +- .../hooks/afterRegistration.ts | 21 --- .../hooks/beforeRegistration.ts | 23 ---- src/modules/google-analytics/index.ts | 55 ++++++-- .../hooks/afterRegistration.ts | 97 -------------- .../hooks/beforeRegistration.ts | 15 --- src/modules/google-tag-manager/index.ts | 124 ++++++++++++++++-- src/modules/hotjar/hooks/afterRegistration.ts | 19 --- src/modules/hotjar/index.ts | 33 +++-- src/modules/index.ts | 69 +++++----- src/modules/instant-checkout/index.ts | 9 +- .../hooks/afterRegistration.ts | 32 ----- src/modules/payment-backend-methods/index.ts | 43 ++++-- .../hooks/afterRegistration.ts | 47 ------- src/modules/payment-cash-on-delivery/index.ts | 56 ++++++-- src/modules/raw-output-example/index.ts | 10 +- 42 files changed, 396 insertions(+), 467 deletions(-) delete mode 100644 core/modules/compare/hooks/afterRegistration.ts delete mode 100644 core/modules/compare/hooks/beforeRegistration.ts delete mode 100644 core/modules/recently-viewed/hooks/afterRegistration.ts delete mode 100644 src/modules/google-analytics/hooks/afterRegistration.ts delete mode 100644 src/modules/google-analytics/hooks/beforeRegistration.ts delete mode 100644 src/modules/google-tag-manager/hooks/afterRegistration.ts delete mode 100644 src/modules/google-tag-manager/hooks/beforeRegistration.ts delete mode 100644 src/modules/hotjar/hooks/afterRegistration.ts delete mode 100644 src/modules/payment-backend-methods/hooks/afterRegistration.ts delete mode 100644 src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts diff --git a/core/modules/catalog-next/index.ts b/core/modules/catalog-next/index.ts index 2b2bc98c70..af2dc74668 100644 --- a/core/modules/catalog-next/index.ts +++ b/core/modules/catalog-next/index.ts @@ -1,10 +1,7 @@ -import { categoryModule } from './store/category' -import { createModule } from '@vue-storefront/core/lib/module' +import { categoryNextStore } from './store/category' +import { StorefrontModule } from '@vue-storefront/module'; export const KEY = 'catalog-next' -export default createModule({ - key: KEY, - store: { modules: [ - { key: 'category-next', module: categoryModule } - ] } -}) +export const CatalogNextModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, categoryNextStore) +} diff --git a/core/modules/catalog-next/store/category/index.ts b/core/modules/catalog-next/store/category/index.ts index 0c19d65082..e7630932e9 100644 --- a/core/modules/catalog-next/store/category/index.ts +++ b/core/modules/catalog-next/store/category/index.ts @@ -5,7 +5,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import CategoryState from './CategoryState' -export const categoryModule: Module = { +export const categoryNextStore: Module = { namespaced: true, state: { categoriesMap: {}, diff --git a/core/modules/compare/hooks/afterRegistration.ts b/core/modules/compare/hooks/afterRegistration.ts deleted file mode 100644 index d95a368d44..0000000000 --- a/core/modules/compare/hooks/afterRegistration.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function afterRegistration ({ Vue, config, store, isServer }) { -} diff --git a/core/modules/compare/hooks/beforeRegistration.ts b/core/modules/compare/hooks/beforeRegistration.ts deleted file mode 100644 index 7dfecfe4e4..0000000000 --- a/core/modules/compare/hooks/beforeRegistration.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' - -export function beforeRegistration ({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - - StorageManager.set('compareCollection', new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'compare', - driver: localForage[config.localForage.defaultDrivers['compare']] - }))) -} diff --git a/core/modules/compare/index.ts b/core/modules/compare/index.ts index e974ceda44..75cf61c2d6 100644 --- a/core/modules/compare/index.ts +++ b/core/modules/compare/index.ts @@ -1,15 +1,14 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import { compareStore } from './store' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; import { plugin } from './store/plugin' +import { StorefrontModule } from '@vue-storefront/module'; +import Vue from 'vue'; -export const KEY = 'compare' +const KEY = 'compare' export const cacheStorage = initCacheStorage(KEY) -export const Compare = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }], plugin }, - beforeRegistration, - afterRegistration -}) +export const CompareModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + Vue.prototype.$db.cartsCollection = initCacheStorage('compare') + + store.registerModule(KEY, compareStore) + store.subscribe(plugin) +} diff --git a/core/modules/compare/store/index.ts b/core/modules/compare/store/index.ts index 5d71458e0e..58f9714794 100644 --- a/core/modules/compare/store/index.ts +++ b/core/modules/compare/store/index.ts @@ -5,7 +5,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import CompareState from '../types/CompareState' -export const module: Module = { +export const compareStore: Module = { namespaced: true, state: { loaded: false, diff --git a/core/modules/mailer/index.ts b/core/modules/mailer/index.ts index cb8ed57668..5aea6d6382 100644 --- a/core/modules/mailer/index.ts +++ b/core/modules/mailer/index.ts @@ -1,8 +1,7 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { StorefrontModule } from '@vue-storefront/module' +import { mailerStore } from './store' -export const KEY = 'mailer' -export const Mailer = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] } -}) +const KEY = 'mailer' +export const MailerModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, mailerStore) +} diff --git a/core/modules/mailer/store/index.ts b/core/modules/mailer/store/index.ts index 8dca52edf3..4a2162be78 100644 --- a/core/modules/mailer/store/index.ts +++ b/core/modules/mailer/store/index.ts @@ -3,7 +3,7 @@ import { Module } from 'vuex' import config from 'config' import { processURLAddress } from '@vue-storefront/core/helpers' -export const module: Module = { +export const mailerStore: Module = { namespaced: true, actions: { sendEmail (context, letter: MailItem) { diff --git a/core/modules/newsletter/index.ts b/core/modules/newsletter/index.ts index 1be1993e9a..f2d9320ee3 100644 --- a/core/modules/newsletter/index.ts +++ b/core/modules/newsletter/index.ts @@ -1,11 +1,9 @@ -import { module } from './store' -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' +import { newsletterStore } from './store' +import { StorefrontModule } from '@vue-storefront/module'; import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -export const KEY = 'newsletter' +const KEY = 'newsletter' export const cacheStorage = initCacheStorage(KEY) -const moduleConfig: VueStorefrontModuleConfig = { - key: KEY, - store: { modules: [{ key: KEY, module }] } +export const NewsletterModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, newsletterStore) } -export const Newsletter = new VueStorefrontModule(moduleConfig) diff --git a/core/modules/newsletter/store/index.ts b/core/modules/newsletter/store/index.ts index d07cbaa351..fcfbcf5395 100644 --- a/core/modules/newsletter/store/index.ts +++ b/core/modules/newsletter/store/index.ts @@ -5,7 +5,7 @@ import { cacheStorage } from '../' import config from 'config' import { processURLAddress } from '@vue-storefront/core/helpers' -export const module: Module = { +export const newsletterStore: Module = { namespaced: true, state: { isSubscribed: null, diff --git a/core/modules/notification/index.ts b/core/modules/notification/index.ts index 3a63f1d9c9..8f205daec9 100644 --- a/core/modules/notification/index.ts +++ b/core/modules/notification/index.ts @@ -1,8 +1,7 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { notificationStore } from './store' +import { StorefrontModule } from '@vue-storefront/module'; -export const KEY = 'notification' -export const Notification = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] } -}) +const KEY = 'notification' +export const NotificationModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, notificationStore) +} diff --git a/core/modules/notification/store/index.ts b/core/modules/notification/store/index.ts index 9f4c9b2a6c..a7bbd80c9a 100644 --- a/core/modules/notification/store/index.ts +++ b/core/modules/notification/store/index.ts @@ -2,7 +2,7 @@ import { Module } from 'vuex' import NotificationItem from '../types/NotificationItem' import NotificationState from '../types/NotificationState' -export const module: Module = { +export const notificationStore: Module = { namespaced: true, state: { notifications: [] diff --git a/core/modules/recently-viewed/hooks/afterRegistration.ts b/core/modules/recently-viewed/hooks/afterRegistration.ts deleted file mode 100644 index c44753d236..0000000000 --- a/core/modules/recently-viewed/hooks/afterRegistration.ts +++ /dev/null @@ -1,4 +0,0 @@ -// This function will be fired both on server and client side context after registering other parts of the module -export function afterRegistration ({ Vue, config, store, isServer }) { - if (!isServer) store.dispatch('recently-viewed/load') -} diff --git a/core/modules/recently-viewed/index.ts b/core/modules/recently-viewed/index.ts index 49e45b0f80..4bf8043683 100644 --- a/core/modules/recently-viewed/index.ts +++ b/core/modules/recently-viewed/index.ts @@ -1,13 +1,14 @@ -import { module } from './store' +import { recentlyViewedStore } from './store' import { plugin } from './store/plugin' -import { createModule } from '@vue-storefront/core/lib/module' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -import { afterRegistration } from './hooks/afterRegistration' +import { StorefrontModule } from '@vue-storefront/module'; +import { isServer } from '@vue-storefront/core/helpers' -export const KEY = 'recently-viewed' +const KEY = 'recently-viewed' export const cacheStorage = initCacheStorage(KEY) -export const RecentlyViewed = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }], plugin }, - afterRegistration -}) +export const RecentlyViewedModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, recentlyViewedStore) + store.subscribe(plugin) + + if (!isServer) store.dispatch('recently-viewed/load') +} diff --git a/core/modules/recently-viewed/store/index.ts b/core/modules/recently-viewed/store/index.ts index 4db935d943..69b73eaf50 100644 --- a/core/modules/recently-viewed/store/index.ts +++ b/core/modules/recently-viewed/store/index.ts @@ -4,7 +4,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import RecentlyViewedState from '../types/RecentlyViewedState' -export const module: Module = { +export const recentlyViewedStore: Module = { namespaced: true, state: { items: [] diff --git a/core/modules/review/index.ts b/core/modules/review/index.ts index f41f262618..e1e207ea4e 100644 --- a/core/modules/review/index.ts +++ b/core/modules/review/index.ts @@ -1,8 +1,7 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { StorefrontModule } from '@vue-storefront/module' +import { reviewStore } from './store' -export const KEY = 'review' -export const Review = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] } -}) +const KEY = 'review' +export const ReviewModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, reviewStore) +} diff --git a/core/modules/review/store/index.ts b/core/modules/review/store/index.ts index b5d0b40f67..70778f8ec6 100644 --- a/core/modules/review/store/index.ts +++ b/core/modules/review/store/index.ts @@ -4,7 +4,7 @@ import mutations from './mutations'; import RootState from '@vue-storefront/core/types/RootState'; import ReviewState from '../types/ReviewState'; -export const module: Module = { +export const reviewStore: Module = { namespaced: true, state: { items: [] diff --git a/core/modules/url/index.ts b/core/modules/url/index.ts index c28473c389..30a5d77607 100644 --- a/core/modules/url/index.ts +++ b/core/modules/url/index.ts @@ -1,15 +1,11 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' - -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' +import { urlStore } from './store' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -import { beforeEach } from './router/beforeEach' +import { StorefrontModule } from '@vue-storefront/module' +import { beforeEachGuard } from './router/beforeEach' export const KEY = 'url' export const cacheStorage = initCacheStorage(KEY) - -export const Url = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] }, - router: { beforeEach } -}) +export const UrlModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, urlStore) + router.beforeEach(beforeEachGuard) +} diff --git a/core/modules/url/router/beforeEach.ts b/core/modules/url/router/beforeEach.ts index c6affceb59..ee6cec17ee 100644 --- a/core/modules/url/router/beforeEach.ts +++ b/core/modules/url/router/beforeEach.ts @@ -14,7 +14,7 @@ export const UrlDispatchMapper = async (to) => { const routeData = await store.dispatch('url/mapUrl', { url: to.fullPath, query: to.query }) return Object.assign({}, to, routeData) } -export function beforeEach (to: Route, from: Route, next) { +export function beforeEachGuard (to: Route, from: Route, next) { if (isServer) { if (config.storeViews.multistore) { // this is called before server-entry.ts router.onReady - so we have to make sure we're in the right store context const storeCode = storeCodeFromRoute(to) diff --git a/core/modules/url/store/index.ts b/core/modules/url/store/index.ts index e928a54949..336bade112 100644 --- a/core/modules/url/store/index.ts +++ b/core/modules/url/store/index.ts @@ -4,7 +4,7 @@ import { mutations } from './mutations' import { actions } from './actions' import { state } from './state' -export const module: Module = { +export const urlStore: Module = { namespaced: true, mutations, actions, diff --git a/core/modules/wishlist/components/AddToWishlist.ts b/core/modules/wishlist/components/AddToWishlist.ts index 00508abc85..c269e67d13 100644 --- a/core/modules/wishlist/components/AddToWishlist.ts +++ b/core/modules/wishlist/components/AddToWishlist.ts @@ -1,6 +1,7 @@ import Product from '@vue-storefront/core/modules/catalog/types/Product' -import { Wishlist as WishlistModule } from '../' +import { WishlistModule } from '../' import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { registerModule } from '@vue-storefront/module'; export const AddToWishlist = { name: 'AddToWishlist', @@ -12,7 +13,7 @@ export const AddToWishlist = { } }, created () { - WishlistModule.register() + registerModule(WishlistModule) }, methods: { addToWishlist (product: Product) { diff --git a/core/modules/wishlist/components/IsOnWishlist.ts b/core/modules/wishlist/components/IsOnWishlist.ts index 8319b723c4..97b34b5d91 100644 --- a/core/modules/wishlist/components/IsOnWishlist.ts +++ b/core/modules/wishlist/components/IsOnWishlist.ts @@ -1,5 +1,6 @@ -import { Wishlist as WishlistModule } from '../' +import { WishlistModule } from '../' import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { registerModule } from '@vue-storefront/module'; export const IsOnWishlist = { name: 'isOnWishlist', @@ -11,7 +12,7 @@ export const IsOnWishlist = { } }, created () { - WishlistModule.register() + registerModule(WishlistModule) }, computed: { isOnWishlist (): boolean { diff --git a/core/modules/wishlist/components/RemoveFromWishlist.ts b/core/modules/wishlist/components/RemoveFromWishlist.ts index 7c3c843c3f..2f5f63a7aa 100644 --- a/core/modules/wishlist/components/RemoveFromWishlist.ts +++ b/core/modules/wishlist/components/RemoveFromWishlist.ts @@ -1,6 +1,7 @@ import Product from '@vue-storefront/core/modules/catalog/types/Product' -import { Wishlist as WishlistModule } from '../' +import { WishlistModule } from '../' import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { registerModule } from '@vue-storefront/module'; export const RemoveFromWishlist = { name: 'RemoveFromWishlist', @@ -13,7 +14,7 @@ export const RemoveFromWishlist = { }, methods: { removeFromWishlist (product: Product) { - WishlistModule.register() + registerModule(WishlistModule) this.$store.dispatch('wishlist/removeItem', product) } } diff --git a/core/modules/wishlist/components/Wishlist.ts b/core/modules/wishlist/components/Wishlist.ts index 8087a2a890..4344f63545 100644 --- a/core/modules/wishlist/components/Wishlist.ts +++ b/core/modules/wishlist/components/Wishlist.ts @@ -1,11 +1,12 @@ -import { Wishlist as WishlistModule } from '../' +import { WishlistModule } from '../' import wishlistMountedMixin from '@vue-storefront/core/modules/wishlist/mixins/wishlistMountedMixin' +import { registerModule } from '@vue-storefront/module'; export const Wishlist = { name: 'Wishlist', mixins: [wishlistMountedMixin], created () { - WishlistModule.register() + registerModule(WishlistModule) }, computed: { isWishlistOpen () { diff --git a/core/modules/wishlist/index.ts b/core/modules/wishlist/index.ts index 5a5824274c..4ab7b24cf1 100644 --- a/core/modules/wishlist/index.ts +++ b/core/modules/wishlist/index.ts @@ -1,12 +1,11 @@ -import { module } from './store' +import { StorefrontModule } from '@vue-storefront/module' +import { wishlistStore } from './store' import { plugin } from './store/plugin' -import { createModule } from '@vue-storefront/core/lib/module' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -export const KEY = 'wishlist' +const KEY = 'wishlist' export const cacheStorage = initCacheStorage(KEY) -export const Wishlist = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }], plugin } +export const WishlistModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, wishlistStore) + store.subscribe(plugin) } -) diff --git a/core/modules/wishlist/store/index.ts b/core/modules/wishlist/store/index.ts index b5238713fe..ad4e65804e 100644 --- a/core/modules/wishlist/store/index.ts +++ b/core/modules/wishlist/store/index.ts @@ -4,7 +4,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import WishlistState from '../types/WishlistState' -export const module: Module = { +export const wishlistStore: Module = { namespaced: true, state: { loaded: false, diff --git a/src/modules/amp-renderer/index.ts b/src/modules/amp-renderer/index.ts index 0847a04e8e..202624f384 100644 --- a/src/modules/amp-renderer/index.ts +++ b/src/modules/amp-renderer/index.ts @@ -1,15 +1,15 @@ -import { createModule } from '@vue-storefront/core/lib/module' import moduleRoutes from './router' +import { StorefrontModule } from '@vue-storefront/module'; -const store = { +const ampRendererStore = { namespaced: true, state: { key: null } } + const KEY = 'amp-renderer' -export const AmpRenderer = createModule({ - key: KEY, - router: { routes: moduleRoutes }, - store: { modules: [{ key: KEY, module: store }] } -}) +export const AmpRendererModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, ampRendererStore) + router.addRoutes(moduleRoutes) +} diff --git a/src/modules/google-analytics/hooks/afterRegistration.ts b/src/modules/google-analytics/hooks/afterRegistration.ts deleted file mode 100644 index 07c2d3f117..0000000000 --- a/src/modules/google-analytics/hooks/afterRegistration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -export function afterRegistration ({ Vue, config, store, isServer }) { - if (config.analytics.id && !isServer) { - EventBus.$on('order-after-placed', event => { - const order = event.order - const ecommerce = (Vue as any).$ga.ecommerce - - order.products.forEach(product => { - ecommerce.addItem({ - id: product.id.toString(), - name: product.name, - sku: product.sku, - category: product.category ? product.category[0].name : '', - price: product.price.toString(), - quantity: product.qty.toString() - }) - }) - ecommerce.send() - }) - } -} diff --git a/src/modules/google-analytics/hooks/beforeRegistration.ts b/src/modules/google-analytics/hooks/beforeRegistration.ts deleted file mode 100644 index 5aae76bca1..0000000000 --- a/src/modules/google-analytics/hooks/beforeRegistration.ts +++ /dev/null @@ -1,23 +0,0 @@ -import VueAnalytics from 'vue-analytics' -import { router } from '@vue-storefront/core/app' -import { Logger } from '@vue-storefront/core/lib/logger' -import { once } from '@vue-storefront/core/helpers' - -export function beforeRegistration ({ Vue, config, store, isServer }) { - if (config.analytics.id && !isServer) { - once('__VUE_EXTEND_ANALYTICS__', () => { - Vue.use(VueAnalytics, { - id: config.analytics.id, - router, - ecommerce: { - enabled: true - } - }) - }) - } else { - Logger.warn( - 'Google Analytics extension is not working. Ensure Google Analytics account ID is defined in config', - 'GA' - )() - } -} diff --git a/src/modules/google-analytics/index.ts b/src/modules/google-analytics/index.ts index f52b536768..293004d11f 100644 --- a/src/modules/google-analytics/index.ts +++ b/src/modules/google-analytics/index.ts @@ -1,8 +1,10 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' +import VueAnalytics from 'vue-analytics' +import { Logger } from '@vue-storefront/core/lib/logger' +import { once, isServer } from '@vue-storefront/core/helpers' +import { StorefrontModule } from '@vue-storefront/module'; +import Vue from 'vue'; -const store = { +const googleAnalyticsStore = { namespaced: true, state: { key: null @@ -10,9 +12,42 @@ const store = { } const KEY = 'google-analytics' -export const GoogleAnalytics = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module: store }] }, - beforeRegistration, - afterRegistration -}) +export const GoogleAnalyticsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + if (appConfig.analytics.id && !isServer) { + once('__VUE_EXTEND_ANALYTICS__', () => { + Vue.use(VueAnalytics, { + id: appConfig.analytics.id, + router, + ecommerce: { + enabled: true + } + }) + }) + } else { + Logger.warn( + 'Google Analytics extension is not working. Ensure Google Analytics account ID is defined in config', + 'GA' + )() + } + + store.registerModule(KEY, googleAnalyticsStore) + + if (appConfig.analytics.id && !isServer) { + Vue.prototype.$bus.$on('order-after-placed', event => { + const order = event.order + const ecommerce = (Vue as any).$ga.ecommerce + + order.products.forEach(product => { + ecommerce.addItem({ + id: product.id.toString(), + name: product.name, + sku: product.sku, + category: product.category ? product.category[0].name : '', + price: product.price.toString(), + quantity: product.qty.toString() + }) + }) + ecommerce.send() + }) + } +} diff --git a/src/modules/google-tag-manager/hooks/afterRegistration.ts b/src/modules/google-tag-manager/hooks/afterRegistration.ts deleted file mode 100644 index 08a5a18656..0000000000 --- a/src/modules/google-tag-manager/hooks/afterRegistration.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { currentStoreView } from '@vue-storefront/core/lib/multistore' - -export function afterRegistration ({ Vue, config, store, isServer }) { - if (config.googleTagManager.id && !isServer) { - const storeView = currentStoreView() - const currencyCode = storeView.i18n.currencyCode - - const getProduct = (item) => { - const { name, id, sku, price_incl_tax: price, category, qty: quantity } = item - let product = { - name, - id, - sku, - price - } - if (quantity) { - product['quantity'] = quantity - } - if (category && category.length > 0) { - product['category'] = category.slice(-1)[0].name - } - - return product - } - - store.subscribe(({ type, payload }, state) => { - // Adding a Product to a Shopping Cart - if (type === 'cart/cart/ADD') { - Vue.gtm.trackEvent({ - event: 'addToCart', - ecommerce: { - currencyCode: currencyCode, - add: { - products: [getProduct(payload.product)] - } - } - }); - } - - // Removing a Product from a Shopping Cart - if (type === 'cart/cart/DEL') { - Vue.gtm.trackEvent({ - event: 'removeFromCart', - ecommerce: { - remove: { - products: [getProduct(payload.product)] - } - } - }); - } - - // Measuring Views of Product Details - if (type === 'product/product/SET_PRODUCT_CURRENT') { - Vue.gtm.trackEvent({ - ecommerce: { - detail: { - 'actionField': { 'list': '' }, // 'detail' actions have an optional list property. - 'products': [getProduct(payload)] - } - } - }); - } - - // Measuring Purchases - if (type === 'order/order/LAST_ORDER_CONFIRMATION') { - const orderId = payload.confirmation.backendOrderId - const products = payload.order.products.map(product => getProduct(product)) - store.dispatch( - 'user/getOrdersHistory', - { refresh: true, useCache: false } - ).then(() => { - const orderHistory = state.user.orders_history - if (orderHistory) { - const order = orderHistory.items.find((order) => order['entity_id'].toString() === orderId) - if (order) { - Vue.gtm.trackEvent({ - 'ecommerce': { - 'purchase': { - 'actionField': { - 'id': orderId, - 'affiliation': order.store_name, - 'revenue': order.total_due, - 'tax': order.tax_amount, - 'shipping': order.shipping_amount, - 'coupon': '' - }, - 'products': products - } - } - }) - } - } - }) - } - }) - } -} diff --git a/src/modules/google-tag-manager/hooks/beforeRegistration.ts b/src/modules/google-tag-manager/hooks/beforeRegistration.ts deleted file mode 100644 index 39cb0aa591..0000000000 --- a/src/modules/google-tag-manager/hooks/beforeRegistration.ts +++ /dev/null @@ -1,15 +0,0 @@ -import VueGtm from 'vue-gtm'; -import { router } from '@vue-storefront/core/app' -import { Logger } from '@vue-storefront/core/lib/logger' -export function beforeRegistration ({ Vue, config, isServer }) { - if (config.googleTagManager.id && !isServer) { - Vue.use(VueGtm, { - id: config.googleTagManager.id, - enabled: true, - debug: config.googleTagManager.debug, - vueRouter: router - }); - } else { - Logger.warn('Google Tag Manager extensions is not working. Ensure Google Tag Manager container ID is defined in config', 'GTM')() - } -} diff --git a/src/modules/google-tag-manager/index.ts b/src/modules/google-tag-manager/index.ts index c670f216c3..3b5cf24eb2 100644 --- a/src/modules/google-tag-manager/index.ts +++ b/src/modules/google-tag-manager/index.ts @@ -1,8 +1,12 @@ -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' -const store = { +import { StorefrontModule } from '@vue-storefront/module'; +import { isServer } from '@vue-storefront/core/helpers'; +import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import VueGtm from 'vue-gtm'; +import Vue from 'vue'; +import { Logger } from '@vue-storefront/core/lib/logger'; + +const googleTagManagerStore = { namespaced: true, state: { key: null @@ -10,12 +14,110 @@ const store = { } const KEY = 'google-tag-manager' +export const GoogleTagManagerModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + if (appConfig.googleTagManager.id && !isServer) { + Vue.use(VueGtm, { + id: appConfig.googleTagManager.id, + enabled: true, + debug: appConfig.googleTagManager.debug, + vueRouter: router + }); + } else { + Logger.warn('Google Tag Manager extensions is not working. Ensure Google Tag Manager container ID is defined in config', 'GTM')() + } -const moduleConfig: VueStorefrontModuleConfig = { - key: KEY, - store: { modules: [{ key: KEY, module: store }] }, - beforeRegistration, - afterRegistration -} + store.registerModule(KEY, googleTagManagerStore) + + // TODO: needs refactoring, property 'gtm' does not exist on type VueConstructor + // if (appConfig.googleTagManager.id && !isServer) { + // const storeView = currentStoreView() + // const currencyCode = storeView.i18n.currencyCode + + // const getProduct = (item) => { + // const { name, id, sku, priceInclTax: price, category, qty: quantity } = item + // let product = { + // name, + // id, + // sku, + // price + // } + // if (quantity) { + // product['quantity'] = quantity + // } + // if (category && category.length > 0) { + // product['category'] = category.slice(-1)[0].name + // } -export const googleTagManager = new VueStorefrontModule(moduleConfig) + // return product + // } + + // store.subscribe(({ type, payload }, state) => { + // // Adding a Product to a Shopping Cart + // if (type === 'cart/cart/ADD') { + // Vue.gtm.trackEvent({ + // event: 'addToCart', + // ecommerce: { + // currencyCode: currencyCode, + // add: { + // products: [getProduct(payload.product)] + // } + // } + // }); + // } + + // // Removing a Product from a Shopping Cart + // if (type === 'cart/cart/DEL') { + // Vue.gtm.trackEvent({ + // event: 'removeFromCart', + // ecommerce: { + // remove: { + // products: [getProduct(payload.product)] + // } + // } + // }); + // } + + // // Measuring Views of Product Details + // if (type === 'product/product/SET_PRODUCT_CURRENT') { + // Vue.gtm.trackEvent({ + // ecommerce: { + // detail: { + // 'actionField': { 'list': '' }, // 'detail' actions have an optional list property. + // 'products': [getProduct(payload)] + // } + // } + // }); + // } + + // // Measuring Purchases + // if (type === 'order/order/LAST_ORDER_CONFIRMATION') { + // const orderId = payload.confirmation.backendOrderId + // const products = payload.order.products.map(product => getProduct(product)) + // store.dispatch( + // 'user/getOrdersHistory', + // { refresh: true, useCache: false } + // ).then(() => { + // const orderHistory = state.user.orders_history + // const order = orderHistory.items.find((order) => order['entity_id'].toString() === orderId) + // if (order) { + // Vue.gtm.trackEvent({ + // 'ecommerce': { + // 'purchase': { + // 'actionField': { + // 'id': orderId, + // 'affiliation': order.store_name, + // 'revenue': order.total_due, + // 'tax': order.tax_amount, + // 'shipping': order.shipping_amount, + // 'coupon': '' + // }, + // 'products': products + // } + // } + // }) + // } + // }) + // } + // }) + // } +} diff --git a/src/modules/hotjar/hooks/afterRegistration.ts b/src/modules/hotjar/hooks/afterRegistration.ts deleted file mode 100644 index 7d88fa31c3..0000000000 --- a/src/modules/hotjar/hooks/afterRegistration.ts +++ /dev/null @@ -1,19 +0,0 @@ -const hotjarSnippet = (hjid) => (function (h, o, t, j, a, r) { - h.hj = - h.hj || - function () { - (h.hj.q = h.hj.q || []).push(arguments); - }; - h._hjSettings = {hjid, hjsv: 6}; - a = o.getElementsByTagName('head')[0]; - r = o.createElement('script'); - r.async = 1; - r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv; - a.appendChild(r); -})(window as any, document, '//static.hotjar.com/c/hotjar-', '.js?sv='); - -export function afterRegistration ({ Vue, config, store, isServer }) { - if (!isServer && config.hotjar && config.hotjar.id) { - hotjarSnippet(config.hotjar.id); - } -} diff --git a/src/modules/hotjar/index.ts b/src/modules/hotjar/index.ts index 9492527b53..7bf763622c 100644 --- a/src/modules/hotjar/index.ts +++ b/src/modules/hotjar/index.ts @@ -1,15 +1,32 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' +import { StorefrontModule } from '@vue-storefront/module'; +import { isServer } from '@vue-storefront/core/helpers' -const store = { +const hotjarStore = { namespaced: true, state: { key: null } }; + +const hotjarSnippet = (hjid) => (function (h, o, t, j, a, r) { + h.hj = + h.hj || + function () { + (h.hj.q = h.hj.q || []).push(arguments); + }; + h._hjSettings = {hjid, hjsv: 6}; + a = o.getElementsByTagName('head')[0]; + r = o.createElement('script'); + r.async = 1; + r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv; + a.appendChild(r); +})(window as any, document, '//static.hotjar.com/c/hotjar-', '.js?sv='); + const KEY = 'hotjar'; -export const Hotjar = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module: store }] }, - afterRegistration -}); +export const HotjarModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, hotjarStore) + + if (!isServer && appConfig.hotjar && appConfig.hotjar.id) { + hotjarSnippet(appConfig.hotjar.id); + } +} diff --git a/src/modules/index.ts b/src/modules/index.ts index 3556fde1d4..1c8e30fbbd 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -1,26 +1,25 @@ // import { extendModule } from '@vue-storefront/core/lib/module' import { VueStorefrontModule } from '@vue-storefront/core/lib/module' import { CatalogModule } from '@vue-storefront/core/modules/catalog' -import CatalogNext from '@vue-storefront/core/modules/catalog-next' +import { CatalogNextModule } from '@vue-storefront/core/modules/catalog-next' import { CartModule } from '@vue-storefront/core/modules/cart' import { CheckoutModule } from '@vue-storefront/core/modules/checkout' -import { Compare } from '@vue-storefront/core/modules/compare' -import { Review } from '@vue-storefront/core/modules/review' -import { Mailer } from '@vue-storefront/core/modules/mailer' -import { Wishlist } from '@vue-storefront/core/modules/wishlist' -import { Newsletter } from '@vue-storefront/core/modules/newsletter' -import { Notification } from '@vue-storefront/core/modules/notification' -import { RecentlyViewed } from '@vue-storefront/core/modules/recently-viewed' -import { Url } from '@vue-storefront/core/modules/url' -// import { GoogleAnalytics } from './google-analytics'; -// import { Hotjar } from './hotjar'; -import { googleTagManager } from './google-tag-manager'; -import { AmpRenderer } from './amp-renderer'; -import { PaymentBackendMethods } from './payment-backend-methods'; -import { PaymentCashOnDelivery } from './payment-cash-on-delivery'; -import { RawOutputExample } from './raw-output-example' -import { InstantCheckout } from './instant-checkout' - +import { CompareModule } from '@vue-storefront/core/modules/compare' +import { ReviewModule } from '@vue-storefront/core/modules/review' +import { MailerModule } from '@vue-storefront/core/modules/mailer' +import { WishlistModule } from '@vue-storefront/core/modules/wishlist' +import { NewsletterModule } from '@vue-storefront/core/modules/newsletter' +import { NotificationModule } from '@vue-storefront/core/modules/notification' +import { RecentlyViewedModule } from '@vue-storefront/core/modules/recently-viewed' +import { UrlModule } from '@vue-storefront/core/modules/url' +// import { GoogleAnalyticsModule } from './google-analytics'; +// import { HotjarModule } from './hotjar'; +import { GoogleTagManagerModule } from './google-tag-manager'; +import { AmpRendererModule } from './amp-renderer'; +import { PaymentBackendMethodsModule } from './payment-backend-methods'; +import { PaymentCashOnDeliveryModule } from './payment-cash-on-delivery'; +import { RawOutputExampleModule } from './raw-output-example' +import { InstantCheckoutModule } from './instant-checkout' // import { Example } from './module-template' import { registerModule } from '@vue-storefront/module' // TODO:distributed across proper pages BEFORE 1.11 @@ -28,26 +27,26 @@ export function registerNewModules () { registerModule(CatalogModule) registerModule(CheckoutModule) registerModule(CartModule) + registerModule(ReviewModule) + registerModule(MailerModule) + registerModule(WishlistModule) + registerModule(NewsletterModule) + registerModule(NotificationModule) + registerModule(RecentlyViewedModule) + registerModule(GoogleTagManagerModule) + // registerModule(GoogleAnalyticsModule) + // registerModule(HotjarModule) + registerModule(PaymentBackendMethodsModule) + registerModule(PaymentCashOnDeliveryModule) + registerModule(RawOutputExampleModule) + registerModule(AmpRendererModule) + registerModule(InstantCheckoutModule) + registerModule(UrlModule) + registerModule(CatalogNextModule) + registerModule(CompareModule) } // Deprecated API, will be removed in 2.0 export const registerModules: VueStorefrontModule[] = [ - Compare, - Review, - Mailer, - Wishlist, - Newsletter, - Notification, - RecentlyViewed, - googleTagManager, - // GoogleAnalytics, - // Hotjar, - PaymentBackendMethods, - PaymentCashOnDelivery, - RawOutputExample, - AmpRenderer, - InstantCheckout, - Url, - CatalogNext // Example ] diff --git a/src/modules/instant-checkout/index.ts b/src/modules/instant-checkout/index.ts index d83cc72fa1..bd776a6415 100644 --- a/src/modules/instant-checkout/index.ts +++ b/src/modules/instant-checkout/index.ts @@ -1,9 +1,4 @@ -import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module' +import { StorefrontModule } from '@vue-storefront/module'; -const KEY = 'instant-checkout' - -const moduleConfig: VueStorefrontModuleConfig = { - key: KEY +export const InstantCheckoutModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { } - -export const InstantCheckout = new VueStorefrontModule(moduleConfig) diff --git a/src/modules/payment-backend-methods/hooks/afterRegistration.ts b/src/modules/payment-backend-methods/hooks/afterRegistration.ts deleted file mode 100644 index 077704ae28..0000000000 --- a/src/modules/payment-backend-methods/hooks/afterRegistration.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as types from './../store/mutation-types' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' - -export function afterRegistration ({ Vue, config, store, isServer }) { - let correctPaymentMethod = false - - // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' - const placeOrder = () => { - if (correctPaymentMethod) { - EventBus.$emit('checkout-do-placeOrder', {}) - } - } - - if (!isServer) { - // Update the methods - EventBus.$on('set-unique-payment-methods', methods => { - store.commit('payment-backend-methods/' + types.SET_BACKEND_PAYMENT_METHODS, methods) - }) - - EventBus.$on('checkout-before-placeOrder', placeOrder) - - // Mount the info component when required - EventBus.$on('checkout-payment-method-changed', (paymentMethodCode) => { - let methods = store.state['payment-backend-methods'].methods - if (methods !== null && methods.find(item => (item.code === paymentMethodCode && item.is_server_method === true))) { - correctPaymentMethod = true - } else { - correctPaymentMethod = false - } - }) - } -} diff --git a/src/modules/payment-backend-methods/index.ts b/src/modules/payment-backend-methods/index.ts index c9fcb923ab..81f2983a19 100644 --- a/src/modules/payment-backend-methods/index.ts +++ b/src/modules/payment-backend-methods/index.ts @@ -1,8 +1,9 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' import * as types from './store/mutation-types' +import { StorefrontModule } from '@vue-storefront/module'; +import { isServer } from '@vue-storefront/core/helpers' +import Vue from 'vue'; -const store = { +const PaymentBackendMethodsStore = { namespaced: true, state: { methods: null @@ -15,8 +16,34 @@ const store = { } const KEY = 'payment-backend-methods' -export const PaymentBackendMethods = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module: store }] }, - afterRegistration -}) +export const PaymentBackendMethodsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule(KEY, PaymentBackendMethodsStore) + + let correctPaymentMethod = false + + // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' + const placeOrder = () => { + if (correctPaymentMethod) { + Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + } + } + + if (!isServer) { + // Update the methods + Vue.prototype.$bus.$on('set-unique-payment-methods', methods => { + store.commit('payment-backend-methods/' + types.SET_BACKEND_PAYMENT_METHODS, methods) + }) + + Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + + // Mount the info component when required + Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { + let methods = store.state['payment-backend-methods'].methods + if (methods !== null && methods.find(item => (item.code === paymentMethodCode && item.is_server_method === true))) { + correctPaymentMethod = true + } else { + correctPaymentMethod = false + } + }) + } +} diff --git a/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts b/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts deleted file mode 100644 index d5a479241a..0000000000 --- a/src/modules/payment-cash-on-delivery/hooks/afterRegistration.ts +++ /dev/null @@ -1,47 +0,0 @@ -import InfoComponent from '../components/Info.vue' -import rootStore from '@vue-storefront/core/store' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' - -export function afterRegistration ({ Vue, config, store, isServer }) { - // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' - let correctPaymentMethod = false - const placeOrder = () => { - if (correctPaymentMethod) { - EventBus.$emit('checkout-do-placeOrder', {}) - } - } - - if (!isServer) { - // Update the methods - let paymentMethodConfig = { - 'title': 'Cash on delivery', - 'code': 'cashondelivery', - 'cost': 0, - 'cost_incl_tax': 0, - 'default': true, - 'offline': true, - 'is_server_method': false - } - rootStore.dispatch('payment/addMethod', paymentMethodConfig) - - EventBus.$on('checkout-before-placeOrder', placeOrder) - - // Mount the info component when required. - EventBus.$on('checkout-payment-method-changed', (paymentMethodCode) => { - let methods = store.state['payment-backend-methods'].methods - if (methods) { - let method = methods.find(item => (item.code === paymentMethodCode)) - if (paymentMethodCode === 'cashondelivery' && ((typeof method !== 'undefined' && !method.is_server_method) || typeof method === 'undefined') /* otherwise it could be a `payment-backend-methods` module */) { - correctPaymentMethod = true - - // Dynamically inject a component into the order review section (optional) - const Component = Vue.extend(InfoComponent) - const componentInstance = (new Component()) - componentInstance.$mount('#checkout-order-review-additional') - } else { - correctPaymentMethod = false - } - } - }) - } -} diff --git a/src/modules/payment-cash-on-delivery/index.ts b/src/modules/payment-cash-on-delivery/index.ts index 1188d12867..72aea80caf 100644 --- a/src/modules/payment-cash-on-delivery/index.ts +++ b/src/modules/payment-cash-on-delivery/index.ts @@ -1,8 +1,48 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' - -const KEY = 'payment-cash-on-delivery' -export const PaymentCashOnDelivery = createModule({ - key: KEY, - afterRegistration -}) +import { StorefrontModule } from '@vue-storefront/module'; +import { isServer } from '@vue-storefront/core/helpers' +import Vue from 'vue'; +import InfoComponent from './components/Info.vue' + +export const PaymentCashOnDeliveryModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' + let correctPaymentMethod = false + const placeOrder = () => { + if (correctPaymentMethod) { + Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + } + } + + if (!isServer) { + // Update the methods + let paymentMethodConfig = { + 'title': 'Cash on delivery', + 'code': 'cashondelivery', + 'cost': 0, + 'costInclTax': 0, + 'default': true, + 'offline': true, + 'is_server_method': false + } + store.dispatch('payment/addMethod', paymentMethodConfig) + + Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + + // Mount the info component when required. + Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { + let methods = store.state['payment-backend-methods'].methods + if (methods) { + let method = methods.find(item => (item.code === paymentMethodCode)) + if (paymentMethodCode === 'cashondelivery' && ((typeof method !== 'undefined' && !method.is_server_method) || typeof method === 'undefined') /* otherwise it could be a `payment-backend-methods` module */) { + correctPaymentMethod = true + + // Dynamically inject a component into the order review section (optional) + const Component = Vue.extend(InfoComponent) + const componentInstance = (new Component()) + componentInstance.$mount('#checkout-order-review-additional') + } else { + correctPaymentMethod = false + } + } + }) + } +} diff --git a/src/modules/raw-output-example/index.ts b/src/modules/raw-output-example/index.ts index 62dc30c83c..ed8a2ad261 100644 --- a/src/modules/raw-output-example/index.ts +++ b/src/modules/raw-output-example/index.ts @@ -1,8 +1,6 @@ -import { createModule } from '@vue-storefront/core/lib/module' import { routes } from './router/routes' +import { StorefrontModule } from '@vue-storefront/module'; -const KEY = 'raw-output-example' -export const RawOutputExample = createModule({ - key: KEY, - router: { routes } -}) +export const RawOutputExampleModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + router.addRoutes(routes); +} From c1f31ec6e6584b7eeb80e9a69261d02e0e5dfe2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=BB=C4=85d=C5=82owski?= Date: Fri, 12 Jul 2019 14:31:08 +0200 Subject: [PATCH 02/27] CR fixes. --- core/modules/catalog-next/index.ts | 5 ++--- core/modules/catalog-next/store/category/index.ts | 2 +- core/modules/mailer/index.ts | 3 +-- core/modules/newsletter/index.ts | 5 ++--- core/modules/notification/index.ts | 3 +-- core/modules/recently-viewed/index.ts | 5 ++--- core/modules/review/index.ts | 3 +-- core/modules/wishlist/index.ts | 5 ++--- src/modules/amp-renderer/index.ts | 3 +-- src/modules/google-analytics/index.ts | 3 +-- src/modules/google-tag-manager/index.ts | 3 +-- src/modules/hotjar/index.ts | 3 +-- src/modules/payment-backend-methods/index.ts | 3 +-- 13 files changed, 17 insertions(+), 29 deletions(-) diff --git a/core/modules/catalog-next/index.ts b/core/modules/catalog-next/index.ts index af2dc74668..932e48e578 100644 --- a/core/modules/catalog-next/index.ts +++ b/core/modules/catalog-next/index.ts @@ -1,7 +1,6 @@ -import { categoryNextStore } from './store/category' +import { categoryModule } from './store/category' import { StorefrontModule } from '@vue-storefront/module'; -export const KEY = 'catalog-next' export const CatalogNextModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, categoryNextStore) + store.registerModule('catalog-next', categoryModule) } diff --git a/core/modules/catalog-next/store/category/index.ts b/core/modules/catalog-next/store/category/index.ts index e7630932e9..0c19d65082 100644 --- a/core/modules/catalog-next/store/category/index.ts +++ b/core/modules/catalog-next/store/category/index.ts @@ -5,7 +5,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import CategoryState from './CategoryState' -export const categoryNextStore: Module = { +export const categoryModule: Module = { namespaced: true, state: { categoriesMap: {}, diff --git a/core/modules/mailer/index.ts b/core/modules/mailer/index.ts index 5aea6d6382..96dfe1aedd 100644 --- a/core/modules/mailer/index.ts +++ b/core/modules/mailer/index.ts @@ -1,7 +1,6 @@ import { StorefrontModule } from '@vue-storefront/module' import { mailerStore } from './store' -const KEY = 'mailer' export const MailerModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, mailerStore) + store.registerModule('mailer', mailerStore) } diff --git a/core/modules/newsletter/index.ts b/core/modules/newsletter/index.ts index f2d9320ee3..c0ad9d923b 100644 --- a/core/modules/newsletter/index.ts +++ b/core/modules/newsletter/index.ts @@ -2,8 +2,7 @@ import { newsletterStore } from './store' import { StorefrontModule } from '@vue-storefront/module'; import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -const KEY = 'newsletter' -export const cacheStorage = initCacheStorage(KEY) +export const cacheStorage = initCacheStorage('newsletter') export const NewsletterModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, newsletterStore) + store.registerModule('newsletter', newsletterStore) } diff --git a/core/modules/notification/index.ts b/core/modules/notification/index.ts index 8f205daec9..71b01ab708 100644 --- a/core/modules/notification/index.ts +++ b/core/modules/notification/index.ts @@ -1,7 +1,6 @@ import { notificationStore } from './store' import { StorefrontModule } from '@vue-storefront/module'; -const KEY = 'notification' export const NotificationModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, notificationStore) + store.registerModule('notification', notificationStore) } diff --git a/core/modules/recently-viewed/index.ts b/core/modules/recently-viewed/index.ts index 4bf8043683..658de45c1e 100644 --- a/core/modules/recently-viewed/index.ts +++ b/core/modules/recently-viewed/index.ts @@ -4,10 +4,9 @@ import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' import { StorefrontModule } from '@vue-storefront/module'; import { isServer } from '@vue-storefront/core/helpers' -const KEY = 'recently-viewed' -export const cacheStorage = initCacheStorage(KEY) +export const cacheStorage = initCacheStorage('recently-viewed') export const RecentlyViewedModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, recentlyViewedStore) + store.registerModule('recently-viewed', recentlyViewedStore) store.subscribe(plugin) if (!isServer) store.dispatch('recently-viewed/load') diff --git a/core/modules/review/index.ts b/core/modules/review/index.ts index e1e207ea4e..ca9e00afc3 100644 --- a/core/modules/review/index.ts +++ b/core/modules/review/index.ts @@ -1,7 +1,6 @@ import { StorefrontModule } from '@vue-storefront/module' import { reviewStore } from './store' -const KEY = 'review' export const ReviewModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, reviewStore) + store.registerModule('review', reviewStore) } diff --git a/core/modules/wishlist/index.ts b/core/modules/wishlist/index.ts index 4ab7b24cf1..743fc147a5 100644 --- a/core/modules/wishlist/index.ts +++ b/core/modules/wishlist/index.ts @@ -3,9 +3,8 @@ import { wishlistStore } from './store' import { plugin } from './store/plugin' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' -const KEY = 'wishlist' -export const cacheStorage = initCacheStorage(KEY) +export const cacheStorage = initCacheStorage('wishlist') export const WishlistModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, wishlistStore) + store.registerModule('wishlist', wishlistStore) store.subscribe(plugin) } diff --git a/src/modules/amp-renderer/index.ts b/src/modules/amp-renderer/index.ts index 202624f384..2d1ab8ad8f 100644 --- a/src/modules/amp-renderer/index.ts +++ b/src/modules/amp-renderer/index.ts @@ -8,8 +8,7 @@ const ampRendererStore = { } } -const KEY = 'amp-renderer' export const AmpRendererModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, ampRendererStore) + store.registerModule('amp-renderer', ampRendererStore) router.addRoutes(moduleRoutes) } diff --git a/src/modules/google-analytics/index.ts b/src/modules/google-analytics/index.ts index 293004d11f..4380935f6f 100644 --- a/src/modules/google-analytics/index.ts +++ b/src/modules/google-analytics/index.ts @@ -11,7 +11,6 @@ const googleAnalyticsStore = { } } -const KEY = 'google-analytics' export const GoogleAnalyticsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { if (appConfig.analytics.id && !isServer) { once('__VUE_EXTEND_ANALYTICS__', () => { @@ -30,7 +29,7 @@ export const GoogleAnalyticsModule: StorefrontModule = function (app, store, rou )() } - store.registerModule(KEY, googleAnalyticsStore) + store.registerModule('google-analytics', googleAnalyticsStore) if (appConfig.analytics.id && !isServer) { Vue.prototype.$bus.$on('order-after-placed', event => { diff --git a/src/modules/google-tag-manager/index.ts b/src/modules/google-tag-manager/index.ts index 3b5cf24eb2..67b2b6c24b 100644 --- a/src/modules/google-tag-manager/index.ts +++ b/src/modules/google-tag-manager/index.ts @@ -13,7 +13,6 @@ const googleTagManagerStore = { } } -const KEY = 'google-tag-manager' export const GoogleTagManagerModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { if (appConfig.googleTagManager.id && !isServer) { Vue.use(VueGtm, { @@ -26,7 +25,7 @@ export const GoogleTagManagerModule: StorefrontModule = function (app, store, ro Logger.warn('Google Tag Manager extensions is not working. Ensure Google Tag Manager container ID is defined in config', 'GTM')() } - store.registerModule(KEY, googleTagManagerStore) + store.registerModule('google-tag-manager', googleTagManagerStore) // TODO: needs refactoring, property 'gtm' does not exist on type VueConstructor // if (appConfig.googleTagManager.id && !isServer) { diff --git a/src/modules/hotjar/index.ts b/src/modules/hotjar/index.ts index 7bf763622c..ae0ab230d9 100644 --- a/src/modules/hotjar/index.ts +++ b/src/modules/hotjar/index.ts @@ -22,9 +22,8 @@ const hotjarSnippet = (hjid) => (function (h, o, t, j, a, r) { a.appendChild(r); })(window as any, document, '//static.hotjar.com/c/hotjar-', '.js?sv='); -const KEY = 'hotjar'; export const HotjarModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, hotjarStore) + store.registerModule('hotjar', hotjarStore) if (!isServer && appConfig.hotjar && appConfig.hotjar.id) { hotjarSnippet(appConfig.hotjar.id); diff --git a/src/modules/payment-backend-methods/index.ts b/src/modules/payment-backend-methods/index.ts index 81f2983a19..62d132b844 100644 --- a/src/modules/payment-backend-methods/index.ts +++ b/src/modules/payment-backend-methods/index.ts @@ -15,9 +15,8 @@ const PaymentBackendMethodsStore = { } } -const KEY = 'payment-backend-methods' export const PaymentBackendMethodsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, PaymentBackendMethodsStore) + store.registerModule('payment-backend-methods', PaymentBackendMethodsStore) let correctPaymentMethod = false From 32113358454185ae13b18ba3965ccebfae522a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=BB=C4=85d=C5=82owski?= Date: Fri, 12 Jul 2019 14:51:11 +0200 Subject: [PATCH 03/27] cr fixes --- core/modules/compare/index.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/core/modules/compare/index.ts b/core/modules/compare/index.ts index 75cf61c2d6..3640acbb71 100644 --- a/core/modules/compare/index.ts +++ b/core/modules/compare/index.ts @@ -1,14 +1,27 @@ + import { compareStore } from './store' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; import { plugin } from './store/plugin' import { StorefrontModule } from '@vue-storefront/module'; -import Vue from 'vue'; +// import * as localForage from 'localforage' +// import UniversalStorage from '@vue-storefront/core/store/lib/storage' +// import { currentStoreView } from '@vue-storefront/core/lib/multistore' +// import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -const KEY = 'compare' -export const cacheStorage = initCacheStorage(KEY) +export const cacheStorage = initCacheStorage('compare') export const CompareModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - Vue.prototype.$db.cartsCollection = initCacheStorage('compare') + // Vue.prototype.$db.compareCollection = initCacheStorage('compare') + // const storeView = currentStoreView() + // const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' + + // StorageManager.set('compareCollection', new UniversalStorage(localForage.createInstance({ + // name: dbNamePrefix + 'shop', + // storeName: 'compare', + // driver: localForage[appConfig.localForage.defaultDrivers['compare']] + // }))) + + initCacheStorage('compare') - store.registerModule(KEY, compareStore) + store.registerModule('compare', compareStore) store.subscribe(plugin) -} +} \ No newline at end of file From 59a24daa5c9b6b707f77916e98f6ed827de526f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=BB=C4=85d=C5=82owski?= Date: Fri, 12 Jul 2019 14:51:36 +0200 Subject: [PATCH 04/27] cr fixes --- core/modules/compare/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/compare/index.ts b/core/modules/compare/index.ts index 3640acbb71..f3dd3f874e 100644 --- a/core/modules/compare/index.ts +++ b/core/modules/compare/index.ts @@ -24,4 +24,4 @@ export const CompareModule: StorefrontModule = function (app, store, router, mod store.registerModule('compare', compareStore) store.subscribe(plugin) -} \ No newline at end of file +} From b517a820c0a76f598e8a01424c02ede74ca18a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=BB=C4=85d=C5=82owski?= Date: Mon, 15 Jul 2019 10:02:50 +0200 Subject: [PATCH 05/27] Fixed wrong key in catalog-next module. --- core/modules/catalog-next/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/catalog-next/index.ts b/core/modules/catalog-next/index.ts index 932e48e578..6edebe18e5 100644 --- a/core/modules/catalog-next/index.ts +++ b/core/modules/catalog-next/index.ts @@ -2,5 +2,5 @@ import { categoryModule } from './store/category' import { StorefrontModule } from '@vue-storefront/module'; export const CatalogNextModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule('catalog-next', categoryModule) + store.registerModule('category-next', categoryModule) } From 569af748b20e56b713a02eacdd447690758ba27d Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Mon, 15 Jul 2019 14:14:33 +0200 Subject: [PATCH 06/27] update storage --- config/default.json | 2 +- core/helpers/initCacheStorage.ts | 13 ++++++---- core/lib/sync/index.ts | 4 +-- core/lib/sync/task.ts | 8 ++---- core/modules/cart/helpers/cartCacheHandler.ts | 6 ++--- core/modules/cart/index.ts | 4 +-- core/modules/cart/store/actions.ts | 6 ++--- .../unit/helpers/cartCacheHandler.spec.ts | 16 ++++++------ core/modules/catalog/index.ts | 21 +++------------- core/modules/checkout/index.ts | 9 +++---- .../checkout/store/checkout/actions.ts | 6 ++--- core/modules/compare/index.ts | 21 +++------------- core/modules/newsletter/index.ts | 5 ++-- core/modules/recently-viewed/index.ts | 5 ++-- core/modules/url/index.ts | 8 +++--- core/modules/user/index.ts | 1 + core/modules/wishlist/index.ts | 5 ++-- core/pages/Checkout.js | 2 +- core/store/lib/storage-manager.ts | 25 ++++++++++++++----- docs/guide/basics/configuration.md | 2 +- 20 files changed, 78 insertions(+), 91 deletions(-) diff --git a/config/default.json b/config/default.json index f8a9884064..c68d4932ce 100644 --- a/config/default.json +++ b/config/default.json @@ -347,7 +347,7 @@ "claims": "LOCALSTORAGE", "syncTasks": "LOCALSTORAGE", "ordersHistory": "LOCALSTORAGE", - "checkoutFieldValues": "LOCALSTORAGE" + "checkout": "LOCALSTORAGE" } }, "reviews": { diff --git a/core/helpers/initCacheStorage.ts b/core/helpers/initCacheStorage.ts index 21fcd87fc4..e240c8a5b3 100644 --- a/core/helpers/initCacheStorage.ts +++ b/core/helpers/initCacheStorage.ts @@ -4,7 +4,8 @@ import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' import { currentStoreView } from '@vue-storefront/core/lib/multistore' import config from 'config' -function _prepareCachestorage (key, localised = true) { +/** create Universal Storage instance */ +export function prepareCacheStorage (key, localised = true, storageQuota = 0) { const storeView = currentStoreView() const dbNamePrefix = storeView && storeView.storeCode ? storeView.storeCode + '-' : '' const cacheDriver = config.localForage && config.localForage.defaultDrivers[key] @@ -15,18 +16,20 @@ function _prepareCachestorage (key, localised = true) { name: localised ? `${dbNamePrefix}shop` : 'shop', storeName: key, driver: localForage[cacheDriver] - })) + }), true, storageQuota) } -/** Inits cache storage for given module. By default via local storage */ +/** @deprecated, to be removed in 2.0 in favor to `StorageManager` + * Inits cache storage for given module. By default via local storage + * */ export function initCacheStorage (key, localised = true, registerStorgeManager = true) { if (registerStorgeManager) { if (!StorageManager.exists(key)) { - return StorageManager.set(key, _prepareCachestorage(key, localised)) + return StorageManager.set(key, prepareCacheStorage(key, localised)) } else { return StorageManager.get(key) } } else { - return _prepareCachestorage(key, localised) + return prepareCacheStorage(key, localised) } } diff --git a/core/lib/sync/index.ts b/core/lib/sync/index.ts index 9407422965..0118867a8b 100644 --- a/core/lib/sync/index.ts +++ b/core/lib/sync/index.ts @@ -11,7 +11,7 @@ import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' /** Syncs given task. If user is offline requiest will be sent to the server after restored connection */ async function queue (task) { - const tasksCollection = StorageManager.get('syncTaskCollection') + const tasksCollection = StorageManager.get('syncTasks') task = _prepareTask(task) Logger.info('Sync task queued ' + task.url, 'sync', { task })() return new Promise((resolve, reject) => { @@ -50,7 +50,7 @@ async function execute (task): Promise { // not offline task /** Clear sync tasks that were not transmitted yet */ function clearNotTransmited () { - const syncTaskCollection = StorageManager.get('syncTaskCollection') + const syncTaskCollection = StorageManager.get('syncTasks') syncTaskCollection.iterate((task, id, iterationNumber) => { if (!task.transmited) { syncTaskCollection.removeItem(id) diff --git a/core/lib/sync/task.ts b/core/lib/sync/task.ts index a4a2adcc21..bf18da872f 100644 --- a/core/lib/sync/task.ts +++ b/core/lib/sync/task.ts @@ -180,11 +180,7 @@ export function initializeSyncTaskStorage () { const storeView = currentStoreView() const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - StorageManager.set('syncTaskCollection', new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'syncTasks', - driver: localForage[config.localForage.defaultDrivers['syncTasks']] - }))) + StorageManager.init('syncTasks') } export function registerSyncTaskProcessor () { @@ -192,7 +188,7 @@ export function registerSyncTaskProcessor () { EventBus.$on('sync/PROCESS_QUEUE', async data => { if (onlineHelper.isOnline) { // event.data.config - configuration, endpoints etc - const syncTaskCollection = StorageManager.get('syncTaskCollection') + const syncTaskCollection = StorageManager.get('syncTasks') const currentUserToken = rootStore.getters['user/getUserToken'] const currentCartToken = rootStore.getters['cart/getCartToken'] diff --git a/core/modules/cart/helpers/cartCacheHandler.ts b/core/modules/cart/helpers/cartCacheHandler.ts index 7d9fabe602..c3bfbf0f8b 100644 --- a/core/modules/cart/helpers/cartCacheHandler.ts +++ b/core/modules/cart/helpers/cartCacheHandler.ts @@ -14,19 +14,19 @@ export function cartCacheHandlerFactory (Vue) { type.endsWith(types.CART_DEL_NON_CONFIRMED_ITEM) || type.endsWith(types.CART_UPD_ITEM_PROPS) ) { - return StorageManager.get('cartsCollection').setItem('current-cart', state.cart.cartItems).catch((reason) => { + return StorageManager.get('cart').setItem('current-cart', state.cart.cartItems).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } else if ( type.endsWith(types.CART_LOAD_CART_SERVER_TOKEN) ) { - return StorageManager.get('cartsCollection').setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => { + return StorageManager.get('cart').setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => { console.error(reason) }) } else if ( type.endsWith(types.CART_SET_ITEMS_HASH) ) { - return StorageManager.get('cartsCollection').setItem('current-cart-hash', state.cart.cartItemsHash).catch((reason) => { + return StorageManager.get('cart').setItem('current-cart-hash', state.cart.cartItemsHash).catch((reason) => { console.error(reason) }) } diff --git a/core/modules/cart/index.ts b/core/modules/cart/index.ts index 1856c31f9a..b6e46db0b9 100644 --- a/core/modules/cart/index.ts +++ b/core/modules/cart/index.ts @@ -3,10 +3,10 @@ import { cartStore } from './store' import { cartCacheHandlerFactory } from './helpers/cartCacheHandler'; import { isServer } from '@vue-storefront/core/helpers' import Vue from 'vue' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export const CartModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - initCacheStorage('carts') + StorageManager.init('cart') store.registerModule('cart', cartStore) diff --git a/core/modules/cart/store/actions.ts b/core/modules/cart/store/actions.ts index 1e61de2f54..b65615301c 100644 --- a/core/modules/cart/store/actions.ts +++ b/core/modules/cart/store/actions.ts @@ -241,11 +241,11 @@ const actions: ActionTree = { let paymentMethod = rootGetters['payment/paymentMethods'].find(item => item.default) commit(types.CART_UPD_PAYMENT, paymentMethod) } - const storedItems = await StorageManager.get('cartsCollection').getItem('current-cart') + const storedItems = await StorageManager.get('cart').getItem('current-cart') commit(types.CART_LOAD_CART, storedItems) if (config.cart.synchronize) { - const token = await StorageManager.get('cartsCollection').getItem('current-cart-token') - const hash = await StorageManager.get('cartsCollection').getItem('current-cart-hash') + const token = await StorageManager.get('cart').getItem('current-cart-token') + const hash = await StorageManager.get('cart').getItem('current-cart-hash') if (hash) { commit(types.CART_SET_ITEMS_HASH, hash) Logger.info('Cart hash received from cache.', 'cache', hash)() diff --git a/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts b/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts index 1ce9a8571c..5088358090 100644 --- a/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts +++ b/core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts @@ -4,7 +4,7 @@ import Vuex from 'vuex' import * as types from '../../../store/mutation-types' const StorageManager = { - cartsCollection: { + cart: { setItem: jest.fn() }, get (key) { @@ -40,11 +40,11 @@ describe('Cart afterRegistration', () => { } }; - StorageManager.get('cartsCollection').setItem.mockImplementationOnce(() => Promise.resolve('foo')); + StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.resolve('foo')); await cartCacheHandlerFactory(Vue)({ type: mutationType }, stateMock); - expect(StorageManager.get('cartsCollection').setItem) + expect(StorageManager.get('cart').setItem) .toBeCalledWith('current-cart', stateMock.cart.cartItems); }); @@ -57,7 +57,7 @@ describe('Cart afterRegistration', () => { const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {}); - StorageManager.get('cartsCollection').setItem.mockImplementationOnce(() => Promise.reject('foo')); + StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo')); await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART }, stateMock); @@ -71,11 +71,11 @@ describe('Cart afterRegistration', () => { } }; - StorageManager.get('cartsCollection').setItem.mockImplementationOnce(() => Promise.resolve('foo')); + StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.resolve('foo')); await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART_SERVER_TOKEN }, stateMock); - expect(StorageManager.get('cartsCollection').setItem) + expect(StorageManager.get('cart').setItem) .toBeCalledWith('current-cart-token', stateMock.cart.cartServerToken); }); @@ -88,7 +88,7 @@ describe('Cart afterRegistration', () => { const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {}); - StorageManager.get('cartsCollection').setItem.mockImplementationOnce(() => Promise.reject('foo')); + StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo')); await cartCacheHandlerFactory(Vue)({ type: types.CART_LOAD_CART_SERVER_TOKEN }, stateMock); @@ -104,7 +104,7 @@ describe('Cart afterRegistration', () => { const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {}); - StorageManager.get('cartsCollection').setItem.mockImplementationOnce(() => Promise.reject('foo')); + StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo')); await cartCacheHandlerFactory(Vue)({ type: 'bar' }, stateMock); diff --git a/core/modules/catalog/index.ts b/core/modules/catalog/index.ts index fd9a93b3ce..3c4c7b6d4e 100644 --- a/core/modules/catalog/index.ts +++ b/core/modules/catalog/index.ts @@ -4,26 +4,13 @@ import { attributeModule } from './store/attribute' import { stockModule } from './store/stock' import { taxModule } from './store/tax' import { categoryModule } from './store/category' -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import Vue from 'vue' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export const CatalogModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - - initCacheStorage('categories') - initCacheStorage('attributes') - initCacheStorage('products') - - StorageManager.set('elasticCacheCollection', new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'elasticCache', - driver: localForage[appConfig.localForage.defaultDrivers['elasticCache']] - }), true, appConfig.server.elasticCacheQuota)) + StorageManager.init('categories') + StorageManager.init('attributes') + StorageManager.init('products') + StorageManager.init('elasticCacheCollection', true, appConfig.server.elasticCacheQuota) store.registerModule('product', productModule) store.registerModule('attribute', attributeModule) diff --git a/core/modules/checkout/index.ts b/core/modules/checkout/index.ts index 7ddd6a5a1c..dac1b8b619 100644 --- a/core/modules/checkout/index.ts +++ b/core/modules/checkout/index.ts @@ -3,11 +3,10 @@ import { checkoutModule } from './store/checkout' import { paymentModule } from './store/payment' import { shippingModule } from './store/shipping' import * as types from './store/checkout/mutation-types' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export const CheckoutModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - initCacheStorage('checkoutFieldValues') + StorageManager.init('checkout') store.registerModule('shipping', shippingModule) store.registerModule('payment', paymentModule) @@ -19,7 +18,7 @@ export const CheckoutModule: StorefrontModule = function (app, store, router, mo if ( type.endsWith(types.CHECKOUT_SAVE_PERSONAL_DETAILS) ) { - StorageManager.get('checkoutFieldsCollection').setItem('personal-details', state.checkout.personalDetails).catch((reason) => { + StorageManager.get('checkout').setItem('personal-details', state.checkout.personalDetails).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } @@ -27,7 +26,7 @@ export const CheckoutModule: StorefrontModule = function (app, store, router, mo if ( type.endsWith(types.CHECKOUT_SAVE_SHIPPING_DETAILS) ) { - StorageManager.get('checkoutFieldsCollection').setItem('shipping-details', state.checkout.shippingDetails).catch((reason) => { + StorageManager.get('checkout').setItem('shipping-details', state.checkout.shippingDetails).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } @@ -35,7 +34,7 @@ export const CheckoutModule: StorefrontModule = function (app, store, router, mo if ( type.endsWith(types.CHECKOUT_SAVE_PAYMENT_DETAILS) ) { - StorageManager.get('checkoutFieldsCollection').setItem('payment-details', state.checkout.paymentDetails).catch((reason) => { + StorageManager.get('checkout').setItem('payment-details', state.checkout.paymentDetails).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } diff --git a/core/modules/checkout/store/checkout/actions.ts b/core/modules/checkout/store/checkout/actions.ts index 2c90bb3fdf..7b407b399c 100644 --- a/core/modules/checkout/store/checkout/actions.ts +++ b/core/modules/checkout/store/checkout/actions.ts @@ -41,19 +41,19 @@ const actions: ActionTree = { commit(types.CHECKOUT_SAVE_PAYMENT_DETAILS, paymentDetails) }, load ({ commit }) { - StorageManager.get('checkoutFieldsCollection').getItem('personal-details', (err, details) => { + StorageManager.get('checkout').getItem('personal-details', (err, details) => { if (err) throw new Error(err) if (details) { commit(types.CHECKOUT_LOAD_PERSONAL_DETAILS, details) } }) - StorageManager.get('checkoutFieldsCollection').getItem('shipping-details', (err, details) => { + StorageManager.get('checkout').getItem('shipping-details', (err, details) => { if (err) throw new Error(err) if (details) { commit(types.CHECKOUT_LOAD_SHIPPING_DETAILS, details) } }) - StorageManager.get('checkoutFieldsCollection').getItem('payment-details', (err, details) => { + StorageManager.get('checkout').getItem('payment-details', (err, details) => { if (err) throw new Error(err) if (details) { commit(types.CHECKOUT_LOAD_PAYMENT_DETAILS, details) diff --git a/core/modules/compare/index.ts b/core/modules/compare/index.ts index f3dd3f874e..23a383a39c 100644 --- a/core/modules/compare/index.ts +++ b/core/modules/compare/index.ts @@ -1,27 +1,12 @@ import { compareStore } from './store' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; import { plugin } from './store/plugin' import { StorefrontModule } from '@vue-storefront/module'; -// import * as localForage from 'localforage' -// import UniversalStorage from '@vue-storefront/core/store/lib/storage' -// import { currentStoreView } from '@vue-storefront/core/lib/multistore' -// import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -export const cacheStorage = initCacheStorage('compare') -export const CompareModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - // Vue.prototype.$db.compareCollection = initCacheStorage('compare') - // const storeView = currentStoreView() - // const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - - // StorageManager.set('compareCollection', new UniversalStorage(localForage.createInstance({ - // name: dbNamePrefix + 'shop', - // storeName: 'compare', - // driver: localForage[appConfig.localForage.defaultDrivers['compare']] - // }))) - - initCacheStorage('compare') +export const cacheStorage = StorageManager.init('compare') +export const CompareModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { store.registerModule('compare', compareStore) store.subscribe(plugin) } diff --git a/core/modules/newsletter/index.ts b/core/modules/newsletter/index.ts index c0ad9d923b..e30df64e27 100644 --- a/core/modules/newsletter/index.ts +++ b/core/modules/newsletter/index.ts @@ -1,8 +1,9 @@ import { newsletterStore } from './store' import { StorefrontModule } from '@vue-storefront/module'; -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' + +export const cacheStorage = StorageManager.init('newsletter') -export const cacheStorage = initCacheStorage('newsletter') export const NewsletterModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { store.registerModule('newsletter', newsletterStore) } diff --git a/core/modules/recently-viewed/index.ts b/core/modules/recently-viewed/index.ts index 658de45c1e..60b54498c2 100644 --- a/core/modules/recently-viewed/index.ts +++ b/core/modules/recently-viewed/index.ts @@ -1,10 +1,11 @@ import { recentlyViewedStore } from './store' import { plugin } from './store/plugin' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' import { StorefrontModule } from '@vue-storefront/module'; import { isServer } from '@vue-storefront/core/helpers' -export const cacheStorage = initCacheStorage('recently-viewed') +export const cacheStorage = StorageManager.init('recently-viewed') + export const RecentlyViewedModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { store.registerModule('recently-viewed', recentlyViewedStore) store.subscribe(plugin) diff --git a/core/modules/url/index.ts b/core/modules/url/index.ts index 30a5d77607..c9a76353be 100644 --- a/core/modules/url/index.ts +++ b/core/modules/url/index.ts @@ -1,11 +1,11 @@ import { urlStore } from './store' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' import { StorefrontModule } from '@vue-storefront/module' import { beforeEachGuard } from './router/beforeEach' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' + +export const cacheStorage = StorageManager.init('url') -export const KEY = 'url' -export const cacheStorage = initCacheStorage(KEY) export const UrlModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - store.registerModule(KEY, urlStore) + store.registerModule('url', urlStore) router.beforeEach(beforeEachGuard) } diff --git a/core/modules/user/index.ts b/core/modules/user/index.ts index 4e75e98d25..ea5f0ba79f 100644 --- a/core/modules/user/index.ts +++ b/core/modules/user/index.ts @@ -5,6 +5,7 @@ import { beforeRegistration } from './hooks/beforeRegistration' import { afterRegistration } from './hooks/afterRegistration' export const KEY = 'user' + export const User = createModule({ key: KEY, store: { modules: [{ key: KEY, module }] }, diff --git a/core/modules/wishlist/index.ts b/core/modules/wishlist/index.ts index 743fc147a5..20bf31075a 100644 --- a/core/modules/wishlist/index.ts +++ b/core/modules/wishlist/index.ts @@ -1,9 +1,10 @@ import { StorefrontModule } from '@vue-storefront/module' import { wishlistStore } from './store' import { plugin } from './store/plugin' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' + +export const cacheStorage = StorageManager.init('wishlist') -export const cacheStorage = initCacheStorage('wishlist') export const WishlistModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { store.registerModule('wishlist', wishlistStore) store.subscribe(plugin) diff --git a/core/pages/Checkout.js b/core/pages/Checkout.js index d436171732..f2de95a299 100644 --- a/core/pages/Checkout.js +++ b/core/pages/Checkout.js @@ -71,7 +71,7 @@ export default { for (let product of this.$store.state.cart.cartItems) { // check the results of online stock check if (product.onlineStockCheckid) { checkPromises.push(new Promise((resolve, reject) => { - StorageManager.get('syncTaskCollection').getItem(product.onlineStockCheckid, (err, item) => { + StorageManager.get('syncTasks').getItem(product.onlineStockCheckid, (err, item) => { if (err || !item) { if (err) Logger.error(err)() resolve(null) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index d17879f295..a4d31096bd 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -1,14 +1,26 @@ import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { initCacheStorage, prepareCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { Logger } from '@vue-storefront/core/lib/logger' + const StorageManager = { currentStoreCode: '', storageMap: {}, + /** + * Register the cache storage index that can be later accessed and modified - this is required prior to accessing the collection + * @param collectionName name of the cache collection to create + * @param isLocalized if set to `false` data will be shared between storeViews (default `true`) + * @param storageQuota max size of storage, 0 if unlimited (default `0`) + */ + init: function (collectionName: string, isLocalised = true, storageQuota = 0) { + this.storageMap[collectionName] = prepareCacheStorage(collectionName, isLocalised, storageQuota) + return this.storageMap[collectionName] + }, /** - * Register the cache storage - this is required prior to accessing the collection - * @param collectionName string name of the cache collection to register - * @param collectionInstance UniversalStorage driver + * Override or register the cache storage - this is required prior to accessing the collection + * @param collectionName { string} string name of the cache collection to register + * @param item UniversalStorage driver */ - set: function (collectionName, collectionInstance: UniversalStorage): UniversalStorage { + set: function (collectionName: string, collectionInstance: UniversalStorage): UniversalStorage { this.storageMap[collectionName] = collectionInstance return collectionInstance }, @@ -25,7 +37,8 @@ const StorageManager = { */ get: function (collectionName): UniversalStorage { if (!this.exists(collectionName)) { - return this.set(collectionName, initCacheStorage(collectionName, true, false)) + Logger.warn('Called cache collection ' + collectionName + ' does not exist. Initializing.', 'cache') + return this.set(collectionName, initCacheStorage(collectionName, true)) } else { return this.storageMap[collectionName] } diff --git a/docs/guide/basics/configuration.md b/docs/guide/basics/configuration.md index 1bf8873a25..087548635c 100644 --- a/docs/guide/basics/configuration.md +++ b/docs/guide/basics/configuration.md @@ -518,7 +518,7 @@ Starting with Vue Storefront v1.6, we changed the default order-placing behavior "syncTasks": "INDEXEDDB", "newsletterPreferences": "INDEXEDDB", "ordersHistory": "INDEXEDDB", - "checkoutFieldValues": "LOCALSTORAGE" + "checkout": "LOCALSTORAGE" } }, ``` From fd0117f7045c0308a8b79b8f0c9c13d166f6a719 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Mon, 15 Jul 2019 14:15:09 +0200 Subject: [PATCH 07/27] lint --- core/helpers/initCacheStorage.ts | 2 +- core/lib/search/adapter/api/searchAdapter.ts | 8 ++++---- core/lib/search/adapter/graphql/searchAdapter.ts | 12 ++++++------ core/store/lib/storage-manager.ts | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/helpers/initCacheStorage.ts b/core/helpers/initCacheStorage.ts index e240c8a5b3..b5b5be6607 100644 --- a/core/helpers/initCacheStorage.ts +++ b/core/helpers/initCacheStorage.ts @@ -20,7 +20,7 @@ export function prepareCacheStorage (key, localised = true, storageQuota = 0) { } /** @deprecated, to be removed in 2.0 in favor to `StorageManager` - * Inits cache storage for given module. By default via local storage + * Inits cache storage for given module. By default via local storage * */ export function initCacheStorage (key, localised = true, registerStorgeManager = true) { if (registerStorgeManager) { diff --git a/core/lib/search/adapter/api/searchAdapter.ts b/core/lib/search/adapter/api/searchAdapter.ts index 4f566dea6c..93d9c02abb 100644 --- a/core/lib/search/adapter/api/searchAdapter.ts +++ b/core/lib/search/adapter/api/searchAdapter.ts @@ -80,10 +80,10 @@ export class SearchAdapter { }, body: config.elasticsearch.queryMethod === 'POST' ? JSON.stringify(ElasticsearchQueryBody) : null }) - .then(resp => { return resp.json() }) - .catch(error => { - throw new Error('FetchError in request to ES: ' + error.toString()) - }) + .then(resp => { return resp.json() }) + .catch(error => { + throw new Error('FetchError in request to ES: ' + error.toString()) + }) } public handleResult (resp, type, start = 0, size = 50): SearchResponse { diff --git a/core/lib/search/adapter/graphql/searchAdapter.ts b/core/lib/search/adapter/graphql/searchAdapter.ts index acc573ad9d..55822decd7 100644 --- a/core/lib/search/adapter/graphql/searchAdapter.ts +++ b/core/lib/search/adapter/graphql/searchAdapter.ts @@ -57,12 +57,12 @@ export class SearchAdapter { }, body: gqlQueryBody }) - .then(resp => { - return resp.json() - }) - .catch(error => { - throw new Error('FetchError in request to ES: ' + error.toString()) - }) + .then(resp => { + return resp.json() + }) + .catch(error => { + throw new Error('FetchError in request to ES: ' + error.toString()) + }) } /** diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index a4d31096bd..c86781cc40 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -5,7 +5,7 @@ import { Logger } from '@vue-storefront/core/lib/logger' const StorageManager = { currentStoreCode: '', storageMap: {}, - /** + /** * Register the cache storage index that can be later accessed and modified - this is required prior to accessing the collection * @param collectionName name of the cache collection to create * @param isLocalized if set to `false` data will be shared between storeViews (default `true`) From b4dbc2e2e7a62bd95f037d5b1fd366daab147af6 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Tue, 16 Jul 2019 13:08:51 +0200 Subject: [PATCH 08/27] rewrite breadcrumbs module to new format --- core/modules-entry.ts | 2 -- core/modules/breadcrumbs/index.ts | 15 +++++------ core/modules/breadcrumbs/store/index.ts | 2 +- src/modules/index.ts | 5 ++-- .../components/ExtensionComponent.ts | 26 ------------------- .../hooks/afterRegistration.ts | 6 ----- .../hooks/beforeRegistration.ts | 18 ------------- src/modules/module-template/index.ts | 20 -------------- .../module-template/pages/ExtensionPage.vue | 18 ------------- .../module-template/queries/exampleQuery.ts | 12 --------- .../module-template/router/afterEach.ts | 8 ------ .../module-template/router/beforeEach.ts | 10 ------- src/modules/module-template/store/actions.ts | 21 --------------- src/modules/module-template/store/getters.ts | 4 --- src/modules/module-template/store/index.ts | 14 ---------- .../module-template/store/mutation-types.ts | 2 -- .../module-template/store/mutations.ts | 11 -------- src/modules/module-template/store/plugin.ts | 10 ------- src/modules/module-template/store/state.ts | 5 ---- .../module-template/types/ExampleState.ts | 5 ---- 20 files changed, 10 insertions(+), 204 deletions(-) delete mode 100644 src/modules/module-template/components/ExtensionComponent.ts delete mode 100644 src/modules/module-template/hooks/afterRegistration.ts delete mode 100644 src/modules/module-template/hooks/beforeRegistration.ts delete mode 100644 src/modules/module-template/index.ts delete mode 100644 src/modules/module-template/pages/ExtensionPage.vue delete mode 100644 src/modules/module-template/queries/exampleQuery.ts delete mode 100644 src/modules/module-template/router/afterEach.ts delete mode 100644 src/modules/module-template/router/beforeEach.ts delete mode 100644 src/modules/module-template/store/actions.ts delete mode 100644 src/modules/module-template/store/getters.ts delete mode 100644 src/modules/module-template/store/index.ts delete mode 100644 src/modules/module-template/store/mutation-types.ts delete mode 100644 src/modules/module-template/store/mutations.ts delete mode 100644 src/modules/module-template/store/plugin.ts delete mode 100644 src/modules/module-template/store/state.ts delete mode 100644 src/modules/module-template/types/ExampleState.ts diff --git a/core/modules-entry.ts b/core/modules-entry.ts index 8908445e75..ef5ade955e 100644 --- a/core/modules-entry.ts +++ b/core/modules-entry.ts @@ -4,11 +4,9 @@ import { Cms } from './modules/cms' import { Order } from './modules/order' import { User } from './modules/user' import { registerModules } from 'src/modules' -import { Breadcrumbs } from './modules/breadcrumbs' // @deprecated from 2.0, use registerModule instead export const enabledModules: VueStorefrontModule[] = [ - Breadcrumbs, Cms, Order, User, diff --git a/core/modules/breadcrumbs/index.ts b/core/modules/breadcrumbs/index.ts index 6530e8cade..e85c2585da 100644 --- a/core/modules/breadcrumbs/index.ts +++ b/core/modules/breadcrumbs/index.ts @@ -1,10 +1,7 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { breadcrumbsStore } from './store' +import { StorefrontModule } from '@vue-storefront/module' -export const KEY = 'breadcrumbs' -export const Breadcrumbs = createModule({ - key: KEY, - store: { modules: [ - { key: KEY, module: module } - ] } -}) + +export const BreadcrumbsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule('breadcrumbs', breadcrumbsStore) +} diff --git a/core/modules/breadcrumbs/store/index.ts b/core/modules/breadcrumbs/store/index.ts index c29ec4e403..b18501a717 100644 --- a/core/modules/breadcrumbs/store/index.ts +++ b/core/modules/breadcrumbs/store/index.ts @@ -1,5 +1,5 @@ -export const module = { +export const breadcrumbsStore = { namespaced: true, state: { routes: [], diff --git a/src/modules/index.ts b/src/modules/index.ts index 1c8e30fbbd..1476007769 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -1,4 +1,3 @@ -// import { extendModule } from '@vue-storefront/core/lib/module' import { VueStorefrontModule } from '@vue-storefront/core/lib/module' import { CatalogModule } from '@vue-storefront/core/modules/catalog' import { CatalogNextModule } from '@vue-storefront/core/modules/catalog-next' @@ -12,6 +11,7 @@ import { NewsletterModule } from '@vue-storefront/core/modules/newsletter' import { NotificationModule } from '@vue-storefront/core/modules/notification' import { RecentlyViewedModule } from '@vue-storefront/core/modules/recently-viewed' import { UrlModule } from '@vue-storefront/core/modules/url' +import { BreadcrumbsModule } from '@vue-storefront/core/modules/breadcrumbs' // import { GoogleAnalyticsModule } from './google-analytics'; // import { HotjarModule } from './hotjar'; import { GoogleTagManagerModule } from './google-tag-manager'; @@ -20,8 +20,8 @@ import { PaymentBackendMethodsModule } from './payment-backend-methods'; import { PaymentCashOnDeliveryModule } from './payment-cash-on-delivery'; import { RawOutputExampleModule } from './raw-output-example' import { InstantCheckoutModule } from './instant-checkout' -// import { Example } from './module-template' import { registerModule } from '@vue-storefront/module' + // TODO:distributed across proper pages BEFORE 1.11 export function registerNewModules () { registerModule(CatalogModule) @@ -44,6 +44,7 @@ export function registerNewModules () { registerModule(UrlModule) registerModule(CatalogNextModule) registerModule(CompareModule) + registerModule(BreadcrumbsModule) } // Deprecated API, will be removed in 2.0 diff --git a/src/modules/module-template/components/ExtensionComponent.ts b/src/modules/module-template/components/ExtensionComponent.ts deleted file mode 100644 index 85f287fe2e..0000000000 --- a/src/modules/module-template/components/ExtensionComponent.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * User list component example. Try to document components like this. You can also export .vue files if you want to provide baseline template. - * - * #### Data - * - `users: String[]` - list of users - * - * #### Methods - * - `addUser(name: Function, success?: Function, failure?: Function)` adds new user to the list, calls failure if user with the same name is already on list - */ -export const ExtensionComponent = { - name: 'ExtensionComponent', - computed: { - users () { - return this.$store.state.example.user - } - }, - methods: { - addUser (user: Record, success: (res: Record) => void, failure: (err: Error) => void): void { - this.$store.dispatch('example/addUser', user).then(res => { - success(res) - }).catch(err => { - failure(err) - }) - } - } -} diff --git a/src/modules/module-template/hooks/afterRegistration.ts b/src/modules/module-template/hooks/afterRegistration.ts deleted file mode 100644 index 8179bdb1ab..0000000000 --- a/src/modules/module-template/hooks/afterRegistration.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Logger } from '@vue-storefront/core/lib/logger' - -// This function will be fired both on server and client side context after registering other parts of the module -export function afterRegistration ({ Vue, config, store, isServer }) { - if (isServer) Logger.info('This will be called after extension registration and only on client side')() -} diff --git a/src/modules/module-template/hooks/beforeRegistration.ts b/src/modules/module-template/hooks/beforeRegistration.ts deleted file mode 100644 index cb495b3a07..0000000000 --- a/src/modules/module-template/hooks/beforeRegistration.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { AsyncDataLoader } from '@vue-storefront/core/lib/async-data-loader' - -// This function will be fired both on server and client side context before registering other parts of the module -export function beforeRegistration ({ Vue, config, store, isServer }) { - if (!isServer) console.info('This will be called before extension registration and only on client side') - AsyncDataLoader.push({ // this is an example showing how to call data loader from another module - execute: ({ route, store, context }) => { - return new Promise((resolve, reject) => { - if (route.name === 'configurable-product') { - store.state.exampleDataFetchedByLoader = 'this is just example data fetched by loader on configurable product page' - } else { - store.state.exampleDataFetchedByLoader = 'this is just example data fetched by loader on any page' - } - resolve(null) - }) - } - }) -} diff --git a/src/modules/module-template/index.ts b/src/modules/module-template/index.ts deleted file mode 100644 index 3c3216bc8c..0000000000 --- a/src/modules/module-template/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Read more about modules: https://github.com/DivanteLtd/vue-storefront/blob/master/doc/api-modules/about-modules.md -import { module } from './store' -import { plugin } from './store/plugin' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeEach } from './router/beforeEach' -import { afterEach } from './router/afterEach' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' - -export const KEY = 'example' -export const cacheStorage = initCacheStorage(KEY) -export const Example = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }], plugin }, - beforeRegistration, - afterRegistration, - router: { beforeEach, afterEach } -} -) diff --git a/src/modules/module-template/pages/ExtensionPage.vue b/src/modules/module-template/pages/ExtensionPage.vue deleted file mode 100644 index 25f7f02998..0000000000 --- a/src/modules/module-template/pages/ExtensionPage.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/src/modules/module-template/queries/exampleQuery.ts b/src/modules/module-template/queries/exampleQuery.ts deleted file mode 100644 index 3dcc12ab73..0000000000 --- a/src/modules/module-template/queries/exampleQuery.ts +++ /dev/null @@ -1,12 +0,0 @@ -// GraphQL and ES queries exposed by this module -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' - -export function exampleQuery (queryText, queryFilter) { - let exampleQuery = new SearchQuery() - - exampleQuery = exampleQuery - .setSearchText(queryText) - .applyFilter(queryFilter) - - return exampleQuery -} diff --git a/src/modules/module-template/router/afterEach.ts b/src/modules/module-template/router/afterEach.ts deleted file mode 100644 index 5d1689035a..0000000000 --- a/src/modules/module-template/router/afterEach.ts +++ /dev/null @@ -1,8 +0,0 @@ -// This function will be executed after entering each route. -// See https://router.vuejs.org/guide/advanced/navigation-guards.html#global-after-hooks -import { Route } from 'vue-router' -import { Logger } from '@vue-storefront/core/lib/logger' - -export function afterEach (to: Route, from: Route) { - Logger.info(`We have just entered ${to.name} from ${from.name}.`)() -} diff --git a/src/modules/module-template/router/beforeEach.ts b/src/modules/module-template/router/beforeEach.ts deleted file mode 100644 index 325247fe49..0000000000 --- a/src/modules/module-template/router/beforeEach.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This function will be executed before entering each route. -// It's important to have 'next()'. It enables navigation to new route. -// See https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards -import { Route } from 'vue-router' -import { Logger } from '@vue-storefront/core/lib/logger' - -export function beforeEach (to: Route, from: Route, next) { - Logger.info('We are going to visit' + to.name)() - next() -} diff --git a/src/modules/module-template/store/actions.ts b/src/modules/module-template/store/actions.ts deleted file mode 100644 index f5fe08ba0e..0000000000 --- a/src/modules/module-template/store/actions.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ExampleState } from '../types/ExampleState' -import { ActionTree } from 'vuex'; -import * as types from './mutation-types' -// you can use this storage if you want to enable offline capabilities -import { cacheStorage } from '../' - -// it's a good practice for all actions to return Promises with effect of their execution -export const actions: ActionTree = { - // if you want to use cache in your module you can load cached data like this - async loadUsers ({ commit }) { - const userData = cacheStorage.getItem('user') - commit(types.SET_USERS, userData) - return userData - }, - // if you are using cache in your module it's a good practice to allow develoeprs to choose either to use it or not - async addUser ({ commit }, { user, useCache = false }) { - commit(types.ADD_USER, user) - if (useCache) cacheStorage.setItem('user', user) - return user - } -} diff --git a/src/modules/module-template/store/getters.ts b/src/modules/module-template/store/getters.ts deleted file mode 100644 index d041866144..0000000000 --- a/src/modules/module-template/store/getters.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ExampleState } from '../types/ExampleState' -import { GetterTree } from 'vuex'; - -export const getters: GetterTree = {} diff --git a/src/modules/module-template/store/index.ts b/src/modules/module-template/store/index.ts deleted file mode 100644 index 463e2f3ba2..0000000000 --- a/src/modules/module-template/store/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from 'vuex' -import { ExampleState } from '../types/ExampleState' -import { mutations } from './mutations' -import { getters } from './getters' -import { actions } from './actions' -import { state } from './state' - -export const module: Module = { - namespaced: true, - mutations, - actions, - getters, - state -} diff --git a/src/modules/module-template/store/mutation-types.ts b/src/modules/module-template/store/mutation-types.ts deleted file mode 100644 index 508f944d83..0000000000 --- a/src/modules/module-template/store/mutation-types.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const SET_USERS = 'TEMPLATE/SET_USERS' -export const ADD_USER = 'TEMPLATE/SET_USER' diff --git a/src/modules/module-template/store/mutations.ts b/src/modules/module-template/store/mutations.ts deleted file mode 100644 index e837caccc4..0000000000 --- a/src/modules/module-template/store/mutations.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { MutationTree } from 'vuex' -import * as types from './mutation-types' - -export const mutations: MutationTree = { - [types.SET_USERS] (state, payload) { - state.users = payload - }, - [types.ADD_USER] (state, payload) { - state.users.push(payload) - } -} diff --git a/src/modules/module-template/store/plugin.ts b/src/modules/module-template/store/plugin.ts deleted file mode 100644 index b3e3bd29ee..0000000000 --- a/src/modules/module-template/store/plugin.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as types from './mutation-types' -import { Logger } from '@vue-storefront/core/lib/logger' - -export function plugin (mutation, state) { - if (types[mutation.type]) { - Logger.info('performed mutation from this store with type' + mutation.type)() - } else { - Logger.info('performed mutation from other store with type' + mutation.type)() - } -} diff --git a/src/modules/module-template/store/state.ts b/src/modules/module-template/store/state.ts deleted file mode 100644 index 3f92fa923f..0000000000 --- a/src/modules/module-template/store/state.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ExampleState } from '../types/ExampleState' - -export const state: ExampleState = { - users: null -} diff --git a/src/modules/module-template/types/ExampleState.ts b/src/modules/module-template/types/ExampleState.ts deleted file mode 100644 index bb9b5a2bb3..0000000000 --- a/src/modules/module-template/types/ExampleState.ts +++ /dev/null @@ -1,5 +0,0 @@ -// This object should represent structure of your modules Vuex state -// It's a good practice is to name this interface accordingly to the KET (for example mailchimpState) -export interface ExampleState { - users: string[] -} From 7523fb70a0187517d9716d46ea9a00f69c95e2ee Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Tue, 16 Jul 2019 16:14:41 +0200 Subject: [PATCH 09/27] order store refactor (initial) --- core/modules-entry.ts | 2 - core/modules/breadcrumbs/index.ts | 1 - .../offline-order/components/CancelOrders.ts | 2 +- .../helpers/onNetworkStatusChange.ts | 2 +- .../modules/order/hooks/beforeRegistration.ts | 115 ---------------- core/modules/order/index.ts | 126 ++++++++++++++++-- core/modules/order/store/index.ts | 2 +- core/modules/order/store/mutations.ts | 2 +- docs/guide/core-themes/service-workers.md | 2 +- src/modules/index.ts | 4 + 10 files changed, 125 insertions(+), 133 deletions(-) delete mode 100644 core/modules/order/hooks/beforeRegistration.ts diff --git a/core/modules-entry.ts b/core/modules-entry.ts index ef5ade955e..73ff9ea6f1 100644 --- a/core/modules-entry.ts +++ b/core/modules-entry.ts @@ -1,14 +1,12 @@ import { VueStorefrontModule } from '@vue-storefront/core/lib/module' import { Cms } from './modules/cms' -import { Order } from './modules/order' import { User } from './modules/user' import { registerModules } from 'src/modules' // @deprecated from 2.0, use registerModule instead export const enabledModules: VueStorefrontModule[] = [ Cms, - Order, User, ...registerModules ] diff --git a/core/modules/breadcrumbs/index.ts b/core/modules/breadcrumbs/index.ts index e85c2585da..96bab71d21 100644 --- a/core/modules/breadcrumbs/index.ts +++ b/core/modules/breadcrumbs/index.ts @@ -1,7 +1,6 @@ import { breadcrumbsStore } from './store' import { StorefrontModule } from '@vue-storefront/module' - export const BreadcrumbsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { store.registerModule('breadcrumbs', breadcrumbsStore) } diff --git a/core/modules/offline-order/components/CancelOrders.ts b/core/modules/offline-order/components/CancelOrders.ts index 5f733504b5..546edf559d 100644 --- a/core/modules/offline-order/components/CancelOrders.ts +++ b/core/modules/offline-order/components/CancelOrders.ts @@ -9,7 +9,7 @@ import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' export const CancelOrders = { methods: { cancelOrders () { - const ordersCollection = initCacheStorage('orders', false, true) + const ordersCollection = initCacheStorage('order', false, true) ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { ordersCollection.removeItem(id) diff --git a/core/modules/offline-order/helpers/onNetworkStatusChange.ts b/core/modules/offline-order/helpers/onNetworkStatusChange.ts index 1e8f0852ff..44cd2f1c6c 100644 --- a/core/modules/offline-order/helpers/onNetworkStatusChange.ts +++ b/core/modules/offline-order/helpers/onNetworkStatusChange.ts @@ -13,7 +13,7 @@ export function onNetworkStatusChange (store) { EventBus.$emit('order/PROCESS_QUEUE', { config: config }) // process checkout queue } else { const ordersToConfirm = [] - const ordersCollection = initCacheStorage('orders', false, true) + const ordersCollection = initCacheStorage('order', false, true) ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { diff --git a/core/modules/order/hooks/beforeRegistration.ts b/core/modules/order/hooks/beforeRegistration.ts deleted file mode 100644 index 0f40656086..0000000000 --- a/core/modules/order/hooks/beforeRegistration.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index' -import { Logger } from '@vue-storefront/core/lib/logger' -import rootStore from '@vue-storefront/core/store' -import i18n from '@vue-storefront/i18n' -import { serial, onlineHelper, processURLAddress } from '@vue-storefront/core/helpers' -import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' - -export function beforeRegistration ({ Vue, config, store, isServer }) { - StorageManager.set('ordersCollection', new UniversalStorage(localForage.createInstance({ - name: 'shop', - storeName: 'orders', - driver: localForage[config.localForage.defaultDrivers['orders']] - }))) - if (!isServer) { - const orderMutex = {} - // TODO: move to external file - EventBus.$on('order/PROCESS_QUEUE', async event => { - if (onlineHelper.isOnline) { - Logger.log('Sending out orders queue to server ...')() - const ordersCollection = initCacheStorage('orders', false, true) - - const fetchQueue = [] - ordersCollection.iterate((order, id) => { - // Resulting key/value pair -- this callback - // will be executed for every item in the - // database. - - if (!order.transmited && !orderMutex[id]) { // not sent to the server yet - orderMutex[id] = true - const config = event.config - const orderData = order - const orderId = id - Logger.log('Pushing out order ' + orderId)() - fetchQueue.push( - /** @todo refactor order synchronisation to proper handling through vuex actions to avoid code duplication */ - fetch(processURLAddress(config.orders.endpoint), - { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(orderData) - }).then(response => { - const contentType = response.headers.get('content-type') - if (contentType && contentType.includes('application/json')) { - return response.json() - } else { - orderMutex[id] = false - Logger.error('Error with response - bad content-type!')() - } - }) - .then(jsonResponse => { - if (jsonResponse) { - Logger.info('Response for: ' + orderId + ' = ' + JSON.stringify(jsonResponse.result))() - orderData.transmited = true // by default don't retry to transmit this order - orderData.transmited_at = new Date() - - if (jsonResponse.code !== 200) { - Logger.error(jsonResponse, 'order-sync')() - - if (jsonResponse.code === 400) { - rootStore.dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t('Address provided in checkout contains invalid data. Please check if all required fields are filled in and also contact us on {email} to resolve this issue for future. Your order has been canceled.', { email: config.mailer.contactAddress }), - action1: { label: i18n.t('OK') } - }) - } else if (jsonResponse.code === 500 && jsonResponse.result === i18n.t('Error: Error while adding products')) { - rootStore.dispatch('notification/spawnNotification', { - type: 'error', - message: i18n.t('Some products you\'ve ordered are out of stock. Your order has been canceled.'), - action1: { label: i18n.t('OK') } - }) - } else { - orderData.transmited = false // probably some server related error. Enqueue - } - } - - ordersCollection.setItem(orderId.toString(), orderData) - } else { - Logger.error(jsonResponse)() - } - orderMutex[id] = false - }).catch(err => { - if (config.orders.offline_orders.notification.enabled) { - navigator.serviceWorker.ready.then(registration => { - registration.sync.register('orderSync') - .then(() => { - Logger.log('Order sync registered')() - }) - .catch(error => { - Logger.log('Unable to sync', error)() - }) - }) - } - Logger.error('Error sending order: ' + orderId, err)() - orderMutex[id] = false - }) - ) - } - }, (err) => { - if (err) Logger.error(err)() - Logger.log('Iteration has completed')() - - // execute them serially - serial(fetchQueue) - Logger.info('Processing orders queue has finished')() - }).catch(err => { - // This code runs if there were any errors - Logger.log(err)() - }) - } - }) - } -} diff --git a/core/modules/order/index.ts b/core/modules/order/index.ts index 9060e4e619..d361a2e61c 100644 --- a/core/modules/order/index.ts +++ b/core/modules/order/index.ts @@ -1,10 +1,116 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { module } from './store' -import { beforeRegistration } from './hooks/beforeRegistration' - -export const KEY = 'order' -export const Order = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] }, - beforeRegistration -}) +import { orderStore } from './store' +import * as localForage from 'localforage' +import UniversalStorage from '@vue-storefront/core/store/lib/storage' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index' +import { Logger } from '@vue-storefront/core/lib/logger' +import rootStore from '@vue-storefront/core/store' +import i18n from '@vue-storefront/i18n' +import { serial, onlineHelper, processURLAddress } from '@vue-storefront/core/helpers' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' +import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { isServer } from '@vue-storefront/core/helpers' +import { StorefrontModule } from '@vue-storefront/module'; + +export const OrderModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + StorageManager.init('order') + + if (!isServer) { + const orderMutex = {} + // TODO: move to external file + EventBus.$on('order/PROCESS_QUEUE', async event => { + if (onlineHelper.isOnline) { + Logger.log('Sending out orders queue to server ...')() + const ordersCollection = initCacheStorage('order', false, true) + + const fetchQueue = [] + ordersCollection.iterate((order, id) => { + // Resulting key/value pair -- this callback + // will be executed for every item in the + // database. + + if (!order.transmited && !orderMutex[id]) { // not sent to the server yet + orderMutex[id] = true + const config = event.config + const orderData = order + const orderId = id + Logger.log('Pushing out order ' + orderId)() + fetchQueue.push( + /** @todo refactor order synchronisation to proper handling through vuex actions to avoid code duplication */ + fetch(processURLAddress(config.orders.endpoint), + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(orderData) + }).then(response => { + const contentType = response.headers.get('content-type') + if (contentType && contentType.includes('application/json')) { + return response.json() + } else { + orderMutex[id] = false + Logger.error('Error with response - bad content-type!')() + } + }) + .then(jsonResponse => { + if (jsonResponse) { + Logger.info('Response for: ' + orderId + ' = ' + JSON.stringify(jsonResponse.result))() + orderData.transmited = true // by default don't retry to transmit this order + orderData.transmited_at = new Date() + + if (jsonResponse.code !== 200) { + Logger.error(jsonResponse, 'order-sync')() + + if (jsonResponse.code === 400) { + rootStore.dispatch('notification/spawnNotification', { + type: 'error', + message: i18n.t('Address provided in checkout contains invalid data. Please check if all required fields are filled in and also contact us on {email} to resolve this issue for future. Your order has been canceled.', { email: config.mailer.contactAddress }), + action1: { label: i18n.t('OK') } + }) + } else if (jsonResponse.code === 500 && jsonResponse.result === i18n.t('Error: Error while adding products')) { + rootStore.dispatch('notification/spawnNotification', { + type: 'error', + message: i18n.t('Some products you\'ve ordered are out of stock. Your order has been canceled.'), + action1: { label: i18n.t('OK') } + }) + } else { + orderData.transmited = false // probably some server related error. Enqueue + } + } + + ordersCollection.setItem(orderId.toString(), orderData) + } else { + Logger.error(jsonResponse)() + } + orderMutex[id] = false + }).catch(err => { + if (config.orders.offline_orders.notification.enabled) { + navigator.serviceWorker.ready.then(registration => { + registration.sync.register('orderSync') + .then(() => { + Logger.log('Order sync registered')() + }) + .catch(error => { + Logger.log('Unable to sync', error)() + }) + }) + } + Logger.error('Error sending order: ' + orderId, err)() + orderMutex[id] = false + }) + ) + } + }, (err) => { + if (err) Logger.error(err)() + Logger.log('Iteration has completed')() + + // execute them serially + serial(fetchQueue) + Logger.info('Processing orders queue has finished')() + }).catch(err => { + // This code runs if there were any errors + Logger.log(err)() + }) + } + }) + } + store.registerModule('order', orderStore) +} diff --git a/core/modules/order/store/index.ts b/core/modules/order/store/index.ts index 4962392ff4..51e22f6e1d 100644 --- a/core/modules/order/store/index.ts +++ b/core/modules/order/store/index.ts @@ -5,7 +5,7 @@ import getters from './getters' import RootState from '@vue-storefront/core/types/RootState' import OrderState from '../types/OrderState' -export const module: Module = { +export const orderStore: Module = { namespaced: true, state: { last_order_confirmation: null, diff --git a/core/modules/order/store/mutations.ts b/core/modules/order/store/mutations.ts index 917b8146fa..a4ab0e4c06 100644 --- a/core/modules/order/store/mutations.ts +++ b/core/modules/order/store/mutations.ts @@ -13,7 +13,7 @@ const mutations: MutationTree = { * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ [types.ORDER_PLACE_ORDER] (state, order) { - const ordersCollection = StorageManager.get('ordersCollection') + const ordersCollection = StorageManager.get('order') const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough order.order_id = orderId.toString() order.created_at = new Date() diff --git a/docs/guide/core-themes/service-workers.md b/docs/guide/core-themes/service-workers.md index f1f54dd297..36402d2be7 100644 --- a/docs/guide/core-themes/service-workers.md +++ b/docs/guide/core-themes/service-workers.md @@ -46,7 +46,7 @@ It allows you to send data to the Service Worker. For example, when the order is * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ [types.CHECKOUT_PLACE_ORDER] (state, order) { - const ordersCollection = StorageManager.get('ordersCollection') + const ordersCollection = StorageManager.get('order') const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough order.id = orderId.toString() order.transmited = false diff --git a/src/modules/index.ts b/src/modules/index.ts index 1476007769..7c07753eda 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -12,6 +12,8 @@ import { NotificationModule } from '@vue-storefront/core/modules/notification' import { RecentlyViewedModule } from '@vue-storefront/core/modules/recently-viewed' import { UrlModule } from '@vue-storefront/core/modules/url' import { BreadcrumbsModule } from '@vue-storefront/core/modules/breadcrumbs' +import { OrderModule } from '@vue-storefront/core/modules/order' + // import { GoogleAnalyticsModule } from './google-analytics'; // import { HotjarModule } from './hotjar'; import { GoogleTagManagerModule } from './google-tag-manager'; @@ -20,6 +22,7 @@ import { PaymentBackendMethodsModule } from './payment-backend-methods'; import { PaymentCashOnDeliveryModule } from './payment-cash-on-delivery'; import { RawOutputExampleModule } from './raw-output-example' import { InstantCheckoutModule } from './instant-checkout' + import { registerModule } from '@vue-storefront/module' // TODO:distributed across proper pages BEFORE 1.11 @@ -45,6 +48,7 @@ export function registerNewModules () { registerModule(CatalogNextModule) registerModule(CompareModule) registerModule(BreadcrumbsModule) + registerModule(OrderModule) } // Deprecated API, will be removed in 2.0 From 1ed87531c49362336587f25d3a48f996b55e6f9d Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 11:14:52 +0200 Subject: [PATCH 10/27] rename order to orders --- core/modules/offline-order/components/CancelOrders.ts | 7 +------ .../offline-order/helpers/onNetworkStatusChange.ts | 2 +- core/modules/order/index.ts | 6 +++--- core/modules/order/store/actions.ts | 2 +- core/modules/order/store/mutation-types.ts | 2 +- core/modules/order/store/mutations.ts | 8 ++++---- docs/guide/core-themes/service-workers.md | 2 +- docs/guide/vuex/sync-store.md | 2 +- 8 files changed, 13 insertions(+), 18 deletions(-) diff --git a/core/modules/offline-order/components/CancelOrders.ts b/core/modules/offline-order/components/CancelOrders.ts index 546edf559d..22609570cd 100644 --- a/core/modules/offline-order/components/CancelOrders.ts +++ b/core/modules/offline-order/components/CancelOrders.ts @@ -1,15 +1,10 @@ -import * as localForage from 'localforage' -import store from '@vue-storefront/core/store' - -import UniversalStorage from '@vue-storefront/core/store/lib/storage' import { Logger } from '@vue-storefront/core/lib/logger' -import config from 'config' import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' export const CancelOrders = { methods: { cancelOrders () { - const ordersCollection = initCacheStorage('order', false, true) + const ordersCollection = initCacheStorage('orders', false, true) ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { ordersCollection.removeItem(id) diff --git a/core/modules/offline-order/helpers/onNetworkStatusChange.ts b/core/modules/offline-order/helpers/onNetworkStatusChange.ts index 44cd2f1c6c..1e8f0852ff 100644 --- a/core/modules/offline-order/helpers/onNetworkStatusChange.ts +++ b/core/modules/offline-order/helpers/onNetworkStatusChange.ts @@ -13,7 +13,7 @@ export function onNetworkStatusChange (store) { EventBus.$emit('order/PROCESS_QUEUE', { config: config }) // process checkout queue } else { const ordersToConfirm = [] - const ordersCollection = initCacheStorage('order', false, true) + const ordersCollection = initCacheStorage('orders', false, true) ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { diff --git a/core/modules/order/index.ts b/core/modules/order/index.ts index d361a2e61c..5897f8cdb5 100644 --- a/core/modules/order/index.ts +++ b/core/modules/order/index.ts @@ -12,7 +12,7 @@ import { isServer } from '@vue-storefront/core/helpers' import { StorefrontModule } from '@vue-storefront/module'; export const OrderModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - StorageManager.init('order') + StorageManager.init('orders') if (!isServer) { const orderMutex = {} @@ -20,7 +20,7 @@ export const OrderModule: StorefrontModule = function (app, store, router, modul EventBus.$on('order/PROCESS_QUEUE', async event => { if (onlineHelper.isOnline) { Logger.log('Sending out orders queue to server ...')() - const ordersCollection = initCacheStorage('order', false, true) + const ordersCollection = initCacheStorage('orders', false, true) const fetchQueue = [] ordersCollection.iterate((order, id) => { @@ -112,5 +112,5 @@ export const OrderModule: StorefrontModule = function (app, store, router, modul } }) } - store.registerModule('order', orderStore) + store.registerModule('orders', orderStore) } diff --git a/core/modules/order/store/actions.ts b/core/modules/order/store/actions.ts index cb8cd10f5f..bfaf23f124 100644 --- a/core/modules/order/store/actions.ts +++ b/core/modules/order/store/actions.ts @@ -63,7 +63,7 @@ const actions: ActionTree = { } else if (task.resultCode === 400) { commit(types.ORDER_REMOVE_SESSION_ORDER_HASH, currentOrderHash) - Logger.error('Internal validation error; Order entity is not compliant with the schema: ' + JSON.stringify(task.result), 'order')() + Logger.error('Internal validation error; Order entity is not compliant with the schema: ' + JSON.stringify(task.result), 'orders')() dispatch('notification/spawnNotification', { type: 'error', message: i18n.t('Internal validation error. Please check if all required fields are filled in. Please contact us on {email}', { email: config.mailer.contactAddress }), diff --git a/core/modules/order/store/mutation-types.ts b/core/modules/order/store/mutation-types.ts index d253a4273f..221bcc83e3 100644 --- a/core/modules/order/store/mutation-types.ts +++ b/core/modules/order/store/mutation-types.ts @@ -1,4 +1,4 @@ -export const SN_ORDER = 'order' +export const SN_ORDER = 'orders' export const ORDER_PLACE_ORDER = SN_ORDER + '/PLACE_ORDER' export const ORDER_PROCESS_QUEUE = SN_ORDER + '/PROCESS_QUEUE' export const ORDER_LAST_ORDER_WITH_CONFIRMATION = SN_ORDER + '/LAST_ORDER_CONFIRMATION' diff --git a/core/modules/order/store/mutations.ts b/core/modules/order/store/mutations.ts index a4ab0e4c06..28dd43d4df 100644 --- a/core/modules/order/store/mutations.ts +++ b/core/modules/order/store/mutations.ts @@ -13,20 +13,20 @@ const mutations: MutationTree = { * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ [types.ORDER_PLACE_ORDER] (state, order) { - const ordersCollection = StorageManager.get('order') + const ordersCollection = StorageManager.get('orders') const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough order.order_id = orderId.toString() order.created_at = new Date() order.updated_at = new Date() ordersCollection.setItem(orderId.toString(), order, (err, resp) => { - if (err) Logger.error(err, 'order')() + if (err) Logger.error(err, 'orders')() if (!order.transmited) { EventBus.$emit('order/PROCESS_QUEUE', { config: config }) // process checkout queue } - Logger.info('Order placed, orderId = ' + orderId, 'order')() + Logger.info('Order placed, orderId = ' + orderId, 'orders')() }).catch((reason) => { - Logger.error(reason, 'order') // it doesn't work on SSR + Logger.error(reason, 'orders') // it doesn't work on SSR }) // populate cache }, [types.ORDER_LAST_ORDER_WITH_CONFIRMATION] (state, payload) { diff --git a/docs/guide/core-themes/service-workers.md b/docs/guide/core-themes/service-workers.md index 36402d2be7..5a3a05ff76 100644 --- a/docs/guide/core-themes/service-workers.md +++ b/docs/guide/core-themes/service-workers.md @@ -46,7 +46,7 @@ It allows you to send data to the Service Worker. For example, when the order is * @param {Object} product data format for products is described in /doc/ElasticSearch data formats.md */ [types.CHECKOUT_PLACE_ORDER] (state, order) { - const ordersCollection = StorageManager.get('order') + const ordersCollection = StorageManager.get('orders') const orderId = entities.uniqueEntityId(order) // timestamp as a order id is not the best we can do but it's enough order.id = orderId.toString() order.transmited = false diff --git a/docs/guide/vuex/sync-store.md b/docs/guide/vuex/sync-store.md index 142dbc37f6..4052b8092f 100644 --- a/docs/guide/vuex/sync-store.md +++ b/docs/guide/vuex/sync-store.md @@ -46,7 +46,7 @@ The `url` can contain two dynamic variable placeholders that will be expanded to An example URL with variables: `http://localhost:8080/api/cart/totals?token={{token}}&cartId={{cartId}}` :::tip Note -The task object and then the results are stored within the `tasksCollection` indexedDb data table under the key of `task.task_id` +The task object and then the results are stored within the `syncTasks` indexedDb/Local storage data table under the key of `task.task_id` ::: ![syncTasks local collection stores the tasks and the results](../images/syncTasks-example.png) From 23cb6b944f249538647abf9e1d2f14f5d391eb93 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 11:51:16 +0200 Subject: [PATCH 11/27] cache cleanup --- core/lib/search.ts | 2 +- core/modules/cart/store/actions.ts | 2 +- core/modules/catalog/index.ts | 2 +- core/modules/catalog/store/attribute/mutations.ts | 2 +- core/modules/catalog/store/product/actions.ts | 4 ++-- core/modules/catalog/store/tax/mutations.ts | 2 +- core/modules/checkout/store/checkout/actions.ts | 2 +- core/modules/user/hooks/afterRegistration.ts | 8 ++++---- core/modules/user/hooks/beforeRegistration.ts | 8 +------- core/modules/user/store/actions.ts | 8 ++++---- 10 files changed, 17 insertions(+), 23 deletions(-) diff --git a/core/lib/search.ts b/core/lib/search.ts index 7e9d99167d..6b31e49bc2 100644 --- a/core/lib/search.ts +++ b/core/lib/search.ts @@ -53,7 +53,7 @@ export const quickSearchByQuery = async ({ query = {}, start = 0, size = 50, ent Request.groupId = rootStore.state.user.groupId } - const cache = StorageManager.get('elasticCacheCollection') // switch to appcache? + const cache = StorageManager.get('elasticCache') // switch to appcache? let servedFromCache = false const cacheKey = sha3_224(JSON.stringify(Request)) const benchmarkTime = new Date() diff --git a/core/modules/cart/store/actions.ts b/core/modules/cart/store/actions.ts index b65615301c..476c651185 100644 --- a/core/modules/cart/store/actions.ts +++ b/core/modules/cart/store/actions.ts @@ -503,7 +503,7 @@ const actions: ActionTree = { }, /** authorize the cart after user got logged in using the current cart token */ authorize ({ dispatch }) { - StorageManager.get('usersCollection').getItem('last-cart-bypass-ts', (err, lastCartBypassTs) => { + StorageManager.get('user').getItem('last-cart-bypass-ts', (err, lastCartBypassTs) => { if (err) { Logger.error(err, 'cart')() } diff --git a/core/modules/catalog/index.ts b/core/modules/catalog/index.ts index 3c4c7b6d4e..6249634052 100644 --- a/core/modules/catalog/index.ts +++ b/core/modules/catalog/index.ts @@ -10,7 +10,7 @@ export const CatalogModule: StorefrontModule = function (app, store, router, mod StorageManager.init('categories') StorageManager.init('attributes') StorageManager.init('products') - StorageManager.init('elasticCacheCollection', true, appConfig.server.elasticCacheQuota) + StorageManager.init('elasticCache', true, appConfig.server.elasticCacheQuota) store.registerModule('product', productModule) store.registerModule('attribute', attributeModule) diff --git a/core/modules/catalog/store/attribute/mutations.ts b/core/modules/catalog/store/attribute/mutations.ts index c88bbf6ab4..08efcc92c6 100644 --- a/core/modules/catalog/store/attribute/mutations.ts +++ b/core/modules/catalog/store/attribute/mutations.ts @@ -22,7 +22,7 @@ const mutations: MutationTree = { attrHashByCode[attr.attribute_code] = attr attrHashById[attr.attribute_id] = attr - const attrCollection = StorageManager.get('attributesCollection') + const attrCollection = StorageManager.get('attributes') try { attrCollection.setItem(entityKeyName('attribute_code', attr.attribute_code.toLowerCase()), attr).catch((reason) => { Logger.error(reason, 'mutations') // it doesn't work on SSR diff --git a/core/modules/catalog/store/product/actions.ts b/core/modules/catalog/store/product/actions.ts index 2dee2da2eb..ebc638c56f 100644 --- a/core/modules/catalog/store/product/actions.ts +++ b/core/modules/catalog/store/product/actions.ts @@ -326,7 +326,7 @@ const actions: ActionTree = { } return calculateTaxes(resp.items, context).then((updatedProducts) => { // handle cache - const cache = StorageManager.get('elasticCacheCollection') + const cache = StorageManager.get('elasticCache') for (let prod of resp.items) { // we store each product separately in cache to have offline access to products/single method if (prod.configurable_children) { for (let configurableChild of prod.configurable_children) { @@ -408,7 +408,7 @@ const actions: ActionTree = { return new Promise((resolve, reject) => { const benchmarkTime = new Date() - const cache = StorageManager.get('elasticCacheCollection') + const cache = StorageManager.get('elasticCache') const setupProduct = (prod) => { // set product quantity to 1 diff --git a/core/modules/catalog/store/tax/mutations.ts b/core/modules/catalog/store/tax/mutations.ts index 8c362360bd..20b167bbec 100644 --- a/core/modules/catalog/store/tax/mutations.ts +++ b/core/modules/catalog/store/tax/mutations.ts @@ -7,7 +7,7 @@ import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' const mutations: MutationTree = { [types.TAX_UPDATE_RULES] (state, taxClasses) { - const cache = StorageManager.get('elasticCacheCollection') + const cache = StorageManager.get('elasticCache') for (let tc of taxClasses.items) { // we store each product separately in cache to have offline acces for products/single method const cacheKey = entityKeyName('tc', tc.id) cache.setItem(cacheKey, tc).catch((err) => { diff --git a/core/modules/checkout/store/checkout/actions.ts b/core/modules/checkout/store/checkout/actions.ts index 7b407b399c..bb490fa43c 100644 --- a/core/modules/checkout/store/checkout/actions.ts +++ b/core/modules/checkout/store/checkout/actions.ts @@ -15,7 +15,7 @@ const actions: ActionTree = { try { const result = await dispatch('order/placeOrder', order, {root: true}) if (!result.resultCode || result.resultCode === 200) { - StorageManager.get('usersCollection').setItem('last-cart-bypass-ts', new Date().getTime()) + StorageManager.get('user').setItem('last-cart-bypass-ts', new Date().getTime()) await dispatch('cart/clear', { recreateAndSyncCart: true }, {root: true}) if (state.personalDetails.createAccount) { commit(types.CHECKOUT_DROP_PASSWORD) diff --git a/core/modules/user/hooks/afterRegistration.ts b/core/modules/user/hooks/afterRegistration.ts index 8fd48b63aa..49a8802c50 100644 --- a/core/modules/user/hooks/afterRegistration.ts +++ b/core/modules/user/hooks/afterRegistration.ts @@ -30,7 +30,7 @@ export async function afterRegistration ({ Vue, config, store, isServer }) { if ( type.endsWith(types.USER_INFO_LOADED) ) { - StorageManager.get('usersCollection').setItem('current-user', state.user.current).catch((reason) => { + StorageManager.get('user').setItem('current-user', state.user.current).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } @@ -38,7 +38,7 @@ export async function afterRegistration ({ Vue, config, store, isServer }) { if ( type.endsWith(types.USER_ORDERS_HISTORY_LOADED) ) { - StorageManager.get('ordersHistoryCollection').setItem('orders-history', state.user.orders_history).catch((reason) => { + StorageManager.get('user').setItem('orders-history', state.user.orders_history).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } @@ -46,11 +46,11 @@ export async function afterRegistration ({ Vue, config, store, isServer }) { if ( type.endsWith(types.USER_TOKEN_CHANGED) ) { - StorageManager.get('usersCollection').setItem('current-token', state.user.token).catch((reason) => { + StorageManager.get('user').setItem('current-token', state.user.token).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache if (state.user.refreshToken) { - StorageManager.get('usersCollection').setItem('current-refresh-token', state.user.refreshToken).catch((reason) => { + StorageManager.get('user').setItem('current-refresh-token', state.user.refreshToken).catch((reason) => { console.error(reason) // it doesn't work on SSR }) // populate cache } diff --git a/core/modules/user/hooks/beforeRegistration.ts b/core/modules/user/hooks/beforeRegistration.ts index ac1c358012..0c01095bc9 100644 --- a/core/modules/user/hooks/beforeRegistration.ts +++ b/core/modules/user/hooks/beforeRegistration.ts @@ -7,15 +7,9 @@ export function beforeRegistration ({ Vue, config, store, isServer }) { const storeView = currentStoreView() const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - StorageManager.set('usersCollection', new UniversalStorage(localForage.createInstance({ + StorageManager.set('user', new UniversalStorage(localForage.createInstance({ name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', storeName: 'user', driver: localForage[config.localForage.defaultDrivers['user']] }))) - - StorageManager.set('ordersHistoryCollection', new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'ordersHistory', - driver: localForage[config.localForage.defaultDrivers['ordersHistory']] - }))) } diff --git a/core/modules/user/store/actions.ts b/core/modules/user/store/actions.ts index e642003e3a..7377b7a41c 100644 --- a/core/modules/user/store/actions.ts +++ b/core/modules/user/store/actions.ts @@ -24,7 +24,7 @@ const actions: ActionTree = { } context.commit(types.USER_START_SESSION) - const cache = StorageManager.get('usersCollection') + const cache = StorageManager.get('user') cache.getItem('current-token', (err, res) => { if (err) { Logger.error(err, 'user')() @@ -118,7 +118,7 @@ const actions: ActionTree = { */ refresh (context) { return new Promise((resolve, reject) => { - const usersCollection = StorageManager.get('usersCollection') + const usersCollection = StorageManager.get('user') usersCollection.getItem('current-refresh-token', (err, refreshToken) => { if (err) { Logger.error(err, 'user')() @@ -172,7 +172,7 @@ const actions: ActionTree = { Logger.warn('No User token, user unauthorized', 'user')() return resolve(null) } - const cache = StorageManager.get('usersCollection') + const cache = StorageManager.get('user') let resolvedFromCache = false if (useCache === true) { // after login for example we shouldn't use cache to be sure we're loading currently logged in user @@ -313,7 +313,7 @@ const actions: ActionTree = { Logger.debug('No User token, user unathorized', 'user')() return resolve(null) } - const cache = StorageManager.get('ordersHistoryCollection') + const cache = StorageManager.get('user') let resolvedFromCache = false if (useCache === true) { // after login for example we shouldn't use cache to be sure we're loading currently logged in user From 60dec2ef78d4f45f904a8807e97c1e30969a6cc4 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 11:58:15 +0200 Subject: [PATCH 12/27] categoriesCollection renamed to categories --- core/modules/catalog/store/category/actions.ts | 2 +- core/modules/catalog/store/category/mutations.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/modules/catalog/store/category/actions.ts b/core/modules/catalog/store/category/actions.ts index 820edbe5e2..c8f2a096e4 100644 --- a/core/modules/catalog/store/category/actions.ts +++ b/core/modules/catalog/store/category/actions.ts @@ -194,7 +194,7 @@ const actions: ActionTree = { if (skipCache || isServer) { fetchCat({ key, value }) } else { - const catCollection = StorageManager.get('categoriesCollection') + const catCollection = StorageManager.get('categories') // Check if category does not exist in the store AND we haven't recursively reached Default category (id=1) catCollection.getItem(entityKeyName(key, value), setcat) } diff --git a/core/modules/catalog/store/category/mutations.ts b/core/modules/catalog/store/category/mutations.ts index 198b82a8d1..c8e5efce09 100644 --- a/core/modules/catalog/store/category/mutations.ts +++ b/core/modules/catalog/store/category/mutations.ts @@ -32,7 +32,7 @@ const mutations: MutationTree = { } catSlugSetter(category) if (categories.includeFields == null) { - const catCollection = StorageManager.get('categoriesCollection') + const catCollection = StorageManager.get('categories') try { catCollection.setItem(entityKeyName('slug', category.slug.toLowerCase()), category).catch((reason) => { Logger.error(reason, 'category') // it doesn't work on SSR From 372559c427a5fdf81b102e0b01ecbd20e2116dae Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 12:39:41 +0200 Subject: [PATCH 13/27] refactor cms module to new format --- core/modules-entry.ts | 2 -- core/modules/cms/hooks/beforeRegistration.ts | 14 ----------- core/modules/cms/index.ts | 25 ++++++++----------- core/modules/user/hooks/beforeRegistration.ts | 12 +-------- src/modules/index.ts | 5 ++-- 5 files changed, 14 insertions(+), 44 deletions(-) delete mode 100644 core/modules/cms/hooks/beforeRegistration.ts diff --git a/core/modules-entry.ts b/core/modules-entry.ts index 73ff9ea6f1..f14b3079c8 100644 --- a/core/modules-entry.ts +++ b/core/modules-entry.ts @@ -1,12 +1,10 @@ import { VueStorefrontModule } from '@vue-storefront/core/lib/module' -import { Cms } from './modules/cms' import { User } from './modules/user' import { registerModules } from 'src/modules' // @deprecated from 2.0, use registerModule instead export const enabledModules: VueStorefrontModule[] = [ - Cms, User, ...registerModules ] diff --git a/core/modules/cms/hooks/beforeRegistration.ts b/core/modules/cms/hooks/beforeRegistration.ts deleted file mode 100644 index 4ef3eb891d..0000000000 --- a/core/modules/cms/hooks/beforeRegistration.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' - -export function beforeRegistration ({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - - StorageManager.set('cmsData', new UniversalStorage(localForage.createInstance({ - name: dbNamePrefix + 'shop', - storeName: 'cms' - }))) -} diff --git a/core/modules/cms/index.ts b/core/modules/cms/index.ts index 737e3935f1..62dfb11a61 100644 --- a/core/modules/cms/index.ts +++ b/core/modules/cms/index.ts @@ -1,20 +1,15 @@ import { cmsPageModule } from './store/page' import { cmsBlockModule } from './store/block' import { cmsHierarchyModule } from './store/hierarchy' -import { createModule } from '@vue-storefront/core/lib/module' -import { beforeRegistration } from './hooks/beforeRegistration' import { plugin } from './store/plugin' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { StorefrontModule } from '@vue-storefront/module'; +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -export const KEY = 'cms' -export const cacheStorage = initCacheStorage(KEY) -export const Cms = createModule({ - key: KEY, - store: { modules: [ - { key: 'cmsPage', module: cmsPageModule }, - { key: 'cmsBlock', module: cmsBlockModule }, - { key: 'cmsHierarchy', module: cmsHierarchyModule } - ], - plugin }, - beforeRegistration -}) +export const cacheStorage = StorageManager.init('cms') + +export const CmsModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + store.registerModule('cmsPage', cmsPageModule) + store.registerModule('cmsBlock', cmsBlockModule) + store.registerModule('cmsHierarchy', cmsHierarchyModule) + store.subscribe(plugin) +} diff --git a/core/modules/user/hooks/beforeRegistration.ts b/core/modules/user/hooks/beforeRegistration.ts index 0c01095bc9..bb197011a0 100644 --- a/core/modules/user/hooks/beforeRegistration.ts +++ b/core/modules/user/hooks/beforeRegistration.ts @@ -1,15 +1,5 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export function beforeRegistration ({ Vue, config, store, isServer }) { - const storeView = currentStoreView() - const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : '' - - StorageManager.set('user', new UniversalStorage(localForage.createInstance({ - name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop', - storeName: 'user', - driver: localForage[config.localForage.defaultDrivers['user']] - }))) + StorageManager.init('user') } diff --git a/src/modules/index.ts b/src/modules/index.ts index 7c07753eda..d8486017f4 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -13,7 +13,7 @@ import { RecentlyViewedModule } from '@vue-storefront/core/modules/recently-view import { UrlModule } from '@vue-storefront/core/modules/url' import { BreadcrumbsModule } from '@vue-storefront/core/modules/breadcrumbs' import { OrderModule } from '@vue-storefront/core/modules/order' - +import { CmsModule } from '@vue-storefront/core/modules/cms' // import { GoogleAnalyticsModule } from './google-analytics'; // import { HotjarModule } from './hotjar'; import { GoogleTagManagerModule } from './google-tag-manager'; @@ -27,6 +27,7 @@ import { registerModule } from '@vue-storefront/module' // TODO:distributed across proper pages BEFORE 1.11 export function registerNewModules () { + registerModule(UrlModule) registerModule(CatalogModule) registerModule(CheckoutModule) registerModule(CartModule) @@ -44,11 +45,11 @@ export function registerNewModules () { registerModule(RawOutputExampleModule) registerModule(AmpRendererModule) registerModule(InstantCheckoutModule) - registerModule(UrlModule) registerModule(CatalogNextModule) registerModule(CompareModule) registerModule(BreadcrumbsModule) registerModule(OrderModule) + registerModule(CmsModule) } // Deprecated API, will be removed in 2.0 From a0c48f460e446cae282822dd5761a71c362925f5 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 13:02:59 +0200 Subject: [PATCH 14/27] refactor user module to new format --- core/modules-entry.ts | 2 - core/modules/user/index.ts | 79 ++++++++++++++++++++++++++------ core/modules/user/store/index.ts | 2 +- src/modules/index.ts | 13 ++++-- 4 files changed, 74 insertions(+), 22 deletions(-) diff --git a/core/modules-entry.ts b/core/modules-entry.ts index f14b3079c8..73d69ec357 100644 --- a/core/modules-entry.ts +++ b/core/modules-entry.ts @@ -1,10 +1,8 @@ import { VueStorefrontModule } from '@vue-storefront/core/lib/module' -import { User } from './modules/user' import { registerModules } from 'src/modules' // @deprecated from 2.0, use registerModule instead export const enabledModules: VueStorefrontModule[] = [ - User, ...registerModules ] diff --git a/core/modules/user/index.ts b/core/modules/user/index.ts index ea5f0ba79f..9caf978579 100644 --- a/core/modules/user/index.ts +++ b/core/modules/user/index.ts @@ -1,15 +1,66 @@ -import { module } from './store' -import { createModule } from '@vue-storefront/core/lib/module' +import { userStore } from './store' import { beforeEach } from './router/beforeEach' -import { beforeRegistration } from './hooks/beforeRegistration' -import { afterRegistration } from './hooks/afterRegistration' - -export const KEY = 'user' - -export const User = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] }, - beforeRegistration, - afterRegistration, - router: { beforeEach } -}) +import { StorefrontModule } from '@vue-storefront/module' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' +import { isServer } from '@vue-storefront/core/helpers' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' +import * as types from './store/mutation-types' + +export const UserModule: StorefrontModule = async function (app, store, router, moduleConfig, appConfig) { + StorageManager.init('user') + store.registerModule('user', userStore) + router.beforeEach(beforeEach) + if (!isServer) { + await store.dispatch('user/startSession') + + EventBus.$on('user-before-logout', () => { + store.dispatch('user/logout', { silent: false }) + // TODO: Move it to theme + store.commit('ui/setSubmenu', { + depth: 0 + }) + }) + + EventBus.$on('user-after-loggedin', receivedData => { + // TODO: Make independent of checkout module + store.dispatch('checkout/savePersonalDetails', { + firstName: receivedData.firstname, + lastName: receivedData.lastname, + emailAddress: receivedData.email + }) + }) + } + + store.subscribe((mutation, state) => { + const type = mutation.type + + if ( + type.endsWith(types.USER_INFO_LOADED) + ) { + StorageManager.get('user').setItem('current-user', state.user.current).catch((reason) => { + console.error(reason) // it doesn't work on SSR + }) // populate cache + } + + if ( + type.endsWith(types.USER_ORDERS_HISTORY_LOADED) + ) { + StorageManager.get('user').setItem('orders-history', state.user.orders_history).catch((reason) => { + console.error(reason) // it doesn't work on SSR + }) // populate cache + } + + if ( + type.endsWith(types.USER_TOKEN_CHANGED) + ) { + StorageManager.get('user').setItem('current-token', state.user.token).catch((reason) => { + console.error(reason) // it doesn't work on SSR + }) // populate cache + if (state.user.refreshToken) { + StorageManager.get('user').setItem('current-refresh-token', state.user.refreshToken).catch((reason) => { + console.error(reason) // it doesn't work on SSR + }) // populate cache + } + } + }) +} diff --git a/core/modules/user/store/index.ts b/core/modules/user/store/index.ts index 94101758ca..eca304504f 100644 --- a/core/modules/user/store/index.ts +++ b/core/modules/user/store/index.ts @@ -5,7 +5,7 @@ import mutations from './mutations' import RootState from '@vue-storefront/core/types/RootState' import UserState from '../types/UserState' -export const module: Module = { +export const userStore: Module = { namespaced: true, state: { token: '', diff --git a/src/modules/index.ts b/src/modules/index.ts index d8486017f4..782a6d37cc 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -14,6 +14,7 @@ import { UrlModule } from '@vue-storefront/core/modules/url' import { BreadcrumbsModule } from '@vue-storefront/core/modules/breadcrumbs' import { OrderModule } from '@vue-storefront/core/modules/order' import { CmsModule } from '@vue-storefront/core/modules/cms' +import { UserModule }from '@vue-storefront/core/modules/user' // import { GoogleAnalyticsModule } from './google-analytics'; // import { HotjarModule } from './hotjar'; import { GoogleTagManagerModule } from './google-tag-manager'; @@ -36,6 +37,12 @@ export function registerNewModules () { registerModule(WishlistModule) registerModule(NewsletterModule) registerModule(NotificationModule) + registerModule(UserModule) + registerModule(CatalogNextModule) + registerModule(CompareModule) + registerModule(BreadcrumbsModule) + registerModule(OrderModule) + registerModule(CmsModule) registerModule(RecentlyViewedModule) registerModule(GoogleTagManagerModule) // registerModule(GoogleAnalyticsModule) @@ -45,11 +52,7 @@ export function registerNewModules () { registerModule(RawOutputExampleModule) registerModule(AmpRendererModule) registerModule(InstantCheckoutModule) - registerModule(CatalogNextModule) - registerModule(CompareModule) - registerModule(BreadcrumbsModule) - registerModule(OrderModule) - registerModule(CmsModule) + } // Deprecated API, will be removed in 2.0 From 64ef84aa1e57012599840d1491a1380c8a09ee85 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 13:33:53 +0200 Subject: [PATCH 15/27] rewrite sample custom gql entity module to new format --- src/modules/index.ts | 3 +- .../sample-custom-entity-graphql/index.ts | 71 ++++++++++++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/modules/index.ts b/src/modules/index.ts index 782a6d37cc..018049cc48 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -14,7 +14,7 @@ import { UrlModule } from '@vue-storefront/core/modules/url' import { BreadcrumbsModule } from '@vue-storefront/core/modules/breadcrumbs' import { OrderModule } from '@vue-storefront/core/modules/order' import { CmsModule } from '@vue-storefront/core/modules/cms' -import { UserModule }from '@vue-storefront/core/modules/user' +import { UserModule } from '@vue-storefront/core/modules/user' // import { GoogleAnalyticsModule } from './google-analytics'; // import { HotjarModule } from './hotjar'; import { GoogleTagManagerModule } from './google-tag-manager'; @@ -52,7 +52,6 @@ export function registerNewModules () { registerModule(RawOutputExampleModule) registerModule(AmpRendererModule) registerModule(InstantCheckoutModule) - } // Deprecated API, will be removed in 2.0 diff --git a/src/modules/sample-custom-entity-graphql/index.ts b/src/modules/sample-custom-entity-graphql/index.ts index 60a4d86a67..1cd664a298 100644 --- a/src/modules/sample-custom-entity-graphql/index.ts +++ b/src/modules/sample-custom-entity-graphql/index.ts @@ -1,8 +1,63 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { afterRegistration } from './hooks/afterRegistration' - -const KEY = 'sample-custom-entity-gql' -export const SampleCustomEntityGql = createModule({ - key: KEY, - afterRegistration -}) +import { getSearchAdapter } from '@vue-storefront/core/lib/search/adapter/searchAdapterFactory' +import { processESResponseType } from '@vue-storefront/core/lib/search/adapter/graphql/processor/processType' +import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' +import { Logger } from '@vue-storefront/core/lib/logger' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' +import { StorefrontModule } from '@vue-storefront/module' + +const TEST_ENTITY_TYPE = 'testentity' + +export const CustomEntityGqlModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { + EventBus.$on('application-after-init', async () => { + Logger.debug('Example of custom entity graphql extension')() + + // create GraphQL searchAdapter + let searchAdapter = await getSearchAdapter('graphql') + + // register custom entity type using registerEntityTypeByQuery + // different GraphQL servers could be used for different entity types + // resolver for testentity should be implemented on the GraphQL server provided + searchAdapter.registerEntityTypeByQuery(TEST_ENTITY_TYPE, { + url: 'http://localhost:8080/graphql/', + query: require('../queries/testentity.gql'), + queryProcessor: (query) => { + // function that can modify the query each time before it's being executed + return query + }, + resultPorcessor: (resp, start, size) => { + if (resp === null) { + throw new Error('Invalid GraphQL result - null not expected') + } + if (resp.hasOwnProperty('data')) { + return processESResponseType(resp.data.testentity, start, size) + } else { + if (resp.error) { + throw new Error(JSON.stringify(resp.error)) + } else { + throw new Error('Unknown error with GraphQL result in resultProcessor for entity type \'category\'') + } + } + } + }) + + const storeView = currentStoreView() + + // create an empty SearchQuery to get all data for the new custom entity + const searchQuery = new SearchQuery() + + // prepare a SearchRequest object + const Request = { + store: storeView.storeCode, // TODO: add grouped product and bundled product support + type: TEST_ENTITY_TYPE, + searchQuery: searchQuery, + sort: '' + } + + // apply test search + searchAdapter.search(Request).then((resp) => { // we're always trying to populate cache - when online + const res = searchAdapter.entities[Request.type].resultPorcessor(resp, 0, 200) + Logger.log('Testentity response: ', res)() + }) + }) +} From 5bb31909b71c1940a796463cdc83a0f85629ca9d Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 13:53:09 +0200 Subject: [PATCH 16/27] rewrite customentityGql and deprecate extensions --- core/app.ts | 4 -- core/compatibility/lib/extensions.ts | 14 ---- src/extensions/index.ts | 5 -- .../hooks/afterRegistration.ts | 64 ------------------- .../sample-custom-entity-graphql/index.ts | 2 +- .../{queries => }/testentity.gql | 0 6 files changed, 1 insertion(+), 88 deletions(-) delete mode 100644 core/compatibility/lib/extensions.ts delete mode 100644 src/extensions/index.ts delete mode 100644 src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts rename src/modules/sample-custom-entity-graphql/{queries => }/testentity.gql (100%) diff --git a/core/app.ts b/core/app.ts index 3b1d731355..fe4da6d06d 100755 --- a/core/app.ts +++ b/core/app.ts @@ -31,9 +31,6 @@ import store from '@vue-storefront/core/store' import { enabledModules } from './modules-entry' -// Will be deprecated in 2.0 -import { registerExtensions } from '@vue-storefront/core/compatibility/lib/extensions' -import { registerExtensions as extensions } from 'src/extensions' import globalConfig from 'config' import { injectReferences } from '@vue-storefront/module' @@ -119,7 +116,6 @@ const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vu injectReferences(app, store, router, globalConfig) registerNewModules() registerModules(enabledModules, appContext) - registerExtensions(extensions, app, router, store, config, ssrContext) registerTheme(globalConfig.theme, app, router, store, globalConfig, ssrContext) coreHooksExecutors.afterAppInit() diff --git a/core/compatibility/lib/extensions.ts b/core/compatibility/lib/extensions.ts deleted file mode 100644 index 6a2567dfd1..0000000000 --- a/core/compatibility/lib/extensions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Logger } from '@vue-storefront/core/lib/logger' - -export function registerExtensions (extensions, app, router, store, config, ssrContext = null) { - for (let extEntryPoint of extensions) { - if (extEntryPoint !== null) { - if (extEntryPoint.default) extEntryPoint = extEntryPoint.default - let extDescriptor = extEntryPoint(app, router, store, config, ssrContext) // register module - if (extDescriptor != null) { - Logger.warn('Extension' + extDescriptor.EXTENSION_KEY + ' registered. Extensions are deprecated and will be removed from VS core. Use modules instead')() - app.$emit('application-after-registerExtensions', extDescriptor) - } - } - } -} diff --git a/src/extensions/index.ts b/src/extensions/index.ts deleted file mode 100644 index 8519f17dce..0000000000 --- a/src/extensions/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** - * If you have some extensions that are not yet ported to modules you can register them here - * Keep in mind that extensions will be depreciated in next versions of Vue Storefront and replaced by modules - */ -export const registerExtensions = [] diff --git a/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts b/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts deleted file mode 100644 index 1195b1ec35..0000000000 --- a/src/modules/sample-custom-entity-graphql/hooks/afterRegistration.ts +++ /dev/null @@ -1,64 +0,0 @@ - -import { getSearchAdapter } from '@vue-storefront/core/lib/search/adapter/searchAdapterFactory' -import { processESResponseType } from '@vue-storefront/core/lib/search/adapter/graphql/processor/processType' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { Logger } from '@vue-storefront/core/lib/logger' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' - -const EXTENSION_KEY = 'sample-custom-entity-graphql-extension' -const TEST_ENTITY_TYPE = 'testentity' - -export function afterRegistration ({ Vue, config, store, isServer }) { - EventBus.$on('application-after-init', async () => { - Logger.debug('Example of custom entity graphql extension')() - - // create GraphQL searchAdapter - let searchAdapter = await getSearchAdapter('graphql') - - // register custom entity type using registerEntityTypeByQuery - // different GraphQL servers could be used for different entity types - // resolver for testentity should be implemented on the GraphQL server provided - searchAdapter.registerEntityTypeByQuery(TEST_ENTITY_TYPE, { - url: 'http://localhost:8080/graphql/', - query: require('../queries/testentity.gql'), - queryProcessor: (query) => { - // function that can modify the query each time before it's being executed - return query - }, - resultPorcessor: (resp, start, size) => { - if (resp === null) { - throw new Error('Invalid GraphQL result - null not expected') - } - if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.testentity, start, size) - } else { - if (resp.error) { - throw new Error(JSON.stringify(resp.error)) - } else { - throw new Error('Unknown error with GraphQL result in resultProcessor for entity type \'category\'') - } - } - } - }) - - const storeView = currentStoreView() - - // create an empty SearchQuery to get all data for the new custom entity - const searchQuery = new SearchQuery() - - // prepare a SearchRequest object - const Request = { - store: storeView.storeCode, // TODO: add grouped product and bundled product support - type: TEST_ENTITY_TYPE, - searchQuery: searchQuery, - sort: '' - } - - // apply test search - searchAdapter.search(Request).then((resp) => { // we're always trying to populate cache - when online - const res = searchAdapter.entities[Request.type].resultPorcessor(resp, 0, 200) - Logger.log('Testentity response: ', res)() - }) - }) -} diff --git a/src/modules/sample-custom-entity-graphql/index.ts b/src/modules/sample-custom-entity-graphql/index.ts index 1cd664a298..f214f91b9a 100644 --- a/src/modules/sample-custom-entity-graphql/index.ts +++ b/src/modules/sample-custom-entity-graphql/index.ts @@ -20,7 +20,7 @@ export const CustomEntityGqlModule: StorefrontModule = function (app, store, rou // resolver for testentity should be implemented on the GraphQL server provided searchAdapter.registerEntityTypeByQuery(TEST_ENTITY_TYPE, { url: 'http://localhost:8080/graphql/', - query: require('../queries/testentity.gql'), + query: require('./testentity.gql'), queryProcessor: (query) => { // function that can modify the query each time before it's being executed return query diff --git a/src/modules/sample-custom-entity-graphql/queries/testentity.gql b/src/modules/sample-custom-entity-graphql/testentity.gql similarity index 100% rename from src/modules/sample-custom-entity-graphql/queries/testentity.gql rename to src/modules/sample-custom-entity-graphql/testentity.gql From 8db9530bfba15149ef3b32d676d176baf5c65a9d Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 14:54:56 +0200 Subject: [PATCH 17/27] rename initCacheStorage to cache.ts --- core/build/webpack.base.config.ts | 3 ++- core/helpers/{initCacheStorage.ts => cache.ts} | 0 core/modules/cart/test/unit/index.spec.ts | 2 +- core/modules/offline-order/components/CancelOrders.ts | 4 ++-- core/modules/offline-order/helpers/onNetworkStatusChange.ts | 4 ++-- core/modules/order/index.ts | 3 +-- core/store/lib/storage-manager.ts | 5 +++-- src/themes/default/index.js | 4 ++-- 8 files changed, 13 insertions(+), 12 deletions(-) rename core/helpers/{initCacheStorage.ts => cache.ts} (100%) diff --git a/core/build/webpack.base.config.ts b/core/build/webpack.base.config.ts index 72b7f6a2cf..88dd15ecd7 100644 --- a/core/build/webpack.base.config.ts +++ b/core/build/webpack.base.config.ts @@ -119,7 +119,8 @@ export default { // Backward compatible '@vue-storefront/core/store/lib/multistore': path.resolve(__dirname, '../lib/multistore.ts'), 'src/modules/order-history/components/UserOrders': path.resolve(__dirname, '../../core/modules/order/components/UserOrdersHistory'), - '@vue-storefront/core/modules/social-share/components/WebShare': path.resolve(__dirname, '../../src/themes/default/components/theme/WebShare.vue') + '@vue-storefront/core/modules/social-share/components/WebShare': path.resolve(__dirname, '../../src/themes/default/components/theme/WebShare.vue'), + '@vue-storefront/core/helpers/initCacheStorage': path.resolve(__dirname, '../lib/cache.ts') } }, module: { diff --git a/core/helpers/initCacheStorage.ts b/core/helpers/cache.ts similarity index 100% rename from core/helpers/initCacheStorage.ts rename to core/helpers/cache.ts diff --git a/core/modules/cart/test/unit/index.spec.ts b/core/modules/cart/test/unit/index.spec.ts index 8b0bbd764e..def95503d6 100644 --- a/core/modules/cart/test/unit/index.spec.ts +++ b/core/modules/cart/test/unit/index.spec.ts @@ -4,7 +4,7 @@ jest.mock('../../store', () => ({})); jest.mock('@vue-storefront/module', () => ({ createModule: jest.fn(() => ({ module: 'cart' })) })); jest.mock('../../helpers/cartCacheHandler', () => ({ cartCacheHandlerFactory: jest.fn() })) jest.mock('@vue-storefront/core/helpers', () => ({ isServer: false })) -jest.mock('@vue-storefront/core/helpers/initCacheStorage', () => ({ initCacheStorage: jest.fn() })); +jest.mock('@vue-storefront/core/helpers/cache', () => ({ initCacheStorage: jest.fn() })); describe('Cart Module', () => { it('can be initialized', () => { diff --git a/core/modules/offline-order/components/CancelOrders.ts b/core/modules/offline-order/components/CancelOrders.ts index 22609570cd..4baf2ca0b1 100644 --- a/core/modules/offline-order/components/CancelOrders.ts +++ b/core/modules/offline-order/components/CancelOrders.ts @@ -1,10 +1,10 @@ import { Logger } from '@vue-storefront/core/lib/logger' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export const CancelOrders = { methods: { cancelOrders () { - const ordersCollection = initCacheStorage('orders', false, true) + const ordersCollection = StorageManager.get('orders') ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { ordersCollection.removeItem(id) diff --git a/core/modules/offline-order/helpers/onNetworkStatusChange.ts b/core/modules/offline-order/helpers/onNetworkStatusChange.ts index 1e8f0852ff..94d38cb310 100644 --- a/core/modules/offline-order/helpers/onNetworkStatusChange.ts +++ b/core/modules/offline-order/helpers/onNetworkStatusChange.ts @@ -1,7 +1,7 @@ import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus/index' import { Logger } from '@vue-storefront/core/lib/logger' import config from 'config' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' export function onNetworkStatusChange (store) { Logger.log('Are we online: ' + navigator.onLine, 'offline-order')() @@ -13,7 +13,7 @@ export function onNetworkStatusChange (store) { EventBus.$emit('order/PROCESS_QUEUE', { config: config }) // process checkout queue } else { const ordersToConfirm = [] - const ordersCollection = initCacheStorage('orders', false, true) + const ordersCollection = StorageManager.get('orders') ordersCollection.iterate((order, id, iterationNumber) => { if (!order.transmited) { diff --git a/core/modules/order/index.ts b/core/modules/order/index.ts index 5897f8cdb5..04e73aea42 100644 --- a/core/modules/order/index.ts +++ b/core/modules/order/index.ts @@ -7,7 +7,6 @@ import rootStore from '@vue-storefront/core/store' import i18n from '@vue-storefront/i18n' import { serial, onlineHelper, processURLAddress } from '@vue-storefront/core/helpers' import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage' import { isServer } from '@vue-storefront/core/helpers' import { StorefrontModule } from '@vue-storefront/module'; @@ -20,7 +19,7 @@ export const OrderModule: StorefrontModule = function (app, store, router, modul EventBus.$on('order/PROCESS_QUEUE', async event => { if (onlineHelper.isOnline) { Logger.log('Sending out orders queue to server ...')() - const ordersCollection = initCacheStorage('orders', false, true) + const ordersCollection = StorageManager.get('orders') const fetchQueue = [] ordersCollection.iterate((order, id) => { diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index c86781cc40..941477e6cc 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -1,5 +1,5 @@ import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { initCacheStorage, prepareCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { initCacheStorage, prepareCacheStorage } from '@vue-storefront/core/helpers/cache'; import { Logger } from '@vue-storefront/core/lib/logger' const StorageManager = { @@ -32,7 +32,8 @@ const StorageManager = { return !!this.storageMap[collectionName] }, /** - * Returns the UniversalStorage driver for specific key + * Returns the UniversalStorage driver for specific key. + * If it doesnt exist it creates it with defaults for `init` * @returns UniversalStorage */ get: function (collectionName): UniversalStorage { diff --git a/src/themes/default/index.js b/src/themes/default/index.js index 593d6e03d6..7eae4e1299 100644 --- a/src/themes/default/index.js +++ b/src/themes/default/index.js @@ -7,11 +7,11 @@ import '@vue-storefront/core/lib/passive-listeners' import { RouterManager } from '@vue-storefront/core/lib/router-manager' import { once } from '@vue-storefront/core/helpers' -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; import { claimsStore } from 'theme/store/claims' import { homepageStore } from 'theme/store/homepage' import { uiStore } from 'theme/store/ui' import { promotedStore } from 'theme/store/promoted-offers' +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' once('__VUE_EXTEND_DROPPOINT_VPB__', () => { Vue.use(VueProgressBar) @@ -26,7 +26,7 @@ function initTheme (app, router, store, config, ssrContext) { setupMultistoreRoutes(config, router, routes) RouterManager.addRoutes(routes, router) - initCacheStorage('claimCollection'); + StorageManager.init('claimCollection'); store.registerModule('claims', claimsStore); store.registerModule('homepage', homepageStore); store.registerModule('ui', uiStore); From 060c21c4c72163e5c6d6ec60a67c789e2133d3ee Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 15:42:46 +0200 Subject: [PATCH 18/27] moved unused modules to sample directory --- core/build/webpack.base.config.ts | 2 +- core/helpers/cache.ts | 35 --- core/store/lib/storage-manager.ts | 41 ++- .../components/DroppointMap.vue | 239 ------------------ src/modules/droppoint-shipping/index.ts | 8 - .../droppoint-shipping/store/actions.ts | 12 - src/modules/droppoint-shipping/store/index.ts | 7 - src/modules/index.ts | 2 - src/modules/payment-cash-on-delivery/index.ts | 21 +- src/modules/raw-output-example/index.ts | 6 - .../raw-output-example/pages/NoJSExample.vue | 33 --- .../pages/NoLayoutAppendPrependExample.vue | 33 --- .../pages/RawOutputExample.vue | 30 --- .../raw-output-example/router/routes.ts | 9 - .../sample-custom-entity-graphql/index.ts | 63 ----- .../testentity.gql | 8 - 16 files changed, 53 insertions(+), 496 deletions(-) delete mode 100644 core/helpers/cache.ts delete mode 100644 src/modules/droppoint-shipping/components/DroppointMap.vue delete mode 100644 src/modules/droppoint-shipping/index.ts delete mode 100644 src/modules/droppoint-shipping/store/actions.ts delete mode 100644 src/modules/droppoint-shipping/store/index.ts delete mode 100644 src/modules/raw-output-example/index.ts delete mode 100755 src/modules/raw-output-example/pages/NoJSExample.vue delete mode 100755 src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue delete mode 100755 src/modules/raw-output-example/pages/RawOutputExample.vue delete mode 100644 src/modules/raw-output-example/router/routes.ts delete mode 100644 src/modules/sample-custom-entity-graphql/index.ts delete mode 100644 src/modules/sample-custom-entity-graphql/testentity.gql diff --git a/core/build/webpack.base.config.ts b/core/build/webpack.base.config.ts index 88dd15ecd7..8e57d5f8c6 100644 --- a/core/build/webpack.base.config.ts +++ b/core/build/webpack.base.config.ts @@ -120,7 +120,7 @@ export default { '@vue-storefront/core/store/lib/multistore': path.resolve(__dirname, '../lib/multistore.ts'), 'src/modules/order-history/components/UserOrders': path.resolve(__dirname, '../../core/modules/order/components/UserOrdersHistory'), '@vue-storefront/core/modules/social-share/components/WebShare': path.resolve(__dirname, '../../src/themes/default/components/theme/WebShare.vue'), - '@vue-storefront/core/helpers/initCacheStorage': path.resolve(__dirname, '../lib/cache.ts') + '@vue-storefront/core/helpers/initCacheStorage': path.resolve(__dirname, '../store/lib/storage-manager.ts') } }, module: { diff --git a/core/helpers/cache.ts b/core/helpers/cache.ts deleted file mode 100644 index b5b5be6607..0000000000 --- a/core/helpers/cache.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as localForage from 'localforage' -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import config from 'config' - -/** create Universal Storage instance */ -export function prepareCacheStorage (key, localised = true, storageQuota = 0) { - const storeView = currentStoreView() - const dbNamePrefix = storeView && storeView.storeCode ? storeView.storeCode + '-' : '' - const cacheDriver = config.localForage && config.localForage.defaultDrivers[key] - ? config.localForage.defaultDrivers[key] - : 'LOCALSTORAGE' - - return new UniversalStorage(localForage.createInstance({ - name: localised ? `${dbNamePrefix}shop` : 'shop', - storeName: key, - driver: localForage[cacheDriver] - }), true, storageQuota) -} - -/** @deprecated, to be removed in 2.0 in favor to `StorageManager` - * Inits cache storage for given module. By default via local storage - * */ -export function initCacheStorage (key, localised = true, registerStorgeManager = true) { - if (registerStorgeManager) { - if (!StorageManager.exists(key)) { - return StorageManager.set(key, prepareCacheStorage(key, localised)) - } else { - return StorageManager.get(key) - } - } else { - return prepareCacheStorage(key, localised) - } -} diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index 941477e6cc..d27adc99fb 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -1,6 +1,8 @@ -import UniversalStorage from '@vue-storefront/core/store/lib/storage' -import { initCacheStorage, prepareCacheStorage } from '@vue-storefront/core/helpers/cache'; import { Logger } from '@vue-storefront/core/lib/logger' +import * as localForage from 'localforage' +import UniversalStorage from '@vue-storefront/core/store/lib/storage' +import { currentStoreView } from '@vue-storefront/core/lib/multistore' +import config from 'config' const StorageManager = { currentStoreCode: '', @@ -12,7 +14,7 @@ const StorageManager = { * @param storageQuota max size of storage, 0 if unlimited (default `0`) */ init: function (collectionName: string, isLocalised = true, storageQuota = 0) { - this.storageMap[collectionName] = prepareCacheStorage(collectionName, isLocalised, storageQuota) + this.storageMap[collectionName] = _prepareCacheStorage(collectionName, isLocalised, storageQuota) return this.storageMap[collectionName] }, /** @@ -32,7 +34,7 @@ const StorageManager = { return !!this.storageMap[collectionName] }, /** - * Returns the UniversalStorage driver for specific key. + * Returns the UniversalStorage driver for specific key. * If it doesnt exist it creates it with defaults for `init` * @returns UniversalStorage */ @@ -46,4 +48,33 @@ const StorageManager = { } } -export { StorageManager } +function _prepareCacheStorage (key, localised = true, storageQuota = 0) { + const storeView = currentStoreView() + const dbNamePrefix = storeView && storeView.storeCode ? storeView.storeCode + '-' : '' + const cacheDriver = config.localForage && config.localForage.defaultDrivers[key] + ? config.localForage.defaultDrivers[key] + : 'LOCALSTORAGE' + + return new UniversalStorage(localForage.createInstance({ + name: localised ? `${dbNamePrefix}shop` : 'shop', + storeName: key, + driver: localForage[cacheDriver] + }), true, storageQuota) +} + +/** + * @deprecated to be removed in 2.0 in favor to `StorageManager` + * */ +function initCacheStorage (key, localised = true, registerStorgeManager = true) { + if (registerStorgeManager) { + if (!StorageManager.exists(key)) { + return StorageManager.set(key, _prepareCacheStorage(key, localised)) + } else { + return StorageManager.get(key) + } + } else { + return _prepareCacheStorage(key, localised) + } +} + +export { StorageManager, initCacheStorage } diff --git a/src/modules/droppoint-shipping/components/DroppointMap.vue b/src/modules/droppoint-shipping/components/DroppointMap.vue deleted file mode 100644 index 8d799e115f..0000000000 --- a/src/modules/droppoint-shipping/components/DroppointMap.vue +++ /dev/null @@ -1,239 +0,0 @@ - - - - - diff --git a/src/modules/droppoint-shipping/index.ts b/src/modules/droppoint-shipping/index.ts deleted file mode 100644 index 2d3050c1dc..0000000000 --- a/src/modules/droppoint-shipping/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { module } from './store' - -export const KEY = 'droppoint-shipping' -export const DroppointShipping = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module }] } -}) diff --git a/src/modules/droppoint-shipping/store/actions.ts b/src/modules/droppoint-shipping/store/actions.ts deleted file mode 100644 index bc96845fb4..0000000000 --- a/src/modules/droppoint-shipping/store/actions.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ActionTree } from 'vuex'; -import { execute as taskExecute } from '@vue-storefront/core/lib/sync/task' -import * as entities from '@vue-storefront/core/store/lib/entities' - -// actions -export const actions: ActionTree = { - fetch ({ commit }, request) { - const taskId = entities.uniqueEntityId(request) - request.task_id = taskId.toString() - return taskExecute(request) - } -} diff --git a/src/modules/droppoint-shipping/store/index.ts b/src/modules/droppoint-shipping/store/index.ts deleted file mode 100644 index 50bde5e22e..0000000000 --- a/src/modules/droppoint-shipping/store/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Module } from 'vuex' -import { actions } from './actions' - -export const module: Module = { - namespaced: true, - actions -} diff --git a/src/modules/index.ts b/src/modules/index.ts index 018049cc48..7d63eaa91d 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -21,7 +21,6 @@ import { GoogleTagManagerModule } from './google-tag-manager'; import { AmpRendererModule } from './amp-renderer'; import { PaymentBackendMethodsModule } from './payment-backend-methods'; import { PaymentCashOnDeliveryModule } from './payment-cash-on-delivery'; -import { RawOutputExampleModule } from './raw-output-example' import { InstantCheckoutModule } from './instant-checkout' import { registerModule } from '@vue-storefront/module' @@ -49,7 +48,6 @@ export function registerNewModules () { // registerModule(HotjarModule) registerModule(PaymentBackendMethodsModule) registerModule(PaymentCashOnDeliveryModule) - registerModule(RawOutputExampleModule) registerModule(AmpRendererModule) registerModule(InstantCheckoutModule) } diff --git a/src/modules/payment-cash-on-delivery/index.ts b/src/modules/payment-cash-on-delivery/index.ts index 72aea80caf..f917911ce2 100644 --- a/src/modules/payment-cash-on-delivery/index.ts +++ b/src/modules/payment-cash-on-delivery/index.ts @@ -2,33 +2,44 @@ import { StorefrontModule } from '@vue-storefront/module'; import { isServer } from '@vue-storefront/core/helpers' import Vue from 'vue'; import InfoComponent from './components/Info.vue' +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' export const PaymentCashOnDeliveryModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' let correctPaymentMethod = false const placeOrder = () => { if (correctPaymentMethod) { - Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + EventBus.$emit('checkout-do-placeOrder', {}) } } - + // Update the methods + let paymentMethodConfig = { + 'title': 'Cash on delivery', + 'code': 'cashondelivery', + 'cost': 0, + 'costInclTax': 0, + 'default': true, + 'offline': true, + 'is_server_method': false + } + store.dispatch('payment/addMethod', paymentMethodConfig) if (!isServer) { // Update the methods let paymentMethodConfig = { 'title': 'Cash on delivery', 'code': 'cashondelivery', 'cost': 0, - 'costInclTax': 0, + 'cost_incl_tax': 0, 'default': true, 'offline': true, 'is_server_method': false } store.dispatch('payment/addMethod', paymentMethodConfig) - Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + EventBus.$on('checkout-before-placeOrder', placeOrder) // Mount the info component when required. - Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { + EventBus.$on('checkout-payment-method-changed', (paymentMethodCode) => { let methods = store.state['payment-backend-methods'].methods if (methods) { let method = methods.find(item => (item.code === paymentMethodCode)) diff --git a/src/modules/raw-output-example/index.ts b/src/modules/raw-output-example/index.ts deleted file mode 100644 index ed8a2ad261..0000000000 --- a/src/modules/raw-output-example/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { routes } from './router/routes' -import { StorefrontModule } from '@vue-storefront/module'; - -export const RawOutputExampleModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - router.addRoutes(routes); -} diff --git a/src/modules/raw-output-example/pages/NoJSExample.vue b/src/modules/raw-output-example/pages/NoJSExample.vue deleted file mode 100755 index 1e09d70888..0000000000 --- a/src/modules/raw-output-example/pages/NoJSExample.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - diff --git a/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue b/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue deleted file mode 100755 index ec0ed77d9d..0000000000 --- a/src/modules/raw-output-example/pages/NoLayoutAppendPrependExample.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - diff --git a/src/modules/raw-output-example/pages/RawOutputExample.vue b/src/modules/raw-output-example/pages/RawOutputExample.vue deleted file mode 100755 index 5033610f6e..0000000000 --- a/src/modules/raw-output-example/pages/RawOutputExample.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - diff --git a/src/modules/raw-output-example/router/routes.ts b/src/modules/raw-output-example/router/routes.ts deleted file mode 100644 index dc935d3cb4..0000000000 --- a/src/modules/raw-output-example/router/routes.ts +++ /dev/null @@ -1,9 +0,0 @@ -import NoJSExample from '../pages/NoJSExample.vue' -import RawOutputExample from '../pages/RawOutputExample.vue' -import NoLayoutAppendPrependExample from '../pages/NoLayoutAppendPrependExample.vue' - -export const routes = [ - { path: '/raw-output-example.xml', component: RawOutputExample, meta: { layout: 'empty' } }, - { path: '/append-prepend.html', component: NoLayoutAppendPrependExample, meta: { layout: 'empty' } }, - { path: '/no-js.html', component: NoJSExample, meta: { layout: 'default' } } -] diff --git a/src/modules/sample-custom-entity-graphql/index.ts b/src/modules/sample-custom-entity-graphql/index.ts deleted file mode 100644 index f214f91b9a..0000000000 --- a/src/modules/sample-custom-entity-graphql/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { getSearchAdapter } from '@vue-storefront/core/lib/search/adapter/searchAdapterFactory' -import { processESResponseType } from '@vue-storefront/core/lib/search/adapter/graphql/processor/processType' -import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import SearchQuery from '@vue-storefront/core/lib/search/searchQuery' -import { Logger } from '@vue-storefront/core/lib/logger' -import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' -import { StorefrontModule } from '@vue-storefront/module' - -const TEST_ENTITY_TYPE = 'testentity' - -export const CustomEntityGqlModule: StorefrontModule = function (app, store, router, moduleConfig, appConfig) { - EventBus.$on('application-after-init', async () => { - Logger.debug('Example of custom entity graphql extension')() - - // create GraphQL searchAdapter - let searchAdapter = await getSearchAdapter('graphql') - - // register custom entity type using registerEntityTypeByQuery - // different GraphQL servers could be used for different entity types - // resolver for testentity should be implemented on the GraphQL server provided - searchAdapter.registerEntityTypeByQuery(TEST_ENTITY_TYPE, { - url: 'http://localhost:8080/graphql/', - query: require('./testentity.gql'), - queryProcessor: (query) => { - // function that can modify the query each time before it's being executed - return query - }, - resultPorcessor: (resp, start, size) => { - if (resp === null) { - throw new Error('Invalid GraphQL result - null not expected') - } - if (resp.hasOwnProperty('data')) { - return processESResponseType(resp.data.testentity, start, size) - } else { - if (resp.error) { - throw new Error(JSON.stringify(resp.error)) - } else { - throw new Error('Unknown error with GraphQL result in resultProcessor for entity type \'category\'') - } - } - } - }) - - const storeView = currentStoreView() - - // create an empty SearchQuery to get all data for the new custom entity - const searchQuery = new SearchQuery() - - // prepare a SearchRequest object - const Request = { - store: storeView.storeCode, // TODO: add grouped product and bundled product support - type: TEST_ENTITY_TYPE, - searchQuery: searchQuery, - sort: '' - } - - // apply test search - searchAdapter.search(Request).then((resp) => { // we're always trying to populate cache - when online - const res = searchAdapter.entities[Request.type].resultPorcessor(resp, 0, 200) - Logger.log('Testentity response: ', res)() - }) - }) -} diff --git a/src/modules/sample-custom-entity-graphql/testentity.gql b/src/modules/sample-custom-entity-graphql/testentity.gql deleted file mode 100644 index 9b23dff992..0000000000 --- a/src/modules/sample-custom-entity-graphql/testentity.gql +++ /dev/null @@ -1,8 +0,0 @@ -query testentity ($filter: TestInput) { - testentity( - filter: $filter - ) - { - hits - } -} \ No newline at end of file From 58f1f24bed07565fd7eddb860167b1123a7eec41 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 15:43:02 +0200 Subject: [PATCH 19/27] moved unused modules to sample repo --- core/store/lib/storage-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index d27adc99fb..04dbee5aa1 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -62,7 +62,7 @@ function _prepareCacheStorage (key, localised = true, storageQuota = 0) { }), true, storageQuota) } -/** +/** * @deprecated to be removed in 2.0 in favor to `StorageManager` * */ function initCacheStorage (key, localised = true, registerStorgeManager = true) { From 0fbe55e3d9f5065f752216616dd10d1738f085f4 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 15:48:04 +0200 Subject: [PATCH 20/27] remove magento-2-cms module --- src/modules/magento-2-cms/README.md | 52 ------------ .../magento-2-cms/components/CmsData.vue | 82 ------------------- .../magento-2-cms/hooks/afterRegistration.ts | 16 ---- src/modules/magento-2-cms/index.ts | 10 --- src/modules/magento-2-cms/store/index.js | 66 --------------- 5 files changed, 226 deletions(-) delete mode 100644 src/modules/magento-2-cms/README.md delete mode 100644 src/modules/magento-2-cms/components/CmsData.vue delete mode 100644 src/modules/magento-2-cms/hooks/afterRegistration.ts delete mode 100644 src/modules/magento-2-cms/index.ts delete mode 100644 src/modules/magento-2-cms/store/index.js diff --git a/src/modules/magento-2-cms/README.md b/src/modules/magento-2-cms/README.md deleted file mode 100644 index cf230860a8..0000000000 --- a/src/modules/magento-2-cms/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# CMS Magento 2 data extension - -To display Cms data: - - install `snowdog/module-cms-api` composer module in your Magento 2 instance, [snowdog/module-cms-api on github](https://github.com/SnowdogApps/magento2-cms-api) - - make sure that in `vue-storefront-api` repo the `cms-data` extension is installed - -## Cms Block -To display Cms Block import CmsData component and use it in template: - -`import CmsData from 'src/modules/magento-2-cms/components/CmsData'` - -we have to options to get Cms Block data: -1. by Magento `identifier`: -`` -where `contact-us-info` is a Cms Block `identifier` from Magento 2 instance - -this option handles different `Store Views` - if multistore is enabled, it takes Cms Block by current Store View, if it's disabled, it set default Store View (`0`) - -2. by Magento id -`` -where `5` is a Magento id of Cms Block. -It doesn't handle differents Store Views so please use it only when multistore it's enabled/ - -## Cms Page -To display Cms Page: - -1. Cms page content like a block -* in custom theme create new page with custom route -* import CmsData component and use it in template: -`import CmsData from '@vue-storefront/extension-magento2-cms/components/CmsData'` - -call Cms Page like a Block using either Magento `identifier`: -`` - -or Magento `id` -`` -where `5` is a cms page identifier from Magento 2 instance - -Like Cms Block, the Cms Page by `identifier` handles different Store Views, Cms Page by `id` handles only Default Store View/ - -2. Cms page content as a page component: -- in custom theme `themes//router/index.js` import `CmsData` component, add custom route and define props: `{identifier: :pageIdentifier, type: 'Page', sync: true}`, example: -``` -import CmsData from '@vue-storefront/extension-magento2-cms/components/CmsData' - -const routes = [ - // ... theme routes - { name: 'cms-page-sync', path: '/cms-page-sync', component: CmsData, props: {identifier: 'about-us', type: 'Page', sync: true} } -] -``` -Complete examples of usage and implementation you can find in Default theme: -1. `/cms-page-sync`, `src/themes/default/router/index.js` diff --git a/src/modules/magento-2-cms/components/CmsData.vue b/src/modules/magento-2-cms/components/CmsData.vue deleted file mode 100644 index 370deaac0b..0000000000 --- a/src/modules/magento-2-cms/components/CmsData.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/src/modules/magento-2-cms/hooks/afterRegistration.ts b/src/modules/magento-2-cms/hooks/afterRegistration.ts deleted file mode 100644 index a707d3d010..0000000000 --- a/src/modules/magento-2-cms/hooks/afterRegistration.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager' - -export function afterRegistration ({ Vue, config, store, isServer }) { - store.subscribe((mutation, state) => { - const type = mutation.type - - if ( - type.endsWith('setCmsBlock') || - type.endsWith('setCmsPage') - ) { - StorageManager.get('cmsData').setItem('cms-data', state.cms).catch((reason) => { - console.error(reason) - }) - } - }) -} diff --git a/src/modules/magento-2-cms/index.ts b/src/modules/magento-2-cms/index.ts deleted file mode 100644 index 458e9ffeda..0000000000 --- a/src/modules/magento-2-cms/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createModule } from '@vue-storefront/core/lib/module' -import { store } from './store' -import { afterRegistration } from './hooks/afterRegistration' - -const KEY = 'cms' -export const Magento2CMS = createModule({ - key: KEY, - store: { modules: [{ key: KEY, module: store }] }, - afterRegistration -}) diff --git a/src/modules/magento-2-cms/store/index.js b/src/modules/magento-2-cms/store/index.js deleted file mode 100644 index e3be878504..0000000000 --- a/src/modules/magento-2-cms/store/index.js +++ /dev/null @@ -1,66 +0,0 @@ -import fetch from 'isomorphic-fetch' -import { Logger } from '@vue-storefront/core/lib/logger' -import { processURLAddress } from '@vue-storefront/core/helpers' - -const state = { - cmsPages: [], - cmsBlocks: [] -} - -const getters = { - getBlock: (state) => (id) => { - return state.cmsBlocks.find(item => item.id === id) - }, - getBlockIdentifier: (state) => (identifier) => { - return state.cmsBlocks.find(item => item.identifier === identifier) - }, - getPage: (state) => (id) => { - return state.cmsPages.find(item => item.id === id) - }, - getPageIdentifier: (state) => (identifier) => { - return state.cmsPages.find(item => item.identifier === identifier) - } -} - -// actions -const actions = { - loadCms (context, {url, type}) { - fetch(processURLAddress(url), { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - mode: 'cors' - }) - .then(response => response.json()) - .then(data => { - if (data.code === 200) { - context.commit(`setCms${type}`, data.result) - } - }) - .catch((err) => { - Logger.log(err)() - Logger.error('You need to install a custom Magento module from Snow.dog to make the CMS magic happen. Please go to https://github.com/SnowdogApps/magento2-cms-api and follow the instructions')() - }) - } -} - -// mutations -const mutations = { - setCmsBlock (state, data) { - if (!state.cmsBlocks.filter(e => e.id === data.id).length > 0) { - state.cmsBlocks.push(data) - } - }, - setCmsPage (state, data) { - if (!state.cmsPages.filter(e => e.id === data.id).length > 0) { - state.cmsPages.push(data) - } - } -} - -export const store = { - namespaced: true, - state, - getters, - actions, - mutations -} From afe0dbf7d8a3b5dd55db3c0b83f4abbb881243ea Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 16:18:57 +0200 Subject: [PATCH 21/27] update changelog and upgrade notes --- CHANGELOG.md | 2 +- docs/guide/upgrade-notes/README.md | 35 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3baa952d6..b2da4d8e0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added configuration for max attempt task & cart by pass - @cnviradiya (#3193) - Added catching of errors when ES is down - @qiqqq - Added debounce for updating quantity method in the cart - @andrzejewsky (#3191) - +- New modules API and rewrite - @filrak (#3144) ## [1.10.0-rc.2] - UNRELEASED ### Fixed diff --git a/docs/guide/upgrade-notes/README.md b/docs/guide/upgrade-notes/README.md index fbb08c2787..fb7d415ef3 100644 --- a/docs/guide/upgrade-notes/README.md +++ b/docs/guide/upgrade-notes/README.md @@ -1,7 +1,29 @@ # Upgrade notes We're trying to keep the upgrade process as easy as possible. Unfortunately, sometimes manual code changes are required. Before pulling out the latest version, please take a look at the upgrade notes below: + ## 1.10 -> 1.11 + +This is the last major release of Vue Storefront 1.x before 2.0 therefore more manual updates are required to keep external packages compatible with 1.x as long as possible. + +- All modules were refactored to new API. You can still register modules in previous format until 2.0 +- `DroppointShipping` and `magento-2-cms `modules were deleted +- example modules moved to https://github.com/DivanteLtd/vsf-samples +- `core/helpers/initCacheStorage.ts` merged with `StorageManager.ts` (import path alias for backward compatibility added) +- Old extensions mechanism (before VS 1.4) was finally removed after being deprecated for almost a year (`src/extensions` removal) +- Cache collections were reorganized. In most cases Local Storage keys remained untouched, only collection keys were unified. also they're used only in the core. Posting changes in case someone is using those collections in their modules; + - `syncTaskCollection` renamed to `syncTasks` + - `compareCollection` renamed to `compare` + - `cmsData` renamed to `cms` + - `cartsCollection` renamed to `carts` + - `checkoutFieldValues`, `checkoutFieldsCollection` renamed to `checkout` (`checkoutFieldsCollection` wasn’t used) + - `ordersCollection` and `orders` renamed to just `orders` (`ordersCollection` wasn’t used) + - `elasticCacheCollection` renamed to `elasticCache` + - `usersCollection` `usersData` merged and renamed to `user` + - `attributesCollection`, `attributes` renamed to just `attributes` + - `ordersHistoryCollection` merged to `user` cache where it belongs + - `categoriesCollection` renamed to categories + - Collections in theme like `claimsCollection` (claims modules) remained untouched - `UserOrder` component has been renamed to `UserOrderHistory` and moved from `src/modules/order-history/components/UserOrders` to `@vue-storefront/core/modules/order/components/UserOrdersHistory`. This component was used in `MyOrders` component found here: `src/themes/default/components/core/blocks/MyAccount/MyOrders.vue`. In this file the `import` path has to be updated. - `claims`, `promoted-offers`, `homepage` adn `ui` modules have been moved from `@vue-storefront/src/modules` to `src/themes/default/store/` and reduced to stores only.
Delete those folders:
@@ -10,9 +32,9 @@ Delete those folders:
-- `src/modules/homepage`
-- `src/modules/ui-store`
Copy folder `theme/store/` from `theme default`.
-Register the stores copied in previous step in `src/themes/default/index.js`. To do that, import them along with `initCacheStorage` method, used to replace `claims beforeRegistration hook`. +Register the stores copied in previous step in `src/themes/default/index.js`. To do that, import them along with `StorageManager` method, used to replace `claims beforeRegistration hook`. ```js -import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'; +import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'; import { store as claimsStore } from 'theme/store/claims' import { store as homeStore } from 'theme/store/homepage' import { store as uiStore } from 'theme/store/ui' @@ -20,7 +42,7 @@ import { store as promotedStore } from 'theme/store/promoted-offers' ``` Next, inside `initTheme` method use `store.registerModule` method to register the stores. ```js -Vue.prototype.$db.claimsCollection = initCacheStorage('claims'); +StorageManager.init('claims'); store.registerModule('claims', claimsStore); store.registerModule('homepage', homeStore); store.registerModule('ui', uiStore); @@ -28,11 +50,8 @@ store.registerModule('promoted', promotedStore); ``` - `WebShare` moved from `@vue-storefront/core/modules/social-share/components/WebShare.vue` to `@vue-storefront/src/themes/default/components/theme/WebShare.vue`. This component was used in `Product` component found here: `src/themes/default/pages/Product.vue`. In this file the `import` path has to be updated. -## 1.10 -> 1.11 -We've fixed the naming strategy for product prices; The following fields were renamed: `special_priceInclTax` -> `special_price_incl_tax`, `priceInclTax` -> `price_incl_tax`, `priceTax` -> `price_tax`; The names have been kept and marked as @deprecated. These fields will be **removed with Vue Storefront 2.0rc-1**. - -We've decreased the `localStorage` quota usage + error handling by introducing new config variables: - +- We've fixed the naming strategy for product prices; The following fields were renamed: `special_priceInclTax` -> `special_price_incl_tax`, `priceInclTax` -> `price_incl_tax`, `priceTax` -> `price_tax`; The names have been kept and marked as @deprecated. These fields will be **removed with Vue Storefront 2.0rc-1**. +- We've decreased the `localStorage` quota usage + error handling by introducing new config variables: - `config.products.disablePersistentProductsCache` to not store products by SKU (by default it's on). Products are cached in ServiceWorker cache anyway so the `product/list` will populate the in-memory cache (`cache.setItem(..., memoryOnly = true)`); - `config.seo.disableUrlRoutesPersistentCache` - to not store the url mappings; they're stored in in-memory cache anyway so no additional requests will be made to the backend for url mapping; however it might cause some issues with url routing in the offline mode (when the offline mode PWA installed on homescreen got reloaded, the in-memory cache will be cleared so there won't potentially be the url mappings; however the same like with `product/list` the ServiceWorker cache SHOULD populate url mappings anyway); - `config.syncTasks.disablePersistentTaskQueue` to not store the network requests queue in service worker. Currently only the stock-check and user-data changes were using this queue. The only downside it introuces can be related to the offline mode and these tasks will not be re-executed after connectivity established, but just in a case when the page got reloaded while offline (yeah it might happen using ServiceWorker; `syncTasks` can't be re-populated in cache from SW) From ab25388d8d39f056666f0b256a703b837b50ff05 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 16:26:57 +0200 Subject: [PATCH 22/27] fix test mock --- core/modules/cart/test/unit/index.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/cart/test/unit/index.spec.ts b/core/modules/cart/test/unit/index.spec.ts index def95503d6..69d90433c1 100644 --- a/core/modules/cart/test/unit/index.spec.ts +++ b/core/modules/cart/test/unit/index.spec.ts @@ -4,7 +4,7 @@ jest.mock('../../store', () => ({})); jest.mock('@vue-storefront/module', () => ({ createModule: jest.fn(() => ({ module: 'cart' })) })); jest.mock('../../helpers/cartCacheHandler', () => ({ cartCacheHandlerFactory: jest.fn() })) jest.mock('@vue-storefront/core/helpers', () => ({ isServer: false })) -jest.mock('@vue-storefront/core/helpers/cache', () => ({ initCacheStorage: jest.fn() })); +jest.mock('@vue-storefront/core/store/lib/storage-manager', () => ({ initCacheStorage: jest.fn() })); describe('Cart Module', () => { it('can be initialized', () => { From 3ac6e36ae67d073bacda4d7f1607b2ecf02e57c4 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 22:15:56 +0200 Subject: [PATCH 23/27] Update core/store/lib/storage-manager.ts Co-Authored-By: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> --- core/store/lib/storage-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index 04dbee5aa1..9e04bc86a4 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -14,7 +14,7 @@ const StorageManager = { * @param storageQuota max size of storage, 0 if unlimited (default `0`) */ init: function (collectionName: string, isLocalised = true, storageQuota = 0) { - this.storageMap[collectionName] = _prepareCacheStorage(collectionName, isLocalised, storageQuota) + this.storageMap[collectionName] = _prepareCacheStorage(collectionName, isLocalized, storageQuota) return this.storageMap[collectionName] }, /** From 1414f7ae69642564c69afc11ce9961fd0f26e4be Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 22:16:11 +0200 Subject: [PATCH 24/27] Update core/store/lib/storage-manager.ts Co-Authored-By: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> --- core/store/lib/storage-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index 9e04bc86a4..af0b609cd9 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -13,7 +13,7 @@ const StorageManager = { * @param isLocalized if set to `false` data will be shared between storeViews (default `true`) * @param storageQuota max size of storage, 0 if unlimited (default `0`) */ - init: function (collectionName: string, isLocalised = true, storageQuota = 0) { + init: function (collectionName: string, isLocalized = true, storageQuota = 0) { this.storageMap[collectionName] = _prepareCacheStorage(collectionName, isLocalized, storageQuota) return this.storageMap[collectionName] }, From d0b525b8d7521de2a9ddc490ad2dc1f16bd8771a Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 22:16:26 +0200 Subject: [PATCH 25/27] Update core/store/lib/storage-manager.ts Co-Authored-By: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> --- core/store/lib/storage-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index af0b609cd9..29410e49a7 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -56,7 +56,7 @@ function _prepareCacheStorage (key, localised = true, storageQuota = 0) { : 'LOCALSTORAGE' return new UniversalStorage(localForage.createInstance({ - name: localised ? `${dbNamePrefix}shop` : 'shop', + name: localized ? `${dbNamePrefix}shop` : 'shop', storeName: key, driver: localForage[cacheDriver] }), true, storageQuota) From 7d84abfea1b933c7d3deee2e7ef0de443cad0e28 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Wed, 17 Jul 2019 22:16:32 +0200 Subject: [PATCH 26/27] Update core/store/lib/storage-manager.ts Co-Authored-By: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> --- core/store/lib/storage-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/store/lib/storage-manager.ts b/core/store/lib/storage-manager.ts index 29410e49a7..498b978f76 100644 --- a/core/store/lib/storage-manager.ts +++ b/core/store/lib/storage-manager.ts @@ -48,7 +48,7 @@ const StorageManager = { } } -function _prepareCacheStorage (key, localised = true, storageQuota = 0) { +function _prepareCacheStorage (key, localized = true, storageQuota = 0) { const storeView = currentStoreView() const dbNamePrefix = storeView && storeView.storeCode ? storeView.storeCode + '-' : '' const cacheDriver = config.localForage && config.localForage.defaultDrivers[key] From f1a4d1c53335c1c2938fee40e888126088718495 Mon Sep 17 00:00:00 2001 From: Filip Rakowski Date: Thu, 18 Jul 2019 08:46:36 +0200 Subject: [PATCH 27/27] CR fixes --- CHANGELOG.md | 2 +- src/modules/index.ts | 18 +++++++++--------- src/modules/payment-backend-methods/index.ts | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2da4d8e0d..45846bb524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added configuration for max attempt task & cart by pass - @cnviradiya (#3193) - Added catching of errors when ES is down - @qiqqq - Added debounce for updating quantity method in the cart - @andrzejewsky (#3191) -- New modules API and rewrite - @filrak (#3144) +- New modules API and rewrite - @filrak, @JCown (#3144) ## [1.10.0-rc.2] - UNRELEASED ### Fixed diff --git a/src/modules/index.ts b/src/modules/index.ts index 7d63eaa91d..047c53f989 100644 --- a/src/modules/index.ts +++ b/src/modules/index.ts @@ -29,27 +29,27 @@ import { registerModule } from '@vue-storefront/module' export function registerNewModules () { registerModule(UrlModule) registerModule(CatalogModule) - registerModule(CheckoutModule) + registerModule(CheckoutModule) // To Checkout registerModule(CartModule) - registerModule(ReviewModule) - registerModule(MailerModule) - registerModule(WishlistModule) - registerModule(NewsletterModule) + registerModule(ReviewModule) // To Product + registerModule(MailerModule) // load lazily + registerModule(WishlistModule) // Trigger on wishlist icon click + registerModule(NewsletterModule) // Load lazily registerModule(NotificationModule) - registerModule(UserModule) + registerModule(UserModule) // Trigger on user icon click registerModule(CatalogNextModule) registerModule(CompareModule) registerModule(BreadcrumbsModule) registerModule(OrderModule) registerModule(CmsModule) - registerModule(RecentlyViewedModule) + registerModule(RecentlyViewedModule) // To HomePage registerModule(GoogleTagManagerModule) // registerModule(GoogleAnalyticsModule) // registerModule(HotjarModule) registerModule(PaymentBackendMethodsModule) - registerModule(PaymentCashOnDeliveryModule) + registerModule(PaymentCashOnDeliveryModule) // To checkout registerModule(AmpRendererModule) - registerModule(InstantCheckoutModule) + registerModule(InstantCheckoutModule) // Load lazily from Microcart } // Deprecated API, will be removed in 2.0 diff --git a/src/modules/payment-backend-methods/index.ts b/src/modules/payment-backend-methods/index.ts index 62d132b844..f48601c067 100644 --- a/src/modules/payment-backend-methods/index.ts +++ b/src/modules/payment-backend-methods/index.ts @@ -1,7 +1,7 @@ import * as types from './store/mutation-types' import { StorefrontModule } from '@vue-storefront/module'; import { isServer } from '@vue-storefront/core/helpers' -import Vue from 'vue'; +import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus' const PaymentBackendMethodsStore = { namespaced: true, @@ -23,20 +23,20 @@ export const PaymentBackendMethodsModule: StorefrontModule = function (app, stor // Place the order. Payload is empty as we don't have any specific info to add for this payment method '{}' const placeOrder = () => { if (correctPaymentMethod) { - Vue.prototype.$bus.$emit('checkout-do-placeOrder', {}) + EventBus.$emit('checkout-do-placeOrder', {}) } } if (!isServer) { // Update the methods - Vue.prototype.$bus.$on('set-unique-payment-methods', methods => { + EventBus.$on('set-unique-payment-methods', methods => { store.commit('payment-backend-methods/' + types.SET_BACKEND_PAYMENT_METHODS, methods) }) - Vue.prototype.$bus.$on('checkout-before-placeOrder', placeOrder) + EventBus.$on('checkout-before-placeOrder', placeOrder) // Mount the info component when required - Vue.prototype.$bus.$on('checkout-payment-method-changed', (paymentMethodCode) => { + EventBus.$on('checkout-payment-method-changed', (paymentMethodCode) => { let methods = store.state['payment-backend-methods'].methods if (methods !== null && methods.find(item => (item.code === paymentMethodCode && item.is_server_method === true))) { correctPaymentMethod = true