Skip to content

Commit

Permalink
Release 2020-04-16 (#291)
Browse files Browse the repository at this point in the history
* Merge latest `DivanteLtd/develop` into `develop` (#280, #289) 
* #196865 Add SEO-Text Component (#285) 
* #199077 Add `icmaa-cdn` module (#286) 
* #197501 Improve `SearchPanel` component (#284) 
* #187376 Bugfix for GTM tracking (#283) 
* #197501 Improve `SearchPanel` category results (#282) 
* Bugfix for build exception in Node v13.13+ (#287) 
* Add defaults to `sortedProductOptions` of `optionsMixin` in `icmaa-imp` theme (#290) 
* Add our custom filter to `SearchPanel` component for custom search (#281) 
* Bugfix for empty cms blocks in `icmaa-cms` block component (#292)
* Remove unnecessary custom `api-search-query` search adapter
  • Loading branch information
cewald authored Apr 16, 2020
2 parents fd433d8 + f1128d3 commit e5442eb
Show file tree
Hide file tree
Showing 53 changed files with 621 additions and 158 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ jobs:

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v1.4.1
with:
node-version: '13.x'

- name: Install
uses: bahmutov/npm-install@v1
uses: bahmutov/npm-install@v1.1.0

- name: Get repository name, and branch name
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v1.4.1
with:
node-version: '13.x'

Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v1.4.1
with:
node-version: '13.x'

Expand Down Expand Up @@ -69,7 +69,7 @@ jobs:

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v1.4.1
with:
node-version: '13.x'

Expand All @@ -82,7 +82,7 @@ jobs:
run: rsync -r ./vue-storefront-workspace/template/vue-storefront/ ./

- name: Install
uses: bahmutov/npm-install@v1
uses: bahmutov/npm-install@v1.1.0

- name: Build
run: yarn build
Expand Down
8 changes: 8 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[submodule "src/modules/vsf-cache-nginx"]
path = src/modules/vsf-cache-nginx
url = https://github.com/new-fantastic/vsf-cache-nginx.git
branch = master
[submodule "src/modules/vsf-cache-varnish"]
path = src/modules/vsf-cache-varnish
url = https://github.com/new-fantastic/vsf-cache-varnish.git
branch = master
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.12.0-rc1] - UNRELEASED

### Added
- Allow parent_ids field on product as an alternative to urlpath based breadcrumb navigation (#4219)
- Pass the original item_id when updating/deleting a cart entry @carlokok (#4218)
- Separating endpoints for CSR/SSR - @Fifciu (#2861)
- Added short hands for version and help flags - @jamesgeorge007 (#3946)
Expand All @@ -26,6 +27,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Product Page Schema implementation as JSON-LD - @Michal-Dziedzinski (#3704)
- Add `/cache-version.json` route to get current cache version
- Built-in module for detecting device type based on UserAgent with SSR support - @Fifciu
- Update to `storefront-query-builder` version `1.0.0` - @cewald (#4234)
- Move generating files from webpack config to script @gibkigonzo (#4236)
- Add correct type matching to `getConfigurationMatchLevel` - @cewald (#4241)
- Support `useSpecificImagePaths` with `useExactUrlsNoProxy` - @cewald (#4243)
- Adds module which handles cache invalidation for Fastly. - @gibkigonzo (#4096)
- Add vsf-cache-nginx and vsf-cache-varnish modules - @gibkigonzo (#4096)

### Fixed

Expand All @@ -45,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed `cart/isVirtualCart` to return `false` when cart is empty - @haelbichalex(#4182)
- Use `setProductGallery` in `product/setCurrent` to use logic of the action - @cewald (#4153)
- Use same data format in getConfigurationMatchLevel - @gibkigonzo (#4208)
- removed possible memory leak in ssr - @resubaka (#4247)

### Changed / Improved

Expand All @@ -59,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed `product/loadConfigurableAttributes` calls - @andrzejewsky, @gibkigonzo (#3336)
- Disable `mapFallback` url by default - @gibkigonzo(#4092)
- Include token in pricing sync - @carlokok (#4156)
- Move 'graphql' search adapter from core to src (deprecated) - @gibkigonzo (#4214)

## [1.11.2] - 2020.03.10

Expand Down
9 changes: 9 additions & 0 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -522,5 +522,14 @@
"enableMapFallbackUrl": false,
"endpoint": "/api/url",
"map_endpoint": "/api/url/map"
},
"fastly": {
"enabled":false
},
"nginx": {
"enabled":false
},
"varnish": {
"enabled":false
}
}
14 changes: 7 additions & 7 deletions core/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ export function slugify (text) {
* @returns {string}
*/
export function getThumbnailPath (relativeUrl: string, width: number = 0, height: number = 0, pathType: string = 'product'): string {
if (config.images.useSpecificImagePaths) {
const path = config.images.paths[pathType] !== undefined ? config.images.paths[pathType] : ''
relativeUrl = path + relativeUrl
}

if (config.images.useExactUrlsNoProxy) {
return coreHooksExecutors.afterProductThumbnailPathGenerate({ path: relativeUrl, sizeX: width, sizeY: height }).path // this is exact url mode
return coreHooksExecutors.afterProductThumbnailPathGenerate({ path: relativeUrl, sizeX: width, sizeY: height, pathType }).path // this is exact url mode
} else {
if (config.images.useSpecificImagePaths) {
const path = config.images.paths[pathType] !== undefined ? config.images.paths[pathType] : ''
relativeUrl = path + relativeUrl
}

let resultUrl
if (relativeUrl && (relativeUrl.indexOf('://') > 0 || relativeUrl.indexOf('?') > 0 || relativeUrl.indexOf('&') > 0)) relativeUrl = encodeURIComponent(relativeUrl)
// proxyUrl is not a url base path but contains {{url}} parameters and so on to use the relativeUrl as a template value and then do the image proxy opertions
Expand All @@ -69,7 +69,7 @@ export function getThumbnailPath (relativeUrl: string, width: number = 0, height
}
const path = relativeUrl && relativeUrl.indexOf('no_selection') < 0 ? resultUrl : config.images.productPlaceholder || ''

return coreHooksExecutors.afterProductThumbnailPathGenerate({ path, sizeX: width, sizeY: height }).path
return coreHooksExecutors.afterProductThumbnailPathGenerate({ path, sizeX: width, sizeY: height, pathType }).path
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const {
const {
hook: afterProductThumbnailPathGeneratedHook,
executor: afterProductThumbnailPathGeneratedExecutor
} = createMutatorHook<{ path: string, sizeX: number, sizeY: number }, { path: string }>()
} = createMutatorHook<{ path: string, pathType: string, sizeX: number, sizeY: number }, { path: string }>()

/** Only for internal usage in core */
const coreHooksExecutors = {
Expand Down
5 changes: 5 additions & 0 deletions core/lib/search/adapter/api-search-query/searchAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export class SearchAdapter {
if (Request.hasOwnProperty('groupToken') && Request.groupToken !== null) {
rawQueryObject['groupToken'] = Request.groupToken
}
if (Request.sort) {
const [ field, options ] = Request.sort.split(':')
rawQueryObject.applySort({ field, options })
delete Request.sort
}
const storeView = (Request.store === null) ? currentStoreView() : await prepareStoreView(Request.store)
Request.index = storeView.elasticsearch.index

Expand Down
4 changes: 2 additions & 2 deletions core/modules/catalog-next/store/category/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const actions: ActionTree<CategoryState, RootState> = {
Vue.prototype.$cacheTags.add(`C${category.id}`)
})
}
const notFoundCategories = searchedIds.filter(categoryId => !categories.some(cat => cat.id === parseInt(categoryId)))
const notFoundCategories = searchedIds.filter(categoryId => !categories.some(cat => cat.id === parseInt(categoryId) || cat.id === categoryId))

commit(types.CATEGORY_ADD_CATEGORIES, categories)
commit(types.CATEGORY_ADD_NOT_FOUND_CATEGORY_IDS, notFoundCategories)
Expand Down Expand Up @@ -216,7 +216,7 @@ const actions: ActionTree<CategoryState, RootState> = {
},
async loadCategoryBreadcrumbs ({ dispatch, getters }, { category, currentRouteName, omitCurrent = false }) {
if (!category) return
const categoryHierarchyIds = _prepareCategoryPathIds(category) // getters.getCategoriesHierarchyMap.find(categoryMapping => categoryMapping.includes(category.id))
const categoryHierarchyIds = category.parent_ids ? [...category.parent_ids, category.id] : _prepareCategoryPathIds(category) // getters.getCategoriesHierarchyMap.find(categoryMapping => categoryMapping.includes(category.id))
const categoryFilters = Object.assign({ 'id': categoryHierarchyIds }, cloneDeep(config.entities.category.breadcrumbFilterFields))
const categories = await dispatch('loadCategories', { filters: categoryFilters, reloadAll: Object.keys(config.entities.category.breadcrumbFilterFields).length > 0 })
const sorted = []
Expand Down
2 changes: 1 addition & 1 deletion docker/vue-storefront/vue-storefront.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -e

yarn install || exit $?

yarn build:client && yarn build:server && yarn build:sw || exit $?
yarn generate-files && yarn build:client && yarn build:server && yarn build:sw || exit $?

if [ "$VS_ENV" = 'dev' ]; then
yarn dev
Expand Down
100 changes: 94 additions & 6 deletions docs/guide/cookbook/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,98 @@ It's hands down no-brainer to bootstrap a module _manually_ because the skeleton
### 2. Recipe
### 3. Peep into the kitchen (what happens internally)
### 4. Chef's secret (protip)
<br />
<br />
## 6. Anti-patterns & Common pitfalls
## 6. Extend Elasticsearch request body using `storefront-query-builder`
If you're using the new [`storefront-query-builder`](https://github.com/DivanteLtd/storefront-query-builder) and the `api-search-query` search-adapter ([introduced with v1.1.12](/guide/upgrade-notes/#_1-11-1-12)) it is now possible to extend it by new filters, or even overwrite a existing filter, to customize your Elasticsearch request-bodies.
So, this way you can add custom Elasticsearch queries to the query-chain and still use the notation of `SearchQuery` in the Vue Storefront.
> **Note:** This will only work from `storefront-query-builder` version `1.0.0` and `vue-storefront` version `1.12.2`.
### Usecases
One usecases where this feature would come in handy is for example if you like to add complex queries on multiple points in your source code. Using the following technique you can just add a custom filter to your `SearchQuery` in a single line inside your VSF source-code using the `query.applyFilter(...)` method and then add the complex logic into your custom-filter inside the API.
### Registering a new filter
The `vue-storefront-api` will only try to load filters that are registered in the configs. The extension/module, that contains the filter, must be enabled and the new filter module-classes needs to be registered in its extension config inside the `catalogFilter` array. The filter files must be located inside `filter/catalog/` of your module folder.
For example: If you have a module called `extend-catalog` with a filter called `StockFilter`, the file path to filter would be `src/api/extensions/extend-catalog/filter/catalog/StockFilter.ts` and the config would look like:
```
{
"registeredExtensions": [ "extend-catalog" ],
"extensions": {
"extend-catalog": {
"catalogFilter": [ "StockFilter" ]
}
}
}
```
### Filter module-class properties
The filter can contain four different properties. Followed a short explaination, what they are doing.
* `check` – This method checks the condition that be must matched to execute the filter. The first valid filter is executed – all afterwards are ignored.
* `priority` – This is the priority in which the filters are going to be called. The sort is lower to higher.
* `mutator` – The mutator method is in charge of prehandling the filter value, to e.g. set defaults or check and change the type.
* `filter` – This method contains the query logic we wan't to add and mutates the `bodybuilder` query-chain.
### Example
Lets assume we like to add a possibility to add a default set of product-attribute filters we can apply to each `SearchQuery` without repeating ourselfs in source-code. So, for example, it should filter for two `color`'s and a specific `cut` to supply a filter for spring-coloured short's we implement at several places in our VSF.
#### Changes in `vue-storefront` repository
The query in the VSF code would look like this (that's it on the VSF side):
```js
import { SearchQuery } from 'storefront-query-builder'
import { quickSearchByQuery } from '@vue-storefront/core/lib/search'
//...
const query = new SearchQuery()
query.applyFilter({ key: 'spring-shorts', value: 'male', scope: 'default' })
const products = await dispatch('product/list', { query, size: 5 })
```
#### Changes in `vue-storefront-api` repository
In the `vue-storefront-api` we are going to add the real filter/query magic.
There is already an example module called `example-custom-filter` which we are going to use for our filter.
As you look inside its module folder `src/api/extensions/example-custom-filter/`, you will find a child folder `filter/catalog/` with all existing custom filters for this module. Inside this folder we are going to duplicate the existing `SampleFilter.ts` into another one called `SpringShorts.ts` – this is our new custom filter module-class.
This file needs to be registered in the config JSON to let the API know that there is a new custom filter inside our extension.
Therefore you open your `default.json` or specific config JSON file and add our new filename `SpringShorts` to the config node `extensions.example-custom-filter.catalogFilter` array.
Our `SpringShorts.ts` contains an object that contains [four properties](#filter-module-class-properties): `priority`, `check`, `filter`, `mutator`. We don't need a `mutator` nor `priority`, so we can remove these lines. `check` and `filter` needs to be changed to fulfill our needs. So, this is how our filter finally looks like:
```js
import { FilterInterface } from 'storefront-query-builder'
const filter: FilterInterface = {
check: ({ attribute }) => attribute === 'spring-shorts',
filter ({ value, attribute, operator, queryChain }) {
return queryChain
.filter('terms', 'pants', [ 'shorts' ])
.filter('terms', 'cut', [ 1, 2 ])
.filter('terms', 'color', [ 3, 4 ])
.filter('terms', 'gender', [ value ])
}
}
export default filter
```
Inside `check` we tell the filter to just be applied if the attribute is named exactly `spring-shorts`.
Inside `filter` we extend the Elasticsearch query-chain by our desired filters, using the `bodybuilder` library syntax.
That's it, now we are able to filter by a complex query in only one line inside VSF.
## 7. Anti-patterns & Common pitfalls
### 1. Preparation
### 2. Recipe
Expand All @@ -699,7 +787,7 @@ _[INSERT VIDEO HERE]_
<br />
<br />
## 7. Building a module from A to Z in an iteration
## 8. Building a module from A to Z in an iteration
### 1. Preparation
Expand All @@ -709,7 +797,7 @@ _[INSERT VIDEO HERE]_
<br />
<br />
## 8. Deprecated legacy of Modules
## 9. Deprecated legacy of Modules
In this recipe, we will take a review of how to deal with modules in an old fashioned way , just in case you really need it.
### 1. Preparation
Expand All @@ -720,7 +808,7 @@ In this recipe, we will take a review of how to deal with modules in an old fash
<br />
## 9. Converting old modules to new modules
## 10. Converting old modules to new modules
There are useful modules out there already developed in the old way.
### 1. Preparation
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"@babel/core": "^7.8.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.6",
"@babel/preset-env": "^7.9.0",
"@types/jest": "^25.1.3",
"@types/node": "^13.7.7",
"@typescript-eslint/eslint-plugin": "^1.7.1-alpha.17",
Expand Down
1 change: 0 additions & 1 deletion packages/cli/vue-storefront
Submodule vue-storefront deleted from 3af5a1
2 changes: 2 additions & 0 deletions src/modules/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { IcmaaExtendedNewsletterModule } from 'icmaa-newsletter'
import { IcmaaExtendedReviewRoutes } from 'icmaa-review'
import { IcmaaCategoryModule } from 'icmaa-category'
import { IcmaaCategoryExtrasModule } from 'icmaa-category-extras'
import { IcmaaCdnModule } from 'icmaa-cdn'
import { IcmaaCmsModule } from 'icmaa-cms'
import { IcmaaFormsModule } from 'icmaa-forms'
import { IcmaaTeaserModule } from 'icmaa-teaser'
Expand Down Expand Up @@ -70,6 +71,7 @@ export function registerClientModules () {
registerModule(IcmaaExtendedReviewRoutes)
registerModule(IcmaaCategoryModule)
registerModule(IcmaaCategoryExtrasModule)
registerModule(IcmaaCdnModule)
registerModule(IcmaaCmsModule)
registerModule(IcmaaFormsModule)
registerModule(IcmaaTeaserModule)
Expand Down
24 changes: 24 additions & 0 deletions src/modules/fastly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# VSF Cache Fastly
This module extends default caching docs/guide/basics/ssr-cache.md to allow using fastly as cache provider.

## How to install
Add to config:
```json
"fastly": {
"enabled": true,
"serviceId": "xyz", // (https://docs.fastly.com/en/guides/finding-and-managing-your-account-info#finding-your-service-id)
"token": "xyz" // fastly api token (https://docs.fastly.com/api/auth#tokens)
}
```

Change those values in `server` section:
```json
"useOutputCacheTagging": true,
"useOutputCache": true
```

## How to purge cache?
Open:
```
http://localhost:3000/invalidate?key=aeSu7aip&tag=home
```
Loading

0 comments on commit e5442eb

Please sign in to comment.