@lancom/shared 0.0.89 → 0.0.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/assets/js/api/helpers.js +2 -1
  2. package/assets/js/utils/filters.js +9 -5
  3. package/assets/js/utils/product.js +3 -3
  4. package/components/checkout/cart/cart.mixin.js +3 -4
  5. package/components/checkout/cart/cart_entity/cart-entity.vue +8 -0
  6. package/components/checkout/cart/cart_price_info/cart-price-info.scss +10 -0
  7. package/components/checkout/cart/cart_price_info/cart-price-info.vue +9 -3
  8. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.scss +44 -0
  9. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.vue +107 -0
  10. package/components/checkout/order/address-form/address-form.vue +1 -1
  11. package/components/checkout/order/order-billing-information/order-billing-information.vue +0 -8
  12. package/components/checkout/order/order-shipping-method/order-shipping-method.vue +1 -1
  13. package/components/common/progress_steps/progress-steps.scss +1 -1
  14. package/components/editor/editor.vue +0 -8
  15. package/components/editor/editor_layers/editor_layer_forms/editor_layer_common_fields/editor-layer-common-fields.vue +0 -49
  16. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_art/editor-layer-form-art.vue +0 -6
  17. package/components/editor/editor_layers/editor_layers_toolbar/editor-layers-toolbar.vue +4 -0
  18. package/components/editor/editor_pricing/editor-pricing.vue +2 -4
  19. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +0 -3
  20. package/components/modals/order_modal/order-modal.vue +1 -1
  21. package/components/order/order_payment/order-payment.vue +0 -4
  22. package/components/order/order_status/order-status.vue +0 -18
  23. package/components/product/layouts/product_model_measurements/product-model-measurements.vue +0 -5
  24. package/components/product/product.vue +0 -7
  25. package/components/products/product_list/product-list.vue +23 -2
  26. package/components/products/product_list_product_placeholder/product-list-product-placeholder.scss +52 -0
  27. package/components/products/product_list_product_placeholder/product-list-product-placeholder.vue +26 -0
  28. package/components/products/products_aside/products-aside.scss +32 -0
  29. package/components/products/products_aside/products-aside.vue +27 -27
  30. package/components/products/products_attributes/products-attributes.vue +0 -3
  31. package/components/products/products_brands/products-brands.vue +2 -2
  32. package/components/products/products_catalog/products-catalog.vue +8 -3
  33. package/components/products/products_colors/products-colors.scss +2 -1
  34. package/components/products/products_colors/products-colors.vue +11 -0
  35. package/components/products/products_filters/products-filters.vue +0 -17
  36. package/components/quotes/quote_request/quote-request.vue +3 -7
  37. package/mixins/payment.js +0 -1
  38. package/mixins/product-preview.js +28 -4
  39. package/nuxt.config.js +8 -5
  40. package/package.json +1 -1
  41. package/plugins/global-components.js +0 -4
  42. package/plugins/vue-recaptcha.js +12 -7
  43. package/store/cart.js +84 -32
  44. package/store/order.js +1 -0
  45. package/store/product.js +0 -2
  46. package/store/products.js +7 -2
@@ -17,7 +17,8 @@ if (process.client) {
17
17
  });
18
18
  }
19
19
 
20
- export const buildPath = path => `${process.env.API_URL}/${path}`;
20
+ const API_URL = process.client ? process.env.API_URL : process.env.LOCAL_API_URL;
21
+ export const buildPath = path => `${API_URL}/${path}`;
21
22
 
22
23
  export const prepareHeaders = method => {
23
24
  const headers = {};
@@ -1,4 +1,4 @@
1
- import moment from 'moment';
1
+ import dayjs from 'dayjs';
2
2
  import DateOnly from 'dateonly';
3
3
 
4
4
  import currencies from '../constants/currencies';
@@ -56,8 +56,12 @@ export const print = type => printsLabels[type];
56
56
 
57
57
  export const side = type => SIDE_TYPES[type];
58
58
 
59
+ export const commaArray = (list = []) => {
60
+ return list.join(', ');
61
+ };
62
+
59
63
  export const printsRange = (prints = []) => {
60
- return prints.join(', ');
64
+ return commaArray(prints);
61
65
  };
62
66
 
63
67
  export const highlight = (string = '', query) => {
@@ -68,11 +72,11 @@ export const highlight = (string = '', query) => {
68
72
  return string.toString().replace(q, matchedTxt => (`<span class="highlight">${matchedTxt}</span>`));
69
73
  };
70
74
 
71
- export const date = d => moment(d).format('lll');
75
+ export const date = d => dayjs(d).format('ddd, MMM D, YYYY h:mm A');
72
76
 
73
- export const shortDate = d => moment(d).format('DD/MM/YYYY');
77
+ export const shortDate = d => dayjs(d).format('DD/MM/YYYY');
74
78
 
75
- export const sydneyTime = d => moment(d).utc().utcOffset(10).format('lll');
79
+ export const sydneyTime = d => dayjs(d).utc().utcOffset(10).format('MMM D, YYYY h:mm A');
76
80
 
77
81
  export const priceInRange = (prices, amount) => (prices.find(({ min, max }) => min <= amount && (!max || max >= amount)) || { price: 0 }).price;
78
82
 
@@ -11,11 +11,12 @@ export function getProductsForCalculatePricing(mainProduct, simpleProducts, laye
11
11
  _id: mainProduct._id,
12
12
  prints: hasPrints ? prints.map(p => isCLearPrintsLayers ? ({ ...p, layers: null }) : p) : null,
13
13
  printSurcharge: mainProduct.printSurcharge || 0,
14
- simpleProducts: simpleProducts.map(({ _id, amount, pricing, unprintedPricing, weight }) => ({
14
+ simpleProducts: simpleProducts.map(({ _id, amount, pricing, unprintedPricing, weight, volume }) => ({
15
15
  _id,
16
16
  amount,
17
17
  pricing: hasPrints ? pricing : unprintedPricing,
18
- weight: weight || mainProduct.weight
18
+ weight: weight || mainProduct.weight,
19
+ volume: volume || mainProduct.volume
19
20
  }))
20
21
  }];
21
22
  }
@@ -121,7 +122,6 @@ export function generateProductsLink($route, data) {
121
122
  }
122
123
 
123
124
  export function generateProductLink(product, color, toEditor = false) {
124
- console.log(product);
125
125
  const baseLink = `/${product.brand.alias}/${product.productType.alias}/${product.alias}`;
126
126
  return `${toEditor ? `${baseLink}/editor` : baseLink}${color ? `?color=${color.alias}` : ''}`;
127
127
  }
@@ -28,15 +28,14 @@ export default {
28
28
  },
29
29
  watch: {
30
30
  entities() {
31
- this.calculateCartPrice(this.shop);
31
+ this.calculateCartPrice({ shop: this.shop });
32
32
  }
33
33
  },
34
34
  mounted() {
35
- this.calculateCartPrice(this.shop);
35
+ this.calculateCartPrice({ shop: this.shop });
36
36
  if (!this.suburb && this.user?.suburb) {
37
37
  this.handleSuburbChange(this.user.suburb);
38
38
  }
39
- console.log('user: ', this.user);
40
39
  },
41
40
  methods: {
42
41
  ...mapMutations('cart', [
@@ -48,7 +47,7 @@ export default {
48
47
  ]),
49
48
  handleSuburbChange(suburb) {
50
49
  this.setSuburb(suburb);
51
- this.calculateCartPrice(this.shop);
50
+ this.calculateCartPrice({ shop: this.shop });
52
51
  },
53
52
  async removeSimpleProducts(simpleProducts) {
54
53
  const message = 'This will delete all items in this row, Press OK to continue or Cancel';
@@ -17,6 +17,14 @@
17
17
  {{ product.SKU }}
18
18
  </div>
19
19
  </div>
20
+ <div class="CartEntity__feature">
21
+ <div class="lc_title-small">
22
+ Brand:
23
+ </div>
24
+ <div class="lc_body-small">
25
+ {{ product.brand.name }}
26
+ </div>
27
+ </div>
20
28
  </div>
21
29
  <div>
22
30
  <cart-entity-color-simple-products
@@ -0,0 +1,10 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .CartPriceInfo {
4
+ &__error {
5
+ padding: 10px;
6
+ font-size: 12px;
7
+ color: $white;
8
+ background-color: $error;
9
+ }
10
+ }
@@ -1,11 +1,16 @@
1
1
  <template>
2
- <div>
2
+ <div class="CartPriceInfo__wrapper">
3
3
  <slot name="cart-pricing" v-bind="{ cartPricing, itemsLabel }">
4
4
  <product-total-pricing
5
5
  v-if="cartPricing && cartPricing.amount"
6
6
  :pricing="cartPricing"
7
7
  :items-label="itemsLabel" />
8
8
  </slot>
9
+ <div
10
+ v-if="cartPricingError"
11
+ class="CartPriceInfo__error">
12
+ {{ cartPricingError }}
13
+ </div>
9
14
  </div>
10
15
  </template>
11
16
 
@@ -39,7 +44,8 @@ export default {
39
44
  ...mapGetters(['shop']),
40
45
  ...mapGetters('cart', [
41
46
  'entities',
42
- 'cartPricing'
47
+ 'cartPricing',
48
+ 'cartPricingError'
43
49
  ])
44
50
  },
45
51
  watch: {
@@ -55,7 +61,7 @@ export default {
55
61
  'calculateCartPrice'
56
62
  ]),
57
63
  calculatePrice() {
58
- this.calculateCartPrice(this.shop);
64
+ this.calculateCartPrice({ shop: this.shop });
59
65
  }
60
66
  }
61
67
  };
@@ -0,0 +1,44 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .CartShipmentsPricing {
4
+ &__title {
5
+ padding-top: 15px;
6
+ display: flex;
7
+ justify-content: space-between;
8
+ a {
9
+ color: $black
10
+ }
11
+ }
12
+ &__supplier {
13
+ padding: 10px 10px 5px 10px;
14
+ &-info {
15
+ display: flex;
16
+ justify-content: space-between;
17
+ font-weight: bold;
18
+ font-size: 16px;
19
+ }
20
+ &-brands {
21
+ display: flex;
22
+ i {
23
+ margin-left: -2px;
24
+ margin-right: 8px;
25
+ cursor: pointer;
26
+ }
27
+ }
28
+ }
29
+ &__rate {
30
+ cursor: pointer;
31
+ display: flex;
32
+ justify-content: space-between;
33
+ align-items: center;
34
+ margin-top: 10px;
35
+ font-size: 16px;
36
+ &-icon {
37
+ margin-right: 10px;
38
+ }
39
+ &-info {
40
+ display: flex;
41
+ align-items: center;
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <div class="CartShipmentsPricing__wrapper">
3
+ <div v-if="hasSuppliersWithRates">
4
+ <div class="CartShipmentsPricing__title">
5
+ <div class="lc_body-large lc_gray-main">Delivery</div>
6
+ <a
7
+ href="/info/shipping-info"
8
+ target="_blank">
9
+ Lern more <i class="icon-target"></i>
10
+ </a>
11
+ </div>
12
+ <div
13
+ v-for="(supplier, index) of suppliersWithRates"
14
+ :key="index"
15
+ class="CartShipmentsPricing__supplier">
16
+ <div class="CartShipmentsPricing__supplier-info">
17
+ <div class="CartShipmentsPricing__supplier-brands">
18
+ <div @click="removeSupplierConfirm(supplier)">
19
+ <i class="icon-delete"></i>
20
+ </div>
21
+ <div>
22
+ {{ supplier.brands.map(b => b.name) | commaArray }}
23
+ </div>
24
+ </div>
25
+ <div>
26
+ {{ supplier | selectedRatePrice | price }}
27
+ </div>
28
+ </div>
29
+ <div
30
+ v-for="(rate, i) of supplier.rates"
31
+ :key="`rate-${i}`"
32
+ class="CartShipmentsPricing__rate"
33
+ @click="selectRate({ supplier, rate, shop })">
34
+ <div class="CartShipmentsPricing__rate-info">
35
+ <div class="CartShipmentsPricing__rate-icon">
36
+ <checked-icon :checked="rate.selected" />
37
+ </div>
38
+ <div class="CartShipmentsPricing__rate-name">
39
+ <div>{{ rate.name }}</div>
40
+ <div
41
+ v-if="rate.note"
42
+ class="lc_regular10">
43
+ {{ rate.note }}
44
+ </div>
45
+ </div>
46
+ </div>
47
+ <div class="CartShipmentsPricing__rate-price">
48
+ {{ rate.totalPriceWithoutTax | price }}
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </template>
55
+
56
+ <script>
57
+ import { mapGetters, mapActions } from 'vuex';
58
+ import { price, commaArray } from '@lancom/shared/assets/js/utils/filters';
59
+ import CheckedIcon from '@lancom/shared/components/common/checked-icon';
60
+ import confirm from '@lancom/shared/mixins/confirm';
61
+
62
+ export default {
63
+ name: 'LancomCartShipmentsPricing',
64
+ components: {
65
+ CheckedIcon
66
+ },
67
+ filters: {
68
+ price,
69
+ commaArray,
70
+ selectedRatePrice(supplier) {
71
+ const { totalPriceWithoutTax = 0 } = supplier.rates.find(r => r.selected) || {};
72
+ return totalPriceWithoutTax;
73
+ }
74
+ },
75
+ mixins: [confirm],
76
+ computed: {
77
+ ...mapGetters(['shop']),
78
+ ...mapGetters('cart', [
79
+ 'cartPricing'
80
+ ]),
81
+ hasSuppliersWithRates() {
82
+ return this.suppliersWithRates.length > 0;
83
+ },
84
+ suppliersWithRates() {
85
+ return this.cartPricing?.shipping?.suppliersWithRates || [];
86
+ }
87
+ },
88
+ methods: {
89
+ ...mapActions('cart', [
90
+ 'selectRate',
91
+ 'removeSupplier'
92
+ ]),
93
+ async removeSupplierConfirm(supplier) {
94
+ const message = `Will be removed all products related to brands: ${commaArray(supplier.brands.map(b => b.name))}. Are you sure?`;
95
+ const reset = await this.showConfirmationModal(message);
96
+
97
+ if (reset) {
98
+ this.removeSupplier({ supplier, shop: this.shop });
99
+ }
100
+ }
101
+ }
102
+ };
103
+ </script>
104
+
105
+ <style lang="scss" scoped>
106
+ @import 'cart-shipments-pricing.scss';
107
+ </style>
@@ -295,7 +295,7 @@ export default {
295
295
  handleSuburbChange(suburb) {
296
296
  this.setAddressSuburb(suburb);
297
297
  this.setSuburb(suburb);
298
- this.calculateCartPrice(this.shop);
298
+ this.calculateCartPrice({ shop: this.shop });
299
299
  }
300
300
  }
301
301
  };
@@ -11,14 +11,6 @@
11
11
  <address-form
12
12
  :address="order.shippingAddress"
13
13
  :without-additional-info="true" />
14
- <!-- <div class="form-row mt-10">
15
- <label class="form-label">
16
- <checkbox v-model="copyToShippingAddress" />
17
- <span class="lc_regular14 lc__grey1">
18
- Ship to this address
19
- </span>
20
- </label>
21
- </div> -->
22
14
  </div>
23
15
  <progress-steps-controls
24
16
  :disabled-next="invalid || !order.shippingAddress.postcode"
@@ -53,7 +53,7 @@ export default {
53
53
  },
54
54
  mounted() {
55
55
  if (!this.shippingPricing) {
56
- this.calculateCartPrice(this.shop);
56
+ this.calculateCartPrice({ shop: this.shop });
57
57
  }
58
58
  },
59
59
  methods: {
@@ -25,7 +25,7 @@
25
25
  &__content-wrapper {
26
26
  padding: 51px;
27
27
  position: relative;
28
- @media (max-width: $bp-extra-small-max) {
28
+ @media (max-width: $bp-large-max) {
29
29
  padding: 15px;
30
30
  }
31
31
  }
@@ -1,13 +1,5 @@
1
1
  <template>
2
2
  <div class="Editor__wrapper">
3
- <!-- <div class="Editor__header">
4
- <nuxt-link
5
- to="/"
6
- class="lc_link">
7
- <i class="icon-left"></i>
8
- Go to all models
9
- </nuxt-link>
10
- </div> -->
11
3
  <div class="Editor__content row">
12
4
  <breakpoint
13
5
  name="md"
@@ -20,55 +20,6 @@
20
20
  </div>
21
21
  </div>
22
22
  </div>
23
- <!-- <div class="form-row">
24
- <div class="form-label">
25
- Align:
26
- </div>
27
- <div class="EditorLayerCommonFields__align-options">
28
- <div
29
- v-tooltip="'Center vertically'"
30
- class="EditorLayerCommonFields__align-option ripple"
31
- :class="{ active: alignVertically === 'center' }"
32
- @click="alignVertically = 'center'">
33
- <i class="icon-vertical-align-center"></i>
34
- </div>
35
- <div
36
- v-tooltip="'Center horizontally'"
37
- class="EditorLayerCommonFields__align-option ripple"
38
- :class="{ active: alignHorizontally === 'center' }"
39
- @click="alignHorizontally = 'center'">
40
- <i class="icon-horizonal-align-center"></i>
41
- </div>
42
- <div
43
- v-tooltip="'Left'"
44
- class="EditorLayerCommonFields__align-option ripple"
45
- :class="{ active: alignHorizontally === 'left' }"
46
- @click="alignHorizontally = 'left'">
47
- <i class="icon-horizonal-align-left"></i>
48
- </div>
49
- <div
50
- v-tooltip="'Right'"
51
- class="EditorLayerCommonFields__align-option ripple"
52
- :class="{ active: alignHorizontally === 'right' }"
53
- @click="alignHorizontally = 'right'">
54
- <i class="icon-horizonal-align-right"></i>
55
- </div>
56
- <div
57
- v-tooltip="'Top'"
58
- class="EditorLayerCommonFields__align-option ripple"
59
- :class="{ active: alignVertically === 'top' }"
60
- @click="alignVertically = 'top'">
61
- <i class="icon-vertical-align-top"></i>
62
- </div>
63
- <div
64
- v-tooltip="'Bottom'"
65
- class="EditorLayerCommonFields__align-option ripple"
66
- :class="{ active: alignVertically === 'bottom' }"
67
- @click="alignVertically = 'bottom'">
68
- <i class="icon-vertical-align-bottom"></i>
69
- </div>
70
- </div>
71
- </div> -->
72
23
  </fragment>
73
24
  </template>
74
25
 
@@ -5,12 +5,6 @@
5
5
  name="header"
6
6
  :invalid="invalid">
7
7
  </slot>
8
- <!-- <div class="EditorLayerFormArt__content">
9
- <input
10
- v-model="url"
11
- readonly
12
- class="form-field" />
13
- </div> -->
14
8
  <editor-layer-common-fields
15
9
  :layer="layer"
16
10
  @set-layer-field="data => $emit('set-layer-field', data)">
@@ -79,12 +79,16 @@
79
79
 
80
80
  <script>
81
81
  import { createNamespacedHelpers, mapGetters } from 'vuex';
82
+ import FileUploader from '@lancom/shared/components/common/file_uploader';
82
83
  import modals from '@lancom/shared/mixins/modals';
83
84
 
84
85
  const { mapActions, mapMutations } = createNamespacedHelpers('product');
85
86
 
86
87
  export default {
87
88
  name: 'EditorLayersToolbar',
89
+ components: {
90
+ FileUploader
91
+ },
88
92
  mixins: [
89
93
  modals
90
94
  ],
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <div class="EditorPricing__wrapper">
3
3
  <div class="EditorPricing__main">
4
- <!-- no qty, no layers -->
5
4
  <fragment v-if="!hasUsedSimpleProducts && !layers.length">
6
5
  <div class="EditorPricing__main-alert">
7
6
  <i class="icon-attention-circled"></i>
@@ -17,7 +16,6 @@
17
16
  </div>
18
17
  </fragment>
19
18
 
20
- <!-- has qty, no layers -->
21
19
  <fragment v-else-if="hasUsedSimpleProducts && !layers.length">
22
20
  <div class="EditorPricing__main-alert">
23
21
  <i class="icon-attention-circled"></i>
@@ -36,7 +34,7 @@
36
34
  </div>
37
35
  </div>
38
36
  </fragment>
39
- <!-- no qty, has layers -->
37
+
40
38
  <fragment v-else-if="!hasUsedSimpleProducts && layers.length">
41
39
  <div class="EditorPricing__main-alert">
42
40
  <i class="icon-attention-circled"></i>
@@ -55,7 +53,7 @@
55
53
  </div>
56
54
  </div>
57
55
  </fragment>
58
- <!-- has qty, has layers -->
56
+
59
57
  <fragment v-else>
60
58
  <div class="EditorPricing__main-row">
61
59
  <div class="lc_regular14 EditorPricing__main-col">
@@ -62,9 +62,6 @@
62
62
  class="EditorWorkspaceSide__alert-error view-transition">
63
63
  <i class="icon-attention-circled"></i>
64
64
  Part of your design layer is outside the print area.
65
- <!-- <i
66
- class="icon-cancel EditorWorkspaceSide__offset-warning-close"
67
- @click="offsetWarningVisible = false"></i> -->
68
65
  </div>
69
66
  </transition-group>
70
67
  </div>
@@ -331,7 +331,7 @@ export default {
331
331
  handleSuburbChange(suburb) {
332
332
  this.form.suburb = suburb;
333
333
  this.setSuburb(suburb);
334
- this.calculateCartPrice(this.shop);
334
+ this.calculateCartPrice({ shop: this.shop });
335
335
  },
336
336
  back() {
337
337
  this.switchModal('showCartModal');
@@ -12,10 +12,6 @@
12
12
  btn-class="green PaymentSuccess__btn"
13
13
  btn-label="GO HOME"
14
14
  to="/" />
15
- <!-- <btn
16
- btn-class="green PaymentSuccess__btn"
17
- btn-label="VIEW ORDER"
18
- :to="`/order/${order.token}`" /> -->
19
15
  </div>
20
16
  </template>
21
17
  </payment-success>
@@ -18,24 +18,6 @@
18
18
  {{ order.status }}
19
19
  </div>
20
20
  </div>
21
- <!-- <h4 class="lc_h4">
22
- Special
23
- </h4>
24
- <div class="OrderStatus__value">
25
- <div v-if="isEditable">
26
- <label class="form-label PaymentModal__label-with-checkbox">
27
- <checkbox v-model="order.special" @change="changeStatus" />
28
- <span class="lc_regular14 lc__grey1">
29
- Special Order
30
- </span>
31
- </label>
32
- </div>
33
- <div
34
- v-else
35
- class="OrderStatus__status">
36
- {{ order.special ? 'Yes' : 'No' }}
37
- </div>
38
- </div> -->
39
21
  </div>
40
22
  </template>
41
23
 
@@ -9,11 +9,6 @@
9
9
  src="~static/images/measurements_model.svg"
10
10
  class="ProductModelMeasurements__icon" />
11
11
  <div class="form-actions center">
12
- <!-- <btn
13
- btn-class="green-link"
14
- btn-label="Show model image"
15
- @click="showModel">
16
- </btn> -->
17
12
  </div>
18
13
  </td>
19
14
  <td>
@@ -30,13 +30,6 @@
30
30
  </section>
31
31
  </div>
32
32
  </div>
33
- <!-- <div class="row Product__section-row">
34
- <div class="col-12">
35
- <section class="Product__section">
36
- <product-labels-customization />
37
- </section>
38
- </div>
39
- </div> -->
40
33
  </div>
41
34
  </template>
42
35
 
@@ -14,7 +14,22 @@
14
14
  }"
15
15
  @mouseenter="setActiveProduct(index)"
16
16
  @mouseleave="setActiveProduct(null)">
17
- <slot name="product" v-bind="{ product, full: activeProduct === index, toEditor }">
17
+ <slot
18
+ v-if="placeholder"
19
+ name="placeholder"
20
+ v-bind="{ product, full: activeProduct === index, toEditor }">
21
+ <product-list-product-placeholder
22
+ :product="product"
23
+ :to-editor="toEditor"
24
+ class="ProductList__item"
25
+ :class="{
26
+ 'ProductList__item--active': activeProduct === index
27
+ }" />
28
+ </slot>
29
+ <slot
30
+ v-else
31
+ name="product"
32
+ v-bind="{ product, full: activeProduct === index, toEditor }">
18
33
  <product-list-product
19
34
  :product="product"
20
35
  :to-editor="toEditor"
@@ -36,11 +51,13 @@
36
51
 
37
52
  <script>
38
53
  import ProductListProduct from '../product_list_product/product-list-product';
54
+ import ProductListProductPlaceholder from '../product_list_product_placeholder/product-list-product-placeholder';
39
55
 
40
56
  export default {
41
57
  name: 'LancomProductList',
42
58
  components: {
43
- ProductListProduct
59
+ ProductListProduct,
60
+ ProductListProductPlaceholder
44
61
  },
45
62
  props: {
46
63
  products: {
@@ -50,6 +67,10 @@ export default {
50
67
  toEditor: {
51
68
  type: Boolean,
52
69
  default: true
70
+ },
71
+ placeholder: {
72
+ type: Boolean,
73
+ default: true
53
74
  }
54
75
  },
55
76
  data() {