@lancom/shared 0.0.287 → 0.0.289

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 (27) hide show
  1. package/assets/js/utils/fabric-helper.js +9 -8
  2. package/assets/js/utils/fonts-helper.js +3 -1
  3. package/assets/js/utils/shop.js +28 -0
  4. package/components/checkout/cart/cart.vue +1 -0
  5. package/components/checkout/cart/cart_entities_group/cart_entities_group_size_cell/cart-entities-group-size-cell.vue +4 -0
  6. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart_entity_color_simple_product/cart-entity-color-simple-product.vue +4 -0
  7. package/components/checkout/order/order-payment-information/order-payment-information.vue +3 -2
  8. package/components/common/postcode_select/postcode-select.vue +14 -3
  9. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_text/editor-layer-form-text.vue +110 -111
  10. package/components/editor/editor_product_details/editor-product-details.vue +1 -3
  11. package/components/editor/editor_workspace/editor-workspace.vue +2 -1
  12. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +1 -1
  13. package/components/order/order_view/order-view.mixin.js +30 -3
  14. package/components/order/order_view/order-view.vue +11 -8
  15. package/components/product/product.vue +10 -4
  16. package/components/product/product_size_selector/product_size_selector_color/product_size_selector_color_cell/product-size-selector-color-cell.vue +4 -0
  17. package/components/product/wizard-editor/wizard-editor-async.vue +30 -0
  18. package/components/product/wizard-editor/wizard-editor.scss +37 -0
  19. package/components/product/wizard-editor/wizard-editor.vue +120 -0
  20. package/components/products/products_autocomplete/products-autocomplete.vue +5 -1
  21. package/components/quotes/quote_view/quote-view.mixin.js +1 -0
  22. package/components/quotes/quote_view/quote-view.vue +1 -1
  23. package/mixins/product-view.js +1 -1
  24. package/package.json +1 -1
  25. package/store/cart.js +2 -2
  26. package/store/index.js +7 -12
  27. package/store/product.js +3 -3
@@ -340,14 +340,15 @@ export default class FabricHelper {
340
340
  object.on('changed', () => {
341
341
  // this.dispatch('setField', { field: 'copy', value: object.text });
342
342
  // this.dispatch('setField', { field: 'boundingRect', value: object.getBoundingRect() });
343
- if (/\n/g.test(object.text || '')) {
344
- this.discardActiveObjects();
345
- object.text = object.text.replace(/\n/g, '');
346
- this.dispatch('setField', { field: 'copy', value: object.text });
347
- } else {
348
- this.dispatch('setDeleteButtonPosition', object.oCoords.tr);
349
- // this.checkBoundingIntersection(object);
350
- }
343
+ // if (/\n/g.test(object.text || '')) {
344
+ // this.discardActiveObjects();
345
+ // object.text = object.text.replace(/\n/g, '');
346
+ // this.dispatch('setField', { field: 'copy', value: object.text });
347
+ // } else {
348
+ // this.dispatch('setDeleteButtonPosition', object.oCoords.tr);
349
+ // // this.checkBoundingIntersection(object);
350
+ // }
351
+ this.dispatch('setDeleteButtonPosition', object.oCoords.tr);
351
352
  });
352
353
  }
353
354
  /*
@@ -3,6 +3,7 @@ import {
3
3
  FONTS, FONTS_HEBREW, FONTS_HINDI, FONTS_BENGALI, FONTS_GUJARATI, FONTS_KANNADA, FONTS_MALYALAM,
4
4
  FONTS_MARATHI, FONTS_TAMIL, FONTS_TELUGU, FONTS_ORIYA
5
5
  } from './../constants/fonts';
6
+ import Vue from 'vue';
6
7
 
7
8
  const fontsLoadList = {};
8
9
 
@@ -61,8 +62,9 @@ export const getFormattedFont = alias => {
61
62
  };
62
63
 
63
64
  export const getFontPath = alias => {
65
+ const { PROD_CDN_URL, DEV_CDN_URL } = Vue.$env;
64
66
  const { path } = getFont(alias) || {};
65
- return path && staticLink(path);
67
+ return path && staticLink(`${PROD_CDN_URL || DEV_CDN_URL || ''}${path}`);
66
68
  };
67
69
 
68
70
  export const loadFont = alias => new Promise((resolve, reject) => {
@@ -0,0 +1,28 @@
1
+ export function getShopCountrySettings(shop, country) {
2
+ const countrySettings = (shop.countries || []).find(c => c.country?._id === country?._id) || { settings: [] };
3
+ const countrySetting = (countrySettings?.settings || [])[0];
4
+
5
+ return {
6
+ ...shop.settings,
7
+ contacts: {
8
+ ...shop.settings.contacts,
9
+ ...settingsValues(countrySetting?.settings?.contacts)
10
+ },
11
+ depositInfo: {
12
+ ...shop.settings.depositInfo,
13
+ ...settingsValues(countrySetting?.settings?.depositInfo)
14
+ },
15
+ order: {
16
+ ...shop.settings.order,
17
+ ...settingsValues(countrySetting?.settings?.order)
18
+ },
19
+ pricing: {
20
+ ...shop.settings.pricing,
21
+ ...settingsValues(countrySetting?.settings?.pricing)
22
+ }
23
+ };
24
+ }
25
+
26
+ function settingsValues(settings) {
27
+ return Object.keys(settings || {}).reduce((s, key) => (!!settings[key] ? { ...s, [key]: settings[key] } : s), {});
28
+ }
@@ -26,6 +26,7 @@
26
26
  <postcode-select
27
27
  :suburb="suburb"
28
28
  :labelless="true"
29
+ :only-postcode="true"
29
30
  :placeholder="postcodeLabel"
30
31
  :label-text="postcodeInfoLabel"
31
32
  @select="handleSuburbChange" />
@@ -14,6 +14,7 @@
14
14
  min="0"
15
15
  class="form-field centered CartEntitiesGroupSizeCell__field"
16
16
  :class="{ empty: !model }"
17
+ @wheel="onWheel"
17
18
  @focus="onFocus()"
18
19
  @blur="onBlur()" />
19
20
  <div
@@ -76,6 +77,9 @@ export default {
76
77
  },
77
78
  methods: {
78
79
  ...mapActions('cart', ['setEntityAmount']),
80
+ onWheel(e) {
81
+ e.target.blur();
82
+ },
79
83
  onFocus() {
80
84
  this.defaultValue = '';
81
85
  },
@@ -20,6 +20,7 @@
20
20
  empty: !model,
21
21
  error: model > simpleProduct.quantityStock
22
22
  }"
23
+ @wheel="onWheel"
23
24
  @change="onChange()"
24
25
  @focus="onFocus()"
25
26
  @blur="onBlur()" />
@@ -119,6 +120,9 @@ export default {
119
120
  },
120
121
  methods: {
121
122
  ...mapActions('cart', ['setSimpleProductAmount']),
123
+ onWheel(e) {
124
+ e.target.blur();
125
+ },
122
126
  onChange() {
123
127
  if (this.$refs.input) {
124
128
  this.$refs.input.blur();
@@ -23,7 +23,7 @@
23
23
  @click="updatePaymentType(true)">
24
24
  <checked-icon :checked="isDepositPayment" />
25
25
  <span class="lc_regular12 lc__grey1 OrderPaymentInformation__checkbox-label">
26
- Direct Deposit
26
+ Bank Transfer
27
27
  </span>
28
28
  </label>
29
29
  </div>
@@ -110,6 +110,7 @@ export default {
110
110
  };
111
111
  },
112
112
  computed: {
113
+ ...mapGetters(['MESSAGES']),
113
114
  ...mapGetters(['country', 'currency']),
114
115
  ...mapGetters(['orderSettings']),
115
116
  ...mapGetters('order', ['card']),
@@ -189,7 +190,7 @@ export default {
189
190
  this.$emit('next');
190
191
  } else {
191
192
  this.$nextTick(async () => {
192
- const message = `Unfortunately our payment gateway has reported the following error: '${this.errorMessage}'. Please check your card number and try again. Alternatively you can proceed with a 'pay later' order and receive an email confirmation now and pay via credit card or direct deposit`;
193
+ const message = `Unfortunately our payment gateway has reported the following error: '${this.errorMessage}'. Please check your card number and try again. Alternatively you can proceed with a 'pay later' order and receive an email confirmation now and pay via credit card or bank transfer`;
193
194
  const options = { submitLabel: 'PAY LATER', cancelLabel: 'TRY AGAIN', warning: true };
194
195
  const isSwitchToDeposit = await this.showConfirmationModal(message, options);
195
196
  if (isSwitchToDeposit) {
@@ -110,6 +110,10 @@ export default {
110
110
  type: Boolean,
111
111
  default: false
112
112
  },
113
+ onlyPostcode: {
114
+ type: Boolean,
115
+ default: false
116
+ },
113
117
  disabled: {
114
118
  type: Boolean,
115
119
  default: false
@@ -154,7 +158,14 @@ export default {
154
158
  this.isLoading = true;
155
159
  const country = this.codeCountry || this.country;
156
160
  const countryName = country ? (country.isoCode === 'GB' ? 'England' : (country.name || country)) : 'Australia';
157
- this.suburbs = await api.fetchSuburbs({ query: query.trim(), country: countryName }, this.shop?._id);
161
+ const params = {
162
+ query: query.trim(),
163
+ country: countryName
164
+ };
165
+ if (this.onlyPostcode) {
166
+ params.onlyPostcode = true;
167
+ }
168
+ this.suburbs = await api.fetchSuburbs(params, this.shop?._id);
158
169
  this.options = this.suburbs.map(this.createOptionFromSuburb);
159
170
  this.isLoading = false;
160
171
  } else {
@@ -163,9 +174,9 @@ export default {
163
174
  },
164
175
  createOptionFromSuburb({ locality, state, postcode, city, _id, address, id }) {
165
176
  return {
166
- label: address || [locality || city, state, postcode].filter(i => !!i).join(', '),
177
+ label: this.onlyPostcode ? postcode : (address || [locality || city, state, postcode].filter(i => !!i).join(', ')),
167
178
  value: postcode,
168
- _id: id || _id
179
+ _id: id || _id || postcode
169
180
  };
170
181
  },
171
182
  async updatePostcode(option) {
@@ -16,133 +16,132 @@
16
16
  class="form-label">
17
17
  Write your text
18
18
  </label>
19
- <input
19
+ <textarea
20
20
  id="copy"
21
21
  ref="copy"
22
22
  v-model="copy"
23
23
  type="text"
24
24
  name="copy"
25
+ style="height: 100px;"
25
26
  class="form-field bordered labelless"
26
27
  placeholder="Your text here"
27
- :class="{ filled: copy }" />
28
+ :class="{ filled: copy }"></textarea>
28
29
  </validation-provider>
29
- <fragment>
30
- <div
31
- v-if="copy.includes('\n')"
32
- class="form-row">
33
- <div class="form-label">
34
- Align text
30
+ <div
31
+ v-if="copy.includes('\n')"
32
+ class="form-row">
33
+ <div class="form-label">
34
+ Align text
35
+ </div>
36
+ <div class="EditorLayerFormText__align-options">
37
+ <div
38
+ class="EditorLayerFormText__align-option ripple"
39
+ :class="{ active: textAlign === 'left' }"
40
+ @click="textAlign = 'left'">
41
+ <i class="icon-align-left"></i>
35
42
  </div>
36
- <div class="EditorLayerFormText__align-options">
37
- <div
38
- class="EditorLayerFormText__align-option ripple"
39
- :class="{ active: textAlign === 'left' }"
40
- @click="textAlign = 'left'">
41
- <i class="icon-align-left"></i>
42
- </div>
43
- <div
44
- class="EditorLayerFormText__align-option ripple"
45
- :class="{ active: textAlign === 'center' }"
46
- @click="textAlign = 'center'">
47
- <i class="icon-align-center"></i>
48
- </div>
49
- <div
50
- class="EditorLayerFormText__align-option ripple"
51
- :class="{ active: textAlign === 'right' }"
52
- @click="textAlign = 'right'">
53
- <i class="icon-align-right"></i>
54
- </div>
43
+ <div
44
+ class="EditorLayerFormText__align-option ripple"
45
+ :class="{ active: textAlign === 'center' }"
46
+ @click="textAlign = 'center'">
47
+ <i class="icon-align-center"></i>
55
48
  </div>
49
+ <div
50
+ class="EditorLayerFormText__align-option ripple"
51
+ :class="{ active: textAlign === 'right' }"
52
+ @click="textAlign = 'right'">
53
+ <i class="icon-align-right"></i>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ <div class="form-row low-dense">
58
+ <font-family-select
59
+ v-model="fontFamily"
60
+ @input="selectFont"
61
+ @select="selectFont" />
62
+ <input
63
+ type="text"
64
+ :value="fontFamily"
65
+ :class="{ 'filled': fontFamily }"
66
+ class="form-hidden-validator form-field" />
67
+ </div>
68
+ <div class="form-row--cols low-dense">
69
+ <div class="form-col col-half">
70
+ <label class="form-label">
71
+ Text color
72
+ </label>
73
+ <color-picker v-model="fill" />
56
74
  </div>
57
- <div class="form-row low-dense">
58
- <font-family-select
59
- v-model="fontFamily"
60
- @input="selectFont"
61
- @select="selectFont" />
75
+ <div class="form-col col-half">
76
+ <label
77
+ for="fontSize"
78
+ class="form-label">
79
+ Text size
80
+ </label>
81
+ <i
82
+ class="icon-minus form-icon-left EditorLayerFormText__field-action"
83
+ @click="decreaseFontSize">
84
+ </i>
62
85
  <input
86
+ id="fontSize"
87
+ ref="fontSize"
88
+ v-model.number="fontSize"
89
+ name="fontSize"
63
90
  type="text"
64
- :value="fontFamily"
65
- :class="{ 'filled': fontFamily }"
66
- class="form-hidden-validator form-field" />
91
+ class="form-field icon-inside-lr filled centered labelless" />
92
+ <i
93
+ class="icon-plus form-icon-right EditorLayerFormText__field-action"
94
+ @click="increaseFontSize">
95
+ </i>
67
96
  </div>
68
- <div class="form-row--cols low-dense">
69
- <div class="form-col col-half">
70
- <label class="form-label">
71
- Text color
72
- </label>
73
- <color-picker v-model="fill" />
74
- </div>
75
- <div class="form-col col-half">
76
- <label
77
- for="fontSize"
78
- class="form-label">
79
- Text size
80
- </label>
81
- <i
82
- class="icon-minus form-icon-left EditorLayerFormText__field-action"
83
- @click="decreaseFontSize">
84
- </i>
85
- <input
86
- id="fontSize"
87
- ref="fontSize"
88
- v-model.number="fontSize"
89
- name="fontSize"
90
- type="text"
91
- class="form-field icon-inside-lr filled centered labelless" />
92
- <i
93
- class="icon-plus form-icon-right EditorLayerFormText__field-action"
94
- @click="increaseFontSize">
95
- </i>
96
- </div>
97
- </div>
98
- <div class="form-row--cols low-dense">
99
- <div class="form-col col-half">
100
- <label class="form-label EditorLayerFormText__label-with-checkbox">
101
- <span>
102
- Outline color
103
- </span>
104
- <Checkbox v-model="enableOutline" />
105
- </label>
106
- <color-picker
107
- v-if="enableOutline"
108
- v-model="stroke">
109
- </color-picker>
110
- </div>
111
- <div
97
+ </div>
98
+ <div class="form-row--cols low-dense">
99
+ <div class="form-col col-half">
100
+ <label class="form-label EditorLayerFormText__label-with-checkbox">
101
+ <span>
102
+ Outline color
103
+ </span>
104
+ <Checkbox v-model="enableOutline" />
105
+ </label>
106
+ <color-picker
112
107
  v-if="enableOutline"
113
- class="form-col col-half">
114
- <label
115
- for="fontSize"
116
- class="form-label">
117
- Outline weight
118
- </label>
119
- <i
120
- class="icon-minus form-icon-left EditorLayerFormText__field-action"
121
- @click="decreaseStrokeWidth">
122
- </i>
123
- <input
124
- id="strokeWidth"
125
- ref="strokeWidth"
126
- v-model.number="strokeWidth"
127
- name="strokeWidth"
128
- type="text"
129
- class="form-field icon-inside-lr filled centered labelless" />
130
- <i
131
- class="icon-plus form-icon-right EditorLayerFormText__field-action"
132
- @click="increaseStrokeWidth">
133
- </i>
134
- </div>
135
- <div
136
- v-else
137
- class="form-col col-half">
138
- &nbsp;
139
- </div>
108
+ v-model="stroke">
109
+ </color-picker>
110
+ </div>
111
+ <div
112
+ v-if="enableOutline"
113
+ class="form-col col-half">
114
+ <label
115
+ for="fontSize"
116
+ class="form-label">
117
+ Outline weight
118
+ </label>
119
+ <i
120
+ class="icon-minus form-icon-left EditorLayerFormText__field-action"
121
+ @click="decreaseStrokeWidth">
122
+ </i>
123
+ <input
124
+ id="strokeWidth"
125
+ ref="strokeWidth"
126
+ v-model.number="strokeWidth"
127
+ name="strokeWidth"
128
+ type="text"
129
+ class="form-field icon-inside-lr filled centered labelless" />
130
+ <i
131
+ class="icon-plus form-icon-right EditorLayerFormText__field-action"
132
+ @click="increaseStrokeWidth">
133
+ </i>
134
+ </div>
135
+ <div
136
+ v-else
137
+ class="form-col col-half">
138
+ &nbsp;
140
139
  </div>
141
- <editor-layer-common-fields
142
- :layer="layer"
143
- @set-layer-field="data => $emit('set-layer-field', data)">
144
- </editor-layer-common-fields>
145
- </fragment>
140
+ </div>
141
+ <editor-layer-common-fields
142
+ :layer="layer"
143
+ @set-layer-field="data => $emit('set-layer-field', data)">
144
+ </editor-layer-common-fields>
146
145
  </div>
147
146
  </validation-observer>
148
147
  </div>
@@ -29,9 +29,7 @@
29
29
  </template>
30
30
  </v-popover>
31
31
  </span>
32
- <span
33
- v-if="isPrintPricing"
34
- class="lc_regular16 lc_grey1 ml-6">
32
+ <span class="lc_regular16 lc_grey1 ml-6">
35
33
  +
36
34
  <v-popover
37
35
  ref="popover"
@@ -91,7 +91,7 @@
91
91
  }">
92
92
  <editor-print-area-options
93
93
  v-if="productDetailsLoaded"
94
- ref="areaOptions"
94
+ :key="editableSide.id"
95
95
  :product="product"
96
96
  :selected="editablePrintArea && editablePrintArea._id"
97
97
  :side="editableSide.id"
@@ -159,6 +159,7 @@ export default {
159
159
  ]),
160
160
  selectTab(value) {
161
161
  if (this.editableSide.id !== value) {
162
+ this.setEditablePrintArea(null);
162
163
  this.setEditableSide({ id: value });
163
164
  }
164
165
  },
@@ -237,7 +237,7 @@ export default {
237
237
  document.removeEventListener('mousedown', this.onDocumentStartClick);
238
238
  window.removeEventListener('resize', this.onResize);
239
239
  },
240
- onDocumentClick({ target }) {
240
+ onDocumentStartClick({ target }) {
241
241
  // todo: replace by click outside plugin?
242
242
  console.log('target: ', target);
243
243
  const isCanvasElement = target.tagName === 'CANVAS';
@@ -1,4 +1,6 @@
1
+ import { mapGetters } from 'vuex';
1
2
  import { price, shortDate, tax } from '@lancom/shared/assets/js/utils/filters';
3
+ import { getShopCountrySettings } from '@lancom/shared/assets/js/utils/shop';
2
4
 
3
5
  export default {
4
6
  filters: {
@@ -22,6 +24,7 @@ export default {
22
24
  },
23
25
  },
24
26
  computed: {
27
+ ...mapGetters(['MESSAGES']),
25
28
  couponTotal() {
26
29
  return Math.abs(this.order.couponTotal || 0);
27
30
  },
@@ -34,11 +37,14 @@ export default {
34
37
  orderId() {
35
38
  return `${this.order.code}`.replace('ORDER', '');
36
39
  },
40
+ settings() {
41
+ return getShopCountrySettings(this.order.shop, this.order.country);
42
+ },
37
43
  shopContacts() {
38
- return this.order.shop.settings?.contacts || {};
44
+ return this.settings?.contacts || {};
39
45
  },
40
46
  depositInfo() {
41
- return this.order.shop.settings?.depositInfo || {};
47
+ return this.settings?.depositInfo || {};
42
48
  },
43
49
  fullName() {
44
50
  return this.invoice?.address?.fullName || this.order.shippingAddress.fullName;
@@ -69,10 +75,31 @@ export default {
69
75
  ].filter(i => !!i).join(', ');
70
76
  },
71
77
  gstTax() {
72
- return this.order.shop.settings?.pricing?.gstTax || 0;
78
+ return this.settings?.pricing?.gstTax || 0;
73
79
  },
74
80
  gstTotal() {
75
81
  return tax(this.model.total, this.gstTax) - this.model.total;
82
+ },
83
+ taxName() {
84
+ return this.settings?.pricing?.taxName || 'GST'
85
+ },
86
+ paymentCard() {
87
+ if (this.model.charge?.card) {
88
+ return {
89
+ number: this.model.charge.card.display_number,
90
+ scheme: this.model.charge.card.scheme
91
+ };
92
+ } else if (this.model.charge) {
93
+ return {
94
+ number: `XXXX-XXXX-XXXX-${this.model.charge.payment_method_details?.card?.last4 || 'XXXX'}`,
95
+ scheme: this.model.charge.payment_method_details?.card?.brand
96
+ };
97
+ }
76
98
  }
99
+ },
100
+ mounted() {
101
+ console.log('');
102
+ console.log('this.settings: ', this.settings);
103
+ console.log('this.order: ', this.order);
77
104
  }
78
105
  };
@@ -27,6 +27,13 @@
27
27
  </h5>
28
28
  </div>
29
29
  </div>
30
+ <div
31
+ v-if="depositInfo.vatNumber"
32
+ class="OrderView__info">
33
+ <h5 class="text-secondary lc_h5">
34
+ VAT Number: {{ depositInfo.vatNumber }}
35
+ </h5>
36
+ </div>
30
37
  <div class="OrderView__info">
31
38
  <div v-if="shopContacts">
32
39
  <div class="lc_regular16">
@@ -86,12 +93,12 @@
86
93
  <div class="lc_regular16">
87
94
  <b>PAID VIA CREDIT CARD</b>
88
95
  </div>
89
- <div v-if="model.charge && model.charge.card">
96
+ <div v-if="paymentCard">
90
97
  <div class="lc_regular16">
91
- Card: {{ model.charge.card.display_number }}
98
+ Card: {{ paymentCard.number }}
92
99
  </div>
93
100
  <div class="lc_regular16">
94
- Scheme: {{ model.charge.card.scheme }}
101
+ Scheme: {{ paymentCard.scheme }}
95
102
  </div>
96
103
  </div>
97
104
  </td>
@@ -99,7 +106,7 @@
99
106
  v-else
100
107
  class="w-33">
101
108
  <div class="lc_regular16">
102
- <b>DIRECT DEPOSIT DETAILS</b>
109
+ <b>{{ MESSAGES.DIRECT_DEPOSIT_DETAILS || 'DIRECT DEPOSIT DETAILS'}}</b>
103
110
  </div>
104
111
  <div class="lc_regular16">
105
112
  Bank: {{ depositInfo.bank }}
@@ -198,7 +205,6 @@
198
205
  </template>
199
206
 
200
207
  <script>
201
- import { mapGetters } from 'vuex';
202
208
  import OrderViewMixin from './order-view.mixin';
203
209
  import OrderViewProduct from './order_view_product/order-view-product';
204
210
 
@@ -213,9 +219,6 @@ export default {
213
219
  type: Boolean,
214
220
  default: true
215
221
  }
216
- },
217
- computed: {
218
- ...mapGetters(['taxName'])
219
222
  }
220
223
  };
221
224
  </script>
@@ -19,11 +19,14 @@
19
19
  <product-main-info :product="product" />
20
20
  </section>
21
21
  <section class="Product__section">
22
- <product-colors-selector v-if="productDetails" />
22
+ <wizard-editor />
23
23
  </section>
24
- <section class="Product__section">
24
+ <!-- <section class="Product__section">
25
+ <product-colors-selector v-if="productDetails" />
26
+ </section> -->
27
+ <!-- <section class="Product__section">
25
28
  <product-tier-prices :product="product" />
26
- </section>
29
+ </section> -->
27
30
  <section class="Product__section">
28
31
  <product-fabric-and-size-info :product="product" />
29
32
  </section>
@@ -50,6 +53,8 @@ import ProductModelMeasurements from './layouts/product_model_measurements/produ
50
53
  import ProductSizeTable from './layouts/product_size_table/product-size-table';
51
54
  import RelatedProducts from '@lancom/shared/components/product/related_products/related-products';
52
55
  import Gallery from '@lancom/shared/components/product/gallery/gallery';
56
+ import WizardEditor from './wizard-editor/wizard-editor.vue';
57
+
53
58
 
54
59
  // import ProductLabelsCustomization from './layouts/product_labels_customization/product-labels-customization';
55
60
 
@@ -64,7 +69,8 @@ export default {
64
69
  ProductModelMeasurements,
65
70
  ProductSizeTable,
66
71
  RelatedProducts,
67
- Gallery
72
+ Gallery,
73
+ WizardEditor
68
74
  // ProductLabelsCustomization
69
75
  },
70
76
  computed: {
@@ -27,6 +27,7 @@
27
27
  :class="{ invalidate: disabled, empty: !model }"
28
28
  :aria-label="size.name"
29
29
  :disabled="disabled"
30
+ @wheel="onWheel"
30
31
  @focus="onFocus()"
31
32
  @blur="onBlur()" />
32
33
  <div
@@ -117,6 +118,9 @@ export default {
117
118
  },
118
119
  methods: {
119
120
  ...mapMutations('product', ['setSimpleProductAmount']),
121
+ onWheel(e) {
122
+ e.target.blur();
123
+ },
120
124
  onFocus() {
121
125
  this.defaultValue = '';
122
126
  },
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <div class="EditorAsync__wrapper">
3
+ <placeholder
4
+ v-if="!isLoadedComponent"
5
+ style="height: 500px" />
6
+ <wizard-editor
7
+ v-else
8
+ v-bind="$attrs" />
9
+ </div>
10
+ </template>
11
+
12
+ <script>
13
+ import Vue from 'vue';
14
+ import ComponentAsyncMixin from '@lancom/shared/mixins/component-async';
15
+ import Placeholder from '@lancom/shared/components/placeholder/placeholder';
16
+
17
+ export default {
18
+ name: 'EditorAsync',
19
+ components: {
20
+ Placeholder
21
+ },
22
+ mixins: [ComponentAsyncMixin],
23
+ methods: {
24
+ async importComponents() {
25
+ const component = await import('./wizard-editor');
26
+ Vue.component('wizard-editor', component.default);
27
+ }
28
+ }
29
+ };
30
+ </script>
@@ -0,0 +1,37 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .Editor {
4
+ &__section {
5
+ margin-bottom: 20px;
6
+ position: relative;
7
+ }
8
+ &__colors-selector {
9
+ &--disabled {
10
+ opacity: 0.5;
11
+ pointer-events: none;
12
+ }
13
+ }
14
+ &__tooltip-message {
15
+ width: 250px;
16
+ font-size: 14px;
17
+ padding: 20px;
18
+ background: $green;
19
+ color: $black;
20
+ position: absolute;
21
+ top: 150px;
22
+ left: 50%;
23
+ width: 272px;
24
+ font-size: 14px;
25
+ padding: 10px;
26
+ line-height: 23px;
27
+ border-radius: 4px;
28
+ text-align: center;
29
+ font-weight: bold;
30
+ z-index: 2;
31
+ margin-left: -125px;
32
+ span {
33
+ text-decoration: underline;
34
+ cursor: pointer;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <div class="Editor__wrapper">
3
+ <div>
4
+ <div
5
+ v-if="productDetailsLoaded"
6
+ class="Editor__wizard">
7
+ <div class="Editor__section">
8
+ <wizard
9
+ ref="wizard"
10
+ v-show="visibleWizard" />
11
+ </div>
12
+ <div
13
+ v-if="editableColor"
14
+ class="Editor__section">
15
+ <product-multipacks-carousel
16
+ :key="editableColor._id"
17
+ :product="product"
18
+ :color="editableColor"
19
+ :simple-products="simpleProducts"
20
+ :with-gst="priceIncludeGST" />
21
+ </div>
22
+ <div
23
+ class="Editor__section"
24
+ @mouseenter="onColorsSelectorMouseenter"
25
+ @mouseleave="onColorsSelectorMouseleave"
26
+ @mousemove="onColorsSelectorMousemoveWithThrottle">
27
+ <product-colors-selector
28
+ class="Editor__colors-selector"
29
+ :class="{
30
+ 'Editor__colors-selector--disabled': disabledProductsSelector
31
+ }" />
32
+ <div
33
+ v-show="disabledProductsSelector"
34
+ ref="message"
35
+ class="Editor__tooltip-message">
36
+ You must complete the print details above, or <span @click="hideWizard()">cancel</span> the print
37
+ </div>
38
+ </div>
39
+ <div class="Editor__section">
40
+ <editor-pricing />
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script>
48
+ import { mapGetters } from 'vuex';
49
+ import throttle from 'lodash.throttle';
50
+ import ProductMultipacksCarousel from '@lancom/shared/components/product/product_multipacks_carousel/product-multipacks-carousel';
51
+ import Wizard from '@lancom/shared/components/product/wizard/wizard';
52
+ import ProductColorsSelector from '@lancom/shared/components/product/product_colors_selector/product-colors-selector';
53
+ import EditorPricing from '@lancom/shared/components/product/editor_pricing/editor-pricing';
54
+
55
+ export default {
56
+ name: 'Editor',
57
+ components: {
58
+ ProductColorsSelector,
59
+ ProductMultipacksCarousel,
60
+ Wizard,
61
+ EditorPricing
62
+ },
63
+ data() {
64
+ return {
65
+ isVisibleMessage: false,
66
+ onColorsSelectorMousemoveWithThrottle: throttle(this.onColorsSelectorMousemove, 20)
67
+ };
68
+ },
69
+ computed: {
70
+ ...mapGetters('product', [
71
+ 'product',
72
+ 'simpleProducts',
73
+ 'editableColorSimpleProducts',
74
+ 'editableColor',
75
+ 'productDetailsLoaded',
76
+ 'hasLayers',
77
+ 'isPrintPricing',
78
+ 'priceIncludeGST'
79
+ ]),
80
+ visibleWizard() {
81
+ return (this.product.printTypes || []).length > 0;
82
+ },
83
+ disabledProductsSelector() {
84
+ return this.isPrintPricing && !this.hasLayers;
85
+ }
86
+ },
87
+ destroyed() {
88
+ if (this.$refs.message) {
89
+ document.body.removeChild(this.$refs.message);
90
+ }
91
+ },
92
+ methods: {
93
+ onColorsSelectorMouseenter() {
94
+ // this.isVisibleMessage = this.disabledProductsSelector;
95
+ },
96
+ onColorsSelectorMousemove({ clientX, clientY }) {
97
+ // if (this.isVisibleMessage && this.$refs.message) {
98
+ // document.body.appendChild(this.$refs.message);
99
+ // this.$refs.message.style.display = 'block';
100
+ // this.$refs.message.style.top = `${clientY}px`;
101
+ // this.$refs.message.style.left = ('ontouchstart' in window) ? '50%' : `${clientX}px`;
102
+ // }
103
+ },
104
+ onColorsSelectorMouseleave() {
105
+ // if (this.isVisibleMessage && this.$refs.message) {
106
+ // document.body.removeChild(this.$refs.message);
107
+ // }
108
+ // this.isVisibleMessage = false;
109
+ // this.$refs.message.style.display = 'none';
110
+ },
111
+ hideWizard() {
112
+ this.$refs.wizard.toggleVisible();
113
+ }
114
+ }
115
+ };
116
+ </script>
117
+
118
+ <style lang="scss">
119
+ @import 'wizard-editor';
120
+ </style>
@@ -38,7 +38,7 @@
38
38
  <products-autocomplete-item
39
39
  v-for="product of products"
40
40
  :key="product._id"
41
- :to-editor="false"
41
+ :to-editor="toEditor"
42
42
  :product="product"
43
43
  class="ProductsAutocomplete__result-item"
44
44
  @select="$emit('select', product)" />
@@ -71,6 +71,10 @@ export default {
71
71
  placeholder: {
72
72
  type: String,
73
73
  default: 'Search products'
74
+ },
75
+ toEditor: {
76
+ type: Boolean,
77
+ default: false
74
78
  }
75
79
  },
76
80
  data() {
@@ -23,6 +23,7 @@ export default {
23
23
  };
24
24
  },
25
25
  computed: {
26
+ ...mapGetters(['MESSAGES']),
26
27
  ...mapGetters('quote', ['quote', 'option', 'proceedOption', 'selectedOption', 'depositInfo', 'shopContacts', 'quoteAddress', 'quoteId', 'options', 'gstTax']),
27
28
  ...mapGetters(['shop', 'country', 'currency'])
28
29
  },
@@ -38,7 +38,7 @@
38
38
  <div>{{ quote.address.additionalInfo }}</div>
39
39
  </td>
40
40
  <td class="w-50">
41
- <div><b>DIRECT DEPOSIT DETAILS</b></div>
41
+ <div><b>{{ MESSAGES.DIRECT_DEPOSIT_DETAILS || 'DIRECT DEPOSIT DETAILS'}}</b></div>
42
42
  <div>Bank: {{ depositInfo.bank }}</div>
43
43
  <div>Account name: {{ depositInfo.accountName }}</div>
44
44
  <div>BSB: {{ depositInfo.BSB }}</div>
@@ -34,7 +34,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING) => ({
34
34
  if (IS_PRODUCT_PRESET_PRINT_PRICING) {
35
35
  const printType = product.printTypes[0];
36
36
  store.commit('product/setSelectedPrintType', printType);
37
- store.commit('product/setIsPrintPricing', true);
37
+ // store.commit('product/setIsPrintPricing', true);
38
38
  }
39
39
 
40
40
  if (query.store) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.287",
3
+ "version": "0.0.289",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/cart.js CHANGED
@@ -45,7 +45,7 @@ const getInvalidStockQuantities = entities => {
45
45
  };
46
46
 
47
47
  const getPrintsQuantities = entities => {
48
- const printTypes = entities.reduce((types, e) => [...types, ...e.prints.map(({ printType }) => ({ ...printType, guid: `${e.guid}-${printType._id}` }))], []);
48
+ const printTypes = entities.reduce((types, e) => [...types, ...e.prints.map(({ printType }) => ({ ...printType, guid: `${e.guid}-${printType?._id}` }))], []);
49
49
  const grouped = groupBy(printTypes, 'guid');
50
50
  const quantities = Object.keys(grouped).map(guid => {
51
51
  const [{ name, minQuantity }] = grouped[guid];
@@ -279,7 +279,7 @@ function generateCalculatePriceData(entities, suburb, suppliersWithRates, coupon
279
279
  return {
280
280
  _id: print._id,
281
281
  guid: print.guid,
282
- costType: print.printType.costType,
282
+ costType: print.printType?.costType,
283
283
  setupCost,
284
284
  printCost,
285
285
  freeSetupOver,
package/store/index.js CHANGED
@@ -3,7 +3,7 @@ import { saveStatePlugin, loadState } from '@lancom/shared/plugins/save-state';
3
3
  import { MESSAGES, COUNTRIES_MESSAGES } from '@/messages';
4
4
  const cookieparser = process.server ? require('cookieparser') : undefined;
5
5
  const CLOSED_NOTIFICATION = 'lancom-closed-notification-1.0';
6
-
6
+ import { getShopCountrySettings } from '@lancom/shared/assets/js/utils/shop';
7
7
 
8
8
  export const state = () => ({
9
9
  country: null,
@@ -50,7 +50,6 @@ export const actions = {
50
50
  const menus = await api.fetchMenus(shop._id);
51
51
  commit('setMenus', menus);
52
52
  commit('setShop', shop);
53
- commit('setSettings', shop.settings);
54
53
  // if (req.headers.cookie) {
55
54
  const { country, currency } = (req.headers.cookie && cookieparser.parse(req.headers.cookie)) || {};
56
55
  const headers = (req && req.headers) ? Object.assign({}, req.headers) : {};
@@ -59,14 +58,16 @@ export const actions = {
59
58
  commit('setCountry', settings.country);
60
59
  commit('setCurrency', settings.currency);
61
60
 
62
- const countrySettings = (shop.countries || []).find(c => c.country?._id === settings.country?._id) || { settings: [] };
63
-
61
+ const countrySetting = getShopCountrySettings(shop, settings.country);
62
+ commit('setSettings', countrySetting);
63
+
64
64
  if (process.env.PINPAYMENT_PUBLISHABLE_API_KEY) {
65
65
  commit('setPayment', {
66
66
  type: 'pinpayment',
67
67
  clientKey: process.env.PINPAYMENT_PUBLISHABLE_API_KEY
68
68
  });
69
69
  } else {
70
+ const countrySettings = (shop.countries || []).find(c => c.country?._id === settings.country?._id) || { settings: [] };
70
71
  const countrySetting = (countrySettings?.settings || []).find(s => !!s.settings.app.STRIPE_PUBLIC_KEY);
71
72
  if (countrySetting) {
72
73
  commit('setPayment', {
@@ -76,13 +77,6 @@ export const actions = {
76
77
  }
77
78
  }
78
79
 
79
-
80
- const pricingSetting = (countrySettings?.settings || []).find(s => !!s.settings.pricing);
81
- commit('setPricing', {
82
- ...shop.settings.pricing,
83
- ...(pricingSetting?.settings?.pricing || {})
84
- });
85
-
86
80
  // }
87
81
  try {
88
82
  if (req.headers.cookie) {
@@ -142,12 +136,13 @@ export const mutations = {
142
136
  setCurrency(state, currency) {
143
137
  state.currency = currency;
144
138
  },
145
- setSettings(state, { contacts, notificationBar, discountPopup, order, depositInfo }) {
139
+ setSettings(state, { contacts, notificationBar, discountPopup, order, depositInfo, pricing }) {
146
140
  state.contacts = contacts;
147
141
  state.orderInfo = order;
148
142
  state.notificationBar = notificationBar;
149
143
  state.discountPopup = discountPopup;
150
144
  state.depositInfo = depositInfo;
145
+ state.pricing = pricing;
151
146
  },
152
147
  setShop(state, shop) {
153
148
  state.shop = shop;
package/store/product.js CHANGED
@@ -364,8 +364,8 @@ export const mutations = {
364
364
  ];
365
365
  Vue.set(state.template, 'layers', layers);
366
366
  if (layers.length === 1 && !state.product.printOnly) {
367
- const printType = state.product.printTypes[0];
368
- state.selectedPrintType = printType;
367
+ // const printType = state.product.printTypes[0];
368
+ // state.selectedPrintType = printType;
369
369
  state.isPrintPricing = true;
370
370
  }
371
371
  },
@@ -376,7 +376,7 @@ export const mutations = {
376
376
  state.selectedLayer = null;
377
377
  }
378
378
  if (state.template.layers.length === 0 && !state.product.printOnly) {
379
- state.selectedPrintType = null;
379
+ // state.selectedPrintType = null;
380
380
  state.isPrintPricing = false;
381
381
  }
382
382
  },