@salla.sa/twilight-components 2.11.45 → 2.11.47
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.
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/salla-add-product-button.cjs.entry.js +47 -23
- package/dist/cjs/salla-button_36.cjs.entry.js +51 -57
- package/dist/cjs/salla-product-options.cjs.entry.js +31 -5
- package/dist/cjs/twilight.cjs.js +1 -1
- package/dist/collection/components/salla-add-product-button/salla-add-product-button.js +94 -32
- package/dist/collection/components/salla-localization-modal/salla-localization-modal.js +5 -0
- package/dist/collection/components/salla-loyalty/salla-loyalty.js +10 -38
- package/dist/collection/components/salla-product-availability/salla-product-availability.js +62 -31
- package/dist/collection/components/salla-product-options/salla-product-options.js +94 -10
- package/dist/components/salla-add-product-button.js +53 -24
- package/dist/components/salla-localization-modal.js +5 -0
- package/dist/components/salla-loyalty.js +6 -31
- package/dist/components/salla-product-availability2.js +44 -29
- package/dist/components/salla-product-options.js +36 -6
- package/dist/esm/loader.js +1 -1
- package/dist/esm/salla-add-product-button.entry.js +47 -23
- package/dist/esm/salla-button_36.entry.js +51 -57
- package/dist/esm/salla-product-options.entry.js +31 -5
- package/dist/esm/twilight.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/salla-add-product-button.entry.js +1 -1
- package/dist/esm-es5/salla-button_36.entry.js +1 -1
- package/dist/esm-es5/salla-product-options.entry.js +2 -2
- package/dist/esm-es5/twilight.js +1 -1
- package/dist/twilight/p-124d2785.entry.js +4 -0
- package/dist/twilight/{p-c221811f.system.entry.js → p-14fd987d.system.entry.js} +5 -5
- package/dist/twilight/p-8343cda2.system.entry.js +4 -0
- package/dist/twilight/p-9fda3312.system.js +1 -1
- package/dist/twilight/p-cb64eda8.system.entry.js +4 -0
- package/dist/twilight/{p-c247d3b2.entry.js → p-d2c63efe.entry.js} +1 -1
- package/dist/twilight/p-e654d498.entry.js +4 -0
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-add-product-button/salla-add-product-button.d.ts +13 -0
- package/dist/types/components/salla-loyalty/salla-loyalty.d.ts +1 -1
- package/dist/types/components/salla-product-availability/salla-product-availability.d.ts +4 -0
- package/dist/types/components/salla-product-options/salla-product-options.d.ts +13 -0
- package/dist/types/components.d.ts +39 -3
- package/package.json +4 -4
- package/dist/twilight/p-4bda1676.entry.js +0 -4
- package/dist/twilight/p-5a1197bb.system.entry.js +0 -4
- package/dist/twilight/p-cc128664.system.entry.js +0 -4
- package/dist/twilight/p-dbb379ce.entry.js +0 -4
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Crafted with ❤ by Salla
|
|
3
3
|
*/
|
|
4
|
-
import { Component, Element, Event, Host, Prop, h } from '@stencil/core';
|
|
4
|
+
import { Component, Element, State, Event, Host, Prop, h } from '@stencil/core';
|
|
5
5
|
export class SallaAddProductButton {
|
|
6
6
|
constructor() {
|
|
7
7
|
this.hostAttributes = {};
|
|
8
|
-
this.hasLabel = false;
|
|
9
|
-
/**
|
|
10
|
-
* Channels.
|
|
11
|
-
*/
|
|
12
|
-
this.channels = null;
|
|
13
|
-
/**
|
|
14
|
-
* Product Quantity
|
|
15
|
-
*/
|
|
16
|
-
this.quantity = 0;
|
|
17
|
-
/**
|
|
18
|
-
* Donating amount.
|
|
19
|
-
*/
|
|
20
|
-
this.donatingAmount = 0;
|
|
21
8
|
/**
|
|
22
9
|
* Product Status.Defaults to `sale`
|
|
23
10
|
*/
|
|
@@ -26,6 +13,7 @@ export class SallaAddProductButton {
|
|
|
26
13
|
* Product type. Defaults to `product`
|
|
27
14
|
*/
|
|
28
15
|
this.productType = 'product';
|
|
16
|
+
this.selectedOptions = [];
|
|
29
17
|
}
|
|
30
18
|
getLabel() {
|
|
31
19
|
if (this.productStatus === 'sale') {
|
|
@@ -59,7 +47,10 @@ export class SallaAddProductButton {
|
|
|
59
47
|
endpoint: 'quickAdd'
|
|
60
48
|
}).reduce((a, [k, v]) => (v ? (a[k] = v, a) : a), {});
|
|
61
49
|
return salla.cart.addItem(data)
|
|
62
|
-
.then(response =>
|
|
50
|
+
.then(response => {
|
|
51
|
+
this.selectedOptions = [];
|
|
52
|
+
this.success.emit(response);
|
|
53
|
+
})
|
|
63
54
|
.catch(error => this.failed.emit(error));
|
|
64
55
|
}
|
|
65
56
|
addBookingProduct() {
|
|
@@ -80,29 +71,64 @@ export class SallaAddProductButton {
|
|
|
80
71
|
}
|
|
81
72
|
return this.hostAttributes;
|
|
82
73
|
}
|
|
74
|
+
pushSelectedOption(data) {
|
|
75
|
+
const index = this.selectedOptions.findIndex(option => option.option_id === data.option.id);
|
|
76
|
+
if (index > -1) {
|
|
77
|
+
this.selectedOptions[index] = Object.assign(Object.assign({}, data.detail), { option_id: data.option.id });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.selectedOptions.push(Object.assign(Object.assign({}, data.detail), { option_id: data.option.id }));
|
|
81
|
+
}
|
|
82
|
+
this.hasOutOfStockOption = this.selectedOptions.some(option => option.is_out);
|
|
83
|
+
}
|
|
83
84
|
componentWillLoad() {
|
|
84
85
|
this.hasLabel = !!this.host.innerHTML.replace('<!---->', '').trim();
|
|
85
86
|
}
|
|
86
87
|
render() {
|
|
87
88
|
var _a;
|
|
88
89
|
//TODO:: find a better fix, this is a patch for issue that duplicates the buttons more than twice @see the screenshot inside this folder
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
h("salla-
|
|
95
|
-
|
|
90
|
+
if ((_a = this.host.closest('.swiper-slide')) === null || _a === void 0 ? void 0 : _a.classList.contains('swiper-slide-duplicate')) {
|
|
91
|
+
return '';
|
|
92
|
+
}
|
|
93
|
+
if (this.hasSubscribedOptions) {
|
|
94
|
+
return h(Host, null,
|
|
95
|
+
h("salla-product-availability", Object.assign({}, this.getBtnAttributes(), { "is-subscribed": true })));
|
|
96
|
+
}
|
|
97
|
+
if ((this.productStatus === 'out-and-notify' && this.channels) || this.hasOutOfStockOption) {
|
|
98
|
+
return h(Host, null,
|
|
99
|
+
h("salla-product-availability", Object.assign({}, this.getBtnAttributes())));
|
|
100
|
+
}
|
|
101
|
+
return h(Host, null,
|
|
102
|
+
h("salla-button", Object.assign({ color: this.productStatus === 'sale' ? 'primary' : 'light', fill: this.productStatus === 'sale' ? 'solid' : 'outline', ref: el => this.btn = el, onClick: event => this.addProductToCart(event), disabled: this.productStatus !== 'sale' }, this.getBtnAttributes(), { "loader-position": "center", type: "button" }),
|
|
103
|
+
h("slot", null)));
|
|
104
|
+
}
|
|
105
|
+
componentDidLoad() {
|
|
106
|
+
if (!this.notifyOptionsAvailability) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
salla.event.on('product-options::change', data => {
|
|
110
|
+
if (!['thumbnail', 'color', 'single-option'].includes(data.option.type)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.pushSelectedOption(data);
|
|
114
|
+
this.hasLabel = false;
|
|
115
|
+
if (!this.subscribedOptions) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
//check if subscribedOptions are the selected now
|
|
119
|
+
this.hasSubscribedOptions = JSON.parse(this.subscribedOptions)
|
|
120
|
+
.filter(ids => ids.every(id => this.selectedOptions.some(option => option.id === id)))
|
|
121
|
+
.length > 0;
|
|
122
|
+
});
|
|
96
123
|
}
|
|
97
124
|
componentDidRender() {
|
|
125
|
+
var _a;
|
|
98
126
|
//if label not passed, get label
|
|
99
127
|
if (this.hasLabel) {
|
|
100
128
|
return;
|
|
101
129
|
}
|
|
102
|
-
this.btn.setText(this.getLabel()
|
|
103
|
-
salla.lang.onLoaded(() => {
|
|
104
|
-
this.btn.setText(this.getLabel() || 'اضافة للسلة');
|
|
105
|
-
});
|
|
130
|
+
(_a = this.btn) === null || _a === void 0 ? void 0 : _a.setText(this.getLabel());
|
|
131
|
+
salla.lang.onLoaded(() => { var _a; return (_a = this.btn) === null || _a === void 0 ? void 0 : _a.setText(this.getLabel()); });
|
|
106
132
|
}
|
|
107
133
|
static get is() { return "salla-add-product-button"; }
|
|
108
134
|
static get originalStyleUrls() { return {
|
|
@@ -127,8 +153,24 @@ export class SallaAddProductButton {
|
|
|
127
153
|
"text": "Channels."
|
|
128
154
|
},
|
|
129
155
|
"attribute": "channels",
|
|
130
|
-
"reflect": true
|
|
131
|
-
|
|
156
|
+
"reflect": true
|
|
157
|
+
},
|
|
158
|
+
"subscribedOptions": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"mutable": false,
|
|
161
|
+
"complexType": {
|
|
162
|
+
"original": "string",
|
|
163
|
+
"resolved": "string",
|
|
164
|
+
"references": {}
|
|
165
|
+
},
|
|
166
|
+
"required": false,
|
|
167
|
+
"optional": false,
|
|
168
|
+
"docs": {
|
|
169
|
+
"tags": [],
|
|
170
|
+
"text": "Subscribed Options ex: \"[[139487,2394739],[1212,1544]]\""
|
|
171
|
+
},
|
|
172
|
+
"attribute": "subscribed-options",
|
|
173
|
+
"reflect": false
|
|
132
174
|
},
|
|
133
175
|
"quantity": {
|
|
134
176
|
"type": "number",
|
|
@@ -145,8 +187,7 @@ export class SallaAddProductButton {
|
|
|
145
187
|
"text": "Product Quantity"
|
|
146
188
|
},
|
|
147
189
|
"attribute": "quantity",
|
|
148
|
-
"reflect": true
|
|
149
|
-
"defaultValue": "0"
|
|
190
|
+
"reflect": true
|
|
150
191
|
},
|
|
151
192
|
"donatingAmount": {
|
|
152
193
|
"type": "number",
|
|
@@ -163,8 +204,24 @@ export class SallaAddProductButton {
|
|
|
163
204
|
"text": "Donating amount."
|
|
164
205
|
},
|
|
165
206
|
"attribute": "donating-amount",
|
|
166
|
-
"reflect": true
|
|
167
|
-
|
|
207
|
+
"reflect": true
|
|
208
|
+
},
|
|
209
|
+
"notifyOptionsAvailability": {
|
|
210
|
+
"type": "boolean",
|
|
211
|
+
"mutable": false,
|
|
212
|
+
"complexType": {
|
|
213
|
+
"original": "boolean",
|
|
214
|
+
"resolved": "boolean",
|
|
215
|
+
"references": {}
|
|
216
|
+
},
|
|
217
|
+
"required": false,
|
|
218
|
+
"optional": false,
|
|
219
|
+
"docs": {
|
|
220
|
+
"tags": [],
|
|
221
|
+
"text": "Listen to product options availability."
|
|
222
|
+
},
|
|
223
|
+
"attribute": "notify-options-availability",
|
|
224
|
+
"reflect": true
|
|
168
225
|
},
|
|
169
226
|
"productId": {
|
|
170
227
|
"type": "any",
|
|
@@ -220,6 +277,11 @@ export class SallaAddProductButton {
|
|
|
220
277
|
"defaultValue": "'product'"
|
|
221
278
|
}
|
|
222
279
|
}; }
|
|
280
|
+
static get states() { return {
|
|
281
|
+
"hasOutOfStockOption": {},
|
|
282
|
+
"hasSubscribedOptions": {},
|
|
283
|
+
"selectedOptions": {}
|
|
284
|
+
}; }
|
|
223
285
|
static get events() { return [{
|
|
224
286
|
"method": "success",
|
|
225
287
|
"name": "success",
|
|
@@ -46,6 +46,11 @@ export class SallaLocalizationModal {
|
|
|
46
46
|
this.modal.open();
|
|
47
47
|
return await salla.api.withoutNotifier(() => this.getLanguages())
|
|
48
48
|
.then(() => this.getCurrencies())
|
|
49
|
+
.then(() => {
|
|
50
|
+
if (this.languages.length < 2 && this.currencies.length < 2) {
|
|
51
|
+
this.modal.close();
|
|
52
|
+
}
|
|
53
|
+
})
|
|
49
54
|
.catch(e => {
|
|
50
55
|
var _a, _b, _c, _d;
|
|
51
56
|
console.log(e);
|
|
@@ -18,18 +18,6 @@ export class SallaLoyalty {
|
|
|
18
18
|
this.askConfirmation = false;
|
|
19
19
|
this.is_loggedin = false;
|
|
20
20
|
this.hasError = false;
|
|
21
|
-
/**
|
|
22
|
-
* The exchanged prize point
|
|
23
|
-
*/
|
|
24
|
-
this.prizePoints = undefined;
|
|
25
|
-
/**
|
|
26
|
-
* Available customer points with which they can exchange.
|
|
27
|
-
*/
|
|
28
|
-
this.customerPoints = undefined;
|
|
29
|
-
/**
|
|
30
|
-
* The exchangable prize title
|
|
31
|
-
*/
|
|
32
|
-
this.prizeTitle = undefined;
|
|
33
21
|
/**
|
|
34
22
|
* Does the merchant allow to login using email
|
|
35
23
|
*/
|
|
@@ -54,6 +42,7 @@ export class SallaLoyalty {
|
|
|
54
42
|
var _a, _b;
|
|
55
43
|
this.prizePoints = (_a = cart.loyalty.prize) === null || _a === void 0 ? void 0 : _a.points;
|
|
56
44
|
this.prizeTitle = (_b = cart.loyalty.prize) === null || _b === void 0 ? void 0 : _b.title;
|
|
45
|
+
this.customerPoints = cart.loyalty.customer_points || this.customerPoints;
|
|
57
46
|
});
|
|
58
47
|
}
|
|
59
48
|
setSelectedPrizeItem(item) {
|
|
@@ -151,13 +140,7 @@ export class SallaLoyalty {
|
|
|
151
140
|
* Cancel Exchanged prizes
|
|
152
141
|
*/
|
|
153
142
|
async resetExchange() {
|
|
154
|
-
return await salla.loyalty.reset()
|
|
155
|
-
.then((response) => {
|
|
156
|
-
var _a;
|
|
157
|
-
this.customerPoints = this.customerPoints || ((_a = response.data) === null || _a === void 0 ? void 0 : _a.customer_points);
|
|
158
|
-
this.prizePoints = undefined;
|
|
159
|
-
this.prizeTitle = undefined;
|
|
160
|
-
}).catch(e => console.log(e));
|
|
143
|
+
return await salla.loyalty.reset();
|
|
161
144
|
}
|
|
162
145
|
/**
|
|
163
146
|
* Open Confirmation modal
|
|
@@ -184,15 +167,7 @@ export class SallaLoyalty {
|
|
|
184
167
|
var _a;
|
|
185
168
|
this.buttonLoading = true;
|
|
186
169
|
return await salla.loyalty.exchange((_a = this.selectedItem) === null || _a === void 0 ? void 0 : _a.id)
|
|
187
|
-
.then((
|
|
188
|
-
var _a, _b, _c, _d;
|
|
189
|
-
this.prizePoints = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.prize) === null || _b === void 0 ? void 0 : _b.points;
|
|
190
|
-
this.prizeTitle = (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.prize) === null || _d === void 0 ? void 0 : _d.title;
|
|
191
|
-
if (this.selectedItem.key == "FREE_PRODUCT" && salla.url.is_page('cart')) {
|
|
192
|
-
window.location.reload();
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
.catch(e => console.log(e))
|
|
170
|
+
.then(() => this.selectedItem.key == "FREE_PRODUCT" && salla.url.is_page('cart') && window.location.reload())
|
|
196
171
|
.finally(() => {
|
|
197
172
|
this.buttonLoading = false;
|
|
198
173
|
this.cancelProcess();
|
|
@@ -265,7 +240,7 @@ export class SallaLoyalty {
|
|
|
265
240
|
static get properties() { return {
|
|
266
241
|
"prizePoints": {
|
|
267
242
|
"type": "any",
|
|
268
|
-
"mutable":
|
|
243
|
+
"mutable": true,
|
|
269
244
|
"complexType": {
|
|
270
245
|
"original": "string | number",
|
|
271
246
|
"resolved": "number | string",
|
|
@@ -278,12 +253,11 @@ export class SallaLoyalty {
|
|
|
278
253
|
"text": "The exchanged prize point"
|
|
279
254
|
},
|
|
280
255
|
"attribute": "prize-points",
|
|
281
|
-
"reflect":
|
|
282
|
-
"defaultValue": "undefined"
|
|
256
|
+
"reflect": true
|
|
283
257
|
},
|
|
284
258
|
"customerPoints": {
|
|
285
259
|
"type": "number",
|
|
286
|
-
"mutable":
|
|
260
|
+
"mutable": true,
|
|
287
261
|
"complexType": {
|
|
288
262
|
"original": "number",
|
|
289
263
|
"resolved": "number",
|
|
@@ -296,12 +270,11 @@ export class SallaLoyalty {
|
|
|
296
270
|
"text": "Available customer points with which they can exchange."
|
|
297
271
|
},
|
|
298
272
|
"attribute": "customer-points",
|
|
299
|
-
"reflect":
|
|
300
|
-
"defaultValue": "undefined"
|
|
273
|
+
"reflect": true
|
|
301
274
|
},
|
|
302
275
|
"prizeTitle": {
|
|
303
276
|
"type": "string",
|
|
304
|
-
"mutable":
|
|
277
|
+
"mutable": true,
|
|
305
278
|
"complexType": {
|
|
306
279
|
"original": "string",
|
|
307
280
|
"resolved": "string",
|
|
@@ -311,11 +284,10 @@ export class SallaLoyalty {
|
|
|
311
284
|
"optional": false,
|
|
312
285
|
"docs": {
|
|
313
286
|
"tags": [],
|
|
314
|
-
"text": "The
|
|
287
|
+
"text": "The prize title"
|
|
315
288
|
},
|
|
316
289
|
"attribute": "prize-title",
|
|
317
|
-
"reflect":
|
|
318
|
-
"defaultValue": "undefined"
|
|
290
|
+
"reflect": true
|
|
319
291
|
},
|
|
320
292
|
"allowEmail": {
|
|
321
293
|
"type": "boolean",
|
|
@@ -9,40 +9,13 @@ export class SallaProductAvailability {
|
|
|
9
9
|
this.isUser = salla.config.isUser();
|
|
10
10
|
this.translationLoaded = false;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Listen to product options availability.
|
|
13
13
|
*/
|
|
14
|
-
this.
|
|
14
|
+
this.notifyOptionsAvailability = false;
|
|
15
15
|
/**
|
|
16
16
|
* is current user already subscribed
|
|
17
17
|
*/
|
|
18
18
|
this.isSubscribed = false;
|
|
19
|
-
// @Method()
|
|
20
|
-
this.submit = async () => {
|
|
21
|
-
if (this.isUser) {
|
|
22
|
-
return salla.api.product.availabilitySubscribe(this.productId)
|
|
23
|
-
.then(() => this.isSubscribed = true);
|
|
24
|
-
}
|
|
25
|
-
let data = { id: this.productId };
|
|
26
|
-
if (this.channels_.includes('sms')) {
|
|
27
|
-
let { phone, countryCode } = await this.mobileInput.getValues();
|
|
28
|
-
data['country_code'] = countryCode;
|
|
29
|
-
data['phone'] = phone;
|
|
30
|
-
}
|
|
31
|
-
if (this.channels_.includes('email')) {
|
|
32
|
-
this.email.value !== '' && (data['email'] = this.email.value);
|
|
33
|
-
}
|
|
34
|
-
await this.validateform();
|
|
35
|
-
return this.btn.load()
|
|
36
|
-
.then(() => this.btn.disable())
|
|
37
|
-
.then(() => salla.api.product.availabilitySubscribe(data))
|
|
38
|
-
.then(() => {
|
|
39
|
-
this.isSubscribed = true;
|
|
40
|
-
salla.storage.set(`product-${this.productId}-subscribed`, true);
|
|
41
|
-
}) //no need to wait until finishing alert animation
|
|
42
|
-
.then(() => this.btn.stop())
|
|
43
|
-
.then(() => this.modal.close())
|
|
44
|
-
.catch(() => this.btn.stop() && this.btn.enable());
|
|
45
|
-
};
|
|
46
19
|
// helpers
|
|
47
20
|
this.typing = (e, submitMethod) => {
|
|
48
21
|
const error = e.target.nextElementSibling;
|
|
@@ -56,6 +29,9 @@ export class SallaProductAvailability {
|
|
|
56
29
|
this.title_ = this.host.title || salla.lang.get('pages.products.notify_availability_title');
|
|
57
30
|
(_a = this.modal) === null || _a === void 0 ? void 0 : _a.setTitle(this.title_);
|
|
58
31
|
});
|
|
32
|
+
if (!this.productId) {
|
|
33
|
+
this.productId = salla.config.get('page.id');
|
|
34
|
+
}
|
|
59
35
|
if (this.isUser)
|
|
60
36
|
return;
|
|
61
37
|
this.channelsWatcher(this.channels);
|
|
@@ -66,6 +42,44 @@ export class SallaProductAvailability {
|
|
|
66
42
|
channelsWatcher(newValue) {
|
|
67
43
|
this.channels_ = !!newValue ? newValue.split(',') : [];
|
|
68
44
|
}
|
|
45
|
+
// @Method()
|
|
46
|
+
async submit() {
|
|
47
|
+
var _a;
|
|
48
|
+
let payload = { id: this.productId };
|
|
49
|
+
if (this.notifyOptionsAvailability) {
|
|
50
|
+
payload.options = [];
|
|
51
|
+
let options = await ((_a = document.querySelector(`salla-product-options[product-id="${this.productId}"]`)) === null || _a === void 0 ? void 0 : _a.getSelectedOptionsData());
|
|
52
|
+
Object.values(options).forEach(option => {
|
|
53
|
+
//inject numbers only, without zeros
|
|
54
|
+
if (option && !isNaN(option)) {
|
|
55
|
+
payload.options.push(Number(option));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (this.isUser) {
|
|
60
|
+
return salla.api.product.availabilitySubscribe(payload)
|
|
61
|
+
.then(() => this.isSubscribed = true);
|
|
62
|
+
}
|
|
63
|
+
if (this.channels_.includes('sms')) {
|
|
64
|
+
let { phone, countryCode } = await this.mobileInput.getValues();
|
|
65
|
+
payload['country_code'] = countryCode;
|
|
66
|
+
payload['phone'] = phone;
|
|
67
|
+
}
|
|
68
|
+
if (this.channels_.includes('email')) {
|
|
69
|
+
this.email.value !== '' && (payload['email'] = this.email.value);
|
|
70
|
+
}
|
|
71
|
+
await this.validateform();
|
|
72
|
+
return this.btn.load()
|
|
73
|
+
.then(() => this.btn.disable())
|
|
74
|
+
.then(() => salla.api.product.availabilitySubscribe(payload))
|
|
75
|
+
.then(() => {
|
|
76
|
+
this.isSubscribed = true;
|
|
77
|
+
salla.storage.set(`product-${this.productId}-subscribed`, true);
|
|
78
|
+
}) //no need to wait until finishing alert animation
|
|
79
|
+
.then(() => this.btn.stop())
|
|
80
|
+
.then(() => this.modal.close())
|
|
81
|
+
.catch(() => this.btn.stop() && this.btn.enable());
|
|
82
|
+
}
|
|
69
83
|
async validateform() {
|
|
70
84
|
try {
|
|
71
85
|
if (this.channels_.includes('email')) {
|
|
@@ -141,6 +155,24 @@ export class SallaProductAvailability {
|
|
|
141
155
|
"attribute": "channels",
|
|
142
156
|
"reflect": false
|
|
143
157
|
},
|
|
158
|
+
"notifyOptionsAvailability": {
|
|
159
|
+
"type": "boolean",
|
|
160
|
+
"mutable": false,
|
|
161
|
+
"complexType": {
|
|
162
|
+
"original": "boolean",
|
|
163
|
+
"resolved": "boolean",
|
|
164
|
+
"references": {}
|
|
165
|
+
},
|
|
166
|
+
"required": false,
|
|
167
|
+
"optional": false,
|
|
168
|
+
"docs": {
|
|
169
|
+
"tags": [],
|
|
170
|
+
"text": "Listen to product options availability."
|
|
171
|
+
},
|
|
172
|
+
"attribute": "notify-options-availability",
|
|
173
|
+
"reflect": false,
|
|
174
|
+
"defaultValue": "false"
|
|
175
|
+
},
|
|
144
176
|
"productId": {
|
|
145
177
|
"type": "number",
|
|
146
178
|
"mutable": false,
|
|
@@ -156,8 +188,7 @@ export class SallaProductAvailability {
|
|
|
156
188
|
"text": "product id that can visitor subscribe to its availability notification"
|
|
157
189
|
},
|
|
158
190
|
"attribute": "product-id",
|
|
159
|
-
"reflect": false
|
|
160
|
-
"defaultValue": "salla.config.get('page.id')"
|
|
191
|
+
"reflect": false
|
|
161
192
|
},
|
|
162
193
|
"isSubscribed": {
|
|
163
194
|
"type": "boolean",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Crafted with ❤ by Salla
|
|
3
3
|
*/
|
|
4
|
-
import { Component, Prop, h, State, Element, Host, Event } from '@stencil/core';
|
|
4
|
+
import { Component, Prop, h, State, Element, Host, Event, Method } from '@stencil/core';
|
|
5
5
|
import { DisplayType } from './interfaces';
|
|
6
6
|
import CheckCircleIcon from '../../assets/svg/check.svg';
|
|
7
7
|
import CameraIcon from '../../assets/svg/camera.svg';
|
|
@@ -18,6 +18,7 @@ export class SallaProductOptions {
|
|
|
18
18
|
};
|
|
19
19
|
this.outOfStockText = salla.lang.get("pages.products.out_of_stock");
|
|
20
20
|
this.donationAmount = salla.lang.get('pages.products.donation_amount');
|
|
21
|
+
this.selectedOptions = [];
|
|
21
22
|
/**
|
|
22
23
|
* The id of the product to which the options are going to be fetched for.
|
|
23
24
|
*/
|
|
@@ -45,6 +46,29 @@ export class SallaProductOptions {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the id's of the selected options.
|
|
51
|
+
* */
|
|
52
|
+
async getSelectedOptionsData() {
|
|
53
|
+
let selectedOptions = {};
|
|
54
|
+
let formData = this.host.getElementSallaData();
|
|
55
|
+
formData.forEach(function (value, key) {
|
|
56
|
+
key.startsWith('options[') && (selectedOptions[key.replace('options[', '').replace(']', '')] = value);
|
|
57
|
+
});
|
|
58
|
+
return selectedOptions;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get selected options.
|
|
62
|
+
* */
|
|
63
|
+
async getSelectedOptions() {
|
|
64
|
+
return this.selectedOptions;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get a specific option by its id.
|
|
68
|
+
* */
|
|
69
|
+
async getOption(option_id) {
|
|
70
|
+
return this.optionsData.find(option => option.id === option_id);
|
|
71
|
+
}
|
|
48
72
|
changedHandler(event, option) {
|
|
49
73
|
let data = { event: event, option: option, detail: null };
|
|
50
74
|
if (option.details) {
|
|
@@ -53,6 +77,8 @@ export class SallaProductOptions {
|
|
|
53
77
|
});
|
|
54
78
|
data.detail = detail;
|
|
55
79
|
}
|
|
80
|
+
const index = this.selectedOptions.findIndex(option => option.option_id === data.option.id);
|
|
81
|
+
index > -1 ? this.selectedOptions[index] = Object.assign(Object.assign({}, data.detail), { option_id: data.option.id }) : this.selectedOptions.push(Object.assign(Object.assign({}, data.detail), { option_id: data.option.id }));
|
|
56
82
|
this.handleRequiredMultipleOptions(option);
|
|
57
83
|
this.changed.emit(data);
|
|
58
84
|
salla.event.emit('product-options::change', data);
|
|
@@ -202,7 +228,7 @@ export class SallaProductOptions {
|
|
|
202
228
|
h("select", { name: `options[${option.id}]`, required: option.required, class: "s-form-control", onChange: e => this.changedHandler(e, option) },
|
|
203
229
|
h("option", { value: "" }, option.placeholder), option === null || option === void 0 ? void 0 :
|
|
204
230
|
option.details.map((detail) => {
|
|
205
|
-
return h("option", { value: detail.id,
|
|
231
|
+
return h("option", { value: detail.id, selected: detail.is_selected }, this.getOptionDetailName(detail));
|
|
206
232
|
})));
|
|
207
233
|
}
|
|
208
234
|
multipleOptions(option) {
|
|
@@ -215,7 +241,7 @@ export class SallaProductOptions {
|
|
|
215
241
|
//@ts-ignore
|
|
216
242
|
colorOption(option) {
|
|
217
243
|
return h("fieldset", { class: "s-product-options-colors-wrapper" }, option === null || option === void 0 ? void 0 : option.details.map((detail) => h("div", null,
|
|
218
|
-
h("input", { type: "radio", value: detail.id,
|
|
244
|
+
h("input", { type: "radio", value: detail.id, required: option.required, checked: detail.is_selected, name: `options[${option.id}]`, id: `color-${this.productId}-${option.id}-${detail.id}`, onChange: e => this.changedHandler(e, option) }),
|
|
219
245
|
h("label", { htmlFor: `color-${this.productId}-${option.id}-${detail.id}` },
|
|
220
246
|
h("span", { style: { "background-color": detail.color } }),
|
|
221
247
|
h("p", null, this.getOptionDetailName(detail))))));
|
|
@@ -224,16 +250,16 @@ export class SallaProductOptions {
|
|
|
224
250
|
thumbnailOption(option) {
|
|
225
251
|
return h("div", { class: "s-product-options-thumbnails-wrapper" }, option.details.map((detail) => {
|
|
226
252
|
return h("div", null,
|
|
227
|
-
h("input", { type: "radio", value: detail.id, "data-itemid": detail.id,
|
|
253
|
+
h("input", { type: "radio", value: detail.id, "data-itemid": detail.id, required: option.required, checked: detail.is_selected, name: `options[${option.id}]`, "data-img-id": detail.option_value, id: `option_${this.productId}-${option.id}_${detail.id}`, onChange: (e) => this.changedHandler(e, option) }),
|
|
228
254
|
h("label", { htmlFor: `option_${this.productId}-${option.id}_${detail.id}`, "data-img-id": detail.option_value, class: "go-to-slide" },
|
|
229
255
|
h("img", { "data-src": detail.image, src: detail.image, title: detail.name, alt: detail.name }),
|
|
230
|
-
h("span", { innerHTML: CheckCircleIcon, class: "s-product-options-thumbnails-icon" })
|
|
256
|
+
h("span", { innerHTML: CheckCircleIcon, class: "s-product-options-thumbnails-icon" }),
|
|
257
|
+
detail.is_out ?
|
|
258
|
+
h("small", { class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText)
|
|
259
|
+
: ''),
|
|
231
260
|
h("p", null,
|
|
232
261
|
this.getOptionDetailName(detail, false),
|
|
233
|
-
" ")
|
|
234
|
-
detail.is_out ?
|
|
235
|
-
[h("small", { class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText), h("div", { class: "s-product-options-thumbnails-badge-overlay" })]
|
|
236
|
-
: '');
|
|
262
|
+
" "));
|
|
237
263
|
}));
|
|
238
264
|
}
|
|
239
265
|
static get is() { return "salla-product-options"; }
|
|
@@ -283,7 +309,8 @@ export class SallaProductOptions {
|
|
|
283
309
|
static get states() { return {
|
|
284
310
|
"optionsData": {},
|
|
285
311
|
"outOfStockText": {},
|
|
286
|
-
"donationAmount": {}
|
|
312
|
+
"donationAmount": {},
|
|
313
|
+
"selectedOptions": {}
|
|
287
314
|
}; }
|
|
288
315
|
static get events() { return [{
|
|
289
316
|
"method": "changed",
|
|
@@ -301,5 +328,62 @@ export class SallaProductOptions {
|
|
|
301
328
|
"references": {}
|
|
302
329
|
}
|
|
303
330
|
}]; }
|
|
331
|
+
static get methods() { return {
|
|
332
|
+
"getSelectedOptionsData": {
|
|
333
|
+
"complexType": {
|
|
334
|
+
"signature": "() => Promise<{}>",
|
|
335
|
+
"parameters": [],
|
|
336
|
+
"references": {
|
|
337
|
+
"Promise": {
|
|
338
|
+
"location": "global"
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
"return": "Promise<{}>"
|
|
342
|
+
},
|
|
343
|
+
"docs": {
|
|
344
|
+
"text": "Get the id's of the selected options.",
|
|
345
|
+
"tags": []
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
"getSelectedOptions": {
|
|
349
|
+
"complexType": {
|
|
350
|
+
"signature": "() => Promise<any[]>",
|
|
351
|
+
"parameters": [],
|
|
352
|
+
"references": {
|
|
353
|
+
"Promise": {
|
|
354
|
+
"location": "global"
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
"return": "Promise<any[]>"
|
|
358
|
+
},
|
|
359
|
+
"docs": {
|
|
360
|
+
"text": "Get selected options.",
|
|
361
|
+
"tags": []
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"getOption": {
|
|
365
|
+
"complexType": {
|
|
366
|
+
"signature": "(option_id: any) => Promise<Option>",
|
|
367
|
+
"parameters": [{
|
|
368
|
+
"tags": [],
|
|
369
|
+
"text": ""
|
|
370
|
+
}],
|
|
371
|
+
"references": {
|
|
372
|
+
"Promise": {
|
|
373
|
+
"location": "global"
|
|
374
|
+
},
|
|
375
|
+
"Option": {
|
|
376
|
+
"location": "import",
|
|
377
|
+
"path": "./interfaces"
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
"return": "Promise<Option>"
|
|
381
|
+
},
|
|
382
|
+
"docs": {
|
|
383
|
+
"text": "Get a specific option by its id.",
|
|
384
|
+
"tags": []
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}; }
|
|
304
388
|
static get elementRef() { return "host"; }
|
|
305
389
|
}
|