Skip to content

Commit

Permalink
Merge branch 'next-12986/add-product-detail-layout-config' into 'master'
Browse files Browse the repository at this point in the history
NEXT-12986 - Add product detail layout config

See merge request shopware/6/product/platform!4235
  • Loading branch information
jleifeld committed Feb 2, 2021
2 parents 6e6c554 + 9f56463 commit 72b2aac
Show file tree
Hide file tree
Showing 36 changed files with 888 additions and 80 deletions.
@@ -0,0 +1,42 @@
---
title: Add layout config for layout tab of product detail
issue: NEXT-12986
flag: FEATURE_NEXT_10078
---
# Core
* Added `slot_config` fields to `product_translation` table
___
# Administration
* Added computed props `isProductPage` in `module/sw-cms/elements/buy-box/config/index.js`
* Added block `sw_cms_element_buy_box_config_content_warning` in `module/sw-cms/elements/buy-box/config/sw-cms-el-config-buy-box.html.twig` to show loaded automatically data information
* Deprecated block `sw_cms_toolbar_slot_language_swtich` in `module/sw-cms/component/sw-cms-toolbar/sw-cms-toolbar.html.twig`
* Added block `sw_cms_toolbar_slot_language_switch` in `module/sw-cms/component/sw-cms-toolbar/sw-cms-toolbar.html.twig`
* Added computed props `assetFilter` in `module/sw-cms/elements/image-gallery/component/index.js`
* Changed method `getPlaceholderItems` in `module/sw-cms/elements/image-gallery/component/index.js` to fix image broken
* Changed computed props `element.config.sliderItems.value` in `module/sw-cms/elements/image-gallery/component/index.js` to reset sliderItems config value of image gallery element
* Changed method `createdComponent` in `module/sw-cms/elements/image-gallery/component/index.js` to initialize config for image gallery element if layout is product detail page
* Added computed props `isProductPage` in `module/sw-cms/elements/image-gallery/config/index.js`
* Added method `initConfig` in `module/sw-cms/elements/image-gallery/config/index.js` to initialize config for image gallery element if layout is product detail page
* Changed method `createdComponent` in `module/sw-cms/elements/image-gallery/config/index.js` to initialize config for image gallery element if layout is product detail page
* Changed handler of watcher `sliderItemsConfigValue` in `module/sw-cms/elements/image-gallery/config/index.js` to fix update `mediaItems` and `element.config.sliderItems.value` when `element.data.sliderItems` is empty
* Changed method `updateMediaDataValue` in `module/sw-cms/elements/image-gallery/config/index.js` to fix update `element.data.sliderItems`
* Added computed props `isProductPage` in `module/sw-cms/elements/manufacturer-logo/config/index.js`
* Changed method `createdComponent` in `module/sw-cms/elements/manufacturer-logo/config/index.js` to initialize config for image gallery element if layout is product detail page
* Added computed props `isProductPage` in `module/sw-cms/elements/product-description-reviews/config/index.js`
* Changed method `createdComponent` in `module/sw-cms/elements/product-description-reviews/config/index.js` to initialize config for image gallery element if layout is product detail page
* Added block `sw_cms_element_product_description_reviews_warning` in `module/sw-cms/elements/product-description-reviews/config/sw-cms-el-config-product-description-reviews.html.twig` to show loaded automatically data information
* Added computed props `isProductPage` in `module/sw-cms/elements/product-name/config/index.js`
* Changed method `createdComponent` in `module/sw-cms/elements/product-name/config/index.js` to initialize config for image gallery element if layout is product detail page
* Changed block `sw_cms_detail_stage_form_view` in `module/sw-cms/page/sw-cms-detail/sw-cms-detail.html.twig` to fix showing incorrect config data when reloading layout with form view
* Changed template in `module/sw-product/component/sw-product-layout-assignment/sw-product-layout-assignment.html.twig` to disabled layout assignment if user only has `product.viewer` permission
* Changed method `onSave` in `module/sw-product/page/sw-product-detail/index.js` to save layout config of a product
* Added method `getCmsPageOverrides` in `module/sw-product/page/sw-product-detail/index.js` to get layout config
* Added computed props `cmsPageId` in `module/sw-product/view/sw-product-detail-layout/index.js`
* Added computed props `cmsPageCriteria` in `module/sw-product/view/sw-product-detail-layout/index.js`
* Added computed props `showCmsForm` in `module/sw-product/view/sw-product-detail-layout/index.js`
* Added method `onOpenLayoutModal` in `module/sw-product/view/sw-product-detail-layout/index.js` to prevent open layout modal if user does not have `product.editor` permission
* Added method `handleGetCmsPage` in `module/sw-product/view/sw-product-detail-layout/index.js` to get cms page
* Added method `updateCmsPageDataMapping` in `module/sw-product/view/sw-product-detail-layout/index.js` to update config data of cms page
* Added watcher `cmsPageId` in `module/sw-product/view/sw-product-detail-layout/index.js` to update cms page
* Changed method `onSelectLayout` in `module/sw-product/view/sw-product-detail-layout/index.js`
* Added block `sw_product_detail_layout_cms_config` in `module/sw-product/view/sw-product-detail-layout/sw-product-detail-layout.html.twig` to show layout config
Expand Up @@ -19,7 +19,9 @@
{% block sw_cms_toolbar_language_switch %}
<div class="sw-cms-toolbar__language-selection">
<slot name="language-switch">
{# @deprecated tag:v6.4.0 - use block sw_cms_toolbar_slot_language_switch instead #}
{% block sw_cms_toolbar_slot_language_swtich %}{% endblock %}
{% block sw_cms_toolbar_slot_language_switch %}{% endblock %}
</slot>
</div>
{% endblock %}
Expand Down
@@ -1,7 +1,7 @@
import template from './sw-cms-el-config-buy-box.html.twig';
import './sw-cms-el-config-buy-box.scss';

const { Component, Mixin } = Shopware;
const { Component, Mixin, Utils } = Shopware;
const { Criteria } = Shopware.Data;

Component.register('sw-cms-el-config-buy-box', {
Expand Down Expand Up @@ -37,6 +37,10 @@ Component.register('sw-cms-el-config-buy-box', {
criteria.addAssociation('deliveryTime');

return criteria;
},

isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type') === 'product_detail';
}
},

Expand Down
Expand Up @@ -15,7 +15,7 @@

{% block sw_cms_element_buy_box_config_tab_option %}
<sw-tabs-item name="options"
:title="$tc('sw-cms.elements.buyBox.config.tab.options')"
:title="$tc('sw-cms.elements.general.config.tab.options')"
:activeTab="active">
{{ $tc('sw-cms.elements.general.config.tab.options') }}
</sw-tabs-item>
Expand All @@ -24,9 +24,17 @@

<template #content="{ active }">
<div v-if="active === 'content'" class="sw-cms-el-config-buy-box__tab-content">
{% block sw_cms_element_buy_box_config_content_warning %}
<sw-alert
v-if="isProductPage"
class="sw-cms-el-config-buy-box__warning" variant="info">
{{ $tc('sw-cms.elements.buyBox.infoText.tooltipSettingDisabled') }}
</sw-alert>
{% endblock %}

{% block sw_cms_element_buy_box_config_product_select %}
<sw-entity-single-select
v-if="!isProductPage"
v-model="element.config.product.value"
ref="cmsProductSelection"
entity="product"
Expand Down
@@ -1,7 +1,7 @@
import template from './sw-cms-el-config-cross-selling.html.twig';
import './sw-cms-el-config-cross-selling.scss';

const { Component, Mixin } = Shopware;
const { Component, Mixin, Utils } = Shopware;
const { Criteria } = Shopware.Data;

Component.register('sw-cms-el-config-cross-selling', {
Expand Down Expand Up @@ -40,7 +40,7 @@ Component.register('sw-cms-el-config-cross-selling', {
},

isProductPageType() {
return this.cmsPageState.currentPage.type === 'product_detail';
return Utils.get(this.cmsPageState, 'currentPage.type') === 'product_detail';
}
},

Expand Down
Expand Up @@ -33,7 +33,7 @@

{% block sw_cms_element_cross_selling_config_content_products %}
<sw-entity-single-select
v-else
v-if="!isProductPageType"
v-model="element.config.product.value"
ref="cmsProductSelection"
entity="product"
Expand Down
@@ -1,7 +1,7 @@
import template from './sw-cms-el-image-gallery.html.twig';
import './sw-cms-el-image-gallery.scss';

const { Component, Mixin, Utils } = Shopware;
const { Component, Mixin, Utils, Filter } = Shopware;

Component.register('sw-cms-el-image-gallery', {
template,
Expand Down Expand Up @@ -52,6 +52,10 @@ Component.register('sw-cms-el-image-gallery', {

isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type', '') === 'product_detail';
},

assetFilter() {
return Filter.getByName('asset');
}
},

Expand All @@ -77,7 +81,12 @@ Component.register('sw-cms-el-image-gallery', {
},

'element.config.sliderItems.value': {
handler() {
handler(value) {
if (!value) {
this.element.config.sliderItems.value = [];
return;
}

this.$nextTick(() => {
this.setGalleryLimit();
});
Expand All @@ -98,10 +107,17 @@ Component.register('sw-cms-el-image-gallery', {
this.initElementConfig('image-gallery');
this.initElementData('image-gallery');

if (this.isProductPage && !this.element.data.sliderItems) {
this.element.config.sliderItems.source = 'mapped';
this.element.config.sliderItems.value = 'product.media';
if (!this.isProductPage || Utils.get(this.element, 'translated.config')) {
return;
}

this.element.config.sliderItems.source = 'mapped';
this.element.config.sliderItems.value = 'product.media';
this.element.config.navigationDots.value = 'inside';
this.element.config.zoom.value = true;
this.element.config.fullScreen.value = true;
this.element.config.displayMode.value = 'contain';
this.element.config.minHeight.value = '430px';
},

mountedComponent() {
Expand All @@ -110,9 +126,9 @@ Component.register('sw-cms-el-image-gallery', {

getPlaceholderItems() {
return [
{ url: '/administration/static/img/cms/preview_mountain_large.jpg' },
{ url: '/administration/static/img/cms/preview_glasses_large.jpg' },
{ url: '/administration/static/img/cms/preview_plant_large.jpg' }
{ url: this.assetFilter('administration/static/img/cms/preview_mountain_large.jpg') },
{ url: this.assetFilter('administration/static/img/cms/preview_glasses_large.jpg') },
{ url: this.assetFilter('administration/static/img/cms/preview_plant_large.jpg') }
];
},

Expand Down
Expand Up @@ -51,6 +51,10 @@ Component.register('sw-cms-el-config-image-gallery', {

gridAutoRows() {
return `grid-auto-rows: ${this.columnWidth}`;
},

isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type', '') === 'product_detail';
}
},

Expand All @@ -60,10 +64,15 @@ Component.register('sw-cms-el-config-image-gallery', {
},

sliderItemsConfigValue(value) {
if (!value) {
this.element.config.sliderItems.value = [];
return;
}

const isSourceMapped = Utils.get(this.element, 'config.sliderItems.source') === 'mapped';
const isSliderLengthValid = value && value.length === this.sliderItems.length;

if (isSourceMapped || isSliderLengthValid) {
if (isSourceMapped || isSliderLengthValid || !this.sliderItems.length) {
return;
}

Expand Down Expand Up @@ -109,12 +118,28 @@ Component.register('sw-cms-el-config-image-gallery', {
return searchResult.get(mediaId);
});
}

this.initConfig();
},

mountedComponent() {
this.updateColumnWidth();
},

initConfig() {
if (!this.isProductPage || Utils.get(this.element, 'translated.config')) {
return;
}

this.element.config.sliderItems.source = 'mapped';
this.element.config.sliderItems.value = 'product.media';
this.element.config.navigationDots.value = 'inside';
this.element.config.zoom.value = true;
this.element.config.fullScreen.value = true;
this.element.config.displayMode.value = 'contain';
this.element.config.minHeight.value = '430px';
},

updateColumnWidth() {
if (!this.$refs.demoMediaGrid) {
return;
Expand Down Expand Up @@ -190,7 +215,12 @@ Component.register('sw-cms-el-config-image-gallery', {
}
});
});
this.$set(this.element.data, 'sliderItems', sliderItems);

if (!this.element.data) {
this.$set(this.element, 'data', { sliderItems });
} else {
this.$set(this.element.data, 'sliderItems', sliderItems);
}
}
},

Expand Down
Expand Up @@ -27,7 +27,7 @@ Component.extend('sw-cms-el-manufacturer-logo', 'sw-cms-el-image', {
this.initElementConfig('manufacturer-logo');
this.initElementData('manufacturer-logo');

if (this.isProductPage && !this.element.data.media) {
if (this.isProductPage && !Utils.get(this.element, 'data.media')) {
this.element.config.media.source = 'mapped';
this.element.config.media.value = 'product.manufacturer.media';
}
Expand Down
@@ -1,9 +1,20 @@
const { Component } = Shopware;
const { Component, Utils } = Shopware;

Component.extend('sw-cms-el-config-manufacturer-logo', 'sw-cms-el-config-image', {
computed: {
isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type', '') === 'product_detail';
}
},

methods: {
createdComponent() {
this.initElementConfig('manufacturer-logo');

if (this.isProductPage && !Utils.get(this.element, 'data.media')) {
this.element.config.media.source = 'mapped';
this.element.config.media.value = 'product.manufacturer.media';
}
}
}
});
Expand Up @@ -2,7 +2,7 @@ import Criteria from 'src/core/data-new/criteria.data';
import template from './sw-cms-el-config-product-description-reviews.html.twig';
import './sw-cms-el-config-product-description-reviews.scss';

const { Component, Mixin } = Shopware;
const { Component, Mixin, Utils } = Shopware;

Component.register('sw-cms-el-config-product-description-reviews', {
template,
Expand Down Expand Up @@ -37,6 +37,10 @@ Component.register('sw-cms-el-config-product-description-reviews', {
criteria.addAssociation('properties');

return criteria;
},

isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type') === 'product_detail';
}
},

Expand Down
Expand Up @@ -25,8 +25,17 @@
<sw-container v-if="active === 'content'"
class="sw-cms-el-config-product-description-reviews-config__tab-content"
:columns="'minmax(300px, 1fr)'">
{% block sw_cms_element_product_description_reviews_warning %}
<sw-alert
v-if="isProductPage"
class="sw-cms-el-config-buy-box__warning" variant="info">
{{ $tc('sw-cms.elements.productDescriptionReviews.infoText.descriptionAndReviewsElement') }}
</sw-alert>
{% endblock %}

{% block sw_cms_element_product_description_reviews_config_product_select %}
<sw-entity-single-select
v-if="!isProductPage"
v-model="element.config.product.value"
ref="cmsProductSelection"
entity="product"
Expand Down
@@ -1,9 +1,20 @@
const { Component } = Shopware;
const { Component, Utils } = Shopware;

Component.extend('sw-cms-el-config-product-name', 'sw-cms-el-config-text', {
computed: {
isProductPage() {
return Utils.get(this.cmsPageState, 'currentPage.type', '') === 'product_detail';
}
},

methods: {
createdComponent() {
this.initElementConfig('product-name');

if (this.isProductPage && !Utils.get(this.element, 'translated.config.content')) {
this.element.config.content.source = 'mapped';
this.element.config.content.value = 'product.name';
}
}
}
});
Expand Up @@ -379,7 +379,6 @@ Component.register('sw-cms-detail', {
updateDataMapping() {
const mappingEntity = this.cmsPageTypeSettings.entity;


if (!mappingEntity) {
Shopware.State.commit('cmsPageState/removeCurrentMappingEntity');
Shopware.State.commit('cmsPageState/removeCurrentMappingTypes');
Expand Down
Expand Up @@ -98,7 +98,7 @@
</div>
{% endblock %}

<sw-cms-page-form :page="page"></sw-cms-page-form>
<sw-cms-page-form v-if="!isLoading" :page="page"></sw-cms-page-form>
</div>
{% endblock %}

Expand Down
Expand Up @@ -44,10 +44,10 @@ Shopware.Service('privileges')
'shipping_method:read',
'product_tag:read',
'product_feature_set:read',
'cms_page:read',
'user_config:read',
'user_config:create',
'user_config:update'
'user_config:update',
Shopware.Service('privileges').getPrivileges('cms.viewer')
],
dependencies: []
},
Expand Down
Expand Up @@ -6,6 +6,8 @@ const { Component } = Shopware;
Component.register('sw-product-layout-assignment', {
template,

inject: ['acl'],

props: {
cmsPage: {
type: Object,
Expand Down

0 comments on commit 72b2aac

Please sign in to comment.