@salla.sa/twilight-components 2.14.272 → 2.14.273
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/{filepond-EG2Mf8a1.js → filepond-B6LUaQ9F.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-DjNsnxTw.js → filepond-plugin-file-poster-DlB67Vv3.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-BlM1btNO.js → filepond-plugin-file-validate-size-D7kuqaEC.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-DhymSoh9.js → filepond-plugin-file-validate-type-CliXp1Qt.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-BQfvfpQ1.js → filepond-plugin-image-edit-BRIZbIyN.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-DOi06s13.js → filepond-plugin-image-exif-orientation-bFbWHyQs.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-Rfix7Xbt.js → filepond-plugin-image-preview-24nxaVX6.js} +1 -1
- package/dist/cjs/{index-DS7mXxWq.js → index-BpUrZ_-D.js} +136 -26
- package/dist/cjs/{index-vIV5iX-W.js → index-xI-pRoDr.js} +1 -1
- package/dist/cjs/loader.cjs.js +3 -4
- package/dist/cjs/{salla-add-product-button_51.cjs.entry.js → salla-accordion_62.cjs.entry.js} +2104 -120
- package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
- package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
- package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
- package/dist/cjs/salla-cart-item-offers.cjs.entry.js +1 -1
- package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters.cjs.entry.js +1 -1
- package/dist/cjs/salla-installment.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-program.cjs.entry.js +1 -1
- package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
- package/dist/cjs/salla-notification-item.cjs.entry.js +2 -2
- package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
- package/dist/cjs/salla-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/{salla-accordion_4.cjs.entry.js → salla-order-details-options.cjs.entry.js} +1 -100
- package/dist/cjs/salla-order-details.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-summary.cjs.entry.js +2 -2
- package/dist/cjs/salla-orders.cjs.entry.js +1 -1
- package/dist/cjs/salla-payments.cjs.entry.js +3 -3
- package/dist/cjs/salla-price-range.cjs.entry.js +3 -3
- package/dist/cjs/salla-review-card.cjs.entry.js +2 -2
- package/dist/cjs/salla-reviews-page.cjs.entry.js +2 -2
- package/dist/cjs/salla-reviews.cjs.entry.js +2 -2
- package/dist/cjs/salla-social.cjs.entry.js +2 -2
- package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-tooltip.cjs.entry.js +2 -2
- package/dist/cjs/salla-verify.cjs.entry.js +1 -1
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/twilight.cjs.js +3 -4
- package/dist/collection/collection-manifest.json +5 -0
- package/dist/collection/components/salla-accordion/salla-accordion-head.js +8 -2
- package/dist/collection/components/salla-comments/salla-comments.js +20 -1
- package/dist/collection/components/salla-conditional-fields/salla-conditional-fields.js +33 -5
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.css +0 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.js +89 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.css +0 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +195 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.css +3 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +595 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.css +0 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +174 -0
- package/dist/collection/components/salla-multiple-bundle-product/interfaces.js +1 -0
- package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.css +3 -0
- package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.js +132 -0
- package/dist/collection/components/salla-notifications/salla-notification-item.js +1 -1
- package/dist/collection/components/salla-offer-modal/salla-offer-modal.js +1 -1
- package/dist/collection/components/salla-order-details/salla-order-details.js +1 -1
- package/dist/collection/components/salla-order-summary/salla-order-summary.js +1 -1
- package/dist/collection/components/salla-payments/salla-payments.js +2 -2
- package/dist/collection/components/salla-placeholder/salla-placeholder.js +1 -1
- package/dist/collection/components/salla-price-range/salla-price-range.js +2 -2
- package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
- package/dist/collection/components/salla-product-card/salla-product-card.js +5 -5
- package/dist/collection/components/salla-product-options/salla-product-options.js +105 -22
- package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
- package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
- package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +1 -1
- package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
- package/dist/collection/components/salla-reviews/salla-reviews.js +1 -1
- package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
- package/dist/collection/components/salla-scopes/salla-scopes.js +1 -1
- package/dist/collection/components/salla-search/salla-search.js +3 -3
- package/dist/collection/components/salla-skeleton/salla-skeleton.js +1 -1
- package/dist/collection/components/salla-slider/salla-slider.js +2 -2
- package/dist/collection/components/salla-social/salla-social.js +1 -1
- package/dist/collection/components/salla-social-share/salla-social-share.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-content.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-header.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tabs.js +1 -1
- package/dist/collection/components/salla-tel-input/salla-tel-input.js +1 -1
- package/dist/collection/components/salla-tooltip/salla-tooltip.js +1 -1
- package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/salla-accordion-head2.js +2 -2
- package/dist/components/salla-comments.js +20 -1
- package/dist/components/salla-conditional-fields2.js +28 -6
- package/dist/components/salla-multiple-bundle-product-cart.d.ts +11 -0
- package/dist/components/salla-multiple-bundle-product-cart.js +9 -0
- package/dist/components/salla-multiple-bundle-product-cart2.js +153 -0
- package/dist/components/salla-multiple-bundle-product-details.d.ts +11 -0
- package/dist/components/salla-multiple-bundle-product-details.js +9 -0
- package/dist/components/salla-multiple-bundle-product-details2.js +283 -0
- package/dist/components/salla-multiple-bundle-product-options-modal.d.ts +11 -0
- package/dist/components/salla-multiple-bundle-product-options-modal.js +9 -0
- package/dist/components/salla-multiple-bundle-product-options-modal2.js +585 -0
- package/dist/components/salla-multiple-bundle-product-slider.d.ts +11 -0
- package/dist/components/salla-multiple-bundle-product-slider.js +9 -0
- package/dist/components/salla-multiple-bundle-product-slider2.js +81 -0
- package/dist/components/salla-multiple-bundle-product.d.ts +11 -0
- package/dist/components/salla-multiple-bundle-product.js +210 -0
- package/dist/components/salla-notification-item2.js +1 -1
- package/dist/components/salla-offer-modal.js +1 -1
- package/dist/components/salla-order-details.js +1 -1
- package/dist/components/salla-order-summary.js +1 -1
- package/dist/components/salla-payments.js +2 -2
- package/dist/components/salla-placeholder2.js +1 -1
- package/dist/components/salla-price-range2.js +2 -2
- package/dist/components/salla-product-availability2.js +1 -1
- package/dist/components/salla-product-card2.js +5 -5
- package/dist/components/salla-product-options.js +1 -810
- package/dist/{esm/salla-product-options.entry.js → components/salla-product-options2.js} +197 -30
- package/dist/components/salla-product-size-guide.js +2 -2
- package/dist/components/salla-quantity-input.js +1 -1
- package/dist/components/salla-quick-buy2.js +1 -1
- package/dist/components/salla-review-card2.js +1 -1
- package/dist/components/salla-reviews-page.js +1 -1
- package/dist/components/salla-reviews.js +1 -1
- package/dist/components/salla-scopes.js +1 -1
- package/dist/components/salla-search.js +3 -3
- package/dist/components/salla-skeleton2.js +1 -1
- package/dist/components/salla-slider2.js +2 -2
- package/dist/components/salla-social-share.js +1 -1
- package/dist/components/salla-social.js +1 -1
- package/dist/components/salla-tab-content2.js +1 -1
- package/dist/components/salla-tab-header2.js +1 -1
- package/dist/components/salla-tabs2.js +1 -1
- package/dist/components/salla-tel-input2.js +1 -1
- package/dist/components/salla-tooltip2.js +1 -1
- package/dist/components/salla-user-settings.js +1 -1
- package/dist/esm/{filepond-DbR8YXoW.js → filepond-C8M-qAIs.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-DEj3O3wZ.js → filepond-plugin-file-poster-UfHq-uvl.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-DYnIp5yF.js → filepond-plugin-file-validate-size-DZ15xnJZ.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-Cx_PD8SU.js → filepond-plugin-file-validate-type-CWR9opI0.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-BwmXRkmP.js → filepond-plugin-image-edit-XbR1h-bg.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-BtsMS4U-.js → filepond-plugin-image-exif-orientation-cSRDvvXQ.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-DQ0c3hIt.js → filepond-plugin-image-preview-B-SvzNFg.js} +1 -1
- package/dist/esm/{index-xiIpq8fU.js → index-Q_DltBmK.js} +1 -1
- package/dist/esm/{index-D5PGwR59.js → index-gLeBNvS1.js} +136 -26
- package/dist/esm/loader.js +3 -4
- package/dist/esm/{salla-add-product-button_51.entry.js → salla-accordion_62.entry.js} +2084 -111
- package/dist/esm/salla-advertisement.entry.js +1 -1
- package/dist/esm/salla-app-install-alert.entry.js +1 -1
- package/dist/esm/salla-apps-icons.entry.js +1 -1
- package/dist/esm/salla-cart-item-offers.entry.js +1 -1
- package/dist/esm/salla-conditional-offer.entry.js +1 -1
- package/dist/esm/salla-contacts.entry.js +1 -1
- package/dist/esm/salla-filters-widget.entry.js +1 -1
- package/dist/esm/salla-filters.entry.js +1 -1
- package/dist/esm/salla-installment.entry.js +1 -1
- package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
- package/dist/esm/salla-loyalty-program.entry.js +1 -1
- package/dist/esm/salla-metadata.entry.js +1 -1
- package/dist/esm/salla-notification-item.entry.js +2 -2
- package/dist/esm/salla-notifications.entry.js +1 -1
- package/dist/esm/salla-offer.entry.js +1 -1
- package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
- package/dist/esm/{salla-accordion_4.entry.js → salla-order-details-options.entry.js} +2 -98
- package/dist/esm/salla-order-details.entry.js +2 -2
- package/dist/esm/salla-order-summary.entry.js +2 -2
- package/dist/esm/salla-orders.entry.js +1 -1
- package/dist/esm/salla-payments.entry.js +3 -3
- package/dist/esm/salla-price-range.entry.js +3 -3
- package/dist/esm/salla-review-card.entry.js +2 -2
- package/dist/esm/salla-reviews-page.entry.js +2 -2
- package/dist/esm/salla-reviews.entry.js +2 -2
- package/dist/esm/salla-social.entry.js +2 -2
- package/dist/esm/salla-tiered-offer.entry.js +1 -1
- package/dist/esm/salla-tooltip.entry.js +2 -2
- package/dist/esm/salla-verify.entry.js +1 -1
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/twilight.js +3 -4
- package/dist/twilight/{p-4611a11b.entry.js → p-00d8544c.entry.js} +1 -1
- package/dist/twilight/{p-b40d5871.entry.js → p-06d126b6.entry.js} +1 -1
- package/dist/twilight/{p-2bf21126.entry.js → p-1cc68ef5.entry.js} +1 -1
- package/dist/twilight/{p-BsHa_73h.js → p-1ekWkYOJ.js} +1 -1
- package/dist/twilight/p-21b37923.entry.js +4 -0
- package/dist/twilight/{p-bcab2639.entry.js → p-263b9b06.entry.js} +1 -1
- package/dist/twilight/{p-8ba8efe1.entry.js → p-2787ff9f.entry.js} +1 -1
- package/dist/twilight/p-3c1484b9.entry.js +11 -0
- package/dist/twilight/{p-c15928d5.entry.js → p-5057b400.entry.js} +1 -1
- package/dist/twilight/{p-280c1f64.entry.js → p-5278b873.entry.js} +1 -1
- package/dist/twilight/{p-e3b0a71f.entry.js → p-56f7a2ba.entry.js} +1 -1
- package/dist/twilight/{p-65b1fcea.entry.js → p-697db5c6.entry.js} +1 -1
- package/dist/twilight/{p-b94ebbd9.entry.js → p-73a8296a.entry.js} +1 -1
- package/dist/twilight/{p-eae51196.entry.js → p-7603a820.entry.js} +1 -1
- package/dist/twilight/{p-56fa3b9c.entry.js → p-7c8d7ca3.entry.js} +1 -1
- package/dist/twilight/{p-e95284d7.entry.js → p-80a07063.entry.js} +1 -1
- package/dist/twilight/{p-eaad31d1.entry.js → p-82c156ab.entry.js} +1 -1
- package/dist/twilight/{p-7df916fc.entry.js → p-8380c411.entry.js} +1 -1
- package/dist/twilight/{p-a61e2b8e.entry.js → p-946e5649.entry.js} +1 -1
- package/dist/twilight/{p-f3c29342.entry.js → p-9bcd9c87.entry.js} +1 -1
- package/dist/twilight/p-9c477fdf.entry.js +4 -0
- package/dist/twilight/{p-DV_VEuIe.js → p-B-nQtFTN.js} +1 -1
- package/dist/twilight/{p-DEUne75O.js → p-BI2zk2yo.js} +1 -1
- package/dist/twilight/{p-C4wd-bXb.js → p-BRD27esZ.js} +1 -1
- package/dist/twilight/{p-Bvez5luh.js → p-CUYEEJ4c.js} +1 -1
- package/dist/twilight/{p-CH8-uKSN.js → p-DUvdNUoC.js} +1 -1
- package/dist/twilight/{p-D0ZZ4jO5.js → p-DhR67rwu.js} +1 -1
- package/dist/twilight/p-a01dd6b7.entry.js +4 -0
- package/dist/twilight/{p-9e3f55be.entry.js → p-a3e000ef.entry.js} +1 -1
- package/dist/twilight/{p-3f412ab2.entry.js → p-a6c14a64.entry.js} +1 -1
- package/dist/twilight/p-b0b79820.entry.js +4 -0
- package/dist/twilight/{p-10856491.entry.js → p-b5581886.entry.js} +1 -1
- package/dist/twilight/p-b81437f4.entry.js +4 -0
- package/dist/twilight/{p-de200512.entry.js → p-bf010154.entry.js} +1 -1
- package/dist/twilight/{p-0ffafdea.entry.js → p-c0388251.entry.js} +1 -1
- package/dist/twilight/{p-2613f6dc.entry.js → p-c9ab361e.entry.js} +1 -1
- package/dist/twilight/{p-92848d53.entry.js → p-ed85bc00.entry.js} +1 -1
- package/dist/twilight/p-f7863a58.entry.js +4 -0
- package/dist/twilight/{p-D5PGwR59.js → p-gLeBNvS1.js} +2 -2
- package/dist/twilight/{p-D5p2t_CX.js → p-j4lbZMJ0.js} +1 -1
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-accordion/salla-accordion-head.d.ts +6 -0
- package/dist/types/components/salla-conditional-fields/salla-conditional-fields.d.ts +2 -0
- package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.d.ts +10 -0
- package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.d.ts +20 -0
- package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.d.ts +46 -0
- package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.d.ts +22 -0
- package/dist/types/components/salla-multiple-bundle-product/interfaces.d.ts +101 -0
- package/dist/types/components/salla-multiple-bundle-product/salla-multiple-bundle-product.d.ts +42 -0
- package/dist/types/components/salla-product-options/salla-product-options.d.ts +21 -1
- package/dist/types/components.d.ts +298 -2
- package/package.json +5 -5
- package/dist/cjs/app-globals-OVEmNa5W.js +0 -38
- package/dist/cjs/camera-DytepEoK.js +0 -13
- package/dist/cjs/minus-CCryh1qf.js +0 -21
- package/dist/cjs/salla-booking-field_2.cjs.entry.js +0 -280
- package/dist/cjs/salla-product-options.cjs.entry.js +0 -715
- package/dist/esm/app-globals-BKgAyoNJ.js +0 -36
- package/dist/esm/camera-C6jIkM-X.js +0 -11
- package/dist/esm/minus-DfeagqF1.js +0 -18
- package/dist/esm/salla-booking-field_2.entry.js +0 -277
- package/dist/twilight/p-19c38b4a.entry.js +0 -11
- package/dist/twilight/p-8272b58f.entry.js +0 -4
- package/dist/twilight/p-989fcbb4.entry.js +0 -4
- package/dist/twilight/p-9f47b72b.entry.js +0 -4
- package/dist/twilight/p-C6jIkM-X.js +0 -4
- package/dist/twilight/p-DfeagqF1.js +0 -4
- package/dist/twilight/p-KHt1Smzh.js +0 -4
- package/dist/twilight/p-b8d41065.entry.js +0 -4
- package/dist/twilight/p-dd9695d6.entry.js +0 -4
- package/dist/twilight/p-e2ebb686.entry.js +0 -4
- package/dist/twilight/p-e30f7c20.entry.js +0 -4
- package/dist/twilight/p-fcb3e719.entry.js +0 -4
package/dist/cjs/{salla-add-product-button_51.cjs.entry.js → salla-accordion_62.cjs.entry.js}
RENAMED
|
@@ -3,38 +3,145 @@
|
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
var index = require('./index-
|
|
6
|
+
var index = require('./index-BpUrZ_-D.js');
|
|
7
7
|
var anime_es = require('./anime.es-BqW8JHZi.js');
|
|
8
8
|
var specialDiscount = require('./special-discount-OVG_9Kf9.js');
|
|
9
9
|
var check = require('./check-CLRvuniI.js');
|
|
10
10
|
var Helper = require('./Helper-C9UmWIYn.js');
|
|
11
11
|
var arrowLeft = require('./arrow-left-xSEmRpp6.js');
|
|
12
12
|
var shoppingBag = require('./shopping-bag-C1gvTVHr.js');
|
|
13
|
-
var minus = require('./minus-CCryh1qf.js');
|
|
14
13
|
var mail = require('./mail-CO8cFZH7.js');
|
|
15
14
|
var whatsapp2 = require('./whatsapp2-D7Sbg8Ey.js');
|
|
16
15
|
var twitter = require('./twitter-pOrUNjXi.js');
|
|
17
16
|
var gift = require('./gift-BPDUPIY_.js');
|
|
18
|
-
var camera = require('./camera-DytepEoK.js');
|
|
19
17
|
|
|
20
18
|
function _interopNamespace(e) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
if (e && e.__esModule) return e;
|
|
20
|
+
var n = Object.create(null);
|
|
21
|
+
if (e) {
|
|
22
|
+
Object.keys(e).forEach(function (k) {
|
|
23
|
+
if (k !== 'default') {
|
|
24
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
25
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () { return e[k]; }
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
30
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
n.default = e;
|
|
35
|
-
return Object.freeze(n);
|
|
31
|
+
}
|
|
32
|
+
n.default = e;
|
|
33
|
+
return Object.freeze(n);
|
|
36
34
|
}
|
|
37
35
|
|
|
36
|
+
const sallaAccordionCss = "";
|
|
37
|
+
|
|
38
|
+
const SallaAccordion = class {
|
|
39
|
+
constructor(hostRef) {
|
|
40
|
+
index.registerInstance(this, hostRef);
|
|
41
|
+
/** Should the accordion be collapsible or not. Default is true. */
|
|
42
|
+
this.collapsible = true;
|
|
43
|
+
this.bordered = false;
|
|
44
|
+
this.size = "md";
|
|
45
|
+
/** Detect if accordion collapsed or not. */
|
|
46
|
+
this.collapsed = true;
|
|
47
|
+
/** Represents the direction of the layout. */
|
|
48
|
+
this.dir = document.dir || 'rtl';
|
|
49
|
+
}
|
|
50
|
+
directionChangedHandler(event) {
|
|
51
|
+
this.dir = event.detail.dir;
|
|
52
|
+
}
|
|
53
|
+
handleCollapse(event) {
|
|
54
|
+
this.collapsed = event.detail.payload.collapsed;
|
|
55
|
+
}
|
|
56
|
+
setcollapsibleProp() {
|
|
57
|
+
const head = this.host.querySelector('salla-accordion-head');
|
|
58
|
+
if (this.collapsible && head) {
|
|
59
|
+
head.setAttribute('collapsible', 'true');
|
|
60
|
+
head.setAttribute('collapsed', this.collapsed.toString());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
componentDidRender() {
|
|
64
|
+
this.setcollapsibleProp();
|
|
65
|
+
const body = this.host.querySelector('salla-accordion-body');
|
|
66
|
+
if (this.collapsible) {
|
|
67
|
+
this.host.setAttribute('data-collapsed', this.collapsed.toString());
|
|
68
|
+
body?.setAttribute('data-collapsed', this.collapsed.toString());
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
render() {
|
|
72
|
+
return (index.h(index.Host, { key: 'ed8e4c0f24fa4462654e94fa46706e892c141351', class: `s-accordion-wrapper ${this.dir} ${this.bordered ? 's-accordion-wrapper-bordered' : ''} ${this.size ? `size-${this.size}` : ''}`, "data-collapsed": this.collapsed.toString() }, index.h("slot", { key: '1dbda01c073f3018a55ebcf5d8613a82a5dc6b27' })));
|
|
73
|
+
}
|
|
74
|
+
get host() { return index.getElement(this); }
|
|
75
|
+
};
|
|
76
|
+
SallaAccordion.style = sallaAccordionCss;
|
|
77
|
+
|
|
78
|
+
const sallaAccordionBodyCss = "";
|
|
79
|
+
|
|
80
|
+
const SallaAccordionBody = class {
|
|
81
|
+
constructor(hostRef) {
|
|
82
|
+
index.registerInstance(this, hostRef);
|
|
83
|
+
}
|
|
84
|
+
render() {
|
|
85
|
+
return (index.h(index.Host, { key: '298d42a5bf1bcefdb181ec35060220cf749b56ed', class: "s-accordion-body-wrapper" }, index.h("slot", { key: '6ab081e8b71b5dc69fb66fbdec82b4725ab53b0d' })));
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
SallaAccordionBody.style = sallaAccordionBodyCss;
|
|
89
|
+
|
|
90
|
+
var Add = `<!-- Generated by IcoMoon.io -->
|
|
91
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
92
|
+
<title>add</title>
|
|
93
|
+
<path d="M26.667 14.667h-9.333v-9.333c0-0.736-0.597-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v9.333h-9.333c-0.736 0-1.333 0.597-1.333 1.333s0.597 1.333 1.333 1.333h9.333v9.333c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-9.333h9.333c0.736 0 1.333-0.597 1.333-1.333s-0.597-1.333-1.333-1.333z"></path>
|
|
94
|
+
</svg>
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
var Minus = `<!-- Generated by IcoMoon.io -->
|
|
98
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
99
|
+
<title>minus</title>
|
|
100
|
+
<path d="M26.667 14.667h-21.333c-0.736 0-1.333 0.597-1.333 1.333s0.597 1.333 1.333 1.333h21.333c0.736 0 1.333-0.597 1.333-1.333s-0.597-1.333-1.333-1.333z"></path>
|
|
101
|
+
</svg>
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
const sallaAccordionHeadCss = "";
|
|
105
|
+
|
|
106
|
+
const SallaAccordionHead = class {
|
|
107
|
+
constructor(hostRef) {
|
|
108
|
+
index.registerInstance(this, hostRef);
|
|
109
|
+
this.accordionToggle = index.createEvent(this, "accordionToggle");
|
|
110
|
+
/** Should the accordion be collapsible or not. */
|
|
111
|
+
this.collapsible = false;
|
|
112
|
+
/** Current collapsed state */
|
|
113
|
+
this.collapsed = true;
|
|
114
|
+
}
|
|
115
|
+
emitCollapsePanel() {
|
|
116
|
+
this.accordionToggle.emit({
|
|
117
|
+
payload: {
|
|
118
|
+
collapsed: this.collapsed,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
toggleCollapse() {
|
|
123
|
+
if (!this.collapsible)
|
|
124
|
+
return;
|
|
125
|
+
this.collapsed = !this.collapsed;
|
|
126
|
+
this.host.parentElement?.setAttribute('data-collapsed', this.collapsed.toString());
|
|
127
|
+
this.host.parentElement
|
|
128
|
+
?.querySelector('salla-accordion-body')
|
|
129
|
+
?.setAttribute('data-collapsed', this.collapsed.toString());
|
|
130
|
+
this.emitCollapsePanel();
|
|
131
|
+
}
|
|
132
|
+
render() {
|
|
133
|
+
return (index.h(index.Host, { key: '9d88d243306cdf451c20d7068fbb9f48807b22e9', "data-collapsed": this.collapsed.toString(), onClick: () => this.toggleCollapse(), class: "s-accordion-head-wrapper" }, index.h("div", { key: 'bad4c5a913ce1c4581b09c0b6d96fcbdb4236638', class: "s-accordion-head-wrapper-start" }, index.h("slot", { key: 'acb83cec8cbca5771a9f84e81c0b955c3edad731', name: "title" }), index.h("slot", { key: 'a4ad42ea6fad4f452c4c218a9ee02dca0adb4a67', name: "progress" }), index.h("slot", { key: '96ab95d413dc906ac299079f4008816f01881990', name: "html" })), (this.collapsible || this.host.querySelector('[slot="note"]')) && (index.h("div", { key: '8f9666a5038cd7b1ac6e357c6920ea26d31c5f03', class: "s-accordion-head-wrapper-end" }, index.h("slot", { key: '14895e8c1385e91c14f046c9ae38ce5e4a4c9a60', name: "note" }), this.collapsible && (index.h("button", { key: '97dc7fabbb207fcc8b68ebf0a86f6c8a980dca13', class: {
|
|
134
|
+
's-accordion-head-wrapper-toggle': true,
|
|
135
|
+
active: !this.collapsed,
|
|
136
|
+
}, onClick: e => {
|
|
137
|
+
e.stopPropagation();
|
|
138
|
+
this.toggleCollapse();
|
|
139
|
+
} }, index.h("span", { key: '3b24faf71dcd332663a354310b2ce09f7879eddc', class: "s-accordion-head-wrapper-toggle-icon", innerHTML: this.collapsed ? Add : Minus })))))));
|
|
140
|
+
}
|
|
141
|
+
get host() { return index.getElement(this); }
|
|
142
|
+
};
|
|
143
|
+
SallaAccordionHead.style = sallaAccordionHeadCss;
|
|
144
|
+
|
|
38
145
|
var PendingOrdersIcon = `<!-- Generated by IcoMoon.io -->
|
|
39
146
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="30" height="32" viewBox="0 0 30 32">
|
|
40
147
|
<title>cart</title>
|
|
@@ -294,6 +401,180 @@ const SallaAlert = class {
|
|
|
294
401
|
};
|
|
295
402
|
SallaAlert.style = sallaAlertCss;
|
|
296
403
|
|
|
404
|
+
var BookingTime = `<!-- Generated by IcoMoon.io -->
|
|
405
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
406
|
+
<title>calendar-time</title>
|
|
407
|
+
<path d="M22.667 17.333c-0.737 0-1.333 0.596-1.333 1.333v2.667h-2.667c-0.737 0-1.333 0.596-1.333 1.333s0.596 1.333 1.333 1.333h4c0.737 0 1.333-0.596 1.333-1.333v-4c0-0.737-0.596-1.333-1.333-1.333zM28 2.667h-2.667v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-13.333v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-2.667c-2.205 0-4 1.795-4 4v21.333c0 2.205 1.795 4 4 4h5.363c0.737 0 1.333-0.596 1.333-1.333s-0.596-1.333-1.333-1.333h-5.363c-0.736 0-1.333-0.597-1.333-1.333v-21.333c0-0.736 0.597-1.333 1.333-1.333h2.667v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h13.333v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h2.667c0.736 0 1.333 0.599 1.333 1.333v2.696c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.696c0-2.205-1.795-4-4-4zM22 12c-5.515 0-10 4.485-10 10s4.485 10 10 10 10-4.485 10-10-4.485-10-10-10zM22 29.333c-4.043 0-7.333-3.291-7.333-7.333s3.291-7.333 7.333-7.333 7.333 3.291 7.333 7.333-3.291 7.333-7.333 7.333z"></path>
|
|
408
|
+
</svg>
|
|
409
|
+
`;
|
|
410
|
+
|
|
411
|
+
var Calendar = `<!-- Generated by IcoMoon.io -->
|
|
412
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
413
|
+
<title>calendar</title>
|
|
414
|
+
<path d="M28 2.667h-2.667v-1.333c0-0.736-0.597-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-13.333v-1.333c0-0.736-0.597-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-2.667c-2.205 0-4 1.795-4 4v21.333c0 2.205 1.795 4 4 4h24c2.205 0 4-1.795 4-4v-21.333c0-2.205-1.795-4-4-4zM29.333 28c0 0.736-0.599 1.333-1.333 1.333h-24c-0.736 0-1.333-0.599-1.333-1.333v-13.333h26.667zM29.333 12h-26.667v-5.333c0-0.736 0.599-1.333 1.333-1.333h2.667v2.667c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h13.333v2.667c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h2.667c0.736 0 1.333 0.599 1.333 1.333z"></path>
|
|
415
|
+
</svg>
|
|
416
|
+
`;
|
|
417
|
+
|
|
418
|
+
var TimeIcon = `<!-- Generated by IcoMoon.io -->
|
|
419
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
420
|
+
<title>time</title>
|
|
421
|
+
<path d="M16 0c-8.823 0-16 7.177-16 16s7.177 16 16 16 16-7.177 16-16-7.177-16-16-16zM16 29.333c-7.352 0-13.333-5.981-13.333-13.333s5.981-13.333 13.333-13.333 13.333 5.981 13.333 13.333-5.981 13.333-13.333 13.333zM16 8c-0.736 0-1.333 0.596-1.333 1.333v6.667h-4c-0.736 0-1.333 0.596-1.333 1.333s0.597 1.333 1.333 1.333h5.333c0.736 0 1.333-0.596 1.333-1.333v-8c0-0.737-0.597-1.333-1.333-1.333z"></path>
|
|
422
|
+
</svg>
|
|
423
|
+
`;
|
|
424
|
+
|
|
425
|
+
const sallaBookingFieldCss = ":host{display:block}";
|
|
426
|
+
|
|
427
|
+
const SallaBookingField = class {
|
|
428
|
+
constructor(hostRef) {
|
|
429
|
+
index.registerInstance(this, hostRef);
|
|
430
|
+
this.invalidInput = index.createEvent(this, "invalidInput");
|
|
431
|
+
this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment', 'حجز موعد');
|
|
432
|
+
this.editLabel = salla.lang.get('pages.cart.edit_an_appointment', 'تعديل الموعد');
|
|
433
|
+
this.bookedLabel = salla.lang.get('pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح');
|
|
434
|
+
this.selectDate = salla.lang.get('pages.cart.select_appointment_date', 'حدد تاريخ الموعد');
|
|
435
|
+
this.bookingUrl = '';
|
|
436
|
+
this.iframeReady = false;
|
|
437
|
+
this.reservations = [];
|
|
438
|
+
// Load translations
|
|
439
|
+
salla.lang.onLoaded(() => this.setTranslations());
|
|
440
|
+
// Register event listeners
|
|
441
|
+
Salla.event.on('booking::open', (data) => this.handleBookingOpen(data));
|
|
442
|
+
}
|
|
443
|
+
async setTranslations() {
|
|
444
|
+
const setNestedAsync = (lang, key, value) => {
|
|
445
|
+
return new Promise((resolve) => {
|
|
446
|
+
salla.helpers.setNested(salla.lang.messages[lang], key, value);
|
|
447
|
+
resolve(true);
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
await setNestedAsync('ar.trans', 'pages.cart.book_an_appointment', 'حجز موعد');
|
|
451
|
+
await setNestedAsync('en.trans', 'pages.cart.book_an_appointment', 'Book an Appointment');
|
|
452
|
+
await setNestedAsync('ar.trans', 'pages.cart.edit_an_appointment', 'تعديل الموعد');
|
|
453
|
+
await setNestedAsync('en.trans', 'pages.cart.edit_an_appointment', 'Edit an Appointment');
|
|
454
|
+
await setNestedAsync('ar.trans', 'pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح');
|
|
455
|
+
await setNestedAsync('en.trans', 'pages.cart.booked_successfully', 'Booked Successfully');
|
|
456
|
+
await setNestedAsync('ar.trans', 'pages.cart.select_appointment_date', 'حدد تاريخ الموعد');
|
|
457
|
+
await setNestedAsync('en.trans', 'pages.cart.select_appointment_date', 'Select appointment date');
|
|
458
|
+
this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment');
|
|
459
|
+
this.editLabel = salla.lang.get('pages.cart.edit_an_appointment');
|
|
460
|
+
this.bookedLabel = salla.lang.get('pages.cart.booked_successfully');
|
|
461
|
+
this.selectDate = salla.lang.get('pages.cart.select_appointment_date');
|
|
462
|
+
}
|
|
463
|
+
openBookingModal(event, afterReload = false) {
|
|
464
|
+
if (afterReload && (!event.detail || typeof event.detail !== 'number' || event.detail !== this.productId)) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
if (salla.config.isGuest()) {
|
|
468
|
+
this.setAfterReloadEvent('booking::open-after-reload', this.productId);
|
|
469
|
+
salla.event.dispatch('login::open');
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
salla.booking.add(this.productId, false)
|
|
473
|
+
.then((resp) => {
|
|
474
|
+
if (resp.data.redirect.to !== 'booking') {
|
|
475
|
+
throw new Error('Unexpected redirect!');
|
|
476
|
+
}
|
|
477
|
+
salla.event.dispatch('booking::open', { url: resp.data.redirect.url, id: this.productId });
|
|
478
|
+
})
|
|
479
|
+
.catch((error) => {
|
|
480
|
+
salla.error(salla.lang.get('common.errors.error_occurred'));
|
|
481
|
+
salla.logger.error(error.response || error);
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
handleBookingOpen(data) {
|
|
485
|
+
if (data.id !== this.productId)
|
|
486
|
+
return;
|
|
487
|
+
this.bookingUrl = salla.url.addParamToUrl('product_id', data.id, data.url);
|
|
488
|
+
this.iframeReady = true;
|
|
489
|
+
setTimeout(() => {
|
|
490
|
+
this.modal.setTitle(this.selectDate);
|
|
491
|
+
this.modal.open();
|
|
492
|
+
}, 100);
|
|
493
|
+
}
|
|
494
|
+
setAfterReloadEvent(event, payload) {
|
|
495
|
+
salla.storage.set('afterReloadEvent', { event, payload });
|
|
496
|
+
}
|
|
497
|
+
emitAfterReloadEvent() {
|
|
498
|
+
const eventDetails = salla.storage.get('afterReloadEvent');
|
|
499
|
+
if (eventDetails && eventDetails.event) {
|
|
500
|
+
const customEvent = new CustomEvent(eventDetails.event, {
|
|
501
|
+
detail: eventDetails.payload
|
|
502
|
+
});
|
|
503
|
+
window.dispatchEvent(customEvent);
|
|
504
|
+
salla.storage.remove('afterReloadEvent');
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
componentWillLoad() {
|
|
508
|
+
if (this.option && this.option.details.length) {
|
|
509
|
+
this.reservations = this.option.details;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
componentDidLoad() {
|
|
513
|
+
window.addEventListener('booking::open-after-reload', (event) => this.openBookingModal(event, true));
|
|
514
|
+
this.emitAfterReloadEvent();
|
|
515
|
+
window.addEventListener('message', this.handleMessageEvent.bind(this));
|
|
516
|
+
this.reservationsInput.addEventListener('invalid', e => this.invalidInput.emit(e));
|
|
517
|
+
this.reservationsInput.addEventListener('input', () => {
|
|
518
|
+
this.reservationsInput.setCustomValidity('');
|
|
519
|
+
this.reservationsInput.reportValidity();
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
handleMessageEvent(event) {
|
|
523
|
+
if (event.data.source !== 'booking')
|
|
524
|
+
return;
|
|
525
|
+
const action = event.data.type;
|
|
526
|
+
const value = event.data.message;
|
|
527
|
+
if (localStorage.getItem('debug'))
|
|
528
|
+
console.log(`Received an action:${action}`, event.data);
|
|
529
|
+
if (action === 'error') {
|
|
530
|
+
if (value.fields?.reservation) {
|
|
531
|
+
salla.notify.error(value.fields.reservation[0]);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const errorList = Object.values(value.fields || [value.message]).flat().map(error => `<li>${error}</li>`).join('');
|
|
535
|
+
salla.notify.error(`<ul>${errorList}</ul>`);
|
|
536
|
+
}
|
|
537
|
+
if (action === 'success') {
|
|
538
|
+
if (Number(value.productId) !== Number(this.productId))
|
|
539
|
+
return;
|
|
540
|
+
this.reservations = value.data.reservations.map(schedule => {
|
|
541
|
+
if (schedule.time && schedule.time.length > 0) {
|
|
542
|
+
const timeSlot = schedule.time[0];
|
|
543
|
+
return {
|
|
544
|
+
date: schedule.date,
|
|
545
|
+
day: schedule.day,
|
|
546
|
+
from_timestamp: timeSlot.from,
|
|
547
|
+
to_timestamp: timeSlot.to,
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
return null;
|
|
551
|
+
}).filter(item => item !== null);
|
|
552
|
+
salla.notify.success(this.bookedLabel);
|
|
553
|
+
this.modal?.close();
|
|
554
|
+
setTimeout(() => window.location.reload());
|
|
555
|
+
}
|
|
556
|
+
if (action === 'height') {
|
|
557
|
+
this.iframe.height = value?.height + 'px';
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
bookingModal() {
|
|
561
|
+
return (index.h("salla-modal", { class: "s-booking-field-modal", ref: modal => (this.modal = modal), width: "md", position: "middle", noPadding: true }, index.h("iframe", { ref: iframe => (this.iframe = iframe), src: this.bookingUrl, frameborder: "0" })));
|
|
562
|
+
}
|
|
563
|
+
renderReservationDate(reservation) {
|
|
564
|
+
return (index.h("span", { class: reservation.from_timestamp ? 's-booking-field-reservations-has-time' : '' }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: Calendar }), reservation.date));
|
|
565
|
+
}
|
|
566
|
+
renderReservationTime(reservation) {
|
|
567
|
+
if (!reservation.from_timestamp)
|
|
568
|
+
return '';
|
|
569
|
+
return (index.h("span", { class: "s-booking-field-reservations-time" }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: TimeIcon }), index.h("span", null, reservation.from_timestamp, " - ", reservation.to_timestamp)));
|
|
570
|
+
}
|
|
571
|
+
render() {
|
|
572
|
+
return (index.h(index.Host, { key: '04c9e3dc3dc825bd6905221d858c260f7ca34748' }, index.h("div", { key: '07ec38cec1bd1798640dd7ea9592bb3b17d945c6', class: "s-booking-field-main" }, this.option.required || this.reservations.length > 0 ? index.h("div", { class: "s-booking-field-price" }, index.h("span", { innerHTML: salla.money(this.option.price) })) : '', index.h("salla-button", { key: '6b71889cfc0429d15c466a6f194df31549f09786', class: "s-booking-field-book-now", size: "small", loaderPosition: "center", fill: "outline", onClick: event => this.openBookingModal(event, false) }, index.h("span", { key: 'a16f8db6f52c7751ea605efcae04057ca0dc5b61', class: "s-booking-field-book-now-content" }, index.h("span", { key: '95f6086a599bcc620c87ece6c6ae9620dba15581', innerHTML: BookingTime }), this.reservations.length ? this.editLabel : this.bookNowLabel))), this.reservations.length > 0 && (index.h("div", { key: 'b3615100bbfff3d98d0ac99145aaf53449790c94', class: "s-booking-field-reservations" }, this.reservations.map((reservation, index$1) => (index.h("div", { key: index$1, class: "s-booking-field-reservations-item" }, this.renderReservationDate(reservation), this.renderReservationTime(reservation)))))), index.h("input", { key: '126f14f2e520b8696bc7450e209bad30b267878b', class: "s-hidden", name: this.option.name, required: this.option.required, value: JSON.stringify(this.reservations) === '[]' ? '' : JSON.stringify(this.reservations), ref: reservations => this.reservationsInput = reservations }), this.iframeReady && this.bookingModal()));
|
|
573
|
+
}
|
|
574
|
+
get host() { return index.getElement(this); }
|
|
575
|
+
};
|
|
576
|
+
SallaBookingField.style = sallaBookingFieldCss;
|
|
577
|
+
|
|
297
578
|
var infoIcon = `<!-- Generated by IcoMoon.io -->
|
|
298
579
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
299
580
|
<title>info</title>
|
|
@@ -2418,7 +2699,8 @@ const SallaComments = class {
|
|
|
2418
2699
|
resp = await salla.api.request('reviews', { params }, 'get');
|
|
2419
2700
|
}
|
|
2420
2701
|
else {
|
|
2421
|
-
|
|
2702
|
+
// Ensure sort is passed for regular comments as well
|
|
2703
|
+
resp = await salla.api.comment.getComments(this.type, this.itemId, 1, 5, this.sort);
|
|
2422
2704
|
}
|
|
2423
2705
|
if (!resp.data || !resp.data.length) {
|
|
2424
2706
|
this.showPlaceholder = false;
|
|
@@ -2432,6 +2714,24 @@ const SallaComments = class {
|
|
|
2432
2714
|
this.pagination = resp.pagination;
|
|
2433
2715
|
this.total = resp.pagination.total;
|
|
2434
2716
|
this.nextPage = typeof resp.pagination.links === 'object' && !!resp.pagination.links.next ? resp.pagination.links.next : null;
|
|
2717
|
+
// Preserve sort param in next page URL for infinite scroll
|
|
2718
|
+
if (this.nextPage && this.sort) {
|
|
2719
|
+
try {
|
|
2720
|
+
const url = new URL(this.nextPage, window.location.origin);
|
|
2721
|
+
if (!url.searchParams.get('sort')) {
|
|
2722
|
+
url.searchParams.set('sort', this.sort);
|
|
2723
|
+
this.nextPage = url.toString();
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
catch (_e) {
|
|
2727
|
+
// fallback for relative next links
|
|
2728
|
+
const hasQuery = this.nextPage.includes('?');
|
|
2729
|
+
const hasSort = /[?&]sort=/.test(this.nextPage);
|
|
2730
|
+
if (!hasSort) {
|
|
2731
|
+
this.nextPage = this.nextPage + (hasQuery ? '&' : '?') + `sort=${this.sort}`;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2435
2735
|
setTimeout(() => {
|
|
2436
2736
|
for (const card of this.handleResponse(resp)) {
|
|
2437
2737
|
this.wrapper.append(card);
|
|
@@ -2473,6 +2773,125 @@ const SallaComments = class {
|
|
|
2473
2773
|
};
|
|
2474
2774
|
SallaComments.style = sallaCommentsCss;
|
|
2475
2775
|
|
|
2776
|
+
const SallaConditionalFields = class {
|
|
2777
|
+
constructor(hostRef) {
|
|
2778
|
+
index.registerInstance(this, hostRef);
|
|
2779
|
+
}
|
|
2780
|
+
hideAllOptions(optionId) {
|
|
2781
|
+
this.host.querySelectorAll(`[data-show-when^="options[${optionId}"]`).forEach((field) => {
|
|
2782
|
+
field.classList.add('hidden');
|
|
2783
|
+
this.hideAllOptions(field.dataset.optionId);
|
|
2784
|
+
this.disableInputs(field);
|
|
2785
|
+
});
|
|
2786
|
+
}
|
|
2787
|
+
disableInputs(field) {
|
|
2788
|
+
field.querySelectorAll('[name]').forEach((input) => {
|
|
2789
|
+
input.setAttribute('disabled', '');
|
|
2790
|
+
input.removeAttribute('required');
|
|
2791
|
+
if (input?.tagName?.toLowerCase() === 'select') {
|
|
2792
|
+
input.value = '';
|
|
2793
|
+
}
|
|
2794
|
+
if (['checkbox'].includes(input.getAttribute('type')) && input.hasOwnProperty('checked')) {
|
|
2795
|
+
// @ts-ignore
|
|
2796
|
+
input.checked = false;
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
}
|
|
2800
|
+
changeHandler(event) {
|
|
2801
|
+
salla.event.emit('salla-onditional-fields::change', event);
|
|
2802
|
+
salla.log('Received the change/input event: ', event);
|
|
2803
|
+
if (!event.target ||
|
|
2804
|
+
(!['SELECT', 'INPUT', 'TEXTAREA'].includes(event.target.tagName) &&
|
|
2805
|
+
!['checkbox', 'radio', 'text'].includes(event.target.getAttribute('type')))) {
|
|
2806
|
+
salla.log('Ignore the event because is not a supported input: ' + (event?.target?.tagName || 'N/A'));
|
|
2807
|
+
return;
|
|
2808
|
+
}
|
|
2809
|
+
// For text inputs, debounce the handling to improve performance on mobile
|
|
2810
|
+
const isTextInput = ['INPUT', 'TEXTAREA'].includes(event.target.tagName) &&
|
|
2811
|
+
(!event.target.getAttribute('type') || event.target.getAttribute('type') === 'text');
|
|
2812
|
+
if (isTextInput && event.type === 'input') {
|
|
2813
|
+
clearTimeout(this.debounceTimeout);
|
|
2814
|
+
this.debounceTimeout = setTimeout(() => {
|
|
2815
|
+
this.processConditionalFields(event);
|
|
2816
|
+
}, 300); // 300ms debounce for text inputs
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
// Process immediately for change events and non-text inputs
|
|
2820
|
+
this.processConditionalFields(event);
|
|
2821
|
+
}
|
|
2822
|
+
processConditionalFields(event) {
|
|
2823
|
+
let optionId = event.target.name.replace('[]', '');
|
|
2824
|
+
let isMultiple = event.target.getAttribute('type') === 'checkbox';
|
|
2825
|
+
let isRadio = event.target.getAttribute('type') === 'radio';
|
|
2826
|
+
let isTextInput = ['INPUT', 'TEXTAREA'].includes(event.target.tagName) &&
|
|
2827
|
+
(!event.target.getAttribute('type') || event.target.getAttribute('type') === 'text');
|
|
2828
|
+
salla.log('Trying to find all elements with condition:', `[data-show-when^="${optionId}"]`);
|
|
2829
|
+
this.host.querySelectorAll(`[data-show-when^="${optionId}"]`)
|
|
2830
|
+
.forEach((field) => {
|
|
2831
|
+
let isEqual = !field?.dataset.showWhen.includes('!=');
|
|
2832
|
+
let value = field?.dataset.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$3').trim();
|
|
2833
|
+
let isSelected;
|
|
2834
|
+
if (isMultiple) {
|
|
2835
|
+
let selectedValues = Array.from(this.host.querySelectorAll(`input[name="${event.target.name}"]:checked`), e => e?.value);
|
|
2836
|
+
isSelected = selectedValues.includes(value.toString());
|
|
2837
|
+
}
|
|
2838
|
+
else if (isRadio) {
|
|
2839
|
+
// Handle radio inputs.
|
|
2840
|
+
isSelected = event.target.checked && event.target.value === value;
|
|
2841
|
+
}
|
|
2842
|
+
else if (isTextInput) {
|
|
2843
|
+
// Handle text inputs and textareas - check if value matches or is not empty for boolean conditions
|
|
2844
|
+
isSelected = value === event.target.value || (value.toLowerCase() === 'true' && event.target.value.trim() !== '');
|
|
2845
|
+
}
|
|
2846
|
+
else {
|
|
2847
|
+
isSelected = value === event.target.value;
|
|
2848
|
+
}
|
|
2849
|
+
salla.log('The input is ', isMultiple ? 'Multiple' : isRadio ? 'Radio' : isTextInput ? 'Text' : 'Single', ' value:', isSelected);
|
|
2850
|
+
let showTheInput = (isEqual && isSelected) || (!isEqual && !isSelected);
|
|
2851
|
+
if (showTheInput) {
|
|
2852
|
+
field.classList.remove('hidden');
|
|
2853
|
+
field.querySelectorAll('[name]').forEach((input) => {
|
|
2854
|
+
input.removeAttribute('disabled');
|
|
2855
|
+
const closestProductOption = input.closest('.s-product-options-option');
|
|
2856
|
+
if (closestProductOption.dataset.optionRequired === 'true') {
|
|
2857
|
+
input.setAttribute('required', '');
|
|
2858
|
+
}
|
|
2859
|
+
if (input.getAttribute('type') === 'checkbox') {
|
|
2860
|
+
const checkboxes = Array.from(document.querySelectorAll(`input[type="checkbox"][name="${input.getAttribute('name')}"]`));
|
|
2861
|
+
const isAnyChecked = checkboxes.some((checkbox) => checkbox.checked);
|
|
2862
|
+
if (isAnyChecked) {
|
|
2863
|
+
checkboxes.forEach((checkbox) => {
|
|
2864
|
+
checkbox.removeAttribute('required');
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
});
|
|
2869
|
+
}
|
|
2870
|
+
else {
|
|
2871
|
+
this.hideAllOptions(field.dataset.optionId);
|
|
2872
|
+
field.classList.add('hidden');
|
|
2873
|
+
this.disableInputs(field);
|
|
2874
|
+
}
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
componentDidRender() {
|
|
2878
|
+
this.host.querySelectorAll(`[data-show-when]`).forEach((field) => {
|
|
2879
|
+
// @ts-ignore
|
|
2880
|
+
let optionName = field?.dataset?.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$1').trim();
|
|
2881
|
+
if (!optionName) {
|
|
2882
|
+
return;
|
|
2883
|
+
}
|
|
2884
|
+
this.changeHandler({
|
|
2885
|
+
target: this.host.querySelector('[name^="' + optionName + '"]')
|
|
2886
|
+
});
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
render() {
|
|
2890
|
+
return (index.h(index.Host, { key: 'b29d3a3e7e7af01540efbd2868cd302e91bba8a4' }, index.h("slot", { key: 'b6d6544834ea082ffcd20deef2da1206a47e98ba' })));
|
|
2891
|
+
}
|
|
2892
|
+
get host() { return index.getElement(this); }
|
|
2893
|
+
};
|
|
2894
|
+
|
|
2476
2895
|
const sallaCountDownCss = "";
|
|
2477
2896
|
|
|
2478
2897
|
const SallaCountDown = class {
|
|
@@ -3095,13 +3514,13 @@ const SallaFileUpload = class {
|
|
|
3095
3514
|
return;
|
|
3096
3515
|
try {
|
|
3097
3516
|
const [FilePondModule, FilePondPluginFileValidateSize, FilePondPluginImageExifOrientation, FilePondPluginImagePreview, FilePondPluginImageEdit, FilePondPluginFileValidateType, FilePondPluginFilePoster] = await Promise.all([
|
|
3098
|
-
Promise.resolve().then(function () { return require('./filepond-
|
|
3099
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-file-validate-size-
|
|
3100
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-image-exif-orientation-
|
|
3101
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-image-preview-
|
|
3102
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-image-edit-
|
|
3103
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-file-validate-type-
|
|
3104
|
-
Promise.resolve().then(function () { return require('./filepond-plugin-file-poster-
|
|
3517
|
+
Promise.resolve().then(function () { return require('./filepond-B6LUaQ9F.js'); }).then(function (n) { return n.filepond; }),
|
|
3518
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-file-validate-size-D7kuqaEC.js'); }).then(function (n) { return n.filepondPluginFileValidateSize; }),
|
|
3519
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-image-exif-orientation-bFbWHyQs.js'); }).then(function (n) { return n.filepondPluginImageExifOrientation; }),
|
|
3520
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-image-preview-24nxaVX6.js'); }).then(function (n) { return n.filepondPluginImagePreview; }),
|
|
3521
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-image-edit-BRIZbIyN.js'); }).then(function (n) { return n.filepondPluginImageEdit; }),
|
|
3522
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-file-validate-type-CliXp1Qt.js'); }).then(function (n) { return n.filepondPluginFileValidateType; }),
|
|
3523
|
+
Promise.resolve().then(function () { return require('./filepond-plugin-file-poster-DlB67Vv3.js'); }).then(function (n) { return n.filepondPluginFilePoster; })
|
|
3105
3524
|
]);
|
|
3106
3525
|
this.FilePond = FilePondModule;
|
|
3107
3526
|
// Register plugins
|
|
@@ -5860,83 +6279,861 @@ const SallaModal = class {
|
|
|
5860
6279
|
};
|
|
5861
6280
|
SallaModal.style = sallaModalCss;
|
|
5862
6281
|
|
|
5863
|
-
|
|
5864
|
-
<title>tag</title>
|
|
5865
|
-
<path d="M28 0h-9.344c-1.059 0-2.056 0.411-2.809 1.153l-14.673 14.456c-1.56 1.56-1.561 4.097-0.001 5.657l9.56 9.56c0.755 0.755 1.76 1.172 2.828 1.173h0.003c1.068 0 2.072-0.416 2.833-1.179l14.451-14.668c0.743-0.753 1.153-1.751 1.153-2.809v-9.344c0-2.205-1.795-4-4-4zM29.333 13.344c0 0.353-0.137 0.685-0.385 0.937l-14.444 14.661c-0.252 0.252-0.587 0.391-0.941 0.391-0.001 0-0.001 0-0.001 0-0.356-0.001-0.691-0.139-0.943-0.392l-9.561-9.56c-0.52-0.52-0.52-1.365-0.005-1.88l14.667-14.449c0.253-0.248 0.585-0.385 0.937-0.385h9.344c0.736 0 1.333 0.597 1.333 1.333zM24 6.673c-0.737 0-1.333 0.604-1.333 1.341s0.596 1.333 1.333 1.333 1.333-0.596 1.333-1.333v-0.015c0-0.737-0.596-1.327-1.333-1.327z"></path>
|
|
5866
|
-
</svg>
|
|
5867
|
-
`;
|
|
6282
|
+
const sallaMultipleBundleProductCss = ":host{display:block}";
|
|
5868
6283
|
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
6284
|
+
const SallaMultipleBundleProduct = class {
|
|
6285
|
+
constructor(hostRef) {
|
|
6286
|
+
index.registerInstance(this, hostRef);
|
|
6287
|
+
this.parsedSections = [];
|
|
6288
|
+
}
|
|
6289
|
+
parseProducts(newValue) {
|
|
6290
|
+
let sections = [];
|
|
6291
|
+
if (typeof newValue === 'string') {
|
|
6292
|
+
try {
|
|
6293
|
+
const parsed = JSON.parse(newValue);
|
|
6294
|
+
sections = this.extractSections(parsed);
|
|
6295
|
+
}
|
|
6296
|
+
catch (e) {
|
|
6297
|
+
console.error('Invalid JSON passed to bundleSections prop:', newValue);
|
|
6298
|
+
sections = [];
|
|
6299
|
+
}
|
|
6300
|
+
}
|
|
6301
|
+
else if (newValue) {
|
|
6302
|
+
sections = this.extractSections(newValue);
|
|
6303
|
+
}
|
|
6304
|
+
this.parsedSections = sections;
|
|
6305
|
+
}
|
|
6306
|
+
extractSections(data) {
|
|
6307
|
+
// Handle new nested structure: data.bundle.sections
|
|
6308
|
+
if (data.bundle && data.bundle.sections && Array.isArray(data.bundle.sections)) {
|
|
6309
|
+
return data.bundle.sections;
|
|
6310
|
+
}
|
|
6311
|
+
// Handle old flat structure: data is directly an array of sections
|
|
6312
|
+
if (Array.isArray(data)) {
|
|
6313
|
+
return data;
|
|
6314
|
+
}
|
|
6315
|
+
// Handle case where data.sections exists at root level
|
|
6316
|
+
if (data.sections && Array.isArray(data.sections)) {
|
|
6317
|
+
return data.sections;
|
|
6318
|
+
}
|
|
6319
|
+
console.warn('No valid sections found in data:', data);
|
|
6320
|
+
return [];
|
|
6321
|
+
}
|
|
6322
|
+
isCartPage() {
|
|
6323
|
+
return salla.url.is_page('cart');
|
|
6324
|
+
}
|
|
6325
|
+
renderCartPage() {
|
|
6326
|
+
return index.h("salla-multiple-bundle-product-cart", { sections: this.parsedSections });
|
|
6327
|
+
}
|
|
6328
|
+
renderDetailsPage() {
|
|
6329
|
+
return index.h("salla-multiple-bundle-product-details", { sections: this.parsedSections });
|
|
6330
|
+
}
|
|
6331
|
+
componentWillLoad() {
|
|
6332
|
+
this.parseProducts(this.bundleSections);
|
|
6333
|
+
}
|
|
6334
|
+
render() {
|
|
6335
|
+
return (index.h(index.Host, { key: '6f9e20c6db0c7d79f84ba197f015f43c1b0a79fc', class: "s-multiple-bundle-product-wrapper" }, this.isCartPage() ? this.renderCartPage() : this.renderDetailsPage()));
|
|
6336
|
+
}
|
|
6337
|
+
static get watchers() { return {
|
|
6338
|
+
"bundleSections": ["parseProducts"]
|
|
6339
|
+
}; }
|
|
6340
|
+
};
|
|
6341
|
+
SallaMultipleBundleProduct.style = sallaMultipleBundleProductCss;
|
|
5875
6342
|
|
|
5876
|
-
const
|
|
6343
|
+
const sallaMultipleBundleProductCartCss = "";
|
|
5877
6344
|
|
|
5878
|
-
const
|
|
6345
|
+
const SallaMultipleBundleProductCart = class {
|
|
5879
6346
|
constructor(hostRef) {
|
|
5880
6347
|
index.registerInstance(this, hostRef);
|
|
5881
|
-
this.
|
|
5882
|
-
this.
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
salla.log('User selected to don\'t show this offer again.');
|
|
5896
|
-
return;
|
|
6348
|
+
this.sections = [];
|
|
6349
|
+
this.itemNumber = '';
|
|
6350
|
+
}
|
|
6351
|
+
deleteItem(sectionId, product) {
|
|
6352
|
+
const form = this.host.closest('form');
|
|
6353
|
+
if (form) {
|
|
6354
|
+
const formId = form.getAttribute('id');
|
|
6355
|
+
if (formId && typeof formId === 'string') {
|
|
6356
|
+
const itemNumber = formId.match(/item-(\d+)/)?.[1];
|
|
6357
|
+
this.itemNumber = itemNumber || '';
|
|
6358
|
+
const selectedAccordion = this.host.querySelector(`#accordion-${product.id}`);
|
|
6359
|
+
salla.cart
|
|
6360
|
+
.deleteItem(`${this.itemNumber}?product_id=${product.id}§ion_id=${sectionId}`)
|
|
6361
|
+
.then(() => selectedAccordion?.remove());
|
|
5897
6362
|
}
|
|
5898
|
-
|
|
5899
|
-
});
|
|
6363
|
+
}
|
|
5900
6364
|
}
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
* @param offer - The offer being viewed in the modal
|
|
5904
|
-
*/
|
|
5905
|
-
emitPromotionViewed(offer) {
|
|
5906
|
-
if (!offer)
|
|
5907
|
-
return;
|
|
5908
|
-
salla.event.emit('promotion::viewed', [{
|
|
5909
|
-
id: offer.id?.toString(),
|
|
5910
|
-
creative: offer.message,
|
|
5911
|
-
name: offer.name,
|
|
5912
|
-
position: `${this.offer_type}_offer_modal`
|
|
5913
|
-
}]);
|
|
6365
|
+
renderRemoveButton(sectionId, product, isText = false) {
|
|
6366
|
+
return (index.h("salla-button", { type: "button", shape: isText ? 'btn' : 'icon', fill: isText ? 'outline' : 'solid', size: "small", color: "danger", "aria-label": "Remove from the cart", onClick: () => this.deleteItem(sectionId, product) }, isText ? salla.lang.get('common.elements.delete') : index.h("i", { class: "sicon-cancel" })));
|
|
5914
6367
|
}
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
*/
|
|
5919
|
-
emitPromotionClicked(offer) {
|
|
5920
|
-
if (!offer)
|
|
5921
|
-
return;
|
|
5922
|
-
salla.event.emit('promotion::clicked', [{
|
|
5923
|
-
id: offer.id?.toString(),
|
|
5924
|
-
creative: offer.message,
|
|
5925
|
-
name: offer.name,
|
|
5926
|
-
position: `${this.offer_type}_offer_modal`
|
|
5927
|
-
}]);
|
|
6368
|
+
renderAccordionHeader(sectionId, product) {
|
|
6369
|
+
const hasOptions = product?.options && product?.options?.length > 0; // undefined or empty array
|
|
6370
|
+
return (index.h("div", { slot: "html", class: "s-multiple-bundle-product-cart-header-wrapper" }, index.h("div", { class: `s-multiple-bundle-product-cart-header ${hasOptions ? '' : 's-multiple-bundle-product-cart-header-no-options'}` }, index.h("div", { class: "s-multiple-bundle-product-cart-header-content" }, index.h("a", { href: product?.url, class: "s-multiple-bundle-product-cart-header-image-wrapper" }, index.h("img", { src: product?.image?.url, alt: product?.image?.alt || product?.name, class: "s-multiple-bundle-product-cart-header-image" })), index.h("div", { class: "s-multiple-bundle-product-cart-header-content-details" }, index.h("h2", { class: "s-multiple-bundle-product-cart-header-content-details-title" }, index.h("a", { href: product?.url, class: "s-multiple-bundle-product-cart-header-content-details-title-link" }, product?.name)), index.h("div", { class: "s-multiple-bundle-product-cart-header-content-details-price" }, index.h("span", { class: "s-multiple-bundle-product-cart-header-content-details-price-regular" }, index.h("span", { innerHTML: product?.price ? salla.money(product?.price) : '' })), product?.sale_price > 0 && (index.h("span", { class: "s-multiple-bundle-product-cart-header-content-details-price-sale" }, index.h("span", { innerHTML: salla.money(product?.sale_price) })))), product?.quantity_in_group > 0 && product?.quantity !== 0 && (index.h("p", { class: "s-multiple-bundle-product-cart-header-content-details-quantity" }, index.h("span", null, salla.lang.get('pages.products.number_of_pieces')), index.h("span", null, product?.quantity_in_group))))), !hasOptions && (index.h("div", { class: "s-multiple-bundle-product-cart-header-remove-button" }, this.renderRemoveButton(sectionId, product, false))))));
|
|
5928
6371
|
}
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
6372
|
+
render() {
|
|
6373
|
+
return (index.h(index.Host, { key: 'b9542b8e0cc7705e6bbd9dc17db8284c11d27846', class: "s-multiple-bundle-product-wrapper" }, index.h("div", { key: '44bfe630604e8d45aa1218eebcdf026b47f9fd99', class: "s-multiple-bundle-product-wrapper-sections" }, this.sections.map((section, sectionIndex) => {
|
|
6374
|
+
return section.products.map(product => {
|
|
6375
|
+
const bundleContext = {
|
|
6376
|
+
sectionId: section.id,
|
|
6377
|
+
sectionIndex: sectionIndex,
|
|
6378
|
+
productId: product.id,
|
|
6379
|
+
};
|
|
6380
|
+
return (index.h("salla-accordion", { key: product.id, collapsed: false, bordered: true, collapsible: product.options && product.options.length > 0 ? true : false, size: "sm", id: `accordion-${product.id}` }, index.h("salla-accordion-head", null, this.renderAccordionHeader(String(section.id), product)), product.options && product.options.length > 0 && (index.h("salla-accordion-body", null, index.h("salla-product-options", { options: JSON.stringify(product.options), key: `${product.id}-persistent`, "product-id": product.id, "bundle-context": JSON.stringify(bundleContext) }), index.h("div", { class: "s-multiple-bundle-product-cart-body-remove-button" }, this.renderRemoveButton(String(section.id), product, true))))));
|
|
6381
|
+
});
|
|
6382
|
+
}))));
|
|
6383
|
+
}
|
|
6384
|
+
get host() { return index.getElement(this); }
|
|
6385
|
+
};
|
|
6386
|
+
SallaMultipleBundleProductCart.style = sallaMultipleBundleProductCartCss;
|
|
6387
|
+
|
|
6388
|
+
const sallaMultipleBundleProductDetailsCss = "";
|
|
6389
|
+
|
|
6390
|
+
const SallaMultipleBundleProductDetails = class {
|
|
6391
|
+
constructor(hostRef) {
|
|
6392
|
+
index.registerInstance(this, hostRef);
|
|
6393
|
+
this.sections = [];
|
|
6394
|
+
// store selected product IDs per section (can be string or number)
|
|
6395
|
+
this.selectedProducts = {};
|
|
6396
|
+
// Event handler reference for cleanup
|
|
6397
|
+
this.productSelectedHandler = null;
|
|
6398
|
+
// handle selecting a product (toggle)
|
|
6399
|
+
this.onSelectProduct = (sectionId, product) => {
|
|
6400
|
+
this.selectedProducts = {
|
|
6401
|
+
...this.selectedProducts,
|
|
6402
|
+
[sectionId]: new Set(this.selectedProducts[sectionId] || []),
|
|
6403
|
+
};
|
|
6404
|
+
const productId = product.id;
|
|
6405
|
+
const wasSelected = this.selectedProducts[sectionId].has(productId);
|
|
6406
|
+
if (wasSelected) {
|
|
6407
|
+
// Product is being deselected
|
|
6408
|
+
this.selectedProducts[sectionId].delete(productId);
|
|
6409
|
+
// Clear form data and modal options for this product in this specific section
|
|
6410
|
+
this.clearProductFormData(productId, sectionId);
|
|
6411
|
+
this.clearProductModalOptions(productId);
|
|
6412
|
+
}
|
|
6413
|
+
else {
|
|
6414
|
+
// Product is being selected
|
|
6415
|
+
this.selectedProducts[sectionId].add(productId);
|
|
6416
|
+
}
|
|
6417
|
+
// force re-render
|
|
6418
|
+
this.selectedProducts = { ...this.selectedProducts };
|
|
6419
|
+
// still dispatch event
|
|
6420
|
+
salla.event.dispatch('on-bundle-product-selected', {
|
|
6421
|
+
id: product.id,
|
|
6422
|
+
name: product.name,
|
|
6423
|
+
options: product.options,
|
|
6424
|
+
wasSelected: wasSelected,
|
|
6425
|
+
isSelected: !wasSelected,
|
|
6426
|
+
});
|
|
6427
|
+
};
|
|
6428
|
+
// ensure product is selected (only add if not already selected)
|
|
6429
|
+
this.ensureProductSelected = (sectionId, product) => {
|
|
6430
|
+
this.selectedProducts = {
|
|
6431
|
+
...this.selectedProducts,
|
|
6432
|
+
[sectionId]: new Set(this.selectedProducts[sectionId] || []),
|
|
6433
|
+
};
|
|
6434
|
+
const productId = product.id;
|
|
6435
|
+
// Only add if not already selected
|
|
6436
|
+
if (!this.selectedProducts[sectionId].has(productId)) {
|
|
6437
|
+
this.selectedProducts[sectionId].add(productId);
|
|
6438
|
+
// force re-render
|
|
6439
|
+
this.selectedProducts = { ...this.selectedProducts };
|
|
6440
|
+
// dispatch event
|
|
6441
|
+
salla.event.dispatch('on-bundle-product-selected', {
|
|
6442
|
+
id: product.id,
|
|
6443
|
+
name: product.name,
|
|
6444
|
+
options: product.options,
|
|
6445
|
+
});
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6448
|
+
// open product options modal
|
|
6449
|
+
this.onSelectProductOptions = (product, sectionId) => {
|
|
6450
|
+
// Find the section index from the sectionId
|
|
6451
|
+
const sectionIndex = this.sections.findIndex(section => section.id == sectionId);
|
|
6452
|
+
// Find the product index within the section
|
|
6453
|
+
const section = this.sections.find(section => section.id == sectionId);
|
|
6454
|
+
const productIndex = section?.products?.findIndex(p => p.id == product.id) ?? 0;
|
|
6455
|
+
salla.event.dispatch('multiple-bundle-product-modal::open', {
|
|
6456
|
+
product,
|
|
6457
|
+
sectionId,
|
|
6458
|
+
sectionIndex,
|
|
6459
|
+
productIndex,
|
|
6460
|
+
});
|
|
6461
|
+
};
|
|
6462
|
+
// Event handlers for bundle slider component
|
|
6463
|
+
this.handleBundleSliderProductSelected = (event) => {
|
|
6464
|
+
const { product, sectionId } = event.detail;
|
|
6465
|
+
this.onSelectProduct(sectionId, product);
|
|
6466
|
+
};
|
|
6467
|
+
this.handleBundleSliderProductOptionsSelected = (event) => {
|
|
6468
|
+
const { product, sectionId } = event.detail;
|
|
6469
|
+
this.onSelectProductOptions(product, sectionId);
|
|
6470
|
+
};
|
|
6471
|
+
}
|
|
6472
|
+
// Clear form data for a specific product in specific section
|
|
6473
|
+
clearProductFormData(productId, sectionId) {
|
|
6474
|
+
const form = this.host.closest('form');
|
|
6475
|
+
if (sectionId) {
|
|
6476
|
+
// Remove inputs for specific section/productIndex combination
|
|
6477
|
+
const productInputPattern = `bundle[${sectionId}][`;
|
|
6478
|
+
const inputsToRemove = Array.from(form.querySelectorAll('input')).filter((input) => input.getAttribute('data-product-id') === String(productId) &&
|
|
6479
|
+
input.name &&
|
|
6480
|
+
input.name.startsWith(productInputPattern));
|
|
6481
|
+
inputsToRemove.forEach(input => input.remove());
|
|
6482
|
+
}
|
|
6483
|
+
else {
|
|
6484
|
+
// Fallback: Remove all hidden inputs related to this product (legacy behavior)
|
|
6485
|
+
const inputsToRemove = form.querySelectorAll(`[data-product-id="${productId}"]`);
|
|
6486
|
+
inputsToRemove.forEach(input => input.remove());
|
|
6487
|
+
}
|
|
6488
|
+
}
|
|
6489
|
+
// Clear modal options state for a specific product
|
|
6490
|
+
clearProductModalOptions(productId) {
|
|
6491
|
+
// Emit event to notify modal to reset its state for this product
|
|
6492
|
+
salla.event.dispatch('multiple-bundle-product-modal::clear-options', {
|
|
6493
|
+
productId,
|
|
6494
|
+
});
|
|
6495
|
+
}
|
|
6496
|
+
renderAccordionHeader(section, selectedCount) {
|
|
6497
|
+
return (index.h(index.Fragment, null, index.h("h2", { slot: "title" }, section?.name), section?.obligatory_products && (index.h("span", { slot: "note" }, salla.lang.get('pages.products.obligatory_products', {
|
|
6498
|
+
count: section?.obligatory_products || 0,
|
|
6499
|
+
}))), index.h("span", { slot: "progress" }, selectedCount, "/", section?.products?.length || 0)));
|
|
6500
|
+
}
|
|
6501
|
+
componentDidLoad() {
|
|
6502
|
+
// Listen for product selected event from modal
|
|
6503
|
+
const modal = this.host.querySelector('salla-multiple-bundle-product-options-modal');
|
|
6504
|
+
if (modal) {
|
|
6505
|
+
this.productSelectedHandler = (e) => {
|
|
6506
|
+
const { productId, sectionId, product, fromModal } = e.detail;
|
|
6507
|
+
if (fromModal) {
|
|
6508
|
+
// When called from modal, only add to selection if not already selected
|
|
6509
|
+
this.ensureProductSelected(sectionId, product || { id: productId });
|
|
6510
|
+
}
|
|
6511
|
+
else {
|
|
6512
|
+
// Normal toggle behavior
|
|
6513
|
+
this.onSelectProduct(sectionId, product || { id: productId });
|
|
6514
|
+
}
|
|
6515
|
+
};
|
|
6516
|
+
modal.addEventListener('productSelected', this.productSelectedHandler);
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6519
|
+
disconnectedCallback() {
|
|
6520
|
+
// Clean up event listener to prevent memory leaks
|
|
6521
|
+
if (this.productSelectedHandler) {
|
|
6522
|
+
const modal = this.host.querySelector('salla-multiple-bundle-product-options-modal');
|
|
6523
|
+
if (modal) {
|
|
6524
|
+
modal.removeEventListener('productSelected', this.productSelectedHandler);
|
|
6525
|
+
}
|
|
6526
|
+
this.productSelectedHandler = null;
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
render() {
|
|
6530
|
+
return (index.h(index.Host, { key: '0a24e2c3ee4bdff3891334a49318a7cfeb668d54', class: "s-multiple-bundle-product-wrapper" }, index.h("div", { key: '713f1b101aed42cabacd17d662aad49520b89f4b', class: "s-multiple-bundle-product-wrapper-sections" }, this.sections.map((section, index$1) => {
|
|
6531
|
+
const selectedCount = this.selectedProducts[section.id]?.size || 0;
|
|
6532
|
+
return (index.h("salla-accordion", { key: section.id, collapsed: index$1 === 1 ? true : false }, index.h("salla-accordion-head", null, this.renderAccordionHeader(section, selectedCount)), index.h("salla-accordion-body", null, index.h("salla-multiple-bundle-product-slider", { section: section, sectionIndex: index$1, selectedProducts: this.selectedProducts, onProductSelected: this.handleBundleSliderProductSelected, onProductOptionsSelected: this.handleBundleSliderProductOptionsSelected }))));
|
|
6533
|
+
})), index.h("salla-multiple-bundle-product-options-modal", { key: '2d889aa72a36040f87cd791363f71600d86458e7' })));
|
|
6534
|
+
}
|
|
6535
|
+
get host() { return index.getElement(this); }
|
|
6536
|
+
};
|
|
6537
|
+
SallaMultipleBundleProductDetails.style = sallaMultipleBundleProductDetailsCss;
|
|
6538
|
+
|
|
6539
|
+
const sallaMultipleBundleProductOptionsModalCss = ":host{display:block}";
|
|
6540
|
+
|
|
6541
|
+
const SallaMultipleBundleProductOptionsModal = class {
|
|
6542
|
+
constructor(hostRef) {
|
|
6543
|
+
index.registerInstance(this, hostRef);
|
|
6544
|
+
this.optionsSaved = index.createEvent(this, "optionsSaved");
|
|
6545
|
+
this.productSelected = index.createEvent(this, "productSelected");
|
|
6546
|
+
this.product = null;
|
|
6547
|
+
this.sectionId = null;
|
|
6548
|
+
this.sectionIndex = 0;
|
|
6549
|
+
this.productIndex = 0;
|
|
6550
|
+
this.selectedOptions = {};
|
|
6551
|
+
this.isLoading = false;
|
|
6552
|
+
this.hasUnsavedChanges = false;
|
|
6553
|
+
this.validationErrors = [];
|
|
6554
|
+
}
|
|
6555
|
+
/**
|
|
6556
|
+
* Generate a unique cache key for selected options using section ID, product index, and product ID
|
|
6557
|
+
*/
|
|
6558
|
+
generateCacheKey(sectionId, productIndex, productId) {
|
|
6559
|
+
return `${sectionId || 'unknown'}-${productIndex || 0}-${productId || 'unknown'}`;
|
|
6560
|
+
}
|
|
6561
|
+
handleProductChange(newValue) {
|
|
6562
|
+
// Use setTimeout to ensure modal is ready
|
|
6563
|
+
setTimeout(() => {
|
|
6564
|
+
if (this.modal && newValue) {
|
|
6565
|
+
const title = newValue.name || '';
|
|
6566
|
+
this.modal.setTitle(title);
|
|
6567
|
+
}
|
|
6568
|
+
}, 100);
|
|
6569
|
+
// Reset validation errors when product changes
|
|
6570
|
+
this.validationErrors = [];
|
|
6571
|
+
this.hasUnsavedChanges = false;
|
|
6572
|
+
}
|
|
6573
|
+
async open() {
|
|
6574
|
+
if (!this.modal) {
|
|
6575
|
+
requestAnimationFrame(() => this.open());
|
|
6576
|
+
return;
|
|
6577
|
+
}
|
|
6578
|
+
this.isLoading = true;
|
|
6579
|
+
// Set the title before opening
|
|
6580
|
+
if (this.product?.name) {
|
|
6581
|
+
this.modal.setTitle(this.product.name);
|
|
6582
|
+
}
|
|
6583
|
+
this.modal.open();
|
|
6584
|
+
// Initialize selectedOptions with current selections from the component
|
|
6585
|
+
setTimeout(async () => {
|
|
6586
|
+
if (this.product?.id) {
|
|
6587
|
+
await this.initializeSelectedOptions();
|
|
6588
|
+
}
|
|
6589
|
+
// Set title again after modal is fully loaded
|
|
6590
|
+
if (this.product?.name) {
|
|
6591
|
+
this.modal.setTitle(this.product.name);
|
|
6592
|
+
}
|
|
6593
|
+
this.modal.stopLoading();
|
|
6594
|
+
this.isLoading = false;
|
|
6595
|
+
}, 300);
|
|
6596
|
+
}
|
|
6597
|
+
async close() {
|
|
6598
|
+
if (this.modal) {
|
|
6599
|
+
this.modal.close();
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
async refreshOptionsState() {
|
|
6603
|
+
// Force re-render by updating the component state
|
|
6604
|
+
this.selectedOptions = { ...this.selectedOptions };
|
|
6605
|
+
}
|
|
6606
|
+
componentDidLoad() {
|
|
6607
|
+
salla.event.on('multiple-bundle-product-modal::open', (data) => {
|
|
6608
|
+
this.product = data.product;
|
|
6609
|
+
this.sectionId = data.sectionId || null;
|
|
6610
|
+
this.sectionIndex = data.sectionIndex || 0;
|
|
6611
|
+
this.productIndex = data.productIndex || 0;
|
|
6612
|
+
this.open();
|
|
6613
|
+
});
|
|
6614
|
+
// Listen for clear-options event when a product is deselected
|
|
6615
|
+
salla.event.on('multiple-bundle-product-modal::clear-options', (data) => {
|
|
6616
|
+
this.clearProductOptions(data.productId);
|
|
6617
|
+
});
|
|
6618
|
+
// Create and store the option change listener for proper cleanup
|
|
6619
|
+
this.optionChangeListener = (e) => {
|
|
6620
|
+
const { productId, option, detail } = e.detail;
|
|
6621
|
+
// Convert productId to the same type as our product ID
|
|
6622
|
+
const normalizedProductId = this.product?.id ? String(this.product.id) : null;
|
|
6623
|
+
const normalizedEventProductId = productId ? String(productId) : null;
|
|
6624
|
+
// Only handle events for the current product
|
|
6625
|
+
if (normalizedProductId &&
|
|
6626
|
+
normalizedEventProductId &&
|
|
6627
|
+
normalizedProductId === normalizedEventProductId &&
|
|
6628
|
+
option &&
|
|
6629
|
+
detail) {
|
|
6630
|
+
this.handleOptionChange(Number(normalizedProductId), option, detail);
|
|
6631
|
+
}
|
|
6632
|
+
};
|
|
6633
|
+
salla.event.on('product-options::change', this.optionChangeListener);
|
|
6634
|
+
// Create and store the checkbox change listener for proper cleanup
|
|
6635
|
+
this.checkboxChangeListener = (e) => {
|
|
6636
|
+
const target = e.target;
|
|
6637
|
+
// Check if this is a product selection checkbox
|
|
6638
|
+
if (target && target.type === 'checkbox' && target.name && target.name.includes('bundle[') && target.name.includes('][id]')) {
|
|
6639
|
+
// Extract section info from the checkbox name: bundle[sectionId][productIndex][id]
|
|
6640
|
+
const nameMatch = target.name.match(/^bundle\[([^\]]+)\]\[([^\]]+)\]\[id\]$/);
|
|
6641
|
+
if (nameMatch && !target.checked) {
|
|
6642
|
+
// Product was deselected, clear its cached options
|
|
6643
|
+
const [, sectionId, productIndex] = nameMatch;
|
|
6644
|
+
const productId = target.value;
|
|
6645
|
+
// Prevent the immediate event to ensure cleanup happens first
|
|
6646
|
+
e.preventDefault();
|
|
6647
|
+
e.stopPropagation();
|
|
6648
|
+
// Ensure the checkbox is actually unchecked
|
|
6649
|
+
target.checked = false;
|
|
6650
|
+
// Generate the same cache key used by the modal
|
|
6651
|
+
const cacheKey = this.generateCacheKey(sectionId, parseInt(productIndex), productId);
|
|
6652
|
+
// Clear the cached options for this product
|
|
6653
|
+
const updatedSelectedOptions = { ...this.selectedOptions };
|
|
6654
|
+
delete updatedSelectedOptions[cacheKey];
|
|
6655
|
+
this.selectedOptions = updatedSelectedOptions;
|
|
6656
|
+
// Force re-render of the modal if it's currently open for this product
|
|
6657
|
+
if (this.product && this.product.id == productId) {
|
|
6658
|
+
this.selectedOptions = { ...this.selectedOptions };
|
|
6659
|
+
}
|
|
6660
|
+
const form = this.host.closest('form');
|
|
6661
|
+
if (form) {
|
|
6662
|
+
const productInputPattern = `bundle[${sectionId}][${productIndex}]`;
|
|
6663
|
+
// Get all form inputs and filter manually
|
|
6664
|
+
const allInputs = Array.from(form.querySelectorAll('input'));
|
|
6665
|
+
const matchingInputs = allInputs.filter(input => input.name && input.name.startsWith(productInputPattern));
|
|
6666
|
+
// Process matching inputs for removal
|
|
6667
|
+
matchingInputs.forEach(el => {
|
|
6668
|
+
// Don't remove the visible checkbox that was just unchecked
|
|
6669
|
+
if (el !== target && (el.type === 'hidden' || el.hasAttribute('data-product-id'))) {
|
|
6670
|
+
el.remove();
|
|
6671
|
+
}
|
|
6672
|
+
});
|
|
6673
|
+
// Method 2: Find inputs by data-product-id BUT only within the same section/productIndex
|
|
6674
|
+
const dataProductInputs = allInputs.filter(input => {
|
|
6675
|
+
// Must have data-product-id matching the productId
|
|
6676
|
+
if (input.getAttribute('data-product-id') !== String(productId)) {
|
|
6677
|
+
return false;
|
|
6678
|
+
}
|
|
6679
|
+
// Must also be within the same section/productIndex pattern
|
|
6680
|
+
return input.name && input.name.startsWith(productInputPattern);
|
|
6681
|
+
});
|
|
6682
|
+
// Process inputs with matching section/productIndex and productId for removal
|
|
6683
|
+
dataProductInputs.forEach(el => {
|
|
6684
|
+
if (el !== target) {
|
|
6685
|
+
el.remove();
|
|
6686
|
+
}
|
|
6687
|
+
});
|
|
6688
|
+
// Method 3: Removed broader search to prevent removing inputs from other products
|
|
6689
|
+
// The cleanup is now more precise and only removes inputs for the specific product
|
|
6690
|
+
// Trigger form change event after cleanup is complete
|
|
6691
|
+
setTimeout(() => {
|
|
6692
|
+
const changeEvent = new window.Event('change', { bubbles: true });
|
|
6693
|
+
form.dispatchEvent(changeEvent);
|
|
6694
|
+
}, 50); // Small delay to ensure cleanup is complete
|
|
6695
|
+
}
|
|
6696
|
+
}
|
|
6697
|
+
}
|
|
6698
|
+
};
|
|
6699
|
+
// Listen for product checkbox changes to reset options when product is deselected
|
|
6700
|
+
document.addEventListener('change', this.checkboxChangeListener);
|
|
6701
|
+
}
|
|
6702
|
+
disconnectedCallback() {
|
|
6703
|
+
// Clean up event listeners to prevent memory leaks
|
|
6704
|
+
if (this.checkboxChangeListener) {
|
|
6705
|
+
document.removeEventListener('change', this.checkboxChangeListener);
|
|
6706
|
+
}
|
|
6707
|
+
}
|
|
6708
|
+
generateFormInputName(sectionId, productIndex, optionParentId) {
|
|
6709
|
+
return `bundle[${sectionId}][${productIndex}][options][${optionParentId}]`;
|
|
6710
|
+
}
|
|
6711
|
+
async initializeSelectedOptions() {
|
|
6712
|
+
if (!this.product?.id)
|
|
6713
|
+
return;
|
|
6714
|
+
const productId = this.product.id;
|
|
6715
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
|
|
6716
|
+
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
|
|
6717
|
+
if (optionsEl) {
|
|
6718
|
+
try {
|
|
6719
|
+
const selectedOptions = await optionsEl.getSelectedOptions();
|
|
6720
|
+
if (selectedOptions && selectedOptions.length > 0) {
|
|
6721
|
+
this.selectedOptions = {
|
|
6722
|
+
...this.selectedOptions,
|
|
6723
|
+
[cacheKey]: selectedOptions,
|
|
6724
|
+
};
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6727
|
+
catch (e) {
|
|
6728
|
+
console.warn('Could not initialize selected options:', e);
|
|
6729
|
+
}
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6732
|
+
// Clear options state for a specific product
|
|
6733
|
+
clearProductOptions(productId) {
|
|
6734
|
+
// Generate cache key for this specific product in current section context
|
|
6735
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
|
|
6736
|
+
// Remove the product from selectedOptions using the cache key
|
|
6737
|
+
const updatedSelectedOptions = { ...this.selectedOptions };
|
|
6738
|
+
delete updatedSelectedOptions[cacheKey];
|
|
6739
|
+
this.selectedOptions = updatedSelectedOptions;
|
|
6740
|
+
// Reset validation errors and unsaved changes
|
|
6741
|
+
this.validationErrors = [];
|
|
6742
|
+
this.hasUnsavedChanges = false;
|
|
6743
|
+
}
|
|
6744
|
+
async handleOptionChange(productId, option, detail) {
|
|
6745
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
|
|
6746
|
+
// Get the current state from the component to ensure we have the latest selections
|
|
6747
|
+
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
|
|
6748
|
+
let currentComponentSelections = [];
|
|
6749
|
+
if (optionsEl) {
|
|
6750
|
+
try {
|
|
6751
|
+
currentComponentSelections = (await optionsEl.getSelectedOptions()) || [];
|
|
6752
|
+
}
|
|
6753
|
+
catch (e) {
|
|
6754
|
+
console.warn('Could not get current selections from component:', e);
|
|
6755
|
+
}
|
|
6756
|
+
}
|
|
6757
|
+
// If component returns data, use it; otherwise, fall back to manual tracking
|
|
6758
|
+
if (currentComponentSelections.length > 0) {
|
|
6759
|
+
// Component returned data, use it
|
|
6760
|
+
this.selectedOptions = {
|
|
6761
|
+
...this.selectedOptions,
|
|
6762
|
+
[cacheKey]: currentComponentSelections,
|
|
6763
|
+
};
|
|
6764
|
+
}
|
|
6765
|
+
else {
|
|
6766
|
+
// If we have existing selections in internal state and component returns empty,
|
|
6767
|
+
// it might be a deselection, so we should use manual tracking
|
|
6768
|
+
if (this.selectedOptions[cacheKey] && this.selectedOptions[cacheKey].length > 0) {
|
|
6769
|
+
// Component didn't return data, use manual tracking
|
|
6770
|
+
const currentSelected = this.selectedOptions[cacheKey] || [];
|
|
6771
|
+
const updatedSelected = [...currentSelected];
|
|
6772
|
+
// Find existing selection for this specific option (by option_id)
|
|
6773
|
+
const existingIndex = updatedSelected.findIndex(opt => opt.option_id === option.id);
|
|
6774
|
+
if (existingIndex > -1) {
|
|
6775
|
+
// Check if this is a deselection (detail might be null or undefined)
|
|
6776
|
+
if (!detail || detail.id === null || detail.id === undefined) {
|
|
6777
|
+
// Remove the option (deselection)
|
|
6778
|
+
updatedSelected.splice(existingIndex, 1);
|
|
6779
|
+
}
|
|
6780
|
+
else {
|
|
6781
|
+
// Replace existing selection for this option
|
|
6782
|
+
updatedSelected[existingIndex] = { ...detail, option_id: option.id };
|
|
6783
|
+
}
|
|
6784
|
+
}
|
|
6785
|
+
else {
|
|
6786
|
+
// Only add if detail exists (not a deselection)
|
|
6787
|
+
if (detail && detail.id !== null && detail.id !== undefined) {
|
|
6788
|
+
updatedSelected.push({ ...detail, option_id: option.id });
|
|
6789
|
+
}
|
|
6790
|
+
}
|
|
6791
|
+
this.selectedOptions = {
|
|
6792
|
+
...this.selectedOptions,
|
|
6793
|
+
[cacheKey]: updatedSelected,
|
|
6794
|
+
};
|
|
6795
|
+
}
|
|
6796
|
+
else {
|
|
6797
|
+
// No existing selections, component returned empty, and we're trying to add
|
|
6798
|
+
// This might be the first selection, so add it manually
|
|
6799
|
+
if (detail && detail.id !== null && detail.id !== undefined) {
|
|
6800
|
+
this.selectedOptions = {
|
|
6801
|
+
...this.selectedOptions,
|
|
6802
|
+
[cacheKey]: [{ ...detail, option_id: option.id }],
|
|
6803
|
+
};
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6806
|
+
}
|
|
6807
|
+
this.hasUnsavedChanges = true;
|
|
6808
|
+
this.validationErrors = []; // Clear validation errors when user makes changes
|
|
6809
|
+
}
|
|
6810
|
+
async validateOptions() {
|
|
6811
|
+
if (!this.product?.options)
|
|
6812
|
+
return true;
|
|
6813
|
+
const errors = [];
|
|
6814
|
+
const productId = this.product.id;
|
|
6815
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
|
|
6816
|
+
// Get the actual selected options from the component
|
|
6817
|
+
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
|
|
6818
|
+
let currentSelected = [];
|
|
6819
|
+
if (optionsEl) {
|
|
6820
|
+
try {
|
|
6821
|
+
currentSelected = (await optionsEl.getSelectedOptions()) || [];
|
|
6822
|
+
// Also check our internal state as fallback
|
|
6823
|
+
const internalSelected = this.selectedOptions[cacheKey] || [];
|
|
6824
|
+
// Use whichever has more selections, or if component returns empty but internal has data, use internal
|
|
6825
|
+
if (internalSelected.length > currentSelected.length ||
|
|
6826
|
+
(currentSelected.length === 0 && internalSelected.length > 0)) {
|
|
6827
|
+
currentSelected = internalSelected;
|
|
6828
|
+
}
|
|
6829
|
+
}
|
|
6830
|
+
catch (e) {
|
|
6831
|
+
// Fallback to internal state
|
|
6832
|
+
currentSelected = this.selectedOptions[cacheKey] || [];
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
else {
|
|
6836
|
+
// Fallback to internal state
|
|
6837
|
+
currentSelected = this.selectedOptions[cacheKey] || [];
|
|
6838
|
+
}
|
|
6839
|
+
// Check if any options are selected at all
|
|
6840
|
+
if (currentSelected.length === 0) {
|
|
6841
|
+
errors.push(salla.lang.get('pages.products.no_options_selected'));
|
|
6842
|
+
}
|
|
6843
|
+
// Check required options
|
|
6844
|
+
this.product.options.forEach(option => {
|
|
6845
|
+
if (option.required) {
|
|
6846
|
+
const hasSelection = currentSelected.some(selected => {
|
|
6847
|
+
return selected.option_id == option.id; // Use == instead of === for type flexibility
|
|
6848
|
+
});
|
|
6849
|
+
if (!hasSelection) {
|
|
6850
|
+
errors.push(salla.lang.get('pages.products.required_option_missing', {
|
|
6851
|
+
option: option.name,
|
|
6852
|
+
}));
|
|
6853
|
+
}
|
|
6854
|
+
}
|
|
6855
|
+
});
|
|
6856
|
+
this.validationErrors = errors;
|
|
6857
|
+
return errors.length === 0;
|
|
6858
|
+
}
|
|
6859
|
+
async onSave(e) {
|
|
6860
|
+
e.preventDefault();
|
|
6861
|
+
const productId = this.product?.id;
|
|
6862
|
+
if (!productId)
|
|
6863
|
+
return;
|
|
6864
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
|
|
6865
|
+
// Small delay to ensure component state is updated
|
|
6866
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
6867
|
+
// Validate options before saving
|
|
6868
|
+
const isValid = await this.validateOptions();
|
|
6869
|
+
if (!isValid) {
|
|
6870
|
+
salla.notify.error(this.validationErrors.join(', '));
|
|
6871
|
+
return;
|
|
6872
|
+
}
|
|
6873
|
+
this.isLoading = true;
|
|
6874
|
+
try {
|
|
6875
|
+
// please don't change this with this.host.querySelector it will return null
|
|
6876
|
+
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
|
|
6877
|
+
let selectedOptions = await optionsEl?.getSelectedOptions();
|
|
6878
|
+
// If component returns empty but we have internal state, use internal state
|
|
6879
|
+
if ((!selectedOptions || selectedOptions.length === 0) &&
|
|
6880
|
+
this.selectedOptions[cacheKey]?.length > 0) {
|
|
6881
|
+
selectedOptions = this.selectedOptions[cacheKey];
|
|
6882
|
+
}
|
|
6883
|
+
if (!selectedOptions || selectedOptions.length === 0) {
|
|
6884
|
+
this.isLoading = false;
|
|
6885
|
+
return;
|
|
6886
|
+
}
|
|
6887
|
+
// Store the selected options for this product using cache key
|
|
6888
|
+
this.selectedOptions = {
|
|
6889
|
+
...this.selectedOptions,
|
|
6890
|
+
[cacheKey]: selectedOptions,
|
|
6891
|
+
};
|
|
6892
|
+
const form = this.host.closest('form');
|
|
6893
|
+
if (!form) {
|
|
6894
|
+
this.isLoading = false;
|
|
6895
|
+
return;
|
|
6896
|
+
}
|
|
6897
|
+
// remove old inputs for this specific product in this specific section/index only
|
|
6898
|
+
const productInputPattern = `bundle[${this.sectionId}][${this.productIndex}]`;
|
|
6899
|
+
// Remove only hidden inputs and inputs with data-product-id, but preserve visible checkboxes
|
|
6900
|
+
Array.from(form.querySelectorAll(`input[name^="${productInputPattern}"][type="hidden"]`)).forEach(el => el.remove());
|
|
6901
|
+
// Also remove any inputs with data-product-id that match this specific pattern
|
|
6902
|
+
Array.from(form.querySelectorAll(`[data-product-id="${productId}"][name^="${productInputPattern}"]`)).forEach(el => el.remove());
|
|
6903
|
+
// Ensure the actual checkbox in the UI is checked to reflect the selection visually
|
|
6904
|
+
const checkboxId = `bundle[${this.sectionId}][${this.productIndex}][id]`;
|
|
6905
|
+
const checkbox = document.getElementById(checkboxId);
|
|
6906
|
+
if (checkbox) {
|
|
6907
|
+
checkbox.checked = true;
|
|
6908
|
+
// Don't dispatch change event here to avoid double API calls
|
|
6909
|
+
}
|
|
6910
|
+
else {
|
|
6911
|
+
// If checkbox doesn't exist, create a hidden input as fallback
|
|
6912
|
+
const productSelectionInput = document.createElement('input');
|
|
6913
|
+
productSelectionInput.type = 'hidden';
|
|
6914
|
+
productSelectionInput.name = `bundle[${this.sectionId}][${this.productIndex}][id]`;
|
|
6915
|
+
productSelectionInput.value = String(productId);
|
|
6916
|
+
productSelectionInput.dataset.productId = String(productId);
|
|
6917
|
+
form.appendChild(productSelectionInput);
|
|
6918
|
+
}
|
|
6919
|
+
// append new hidden inputs for options
|
|
6920
|
+
selectedOptions.forEach((option) => {
|
|
6921
|
+
// how to get option parent id?
|
|
6922
|
+
const optionParentId = option.option_id;
|
|
6923
|
+
const hidden = document.createElement('input');
|
|
6924
|
+
hidden.type = 'hidden';
|
|
6925
|
+
// Use productIndex for the form input name
|
|
6926
|
+
hidden.name = this.generateFormInputName(this.sectionId, this.productIndex ?? 0, optionParentId);
|
|
6927
|
+
hidden.value = String(option.id);
|
|
6928
|
+
hidden.dataset.productId = String(productId);
|
|
6929
|
+
form.appendChild(hidden);
|
|
6930
|
+
});
|
|
6931
|
+
// Trigger single form change event with all updates (product selection + options)
|
|
6932
|
+
const changeEvent = new window.Event('change', { bubbles: true });
|
|
6933
|
+
form.dispatchEvent(changeEvent);
|
|
6934
|
+
// Emit custom event
|
|
6935
|
+
this.optionsSaved.emit({
|
|
6936
|
+
productId: Number(productId),
|
|
6937
|
+
selectedOptions,
|
|
6938
|
+
});
|
|
6939
|
+
// Emit product selected event to check the card
|
|
6940
|
+
if (this.sectionId) {
|
|
6941
|
+
this.productSelected.emit({
|
|
6942
|
+
productId: Number(productId),
|
|
6943
|
+
sectionId: this.sectionId,
|
|
6944
|
+
product: this.product,
|
|
6945
|
+
fromModal: true,
|
|
6946
|
+
});
|
|
6947
|
+
}
|
|
6948
|
+
// Show success message
|
|
6949
|
+
salla.notify.success(salla.lang.get('pages.products.options_saved'));
|
|
6950
|
+
this.hasUnsavedChanges = false;
|
|
6951
|
+
this.validationErrors = [];
|
|
6952
|
+
// close modal
|
|
6953
|
+
this.modal.close();
|
|
6954
|
+
}
|
|
6955
|
+
catch (error) {
|
|
6956
|
+
salla.notify.error(salla.lang.get('pages.products.options_save_error'));
|
|
6957
|
+
}
|
|
6958
|
+
finally {
|
|
6959
|
+
this.isLoading = false;
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
// Method to get options with selected state preserved
|
|
6963
|
+
getOptionsWithSelectedState() {
|
|
6964
|
+
if (!this.product?.options)
|
|
6965
|
+
return [];
|
|
6966
|
+
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, this.product.id);
|
|
6967
|
+
const savedOptions = this.selectedOptions[cacheKey] || [];
|
|
6968
|
+
return this.product.options.map(option => ({
|
|
6969
|
+
...option,
|
|
6970
|
+
details: option.details.map(detail => {
|
|
6971
|
+
const isSelected = savedOptions.some(saved => {
|
|
6972
|
+
return saved.id === detail.id;
|
|
6973
|
+
});
|
|
6974
|
+
return {
|
|
6975
|
+
...detail,
|
|
6976
|
+
is_selected: isSelected,
|
|
6977
|
+
};
|
|
6978
|
+
}),
|
|
6979
|
+
}));
|
|
6980
|
+
}
|
|
6981
|
+
render() {
|
|
6982
|
+
const productId = this.product?.id;
|
|
6983
|
+
const optionsWithSelectedState = this.getOptionsWithSelectedState();
|
|
6984
|
+
return (index.h(index.Host, { key: '52efc988e52036a0be8c5dfe7d9375aed2072b55' }, index.h("salla-modal", { key: 'e07dd856effc65a718528c6836884cd82520e94e', isLoading: this.isLoading, ref: el => (this.modal = el), width: "md", centered: false, id: `s-multiple-bundle-product-options-modal-options-${productId}`, class: "s-multiple-bundle-product-options-modal-wrapper" }, index.h("div", { key: '5365b7d796d48759a8cd0e7bb7e6cd755382afc8', slot: "loading" }, index.h("salla-skeleton", { key: 'deb66b5f95587584ade5581da3c891a95d3750af', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (index.h("salla-slider", { key: 'e79b63e49ba9c29ef9d625ca99ffd17bbf282f79', id: `details-slider-${this.product?.id}`, type: "thumbs", loop: false, "auto-height": true, "listen-to-thumbnails-option": true, showThumbsControls: false, controlsOuter: false, showControls: false, class: "s-multiple-bundle-product-options-modal-slider", verticalThumbs: true, thumbsConfig: {
|
|
6985
|
+
centeredSlides: true,
|
|
6986
|
+
centeredSlidesBounds: true,
|
|
6987
|
+
slidesPerView: Math.min(5, Math.max(1, this.product?.images.length)),
|
|
6988
|
+
watchOverflow: true,
|
|
6989
|
+
watchSlidesVisibility: true,
|
|
6990
|
+
watchSlidesProgress: true,
|
|
6991
|
+
direction: 'vertical',
|
|
6992
|
+
spaceBetween: 10,
|
|
6993
|
+
} }, index.h("div", { key: '3c3f3d2a1de4869a0d2d15583630d04a400097d7', slot: "items" }, this.product?.images &&
|
|
6994
|
+
this.product?.images.map((image, index$1) => (index.h("div", { key: index$1, class: "swiper-slide" }, index.h("img", { src: image.url, alt: image.alt || `${this.product?.name} - Image ${index$1 + 1}`, loading: "lazy", onError: e => {
|
|
6995
|
+
e.target.style.display = 'none';
|
|
6996
|
+
} }))))), this.product?.images && this.product?.images.length > 1 && (index.h("div", { key: '5d0f67677595c442d76f0fb3a42dacb1996e58db', slot: "thumbs" }, this.product?.images &&
|
|
6997
|
+
this.product?.images.map((image, index$1) => (index.h("div", { key: index$1, "data-caption": `${this.product?.name} - Image ${index$1 + 1}` }, index.h("img", { src: image.url, loading: "eager", class: "s-multiple-bundle-product-options-modal-slider-thumb", title: `${this.product?.name} - ${index$1 + 1}`, alt: image.alt || `${this.product?.name} - ${index$1 + 1}`, onError: e => {
|
|
6998
|
+
e.target.style.display = 'none';
|
|
6999
|
+
} })))))))), index.h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${this.sectionId}-${this.sectionIndex}-${productId}-persistent`, "product-id": productId }), index.h("div", { key: '1f166bdaf78a78b99aeecc141e6f99b9fa1e50b1', slot: "footer" }, index.h("div", { key: 'e4ea869eaf9690ee3aba7319f976a82f8187767e', class: "s-multiple-bundle-product-options-modal-footer" }, index.h("salla-button", { key: '17e4f97284528019b25bd640ff3843dbbefb5dae', onClick: e => this.onSave(e), loading: this.isLoading, disabled: this.isLoading }, this.isLoading
|
|
7000
|
+
? salla.lang.get('common.elements.saving')
|
|
7001
|
+
: salla.lang.get('common.elements.save')))))));
|
|
7002
|
+
}
|
|
7003
|
+
get host() { return index.getElement(this); }
|
|
7004
|
+
static get watchers() { return {
|
|
7005
|
+
"product": ["handleProductChange"]
|
|
7006
|
+
}; }
|
|
7007
|
+
};
|
|
7008
|
+
SallaMultipleBundleProductOptionsModal.style = sallaMultipleBundleProductOptionsModalCss;
|
|
7009
|
+
|
|
7010
|
+
const sallaMultipleBundleProductSliderCss = "";
|
|
7011
|
+
|
|
7012
|
+
const SallaMultipleBundleProductSlider = class {
|
|
7013
|
+
constructor(hostRef) {
|
|
7014
|
+
index.registerInstance(this, hostRef);
|
|
7015
|
+
this.productSelected = index.createEvent(this, "productSelected");
|
|
7016
|
+
this.productOptionsSelected = index.createEvent(this, "productOptionsSelected");
|
|
7017
|
+
this.selectedProducts = {};
|
|
7018
|
+
this.handleProductClick = (product, productIndex) => {
|
|
7019
|
+
// Find the checkbox input for this product
|
|
7020
|
+
const checkboxId = this.generateEventName(this.section.id, productIndex);
|
|
7021
|
+
const checkbox = document.getElementById(checkboxId);
|
|
7022
|
+
if (!checkbox)
|
|
7023
|
+
return;
|
|
7024
|
+
if (checkbox) {
|
|
7025
|
+
// Toggle the checkbox state
|
|
7026
|
+
checkbox.checked = !checkbox.checked;
|
|
7027
|
+
// Dispatch a change event to trigger form validation/submission
|
|
7028
|
+
const changeEvent = new window.Event('change', { bubbles: true });
|
|
7029
|
+
checkbox.dispatchEvent(changeEvent);
|
|
7030
|
+
}
|
|
7031
|
+
this.productSelected.emit({
|
|
7032
|
+
product,
|
|
7033
|
+
sectionId: this.section.id,
|
|
7034
|
+
});
|
|
7035
|
+
};
|
|
7036
|
+
this.handleOptionsClick = (product) => {
|
|
7037
|
+
this.productOptionsSelected.emit({
|
|
7038
|
+
product,
|
|
7039
|
+
sectionId: this.section.id,
|
|
7040
|
+
});
|
|
7041
|
+
};
|
|
7042
|
+
}
|
|
7043
|
+
generateEventName(sectionId, productIndex) {
|
|
7044
|
+
return `bundle[${sectionId}][${productIndex}][id]`;
|
|
7045
|
+
}
|
|
7046
|
+
render() {
|
|
7047
|
+
return (index.h(index.Host, { key: '8c1d316ceeb7a0833d689695f00569a0da1d642e' }, index.h("salla-slider", { key: 'ca86cee09dc4f8c48edf14bfb4a26b86982fd84d', type: "carousel", controlsOuter: false, showControls: false, id: "accordion-multiple-bundle-product", pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: {
|
|
7048
|
+
spaceBetween: 0,
|
|
7049
|
+
} }, index.h("div", { key: 'b59ac0393f6e826658dcca7eef8c2c21019664d4', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
|
|
7050
|
+
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
|
|
7051
|
+
return (index.h("div", { class: `swiper-slide s-multiple-bundle-product-slide-one-third ${product.quantity == 0
|
|
7052
|
+
? 's-multiple-bundle-product-slide-one-third-disabled'
|
|
7053
|
+
: ''}`, key: product.id }, index.h("div", { class: "s-multiple-bundle-product-card" }, index.h("div", { class: "s-multiple-bundle-product-image-wrapper", onClick: () => this.handleProductClick(product, productIndex) }, index.h("input", { id: this.generateEventName(this.section.id, productIndex), type: "checkbox", class: "s-multiple-bundle-product-checkbox", checked: isChecked, name: this.generateEventName(this.section.id, productIndex), value: product.id }), index.h("img", { src: product.image.url || salla.url.cdn('images/s-empty.png'), loading: "lazy", alt: product.image.alt || product.name, class: "s-multiple-bundle-product-image" })), index.h("div", { class: "s-multiple-bundle-product-content-wrapper" }, index.h("div", { class: "s-multiple-bundle-product-content" }, index.h("div", { class: "s-multiple-bundle-product-details" }, index.h("div", { class: "s-multiple-bundle-product-title-wrapper" }, index.h("h2", { class: "s-multiple-bundle-product-title" }, product.name)), index.h("div", { class: "s-multiple-bundle-product-price-wrapper" }, index.h("span", { class: "s-multiple-bundle-product-price" }, index.h("span", { innerHTML: salla.money(product.price) })), product.sale_price > 0 && (index.h("span", { class: "s-multiple-bundle-product-price-discount" }, index.h("span", { innerHTML: salla.money(product.sale_price) }))))), product.quantity_in_group > 0 && product.quantity !== 0 && (index.h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.pieces'), index.h("span", null, product.quantity_in_group))), product.quantity === 0 && (index.h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.quantity_in_group_finished')))), product.options?.length > 0 && (index.h("button", { class: "s-multiple-bundle-product-button", onClick: () => this.handleOptionsClick(product), type: "button" }, salla.lang.get('pages.products.choose_from_options'), index.h("i", { class: "sicon-keyboard_arrow_left s-multiple-bundle-product-button-icon" })))))));
|
|
7054
|
+
})))));
|
|
7055
|
+
}
|
|
7056
|
+
get host() { return index.getElement(this); }
|
|
7057
|
+
};
|
|
7058
|
+
SallaMultipleBundleProductSlider.style = sallaMultipleBundleProductSliderCss;
|
|
7059
|
+
|
|
7060
|
+
var Tag = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
7061
|
+
<title>tag</title>
|
|
7062
|
+
<path d="M28 0h-9.344c-1.059 0-2.056 0.411-2.809 1.153l-14.673 14.456c-1.56 1.56-1.561 4.097-0.001 5.657l9.56 9.56c0.755 0.755 1.76 1.172 2.828 1.173h0.003c1.068 0 2.072-0.416 2.833-1.179l14.451-14.668c0.743-0.753 1.153-1.751 1.153-2.809v-9.344c0-2.205-1.795-4-4-4zM29.333 13.344c0 0.353-0.137 0.685-0.385 0.937l-14.444 14.661c-0.252 0.252-0.587 0.391-0.941 0.391-0.001 0-0.001 0-0.001 0-0.356-0.001-0.691-0.139-0.943-0.392l-9.561-9.56c-0.52-0.52-0.52-1.365-0.005-1.88l14.667-14.449c0.253-0.248 0.585-0.385 0.937-0.385h9.344c0.736 0 1.333 0.597 1.333 1.333zM24 6.673c-0.737 0-1.333 0.604-1.333 1.341s0.596 1.333 1.333 1.333 1.333-0.596 1.333-1.333v-0.015c0-0.737-0.596-1.327-1.333-1.327z"></path>
|
|
7063
|
+
</svg>
|
|
7064
|
+
`;
|
|
7065
|
+
|
|
7066
|
+
var Cart2 = `<!-- Generated by IcoMoon.io -->
|
|
7067
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
7068
|
+
<title>cart2</title>
|
|
7069
|
+
<path d="M6.845 5.333l-1.905-5.333h-3.607c-0.736 0-1.333 0.597-1.333 1.333s0.597 1.333 1.333 1.333v0h1.727l5.72 16.012c0.569 1.56 2.039 2.654 3.765 2.655h12.133c0.001 0 0.002 0 0.003 0 1.825 0 3.364-1.222 3.845-2.892l0.007-0.028 3.161-13.080zM25.96 17.716c-0.167 0.554-0.672 0.951-1.27 0.951-0.002 0-0.005 0-0.007-0h-12.133c-0.575-0-1.065-0.364-1.252-0.875l-0.003-0.009-3.497-9.783h20.508zM13.333 24c-2.209 0-4 1.791-4 4s1.791 4 4 4c2.209 0 4-1.791 4-4v0c0-2.209-1.791-4-4-4v0zM13.333 29.333c-0.736 0-1.333-0.597-1.333-1.333s0.597-1.333 1.333-1.333c0.736 0 1.333 0.597 1.333 1.333v0c0 0.736-0.597 1.333-1.333 1.333v0zM24 24c-2.209 0-4 1.791-4 4s1.791 4 4 4c2.209 0 4-1.791 4-4v0c0-2.209-1.791-4-4-4v0zM24 29.333c-0.736 0-1.333-0.597-1.333-1.333s0.597-1.333 1.333-1.333c0.736 0 1.333 0.597 1.333 1.333v0c0 0.736-0.597 1.333-1.333 1.333v0z"></path>
|
|
7070
|
+
</svg>
|
|
7071
|
+
`;
|
|
7072
|
+
|
|
7073
|
+
const sallaOfferModalCss = ".s-offer-modal-type-products .s-modal-body{min-height:690px;position:relative}";
|
|
7074
|
+
|
|
7075
|
+
const SallaOfferModal = class {
|
|
7076
|
+
constructor(hostRef) {
|
|
7077
|
+
index.registerInstance(this, hostRef);
|
|
7078
|
+
this.offer = null;
|
|
7079
|
+
this.hasError = false;
|
|
7080
|
+
this.translationLoaded = false;
|
|
7081
|
+
this.addToCartLabel = salla.lang.get("pages.cart.add_to_cart");
|
|
7082
|
+
salla.event.on('offer-modal::open', product_id => this.open(product_id));
|
|
7083
|
+
salla.lang.onLoaded(() => {
|
|
7084
|
+
this.addToCartLabel = salla.lang.get("pages.cart.add_to_cart");
|
|
7085
|
+
this.translationLoaded = true;
|
|
7086
|
+
});
|
|
7087
|
+
this.categorySlot = this.host.querySelector('[slot="category"]')?.innerHTML || `<span class="s-offer-modal-badge-icon">{tagIcon}</span><span class="s-offer-modal-badge-text">{name}</span>`;
|
|
7088
|
+
// this.productSlot = this.host.querySelector('[slot="product"]')?.innerHTML || this.defaultProductSlot();
|
|
7089
|
+
salla.event.on('offer-modal::open', product_id => this.open(product_id));
|
|
7090
|
+
salla.product.event.onOfferExisted(offer => {
|
|
7091
|
+
if (salla.storage.get('remember-offer-' + offer.id)) {
|
|
7092
|
+
salla.log('User selected to don\'t show this offer again.');
|
|
7093
|
+
return;
|
|
7094
|
+
}
|
|
7095
|
+
this.open(offer.product_id);
|
|
7096
|
+
});
|
|
7097
|
+
}
|
|
7098
|
+
/**
|
|
7099
|
+
* Emits a promotion viewed event for analytics tracking
|
|
7100
|
+
* @param offer - The offer being viewed in the modal
|
|
7101
|
+
*/
|
|
7102
|
+
emitPromotionViewed(offer) {
|
|
7103
|
+
if (!offer)
|
|
7104
|
+
return;
|
|
7105
|
+
salla.event.emit('promotion::viewed', [{
|
|
7106
|
+
id: offer.id?.toString(),
|
|
7107
|
+
creative: offer.message,
|
|
7108
|
+
name: offer.name,
|
|
7109
|
+
position: `${this.offer_type}_offer_modal`
|
|
7110
|
+
}]);
|
|
7111
|
+
}
|
|
7112
|
+
/**
|
|
7113
|
+
* Emits a promotion clicked event for analytics tracking
|
|
7114
|
+
* @param offer - The offer being clicked in the modal
|
|
7115
|
+
*/
|
|
7116
|
+
emitPromotionClicked(offer) {
|
|
7117
|
+
if (!offer)
|
|
7118
|
+
return;
|
|
7119
|
+
salla.event.emit('promotion::clicked', [{
|
|
7120
|
+
id: offer.id?.toString(),
|
|
7121
|
+
creative: offer.message,
|
|
7122
|
+
name: offer.name,
|
|
7123
|
+
position: `${this.offer_type}_offer_modal`
|
|
7124
|
+
}]);
|
|
7125
|
+
}
|
|
7126
|
+
/**
|
|
7127
|
+
* Show the available offers for the product
|
|
7128
|
+
* @param product_id
|
|
7129
|
+
*/
|
|
7130
|
+
async open(product_id) {
|
|
7131
|
+
this.productID = product_id;
|
|
7132
|
+
//TODO:: make sure there is only one offer
|
|
7133
|
+
this.hasError = false;
|
|
7134
|
+
this.modal.open();
|
|
7135
|
+
return await salla.api.withoutNotifier(() => salla.product.offers(product_id))
|
|
7136
|
+
.then(response => this.showOffer(response.data[0]))
|
|
5940
7137
|
.catch(e => {
|
|
5941
7138
|
this.hasError = true;
|
|
5942
7139
|
this.errorMessage = e.response?.data?.error?.message || e.response?.data;
|
|
@@ -6031,7 +7228,7 @@ const SallaOfferModal = class {
|
|
|
6031
7228
|
// '</div>';
|
|
6032
7229
|
// }
|
|
6033
7230
|
render() {
|
|
6034
|
-
return index.h("salla-modal", { key: '
|
|
7231
|
+
return index.h("salla-modal", { key: '6dce27c3f20b031aa33b7e15980c55af84d1c9f6', "has-skeleton": true, "sub-title": this.offer_message, ref: modal => this.modal = modal, isLoading: true, class: `s-offer-modal-type-${this.offer_type ? this.offer_type : ''}` }, index.h("div", { key: '1f63aa0fd3a95ba54e8ed5168f1439f4cafce036', slot: 'loading' }, index.h("div", { key: '748de710f2ad5c6c60a9e324d1e1b44672dee28f', class: "s-offer-modal-skeleton" }, index.h("div", { key: '96d6d1d8edc3e511c87eaa44539617d529e8a3e0', class: "s-offer-modal-skeleton-header" }, index.h("salla-skeleton", { key: '1abe6ddf5096af877c9ce59dfbcdecb08a263e4b', type: 'circle', height: '80px', width: '80px' }), index.h("salla-skeleton", { key: '7010a9056b168f4df7168a55dbfde1da2726c913', height: '15px', width: '50%' }), index.h("salla-skeleton", { key: '4168b53b7a4358240f8f6d4d3b9f9a999992ddcb', height: '10px', width: '30%' })), index.h("div", { key: 'd019372cebf6d3e4d80842fa48e3ce1433457f06', class: "s-offer-modal-skeleton-items" }, [...Array(3)].map(() => index.h("div", { class: "s-offer-modal-skeleton-item" }, index.h("salla-skeleton", { height: '9rem' }), index.h("div", { class: "s-offer-modal-skeleton-item-title" }, index.h("salla-skeleton", { height: '15px', width: '100%' })), index.h("div", { class: "s-offer-modal-skeleton-item-subtitle" }, index.h("salla-skeleton", { height: '9px', width: '50%' }), index.h("div", { innerHTML: Cart2 }))))), index.h("div", { key: '4cbc9f99a98ccc9ea27f41e50fa037ea44d85048', class: "s-offer-modal-skeleton-footer" }, index.h("salla-skeleton", { key: '467546d4ded93cd95a7be78e6dd39935a20867c8', height: '15px', width: '50%' }), index.h("salla-skeleton", { key: '399a4a4ebedcc54def70ff428f3c5f24fd98a775', height: '15px', width: '30%' })))), !this.hasError && this.offer !== null
|
|
6035
7232
|
? [index.h("span", { slot: 'icon', class: "s-offer-modal-header-icon", innerHTML: specialDiscount.SpecialDiscountIcon }), this.getOfferContent(), index.h("div", { class: "s-offer-modal-footer", slot: "footer" }, this.offer.formatted_date ?
|
|
6036
7233
|
index.h("p", { class: "s-offer-modal-expiry" }, salla.lang.get('pages.products.offer_expires_in'), " ", this.offer.formatted_date)
|
|
6037
7234
|
: '', index.h("label", { class: "s-offer-modal-remember-label" }, index.h("input", { type: "checkbox", onChange: e => this.rememberMe(e), class: "s-offer-modal-remember-input" }), "\u00A0 ", salla.lang.get('common.elements.remember_my_choice'))),
|
|
@@ -6080,7 +7277,7 @@ const SallaPlaceholder = class {
|
|
|
6080
7277
|
};
|
|
6081
7278
|
}
|
|
6082
7279
|
render() {
|
|
6083
|
-
return (index.h(index.Host, { key: '
|
|
7280
|
+
return (index.h(index.Host, { key: '9bf5c9b70ee7dddc65bdb550f98681aa6eb4a2b1', class: this.alignmentClass() }, index.h("div", { key: '05bf79dd66fb30d76ffe05ea50b66d1bab976bb0', class: `s-placeholder-icon s-placeholder-icon-${this.iconSize}`, innerHTML: this.icon }), index.h("div", { key: '1373cfaad7e993e6cc888047346348083ee8bf7e', class: "s-placeholder-title" }, index.h("slot", { key: '5a6d70c7fee74334cf46143511bf2465e32025be', name: 'title' }, index.h("span", { key: '5b531362a3dea0a8a59960a28925c03bdfc64f82' }, salla.lang.get('common.elements.no_options')))), index.h("div", { key: 'd9d0c28b47f7c2972817630a9011e17116fa66c8', class: "s-placeholder-description" }, index.h("slot", { key: '0b67052476e584464107d56b4c8f263cfebaac87', name: 'description' }, index.h("span", { key: '61b16c16799ce96a53eca32936c8d49b2e81ff03' }, salla.lang.get('common.errors.empty_results'))))));
|
|
6084
7281
|
}
|
|
6085
7282
|
};
|
|
6086
7283
|
SallaPlaceholder.style = sallaPlaceholderCss;
|
|
@@ -6222,7 +7419,7 @@ const SallaProductAvailability = class {
|
|
|
6222
7419
|
field.nextElementSibling['innerText'] = '* ' + errorMsg;
|
|
6223
7420
|
}
|
|
6224
7421
|
render() {
|
|
6225
|
-
return (index.h(index.Host, { key: '
|
|
7422
|
+
return (index.h(index.Host, { key: '631de4fa7186561daed53943f2ece491a8dbe934', class: "s-product-availability-wrap" }, this.isSubscribed || this.isVisitorSubscribed
|
|
6226
7423
|
? index.h("div", { class: "s-product-availability-subscribed" }, index.h("span", { innerHTML: BellRing, class: "s-product-availability-subs-icon" }), salla.lang.get('pages.products.notify_availability_success'))
|
|
6227
7424
|
:
|
|
6228
7425
|
index.h("salla-button", { width: "wide", onClick: () => this.isUser ? this.submit() : this.openModel() }, salla.lang.get('pages.products.notify_availability')), this.isUser || this.isSubscribed || this.isVisitorSubscribed ? '' : this.renderModal()));
|
|
@@ -6338,14 +7535,14 @@ const SallaProductCard = class {
|
|
|
6338
7535
|
's-product-card-out-of-stock': this.productData?.is_out_of_stock,
|
|
6339
7536
|
};
|
|
6340
7537
|
const hrefProp = this.productData?.url ? { href: this.productData.url, title: `Learn more about ${this.productData?.name}` } : {};
|
|
6341
|
-
return (index.h(index.Host, { key: '
|
|
7538
|
+
return (index.h(index.Host, { key: 'e46cba8a24104176d7a95c02ead575a6fa360783', id: `product-${this.productData?.id}`, class: classes }, index.h("div", { key: '6370f6a5ca0a63ab4f4d97492ef1f8911ef82bda', class: !this.fullImage ? 's-product-card-image' : 's-product-card-image-full' }, index.h("a", { key: '37f2f82fa1c500e9cdb4a0aabe570429b9b9daaa', ...hrefProp }, index.h("img", { key: '4ce43329b5a44b4d5ef174469c510ef28d547440', class: `s-product-card-image-${salla.url.is_placeholder(this.productData?.image?.url)
|
|
6342
7539
|
? 'contain'
|
|
6343
7540
|
: this.fitImageHeight
|
|
6344
7541
|
? this.fitImageHeight
|
|
6345
|
-
: 'cover'} lazy`, src: this.placeholder, alt: this.productData?.image?.alt || this.productData?.name, "data-src": this.productData?.image?.url || this.productData?.thumbnail }), !this.fullImage && !this.minimal ? this.getProductBadge() : ''), this.fullImage && index.h("a", { key: '
|
|
6346
|
-
index.h("salla-button", { shape: "icon", fill: "none", color: "light", "aria-label": "Add or remove to wishlist", ref: el => this.wishlistBtn = el, class: "s-product-card-wishlist-btn animated", onClick: () => salla.wishlist.toggle(this.productData.id) }, index.h("span", { innerHTML: Heart })) : ''), index.h("div", { key: '
|
|
7542
|
+
: 'cover'} lazy`, src: this.placeholder, alt: this.productData?.image?.alt || this.productData?.name, "data-src": this.productData?.image?.url || this.productData?.thumbnail }), !this.fullImage && !this.minimal ? this.getProductBadge() : ''), this.fullImage && index.h("a", { key: '87a4e4caafb0edba3c634ff5760ae0556a510d3c', ...hrefProp, class: "s-product-card-overlay" }), !this.horizontal && !this.fullImage ?
|
|
7543
|
+
index.h("salla-button", { shape: "icon", fill: "none", color: "light", "aria-label": "Add or remove to wishlist", ref: el => this.wishlistBtn = el, class: "s-product-card-wishlist-btn animated", onClick: () => salla.wishlist.toggle(this.productData.id) }, index.h("span", { innerHTML: Heart })) : ''), index.h("div", { key: '7cb392ea3fe61d41d5ba5a36650725545ddd3cf8', class: "s-product-card-content" }, this.isSpecial && this.productData?.quantity ?
|
|
6347
7544
|
index.h("div", { class: "s-product-card-content-pie", ref: pie => this.pie = pie }, index.h("span", null, index.h("b", null, salla.helpers.number(this.productData?.quantity)), this.remained), index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "-2 -1 36 34", class: "s-product-card-content-pie-svg" }, index.h("circle", { cx: "16", cy: "16", r: "15.9155", class: "s-product-card-content-pie-svg-base" }), index.h("circle", { cx: "16", cy: "16", r: "15.9155", class: "s-product-card-content-pie-svg-bar" })))
|
|
6348
|
-
: '', index.h("div", { key: '
|
|
7545
|
+
: '', index.h("div", { key: '28322ef080ae243b55ed4c982f59226159b81d6b', class: { 's-product-card-content-main': true, 's-product-card-content-extra-padding': this.isSpecial } }, index.h("h3", { key: 'dc378461ca91f1af0c29b35271e8f6b76321f133', class: "s-product-card-content-title" }, index.h("a", { key: '1bf4c4cf4d04ebb4990053d9721581b276083f30', ...hrefProp }, this.productData?.name)), this.productData?.subtitle && !this.minimal ?
|
|
6349
7546
|
index.h("p", { class: "s-product-card-content-subtitle" }, this.productData?.subtitle)
|
|
6350
7547
|
: ''), this.productData?.donation && !this.minimal && !this.fullImage ?
|
|
6351
7548
|
[index.h("salla-progress-bar", { donation: this.productData?.donation }), index.h("div", { class: "s-product-card-donation-input" }, this.productData?.donation?.can_donate ?
|
|
@@ -6354,7 +7551,7 @@ const SallaProductCard = class {
|
|
|
6354
7551
|
this.addBtn.donatingAmount = e.target.value;
|
|
6355
7552
|
}, id: "donation-amount", name: "donating_amount", class: "s-form-control", placeholder: this.donationAmount })]
|
|
6356
7553
|
: '')]
|
|
6357
|
-
: '', index.h("div", { key: '
|
|
7554
|
+
: '', index.h("div", { key: '86474ac2519b7589053b39dc36ae316ad64c8e29', class: { 's-product-card-content-sub': true, 's-product-card-content-extra-padding': this.isSpecial } }, this.getProductPrice(), this.productData?.rating?.stars && !this.minimal ?
|
|
6358
7555
|
index.h("div", { class: "s-product-card-rating" }, index.h("span", { innerHTML: Rate }), index.h("span", null, this.productData.rating.stars))
|
|
6359
7556
|
: ''), this.isSpecial && this.productData.discount_ends
|
|
6360
7557
|
? index.h("salla-count-down", { date: this.formatDate(this.productData.discount_ends), "end-of-day": true, boxed: true, labeled: true })
|
|
@@ -6378,6 +7575,782 @@ const SallaProductCard = class {
|
|
|
6378
7575
|
};
|
|
6379
7576
|
SallaProductCard.style = sallaProductCardCss;
|
|
6380
7577
|
|
|
7578
|
+
var DisplayType;
|
|
7579
|
+
(function (DisplayType) {
|
|
7580
|
+
DisplayType["COLOR"] = "color";
|
|
7581
|
+
DisplayType["DATE"] = "date";
|
|
7582
|
+
DisplayType["DATETIME"] = "datetime";
|
|
7583
|
+
DisplayType["DONATION"] = "donation";
|
|
7584
|
+
DisplayType["IMAGE"] = "image";
|
|
7585
|
+
DisplayType["MULTIPLE_OPTIONS"] = "multiple-options";
|
|
7586
|
+
DisplayType["NUMBER"] = "number";
|
|
7587
|
+
DisplayType["SINGLE_OPTION"] = "single-option";
|
|
7588
|
+
DisplayType["DIGITAL_CARD_VALUE"] = "digital-code-value";
|
|
7589
|
+
DisplayType["COUNTRY"] = "country";
|
|
7590
|
+
DisplayType["SPLITTER"] = "splitter";
|
|
7591
|
+
DisplayType["TEXT"] = "text";
|
|
7592
|
+
DisplayType["TEXTAREA"] = "textarea";
|
|
7593
|
+
DisplayType["THUMBNAIL"] = "thumbnail";
|
|
7594
|
+
DisplayType["TIME"] = "time";
|
|
7595
|
+
DisplayType["RADIO"] = "radio";
|
|
7596
|
+
DisplayType["CHECKBOX"] = "checkbox";
|
|
7597
|
+
DisplayType["MAP"] = "map";
|
|
7598
|
+
DisplayType["FILE"] = "file";
|
|
7599
|
+
DisplayType["COLOR_PICKER"] = "color_picker";
|
|
7600
|
+
DisplayType["BOOKING"] = "booking";
|
|
7601
|
+
})(DisplayType || (DisplayType = {}));
|
|
7602
|
+
var Currency;
|
|
7603
|
+
(function (Currency) {
|
|
7604
|
+
Currency["Sar"] = "SAR";
|
|
7605
|
+
})(Currency || (Currency = {}));
|
|
7606
|
+
|
|
7607
|
+
var CameraIcon = `<!-- Generated by IcoMoon.io -->
|
|
7608
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
7609
|
+
<title>camera</title>
|
|
7610
|
+
<path d="M16 10.667c-4.044 0-7.333 3.289-7.333 7.333s3.289 7.333 7.333 7.333 7.333-3.289 7.333-7.333-3.289-7.333-7.333-7.333zM16 22.667c-2.573 0-4.667-2.093-4.667-4.667s2.093-4.667 4.667-4.667 4.667 2.093 4.667 4.667-2.093 4.667-4.667 4.667zM28 5.333h-3.287l-2.271-3.407c-0.248-0.371-0.664-0.593-1.109-0.593h-10.667c-0.445 0-0.861 0.223-1.109 0.593l-2.271 3.407h-3.287c-2.205 0-4 1.795-4 4v17.333c0 2.205 1.795 4 4 4h24c2.205 0 4-1.795 4-4v-17.333c0-2.205-1.795-4-4-4zM29.333 26.667c0 0.735-0.599 1.333-1.333 1.333h-24c-0.735 0-1.333-0.599-1.333-1.333v-17.333c0-0.735 0.599-1.333 1.333-1.333h4c0.445 0 0.861-0.223 1.109-0.593l2.272-3.407h9.239l2.271 3.407c0.248 0.371 0.664 0.593 1.109 0.593h4c0.735 0 1.333 0.599 1.333 1.333zM25.333 10.66c-0.736 0-1.333 0.604-1.333 1.34s0.597 1.333 1.333 1.333 1.333-0.597 1.333-1.333v-0.013c0-0.736-0.597-1.327-1.333-1.327z"></path>
|
|
7611
|
+
</svg>
|
|
7612
|
+
`;
|
|
7613
|
+
|
|
7614
|
+
var FileIcon = `<!-- Generated by IcoMoon.io -->
|
|
7615
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
7616
|
+
<title>file-upload</title>
|
|
7617
|
+
<path d="M21.333 24c0.341 0 0.683-0.131 0.943-0.391 0.521-0.521 0.521-1.364 0-1.885l-5.333-5.333c-0.123-0.123-0.271-0.22-0.433-0.288-0.327-0.135-0.693-0.135-1.019 0-0.163 0.068-0.311 0.165-0.433 0.288l-5.333 5.333c-0.521 0.521-0.521 1.364 0 1.885s1.364 0.521 1.885 0l3.057-3.057v10.115c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-10.115l3.057 3.057c0.26 0.26 0.601 0.391 0.943 0.391zM28.943 9.724l-9.333-9.333c-0.249-0.251-0.589-0.391-0.943-0.391h-12c-2.205 0-4 1.795-4 4v24c0 2.205 1.795 4 4 4h4c0.736 0 1.333-0.597 1.333-1.333s-0.597-1.333-1.333-1.333h-4c-0.735 0-1.333-0.599-1.333-1.333v-24c0-0.735 0.599-1.333 1.333-1.333h11.448l8.552 8.552v16.781c0 0.735-0.599 1.333-1.333 1.333h-4c-0.736 0-1.333 0.597-1.333 1.333s0.597 1.333 1.333 1.333h4c2.205 0 4-1.795 4-4v-17.333c0-0.353-0.14-0.693-0.391-0.943z"></path>
|
|
7618
|
+
</svg>
|
|
7619
|
+
`;
|
|
7620
|
+
|
|
7621
|
+
const sallaProductOptionsCss = "";
|
|
7622
|
+
|
|
7623
|
+
const SallaProductOptions = class {
|
|
7624
|
+
constructor(hostRef) {
|
|
7625
|
+
index.registerInstance(this, hostRef);
|
|
7626
|
+
this.changed = index.createEvent(this, "changed");
|
|
7627
|
+
this.fileTypes = {
|
|
7628
|
+
pdf: 'application/pdf',
|
|
7629
|
+
png: 'image/png',
|
|
7630
|
+
jpg: 'image/jpeg',
|
|
7631
|
+
word: 'application/doc,application/ms-doc,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
7632
|
+
exl: 'application/excel,application/vnd.ms-excel,application/x-excel,application/x-msexcel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
7633
|
+
txt: 'text/plain',
|
|
7634
|
+
};
|
|
7635
|
+
this.outOfStockText = "";
|
|
7636
|
+
this.donationAmount = salla.lang.get('pages.products.donation_amount');
|
|
7637
|
+
this.selectDonationAmount = salla.lang.getWithDefault('pages.products.select_donation_amount', 'تحديد مبلغ التبرع');
|
|
7638
|
+
this.selectAmount = salla.lang.getWithDefault('pages.products.select_amount', 'اختر المبلغ');
|
|
7639
|
+
this.isCustomDonation = false;
|
|
7640
|
+
this.selectedOptions = [];
|
|
7641
|
+
this.disableCardValue = true;
|
|
7642
|
+
this.availableDigitalCardValues = [];
|
|
7643
|
+
this.userInitiatedValidation = false;
|
|
7644
|
+
this.outSkus = [];
|
|
7645
|
+
/**
|
|
7646
|
+
* Avoid selection of previous default or selected card value option
|
|
7647
|
+
* when switching between digital card country options for the 1st time
|
|
7648
|
+
*/
|
|
7649
|
+
this.ignoreDefaultCardValue = false;
|
|
7650
|
+
/**
|
|
7651
|
+
* The id of the product to which the options are going to be fetched for.
|
|
7652
|
+
*/
|
|
7653
|
+
this.productId = salla.config.get('page.id');
|
|
7654
|
+
this.handleDonationOptions = (event, detail, type) => {
|
|
7655
|
+
if (detail === 'custom' && type === 'input') {
|
|
7656
|
+
salla.helpers.inputDigitsOnly(event.target);
|
|
7657
|
+
salla.event.emit('product-options::donation-changed', {
|
|
7658
|
+
id: this.productId,
|
|
7659
|
+
price: event.target.value
|
|
7660
|
+
});
|
|
7661
|
+
return;
|
|
7662
|
+
}
|
|
7663
|
+
event.preventDefault();
|
|
7664
|
+
event.stopPropagation();
|
|
7665
|
+
this.isCustomDonation = event.target.value === 'custom';
|
|
7666
|
+
if (this.donationInput) {
|
|
7667
|
+
if (event.target.value === 'custom') {
|
|
7668
|
+
this.donationInput.value = '';
|
|
7669
|
+
this.donationInput.focus();
|
|
7670
|
+
}
|
|
7671
|
+
else {
|
|
7672
|
+
this.donationInput.value = event.target.value;
|
|
7673
|
+
}
|
|
7674
|
+
if (detail === 'custom') {
|
|
7675
|
+
return;
|
|
7676
|
+
}
|
|
7677
|
+
salla.event.emit('product-options::donation-changed', {
|
|
7678
|
+
id: this.productId,
|
|
7679
|
+
price: event.target.value
|
|
7680
|
+
});
|
|
7681
|
+
}
|
|
7682
|
+
};
|
|
7683
|
+
this.hideLabel = (option) => {
|
|
7684
|
+
if (option.type === DisplayType.DONATION && (option.donation && !option.donation.can_donate)) {
|
|
7685
|
+
return true;
|
|
7686
|
+
}
|
|
7687
|
+
return false;
|
|
7688
|
+
};
|
|
7689
|
+
this.getExpireDonationMessage = (option) => {
|
|
7690
|
+
if (!option.donation) {
|
|
7691
|
+
return;
|
|
7692
|
+
}
|
|
7693
|
+
const completed = option.donation.target_amount <= option.donation.collected_amount;
|
|
7694
|
+
return index.h("div", { class: { "s-product-options-donation-message": true, "s-product-options-donation-completed": completed, "s-product-options-donation-expired": !completed } }, index.h("p", null, option.donation.target_message), index.h("span", { innerHTML: completed ? salla.money(option.donation.target_amount) : '' }));
|
|
7695
|
+
};
|
|
7696
|
+
this.canDisabled = !salla.config.get('store.settings.product.notify_options_availability') || salla.url.is_page('cart');
|
|
7697
|
+
salla.lang.onLoaded(() => {
|
|
7698
|
+
this.outOfStockText = salla.lang.get("pages.products.out_of_stock");
|
|
7699
|
+
this.donationAmount = salla.lang.get('pages.products.donation_amount');
|
|
7700
|
+
this.selectDonationAmount = salla.lang.getWithDefault('pages.products.select_donation_amount', 'تحديد مبلغ التبرع');
|
|
7701
|
+
this.selectAmount = salla.lang.getWithDefault('pages.products.select_amount', 'اختر المبلغ');
|
|
7702
|
+
});
|
|
7703
|
+
if (this.options) {
|
|
7704
|
+
try {
|
|
7705
|
+
this.setOptionsData(Array.isArray(this.options) ? this.options : JSON.parse(this.options));
|
|
7706
|
+
return;
|
|
7707
|
+
}
|
|
7708
|
+
catch (e) {
|
|
7709
|
+
salla.log('Bad json passed via options prop');
|
|
7710
|
+
}
|
|
7711
|
+
}
|
|
7712
|
+
if (!Array.isArray(this.optionsData)) {
|
|
7713
|
+
salla.log('Options is not an array[] ---> ', this.optionsData);
|
|
7714
|
+
this.setOptionsData([]);
|
|
7715
|
+
}
|
|
7716
|
+
if (this.productId && !salla.url.is_page('cart')) {
|
|
7717
|
+
salla.api.product.getDetails(this.productId, ['options']).then(resp => this.setOptionsData(resp.data.options));
|
|
7718
|
+
}
|
|
7719
|
+
}
|
|
7720
|
+
/**
|
|
7721
|
+
* Sets the options data for the product
|
|
7722
|
+
* @param optionsData - Array of product options
|
|
7723
|
+
*/
|
|
7724
|
+
async setOptionsData(optionsData) {
|
|
7725
|
+
this.optionsData = optionsData;
|
|
7726
|
+
const that = this;
|
|
7727
|
+
this.optionsData[0]?.details?.forEach(function (detail) {
|
|
7728
|
+
Object.entries(detail.skus_availability || {})
|
|
7729
|
+
.filter(sku => !sku[1])
|
|
7730
|
+
.map(sku => that.outSkus.push(Number(sku[0])));
|
|
7731
|
+
});
|
|
7732
|
+
}
|
|
7733
|
+
/**
|
|
7734
|
+
* Get the id's of the selected options.
|
|
7735
|
+
* */
|
|
7736
|
+
async getSelectedOptionsData() {
|
|
7737
|
+
const selectedOptions = {};
|
|
7738
|
+
const formData = this.host.getElementSallaData();
|
|
7739
|
+
// Check if bundleContext is defined as a prop on the component before accessing it
|
|
7740
|
+
const contextData = (typeof this.bundleContext !== 'undefined') ? this.bundleContext : null;
|
|
7741
|
+
formData.forEach((value, key) => {
|
|
7742
|
+
if (contextData) {
|
|
7743
|
+
// Handle bundle naming convention: bundle[sectionId][index][options][optionId]
|
|
7744
|
+
if (key.startsWith('bundle[') && key.includes('[options][')) {
|
|
7745
|
+
const optionId = key.split('[options][')[1].replace(']', '');
|
|
7746
|
+
selectedOptions[optionId] = value;
|
|
7747
|
+
}
|
|
7748
|
+
}
|
|
7749
|
+
else {
|
|
7750
|
+
// Handle standard naming convention: options[optionId]
|
|
7751
|
+
if (key.startsWith('options[')) {
|
|
7752
|
+
selectedOptions[key.replace('options[', '').replace(']', '')] = value;
|
|
7753
|
+
}
|
|
7754
|
+
}
|
|
7755
|
+
});
|
|
7756
|
+
return selectedOptions;
|
|
7757
|
+
}
|
|
7758
|
+
/**
|
|
7759
|
+
* Report options form validity.
|
|
7760
|
+
* */
|
|
7761
|
+
async reportValidity() {
|
|
7762
|
+
const requiredElements = this.host.querySelectorAll('[required]');
|
|
7763
|
+
let pass = true;
|
|
7764
|
+
for (let i = 0; i < requiredElements.length; i++) {
|
|
7765
|
+
//if there is only one invalid option, return false
|
|
7766
|
+
if ('reportValidity' in requiredElements[i] && !requiredElements[i].reportValidity()) {
|
|
7767
|
+
pass = false;
|
|
7768
|
+
}
|
|
7769
|
+
}
|
|
7770
|
+
return pass;
|
|
7771
|
+
}
|
|
7772
|
+
/**
|
|
7773
|
+
* Return true if there is any out of stock options are selected and vise versa.
|
|
7774
|
+
* */
|
|
7775
|
+
async hasOutOfStockOption() {
|
|
7776
|
+
return this.selectedOptions.some(option => option.is_out) || (this.selectedSkus?.length && this.selectedSkus?.every(sku => this.outSkus.includes(sku)));
|
|
7777
|
+
}
|
|
7778
|
+
/**
|
|
7779
|
+
* Get selected options.
|
|
7780
|
+
* */
|
|
7781
|
+
async getSelectedOptions() {
|
|
7782
|
+
return this.selectedOptions;
|
|
7783
|
+
}
|
|
7784
|
+
/**
|
|
7785
|
+
* Get a specific option by its id.
|
|
7786
|
+
* */
|
|
7787
|
+
async getOption(option_id) {
|
|
7788
|
+
return this.optionsData.find(option => option.id === option_id);
|
|
7789
|
+
}
|
|
7790
|
+
// @ts-ignore
|
|
7791
|
+
invalidHandler(event, option) {
|
|
7792
|
+
const closestProductOption = event.target.closest('.s-product-options-option');
|
|
7793
|
+
if (!closestProductOption.classList.contains('s-product-options-option-error')) {
|
|
7794
|
+
closestProductOption.classList.add('s-product-options-option-error');
|
|
7795
|
+
}
|
|
7796
|
+
if (this.userInitiatedValidation && !salla.url.is_page('cart')) {
|
|
7797
|
+
const firstInvalidElement = this.host.querySelector('.s-product-options-option-error');
|
|
7798
|
+
if (firstInvalidElement === closestProductOption) {
|
|
7799
|
+
this.scrollToElement(closestProductOption);
|
|
7800
|
+
}
|
|
7801
|
+
}
|
|
7802
|
+
}
|
|
7803
|
+
scrollToElement(element) {
|
|
7804
|
+
if (element) {
|
|
7805
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
7806
|
+
}
|
|
7807
|
+
}
|
|
7808
|
+
changedHandler(event, option, fireChangeEvent = true) {
|
|
7809
|
+
const data = {
|
|
7810
|
+
event: event,
|
|
7811
|
+
option: option,
|
|
7812
|
+
detail: null,
|
|
7813
|
+
productId: this.productId
|
|
7814
|
+
};
|
|
7815
|
+
if (option.details) {
|
|
7816
|
+
const detail = option.details.find((detail) => {
|
|
7817
|
+
return Number(detail.id) === Number(event.target.value);
|
|
7818
|
+
});
|
|
7819
|
+
data.detail = detail;
|
|
7820
|
+
}
|
|
7821
|
+
if (option.type === 'country') {
|
|
7822
|
+
this.handleCountryOptionChange(event, data.detail);
|
|
7823
|
+
}
|
|
7824
|
+
const optionElement = event.target.closest('.s-product-options-option');
|
|
7825
|
+
if (event.target.value ||
|
|
7826
|
+
((option.type === DisplayType.FILE || option.type === DisplayType.IMAGE) && event.type === 'added') ||
|
|
7827
|
+
(option.type === DisplayType.MAP && event.type === 'selected' && (event.target.lat && event.target.lng))) {
|
|
7828
|
+
setTimeout(() => {
|
|
7829
|
+
optionElement.classList.remove('s-product-options-option-error');
|
|
7830
|
+
}, 200);
|
|
7831
|
+
}
|
|
7832
|
+
if (option.type === DisplayType.DONATION) {
|
|
7833
|
+
salla.event.emit('product-options::donation-changed', {
|
|
7834
|
+
id: this.productId,
|
|
7835
|
+
price: event.target.value
|
|
7836
|
+
});
|
|
7837
|
+
}
|
|
7838
|
+
this.setSelectedSkus();
|
|
7839
|
+
this.handleRequiredMultipleOptions(option);
|
|
7840
|
+
const index = this.selectedOptions.findIndex(opt => opt.option_id === data.option.id);
|
|
7841
|
+
if (data.option.type === DisplayType.MULTIPLE_OPTIONS) {
|
|
7842
|
+
// Handle multiple selections
|
|
7843
|
+
const detailIndex = this.selectedOptions.findIndex(opt => opt.option_id === data.option.id && opt?.id === data.detail?.id);
|
|
7844
|
+
if (detailIndex > -1) {
|
|
7845
|
+
// If the option is already selected, remove it (unselect)
|
|
7846
|
+
this.selectedOptions.splice(detailIndex, 1);
|
|
7847
|
+
}
|
|
7848
|
+
else {
|
|
7849
|
+
// If the option is not selected, add it to the selectedOptions array
|
|
7850
|
+
this.selectedOptions.push({ ...data.detail, option_id: data.option.id });
|
|
7851
|
+
}
|
|
7852
|
+
}
|
|
7853
|
+
else {
|
|
7854
|
+
// Handle single selection
|
|
7855
|
+
if (!data.detail || Object.keys(data.detail).length === 0) {
|
|
7856
|
+
// If there is no value for the single-select, remove it from the selectedOptions array
|
|
7857
|
+
if (index > -1) {
|
|
7858
|
+
this.selectedOptions.splice(index, 1);
|
|
7859
|
+
}
|
|
7860
|
+
}
|
|
7861
|
+
else {
|
|
7862
|
+
// If a value exists, update or add the selection
|
|
7863
|
+
if (index > -1) {
|
|
7864
|
+
// Replace the existing selection with the new one
|
|
7865
|
+
this.selectedOptions[index] = { ...data.detail, option_id: data.option.id };
|
|
7866
|
+
}
|
|
7867
|
+
else {
|
|
7868
|
+
// If no selection exists for this input, add the new selection
|
|
7869
|
+
this.selectedOptions.push({ ...data.detail, option_id: data.option.id });
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
}
|
|
7873
|
+
// Update optionsData directly
|
|
7874
|
+
this.optionsData = this.optionsData.map(opt => {
|
|
7875
|
+
if (opt.id === data.option.id) {
|
|
7876
|
+
return {
|
|
7877
|
+
...opt,
|
|
7878
|
+
details: opt.details.map(detail => ({
|
|
7879
|
+
...detail,
|
|
7880
|
+
is_selected: data.option.type === DisplayType.MULTIPLE_OPTIONS
|
|
7881
|
+
? this.selectedOptions.some(selected => selected.id === detail.id)
|
|
7882
|
+
: Number(detail.id) === Number(data.detail?.id),
|
|
7883
|
+
value: data.detail?.value
|
|
7884
|
+
}))
|
|
7885
|
+
};
|
|
7886
|
+
}
|
|
7887
|
+
return opt;
|
|
7888
|
+
});
|
|
7889
|
+
// Emit the event only if fireChangeEvent is true
|
|
7890
|
+
if (fireChangeEvent) {
|
|
7891
|
+
this.changed.emit(data);
|
|
7892
|
+
salla.event.emit('product-options::change', data);
|
|
7893
|
+
}
|
|
7894
|
+
}
|
|
7895
|
+
/**
|
|
7896
|
+
* loop throw all selected details, then get common sku, if it's only one, means we selected all of them;
|
|
7897
|
+
*/
|
|
7898
|
+
setSelectedSkus() {
|
|
7899
|
+
this.selectedSkus = this.selectedOptions.map(detail => Object.keys(detail.skus_availability || {}))
|
|
7900
|
+
.reduce((p, c) => p.filter(e => c.includes(e)), []) // Initialize accumulator as an empty array
|
|
7901
|
+
.map(sku => Number(sku));
|
|
7902
|
+
}
|
|
7903
|
+
handleRequiredMultipleOptions(option) {
|
|
7904
|
+
if (option.type !== DisplayType.MULTIPLE_OPTIONS || !option.required) {
|
|
7905
|
+
return;
|
|
7906
|
+
}
|
|
7907
|
+
const optionContainer = this.host.querySelector(`[data-option-id="${option.id}"]`);
|
|
7908
|
+
const hasChecked = optionContainer.querySelectorAll('input:checked').length;
|
|
7909
|
+
optionContainer.querySelectorAll('input').forEach(input => input.toggleAttribute('required', !hasChecked));
|
|
7910
|
+
}
|
|
7911
|
+
getLatLng(value, type) {
|
|
7912
|
+
return value
|
|
7913
|
+
? value.split(',')[type === 'lat' ? 0 : 1]
|
|
7914
|
+
: '';
|
|
7915
|
+
}
|
|
7916
|
+
getDisplayForType(option) {
|
|
7917
|
+
if (this[`${option.type}Option`]) {
|
|
7918
|
+
return this[`${option.type}Option`](option);
|
|
7919
|
+
}
|
|
7920
|
+
if (option.type === DisplayType.COLOR_PICKER) {
|
|
7921
|
+
return this.colorPickerOption(option);
|
|
7922
|
+
}
|
|
7923
|
+
if (option.type === DisplayType.MULTIPLE_OPTIONS) {
|
|
7924
|
+
return this.multipleOptions(option);
|
|
7925
|
+
}
|
|
7926
|
+
if (option.type === DisplayType.SINGLE_OPTION) {
|
|
7927
|
+
return this.singleOption(option);
|
|
7928
|
+
}
|
|
7929
|
+
// Handle radio type as single option for bundle products
|
|
7930
|
+
if (option.type === DisplayType.RADIO) {
|
|
7931
|
+
return this.radioOption(option);
|
|
7932
|
+
}
|
|
7933
|
+
if (option.type === DisplayType.DIGITAL_CARD_VALUE) {
|
|
7934
|
+
return this.digitalCardValuesOption(option);
|
|
7935
|
+
}
|
|
7936
|
+
if (option.type === DisplayType.COUNTRY) {
|
|
7937
|
+
return this.countryOption(option);
|
|
7938
|
+
}
|
|
7939
|
+
if (option.type === DisplayType.BOOKING && salla.url.is_page("cart")) {
|
|
7940
|
+
return index.h("salla-booking-field", { onInvalidInput: (e) => this.invalidHandler(e, option), option: option, productId: option.value });
|
|
7941
|
+
}
|
|
7942
|
+
salla.log(`Couldn't find options type(${option.type})😢`);
|
|
7943
|
+
return '';
|
|
7944
|
+
}
|
|
7945
|
+
getOptionShownWhen(option) {
|
|
7946
|
+
return option.visibility_condition
|
|
7947
|
+
? { "data-show-when": `options[${option.visibility_condition.option}] ${option.visibility_condition.operator} ${option.visibility_condition.value}` }
|
|
7948
|
+
: {};
|
|
7949
|
+
}
|
|
7950
|
+
getAvailableDigitalCardSKUs(detail) {
|
|
7951
|
+
const digitalCardOption = this.optionsData.find(({ type }) => type === 'digital-code-value');
|
|
7952
|
+
if (!digitalCardOption)
|
|
7953
|
+
throw new Error('product-options:: No digital card options found');
|
|
7954
|
+
const outofStockSKUs = Object.keys(detail.skus_availability).filter(key => detail.skus_availability[key] === false);
|
|
7955
|
+
this.availableDigitalCardValues = digitalCardOption.details.filter((op) => {
|
|
7956
|
+
return !Object.keys(op.skus_availability).filter(SKU_key => outofStockSKUs.includes(SKU_key)).length;
|
|
7957
|
+
});
|
|
7958
|
+
}
|
|
7959
|
+
handleCountryOptionChange(event, detail) {
|
|
7960
|
+
event.stopImmediatePropagation();
|
|
7961
|
+
this.ignoreDefaultCardValue = true;
|
|
7962
|
+
const currentCardValue = this.host.querySelector("input[data-code-value]:checked");
|
|
7963
|
+
if (currentCardValue)
|
|
7964
|
+
currentCardValue.checked = false;
|
|
7965
|
+
const digitalCardOption = this.optionsData.find(({ type }) => type === 'digital-code-value');
|
|
7966
|
+
if (!digitalCardOption)
|
|
7967
|
+
throw new Error('product-options:: No digital card options found');
|
|
7968
|
+
this.getAvailableDigitalCardSKUs(detail);
|
|
7969
|
+
}
|
|
7970
|
+
getSelectedDigitalCardOptions(option) {
|
|
7971
|
+
const selectedOption = option.details.find(detail => detail.is_selected);
|
|
7972
|
+
const defaultOption = option.details.find(detail => !!detail.is_default) || option.details[0]; /*option.details[0] only applys for counrty options*/
|
|
7973
|
+
if (!['digital-code-value', 'country'].includes(option.type))
|
|
7974
|
+
return;
|
|
7975
|
+
return selectedOption || defaultOption;
|
|
7976
|
+
}
|
|
7977
|
+
//we need the cart Id for productOption Image
|
|
7978
|
+
async componentWillLoad() {
|
|
7979
|
+
if (salla.url.is_page("cart")) {
|
|
7980
|
+
this.disableCardValue = false;
|
|
7981
|
+
this.fillSelectedOptions();
|
|
7982
|
+
}
|
|
7983
|
+
if (this.config) {
|
|
7984
|
+
try {
|
|
7985
|
+
this.optionConfig = typeof this.config === 'string' ? JSON.parse(this.config) : this.config;
|
|
7986
|
+
}
|
|
7987
|
+
catch (error) {
|
|
7988
|
+
console.error('Failed to parse JSON in config prop:', error);
|
|
7989
|
+
}
|
|
7990
|
+
}
|
|
7991
|
+
const shouldSelectDefaultOption = this.optionsData.filter(({ type }) => ["country", "digital-card-value"].includes(type)).length > 0 && salla.url.is_page('cart');
|
|
7992
|
+
if (shouldSelectDefaultOption) {
|
|
7993
|
+
const countryOption = this.optionsData.find(option => option.type === 'country');
|
|
7994
|
+
const defaultSelection = countryOption && this.getSelectedDigitalCardOptions(countryOption);
|
|
7995
|
+
if (defaultSelection) {
|
|
7996
|
+
this.getAvailableDigitalCardSKUs(defaultSelection);
|
|
7997
|
+
}
|
|
7998
|
+
}
|
|
7999
|
+
this.outOfStockText = salla.lang.get('pages.products.out_of_stock');
|
|
8000
|
+
await salla.onReady();
|
|
8001
|
+
document.addEventListener("paste", this.handlePaste.bind(this));
|
|
8002
|
+
const needsCartId = (!salla.storage.get('cart.id') && this.optionsData.some(option => ['file', 'image'].includes(option.type)));
|
|
8003
|
+
return needsCartId ? salla.api.cart.getCurrentCartId(false, "salla-product-options") : null;
|
|
8004
|
+
}
|
|
8005
|
+
/**
|
|
8006
|
+
* This is a workaround for a bug in iOS 26 Safari, when pasting English text to RTL inputs, it adds extra text!!
|
|
8007
|
+
* To avoid any break changes, we will make it only work on these conditions:
|
|
8008
|
+
* - content_copyright is on
|
|
8009
|
+
* - Apple Pay is enabled (means it's iOS/safari)
|
|
8010
|
+
* - Input is an input or textarea
|
|
8011
|
+
* - Salla form control
|
|
8012
|
+
* - Options array
|
|
8013
|
+
*/
|
|
8014
|
+
handlePaste(event) {
|
|
8015
|
+
const target = event.target;
|
|
8016
|
+
if (!Salla.config.get('store.settings.content_copyright')
|
|
8017
|
+
|| !Salla.helpers.hasApplePay()
|
|
8018
|
+
|| !(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)
|
|
8019
|
+
|| !target.classList.contains('s-form-control')
|
|
8020
|
+
|| !target.name.startsWith('options[')) {
|
|
8021
|
+
return;
|
|
8022
|
+
}
|
|
8023
|
+
// Prevent default paste (to avoid Safari inserting extra content)
|
|
8024
|
+
event.preventDefault();
|
|
8025
|
+
// Read only the clipboard data
|
|
8026
|
+
const text = event.clipboardData?.getData("text") || "";
|
|
8027
|
+
// Insert it manually at cursor if you want
|
|
8028
|
+
const start = target.selectionStart;
|
|
8029
|
+
const end = target.selectionEnd;
|
|
8030
|
+
const newValue = target.value.slice(0, start) + text + target.value.slice(end);
|
|
8031
|
+
target.value = newValue;
|
|
8032
|
+
// Reset cursor position
|
|
8033
|
+
target.setSelectionRange(start + text.length, start + text.length);
|
|
8034
|
+
}
|
|
8035
|
+
hideDigitalCardsOptions(option) {
|
|
8036
|
+
return (this.disableCardValue && option.type === DisplayType.DIGITAL_CARD_VALUE && !salla.url.is_page("cart"));
|
|
8037
|
+
}
|
|
8038
|
+
render() {
|
|
8039
|
+
if (this.optionsData?.length === 0) {
|
|
8040
|
+
return;
|
|
8041
|
+
}
|
|
8042
|
+
return (index.h(index.Host, { class: "s-product-options-wrapper" }, index.h("salla-conditional-fields", null, this.optionsData.map((option) => index.h("div", { key: option.id, class: `s-product-options-option-container${option.visibility_condition || this.hideDigitalCardsOptions(option) ? ' hidden' : ''}`, "data-option-id": option.id, ...this.getOptionShownWhen(option) }, option.name === 'splitter' ?
|
|
8043
|
+
this.splitterOption()
|
|
8044
|
+
: index.h("div", { class: { "s-product-options-option": true, "s-product-options-option-booking": option.type === DisplayType.BOOKING && salla.url.is_page("cart") }, "data-option-type": option.type, "data-option-required": `${option.required}` }, index.h("label", { htmlFor: this.generateInputName(option.id), class: `s-product-options-option-label ${this.hideLabel(option) ? 's-product-options-option-label-hidden' : ''}` }, index.h("b", null, option.name, option.required && index.h("span", null, " * "), " "), index.h("small", null, option.placeholder)), index.h("div", { class: `s-product-options-option-content ${this.hideLabel(option) || (option.type === DisplayType.BOOKING && salla.url.is_page("cart")) ? 's-product-options-option-content-full-width' : ''}` }, this.getDisplayForType(option))))))));
|
|
8045
|
+
}
|
|
8046
|
+
generateUniqueKey(defaultValue) {
|
|
8047
|
+
const contextData = this.bundleContext;
|
|
8048
|
+
let baseKey = this.uniqueKey ? `${defaultValue}-${this.uniqueKey}` : defaultValue;
|
|
8049
|
+
if (contextData) {
|
|
8050
|
+
try {
|
|
8051
|
+
// Handle both string and object types
|
|
8052
|
+
const context = typeof contextData === 'string'
|
|
8053
|
+
? JSON.parse(contextData)
|
|
8054
|
+
: contextData;
|
|
8055
|
+
const { sectionId, productId } = context;
|
|
8056
|
+
baseKey = `${baseKey}-bundle-${sectionId}-${productId}`;
|
|
8057
|
+
}
|
|
8058
|
+
catch (e) {
|
|
8059
|
+
// If parsing fails, just use the base key
|
|
8060
|
+
}
|
|
8061
|
+
}
|
|
8062
|
+
return baseKey;
|
|
8063
|
+
}
|
|
8064
|
+
/**
|
|
8065
|
+
* Generate the correct input name based on bundle context
|
|
8066
|
+
* @param optionId - The option ID
|
|
8067
|
+
* @returns The formatted input name
|
|
8068
|
+
*/
|
|
8069
|
+
generateInputName(optionId) {
|
|
8070
|
+
const contextData = this.bundleContext;
|
|
8071
|
+
if (contextData) {
|
|
8072
|
+
try {
|
|
8073
|
+
// Handle both string and object types
|
|
8074
|
+
const context = typeof contextData === 'string'
|
|
8075
|
+
? JSON.parse(contextData)
|
|
8076
|
+
: contextData;
|
|
8077
|
+
const { sectionId, productId } = context;
|
|
8078
|
+
return `bundle[${sectionId}][${productId}][options][${optionId}]`;
|
|
8079
|
+
}
|
|
8080
|
+
catch (e) {
|
|
8081
|
+
return `options[${optionId}]`;
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
8084
|
+
return `options[${optionId}]`;
|
|
8085
|
+
}
|
|
8086
|
+
fillSelectedOptions() {
|
|
8087
|
+
this.selectedOptions = this.optionsData.reduce((acc, opt) => {
|
|
8088
|
+
const selectedDetails = opt.details.filter(detail => detail.is_selected);
|
|
8089
|
+
const mappedDetails = selectedDetails.map(detail => ({
|
|
8090
|
+
...detail,
|
|
8091
|
+
option_id: opt.id
|
|
8092
|
+
}));
|
|
8093
|
+
return acc.concat(mappedDetails);
|
|
8094
|
+
}, []);
|
|
8095
|
+
}
|
|
8096
|
+
componentDidLoad() {
|
|
8097
|
+
if (this.optionsData?.length === 0 && !this.optionsData.some(option => option.type === DisplayType.DONATION)) {
|
|
8098
|
+
return;
|
|
8099
|
+
}
|
|
8100
|
+
const selectedDonationOption = this.optionsData.find(option => option.type === DisplayType.DONATION)?.details.find(detail => detail.is_selected);
|
|
8101
|
+
if (!selectedDonationOption) {
|
|
8102
|
+
return;
|
|
8103
|
+
}
|
|
8104
|
+
setTimeout(() => {
|
|
8105
|
+
salla.event.emit('product-options::donation-changed', {
|
|
8106
|
+
id: this.productId,
|
|
8107
|
+
price: selectedDonationOption.additional_price
|
|
8108
|
+
});
|
|
8109
|
+
}, 1000);
|
|
8110
|
+
}
|
|
8111
|
+
/**
|
|
8112
|
+
* Enable user-initiated validation mode so invalid fields will scroll into view
|
|
8113
|
+
*/
|
|
8114
|
+
async enableUserInitiatedValidation() {
|
|
8115
|
+
this.userInitiatedValidation = true;
|
|
8116
|
+
}
|
|
8117
|
+
/**
|
|
8118
|
+
* Validate options and trigger scrolling to the first invalid option if any
|
|
8119
|
+
*/
|
|
8120
|
+
async validateAndScroll() {
|
|
8121
|
+
await this.enableUserInitiatedValidation();
|
|
8122
|
+
return this.reportValidity();
|
|
8123
|
+
}
|
|
8124
|
+
//@ts-ignore
|
|
8125
|
+
donationOption(option, product) {
|
|
8126
|
+
return index.h("div", { class: "s-product-options-donation-wrapper" }, option.donation?.can_donate ? [
|
|
8127
|
+
option.donation ?
|
|
8128
|
+
index.h("div", { key: option.id, class: "s-product-options-donation-progress" }, index.h("salla-progress-bar", { donation: option.donation }))
|
|
8129
|
+
: '',
|
|
8130
|
+
option.details.length ?
|
|
8131
|
+
[index.h("h4", { key: option.id }, this.selectAmount), index.h("div", { key: option.id, class: "s-product-options-donation-options" }, option.details.map((detail, i) => index.h("div", { key: option.id, class: "s-product-options-donation-options-item" }, index.h("input", { id: this.generateUniqueKey(`donation-option-${i}`), type: "radio", name: "donating_option", checked: detail.is_selected, value: detail.additional_price, onChange: e => this.handleDonationOptions(e, detail, 'option') }), index.h("label", { htmlFor: this.generateUniqueKey(`donation-option-${i}`) }, index.h("span", { innerHTML: salla.money(detail.name) })))), option.donation?.custom_amount_enabled ?
|
|
8132
|
+
index.h("div", { class: "s-product-options-donation-options-item" }, index.h("input", { id: this.generateUniqueKey("donation-option-custom"), type: "radio", name: "donating_option", value: "custom", onChange: e => this.handleDonationOptions(e, 'custom', 'option') }), index.h("label", { htmlFor: this.generateUniqueKey("donation-option-custom") }, index.h("span", null, " ", this.selectDonationAmount, " ")))
|
|
8133
|
+
: '')] : '',
|
|
8134
|
+
index.h("div", { key: option.id, class: { "s-product-options-donation-input-group": true, "shown": !option.details.length || (option.details.length && this.isCustomDonation) } }, index.h("input", { type: "text", id: "donating-amount", name: "donation_amount", class: "s-form-control", ref: el => { this.donationInput = el; }, value: option.details.length
|
|
8135
|
+
&& option.details.some(detail => detail.is_selected)
|
|
8136
|
+
? option.details.find(detail => detail.is_selected).additional_price
|
|
8137
|
+
: option.value,
|
|
8138
|
+
// required
|
|
8139
|
+
placeholder: option.placeholder, onInput: e => this.handleDonationOptions(e, 'custom', 'input'), onBlur: e => this.changedHandler(e, option), onInvalid: (e) => this.invalidHandler(e, option) }), index.h("span", { class: "s-product-options-donation-amount-currency" }, salla.config.currency(salla.config.get('user.currency_code')).symbol))
|
|
8140
|
+
] :
|
|
8141
|
+
this.getExpireDonationMessage(option));
|
|
8142
|
+
}
|
|
8143
|
+
fileUploader(option, additions = null) {
|
|
8144
|
+
return index.h("salla-file-upload", { ...(additions || {}), "payload-name": "file", value: option.value, "instant-upload": true, name: this.generateInputName(option.id), required: !option.visibility_condition && option.required, height: "120px", onAdded: (e) => this.changedHandler(e, option), url: salla.cart.api.getUploadImageEndpoint(), "form-data": { cart_item_id: this.productId, product_id: this.productId }, onInvalidInput: (e) => this.invalidHandler(e, option), class: { "s-product-options-image-input": true, required: option.required } }, index.h("div", { class: "s-product-options-filepond-placeholder" }, index.h("span", { class: "s-product-options-filepond-placeholder-icon", innerHTML: additions.accept?.split(',').every(type => type.includes('image'))
|
|
8145
|
+
? CameraIcon
|
|
8146
|
+
: FileIcon }), index.h("p", { class: "s-product-options-filepond-placeholder-text" }, salla.lang.get('common.uploader.drag_and_drop')), index.h("span", { class: "filepond--label-action" }, salla.lang.get('common.uploader.browse'))));
|
|
8147
|
+
}
|
|
8148
|
+
//@ts-ignore
|
|
8149
|
+
imageOption(option) {
|
|
8150
|
+
return this.fileUploader(option, { accept: 'image/png,image/jpeg,image/jpg,image/gif' });
|
|
8151
|
+
}
|
|
8152
|
+
//@ts-ignore
|
|
8153
|
+
fileOption(option) {
|
|
8154
|
+
const types = option.details.map(detail => this.fileTypes[detail.name]).filter(Boolean);
|
|
8155
|
+
return types?.length
|
|
8156
|
+
? this.fileUploader(option, { accept: types.join(',') })
|
|
8157
|
+
: 'File types not selected.';
|
|
8158
|
+
}
|
|
8159
|
+
// TODO: (ONLY FOR TESTING!) find a better way to make it testable, e.g. wrap it with a unique class like textOption
|
|
8160
|
+
//@ts-ignore
|
|
8161
|
+
numberOption(option) {
|
|
8162
|
+
return index.h("input", { type: "text", value: option.value, class: "s-form-control", required: !option.visibility_condition && option.required, name: this.generateInputName(option.id), placeholder: option.placeholder, onBlur: e => this.changedHandler(e, option), onInvalid: (e) => this.invalidHandler(e, option), onInput: e => salla.helpers.inputDigitsOnly(e.target) });
|
|
8163
|
+
}
|
|
8164
|
+
//@ts-ignore
|
|
8165
|
+
splitterOption() {
|
|
8166
|
+
return index.h("div", { class: "s-product-options-splitter" });
|
|
8167
|
+
}
|
|
8168
|
+
//@ts-ignore
|
|
8169
|
+
textOption(option) {
|
|
8170
|
+
return index.h("div", { class: "s-product-options-text" }, index.h("input", { type: "text", value: option.value, maxLength: option?.length, class: 's-form-control', required: !option.visibility_condition && option.required, name: this.generateInputName(option.id), placeholder: option.placeholder, onInvalid: (e) => this.invalidHandler(e, option), onChange: e => this.changedHandler(e, option) }));
|
|
8171
|
+
}
|
|
8172
|
+
//@ts-ignore
|
|
8173
|
+
textareaOption(option) {
|
|
8174
|
+
//todo::remove mt-1 class, and if it's okay to remove the tag itself will be great
|
|
8175
|
+
return index.h("div", { class: "s-product-options-textarea" }, index.h("div", { class: "mt-1" }, index.h("textarea", { rows: 4, value: option.value, maxLength: option?.length, class: "s-form-control", required: !option.visibility_condition && option.required, id: this.generateUniqueKey(option.id.toString()), name: this.generateInputName(option.id), placeholder: option.placeholder, onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) })));
|
|
8176
|
+
}
|
|
8177
|
+
//@ts-ignore
|
|
8178
|
+
mapOption(option) {
|
|
8179
|
+
return index.h("salla-map", { zoom: 15, lat: this.getLatLng(option.value, 'lat'), lng: this.getLatLng(option.value, 'lng'), name: this.generateInputName(option.id), searchable: true, required: option.required, onInvalidInput: (e) => this.invalidHandler(e, option), onSelected: e => this.changedHandler(e, option) });
|
|
8180
|
+
}
|
|
8181
|
+
colorPickerOption(option) {
|
|
8182
|
+
return index.h("salla-color-picker", { onSubmitted: e => this.changedHandler(e, option), name: this.generateInputName(option.id), required: !option.visibility_condition && option.required, onInvalidInput: (e) => this.invalidHandler(e, option), color: option.value });
|
|
8183
|
+
}
|
|
8184
|
+
/**
|
|
8185
|
+
* ============= Date Time options =============
|
|
8186
|
+
*/
|
|
8187
|
+
//@ts-ignore
|
|
8188
|
+
timeOption(option) {
|
|
8189
|
+
return index.h("salla-datetime-picker", { noCalendar: true, enableTime: true, dateFormat: "h:i K", value: option.value, placeholder: option.name, required: !option.visibility_condition && option.required, name: this.generateInputName(option.id), class: "s-product-options-time-element", onInvalidInput: (e) => this.invalidHandler(e, option), onPicked: e => this.changedHandler(e, option) });
|
|
8190
|
+
}
|
|
8191
|
+
//@ts-ignore
|
|
8192
|
+
dateOption(option) {
|
|
8193
|
+
//todo:: consider date-range @see https://github.com/SallaApp/theme-raed/blob/master/src/assets/js/partials/product-options.js#L8-L23
|
|
8194
|
+
return index.h("div", { class: "s-product-options-date-element" }, index.h("salla-datetime-picker", { value: option.value, placeholder: option.name, required: !option.visibility_condition && option.required, minDate: new Date(), name: this.generateInputName(option.id), onInvalidInput: (e) => this.invalidHandler(e, option), onPicked: e => this.changedHandler(e, option) }));
|
|
8195
|
+
}
|
|
8196
|
+
//@ts-ignore
|
|
8197
|
+
datetimeOption(option) {
|
|
8198
|
+
//todo:: consider date-range @see https://github.com/SallaApp/theme-raed/blob/master/src/assets/js/partials/product-options.js#L8-L23
|
|
8199
|
+
return index.h("div", { class: "s-product-options-datetime-element" }, index.h("salla-datetime-picker", { enableTime: true, value: option.value, dateFormat: "Y-m-d G:i:K", placeholder: option.name, required: !option.visibility_condition && option.required, name: this.generateInputName(option.id), maxDate: option.to_date_time, minDate: option.from_date_time, onInvalidInput: (e) => this.invalidHandler(e, option), onPicked: e => this.changedHandler(e, option) }));
|
|
8200
|
+
}
|
|
8201
|
+
/**
|
|
8202
|
+
* ============= Advanced options =============
|
|
8203
|
+
*/
|
|
8204
|
+
getOptionDetailName(detail, outOfStock = true, optionType) {
|
|
8205
|
+
let detailName;
|
|
8206
|
+
if (optionType && optionType === DisplayType.COLOR) {
|
|
8207
|
+
detailName = detail.name
|
|
8208
|
+
+ ((outOfStock && this.isOptionDetailOut(detail) && !salla.url.is_page("cart")) && !this.hideOutLabel ? ` <br/> <p> ${this.outOfStockText} </p>` : '')
|
|
8209
|
+
+ (detail.additional_price ? ` <p> (${salla.money(detail.additional_price, false)}) </p>` : '');
|
|
8210
|
+
}
|
|
8211
|
+
if (!detailName) {
|
|
8212
|
+
detailName = detail.name
|
|
8213
|
+
+ ((outOfStock && this.isOptionDetailOut(detail) && !salla.url.is_page("cart")) && !this.hideOutLabel ? ` - ${this.outOfStockText}` : '')
|
|
8214
|
+
+ (detail.additional_price ? ` (${salla.money(detail.additional_price, false)})` : '');
|
|
8215
|
+
}
|
|
8216
|
+
//Some merchants adding price to the names of the options,
|
|
8217
|
+
//and because we are using this inside select option, we need to replace the html currency symbol with the store currency symbol
|
|
8218
|
+
return detailName.replace('<i class=sicon-sar></i>', salla.config.currency()?.symbol || 'ر.س');
|
|
8219
|
+
}
|
|
8220
|
+
isOptionDetailOut(detail) {
|
|
8221
|
+
if (detail.is_out || !detail.skus_availability || !this.selectedSkus?.length) {
|
|
8222
|
+
return detail.is_out;
|
|
8223
|
+
}
|
|
8224
|
+
const isDetailSelected = this.selectedOptions.filter(option => option.id === detail.id).length;
|
|
8225
|
+
//if the current options is the only selected option, so we are sure that it's not out, because there is no other options selected yet
|
|
8226
|
+
if (isDetailSelected && this.selectedOptions.length === 1) {
|
|
8227
|
+
return false;
|
|
8228
|
+
}
|
|
8229
|
+
//if current details has sku in the possible outSkus it's out for sure
|
|
8230
|
+
if (isDetailSelected) {
|
|
8231
|
+
//here we will get the possible outSkus for current selected options
|
|
8232
|
+
const outSelectableSkus = this.selectedSkus.filter(sku => this.outSkus.includes(sku));
|
|
8233
|
+
return Object.keys(detail.skus_availability).some(sku => outSelectableSkus.includes(Number(sku)));
|
|
8234
|
+
}
|
|
8235
|
+
return this.selectedOptions.some(option => option.is_out && option.option_id !== detail.option_id);
|
|
8236
|
+
}
|
|
8237
|
+
/**
|
|
8238
|
+
* Renders a single input element (radio or checkbox) for an option detail.
|
|
8239
|
+
* @param type - The type of input element ('radio' or 'checkbox').
|
|
8240
|
+
* @param detail - The detail object representing an option detail.
|
|
8241
|
+
* @param option - The parent option object containing the details.
|
|
8242
|
+
* @param isRequired - Indicates if the input is required based on the option's rules.
|
|
8243
|
+
* @param name - The name attribute for the input element.
|
|
8244
|
+
* @returns HTMLElement - A labeled input element.
|
|
8245
|
+
*/
|
|
8246
|
+
renderInput(type, detail, option, isRequired, name, buttonStyle) {
|
|
8247
|
+
const id = this.generateUniqueKey(`${type}-${option.id}-${detail.id}`);
|
|
8248
|
+
const isDisabled = this.isOptionDetailOut(detail);
|
|
8249
|
+
return (index.h("label", { class: {
|
|
8250
|
+
"s-product-options-disabled": isDisabled,
|
|
8251
|
+
} }, index.h("input", { id: id, type: type, name: name, value: detail.id, disabled: isDisabled, required: isRequired, checked: detail.is_selected, onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), index.h("div", { class: { "s-product-options-grid-mode-span": buttonStyle, "s-product-options-disabled": isDisabled } }, this.getOptionDetailName(detail))));
|
|
8252
|
+
}
|
|
8253
|
+
/**
|
|
8254
|
+
* Renders a collection of input elements for all details of an option.
|
|
8255
|
+
* @param type - The type of input elements ('radio' or 'checkbox').
|
|
8256
|
+
* @param option - The parent option object containing the details.
|
|
8257
|
+
* @param isRequired - Indicates if the inputs are required based on the option's rules.
|
|
8258
|
+
* @returns HTMLElement[] - An array of labeled input elements.
|
|
8259
|
+
*/
|
|
8260
|
+
renderOptionDetails(type, option, isRequired, buttonStyle = false) {
|
|
8261
|
+
const baseName = this.generateInputName(option.id);
|
|
8262
|
+
const name = type === 'radio' ? baseName : `${baseName}[]`;
|
|
8263
|
+
return option?.details.map((detail) => this.renderInput(type, detail, option, isRequired, name, buttonStyle));
|
|
8264
|
+
}
|
|
8265
|
+
/**
|
|
8266
|
+
* Renders a dropdown (select) element for a single-option selection.
|
|
8267
|
+
* @param option - The parent option object.
|
|
8268
|
+
* @returns HTMLElement - A select dropdown element with all option details.
|
|
8269
|
+
*/
|
|
8270
|
+
renderSelect(option) {
|
|
8271
|
+
return (index.h("div", null, index.h("select", { name: this.generateInputName(option.id), required: !option.visibility_condition && option.required, class: "s-form-control", onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }, index.h("option", { value: "" }, option.placeholder), option?.details.map((detail) => (index.h("option", { key: detail.id, value: detail.id, disabled: this.canDisabled && this.isOptionDetailOut(detail), selected: detail.is_selected }, this.getOptionDetailName(detail)))))));
|
|
8272
|
+
}
|
|
8273
|
+
/**
|
|
8274
|
+
* Renders a grid-based layout for option inputs (radio or checkbox).
|
|
8275
|
+
* @param type - The type of input elements ('radio' or 'checkbox').
|
|
8276
|
+
* @param option - The parent option object containing the details.
|
|
8277
|
+
* @param isRequired - Indicates if the inputs are required based on the option's rules.
|
|
8278
|
+
* @returns HTMLElement - A grid-based container with input elements.
|
|
8279
|
+
*/
|
|
8280
|
+
renderButtonStyle(type, option, isRequired) {
|
|
8281
|
+
return (index.h("div", { class: "s-product-options-grid-mode" }, this.renderOptionDetails(type, option, isRequired, true)));
|
|
8282
|
+
}
|
|
8283
|
+
/**
|
|
8284
|
+
* Renders a single-option selection, either as a grid or dropdown, based on configuration.
|
|
8285
|
+
* @param option - The parent option object.
|
|
8286
|
+
* @returns HTMLElement - The rendered single-option element.
|
|
8287
|
+
*/
|
|
8288
|
+
singleOption(option) {
|
|
8289
|
+
const buttonStyle = this.optionConfig?.['single-option']?.type === 'button';
|
|
8290
|
+
const isRequired = !option.visibility_condition && option.required;
|
|
8291
|
+
return buttonStyle
|
|
8292
|
+
? this.renderButtonStyle('radio', option, isRequired)
|
|
8293
|
+
: this.renderSelect(option);
|
|
8294
|
+
}
|
|
8295
|
+
/**
|
|
8296
|
+
* Renders a multiple-option selection, either as a grid or list, based on configuration.
|
|
8297
|
+
* @param option - The parent option object.
|
|
8298
|
+
* @returns HTMLElement - The rendered multiple-option element.
|
|
8299
|
+
*/
|
|
8300
|
+
multipleOptions(option) {
|
|
8301
|
+
const buttonStyle = this.optionConfig?.['multiple-option']?.type === 'button';
|
|
8302
|
+
const isRequired = option.required &&
|
|
8303
|
+
!option.details.some((detail) => detail.is_selected) &&
|
|
8304
|
+
!option.visibility_condition;
|
|
8305
|
+
return buttonStyle
|
|
8306
|
+
? this.renderButtonStyle('checkbox', option, isRequired)
|
|
8307
|
+
: (index.h("div", { class: {
|
|
8308
|
+
's-product-options-multiple-options-wrapper': true,
|
|
8309
|
+
required: option.required,
|
|
8310
|
+
} }, this.renderOptionDetails('checkbox', option, isRequired)));
|
|
8311
|
+
}
|
|
8312
|
+
/**
|
|
8313
|
+
* Renders a radio option selection (used for bundle products).
|
|
8314
|
+
* This is essentially the same as single option but with explicit radio handling.
|
|
8315
|
+
* @param option - The parent option object.
|
|
8316
|
+
* @returns HTMLElement - The rendered radio option element.
|
|
8317
|
+
*/
|
|
8318
|
+
radioOption(option) {
|
|
8319
|
+
// Radio options behave the same as single options
|
|
8320
|
+
return this.singleOption(option);
|
|
8321
|
+
}
|
|
8322
|
+
//@ts-ignore
|
|
8323
|
+
colorOption(option) {
|
|
8324
|
+
return (index.h("fieldset", { class: "s-product-options-colors-wrapper" }, option?.details.map((detail) => (index.h("div", { class: "s-product-options-colors-item", key: detail.id }, index.h("input", { type: "radio", value: detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), disabled: this.canDisabled && this.isOptionDetailOut(detail), id: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), index.h("label", { htmlFor: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`) }, index.h("span", { style: { backgroundColor: detail.color } }), index.h("div", { innerHTML: this.getOptionDetailName(detail, true, option.type) })))))));
|
|
8325
|
+
}
|
|
8326
|
+
//@ts-ignore
|
|
8327
|
+
thumbnailOption(option) {
|
|
8328
|
+
return index.h("div", { class: "s-product-options-thumbnails-wrapper" }, option.details.map((detail) => {
|
|
8329
|
+
return index.h("div", { key: detail.id }, index.h("input", { type: "radio", value: detail.id, "data-itemid": detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), "data-img-id": detail.option_value, disabled: this.canDisabled && this.isOptionDetailOut(detail), id: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), index.h("label", { htmlFor: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), "data-img-id": detail.option_value, class: "go-to-slide" }, index.h("img", { "data-src": detail.image, src: detail.image, title: detail.name, alt: detail.name }), index.h("span", { innerHTML: check.IconVerified, class: "s-product-options-thumbnails-icon" }), this.isOptionDetailOut(detail) ?
|
|
8330
|
+
[
|
|
8331
|
+
index.h("small", { key: detail.id, class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText),
|
|
8332
|
+
this.canDisabled ? index.h("div", { key: detail.id, class: "s-product-options-thumbnails-badge-overlay" }) : '',
|
|
8333
|
+
]
|
|
8334
|
+
: ''), index.h("p", null, this.getOptionDetailName(detail, false), " "));
|
|
8335
|
+
}));
|
|
8336
|
+
}
|
|
8337
|
+
// Digital card options
|
|
8338
|
+
digitalCardValuesOption(option) {
|
|
8339
|
+
return index.h("div", { class: "s-product-options-digital-card-wrapper" }, this.availableDigitalCardValues.length > 0 ? this.availableDigitalCardValues.map((detail) => {
|
|
8340
|
+
const id = String(detail.id);
|
|
8341
|
+
return index.h("label", { htmlFor: this.generateUniqueKey(id.toString()), key: id, class: "s-product-options-digital-card-option" }, index.h("input", { type: "radio", "data-code-value": true, class: "s-form-control s-product-options-digital-card-input", value: detail.id, name: this.generateInputName(option.id), id: this.generateUniqueKey(id.toString()), required: !option.visibility_condition && option.required, onInvalid: (e) => this.invalidHandler(e, option), ...(!this.ignoreDefaultCardValue ? { defaultChecked: this.getSelectedDigitalCardOptions(option)?.id === detail.id } : {}) }), index.h("span", null, detail.name, " ", salla.config?.currency()?.symbol));
|
|
8342
|
+
})
|
|
8343
|
+
: index.h("div", { class: "s-product-options-digital-card-out-of-stock" }));
|
|
8344
|
+
}
|
|
8345
|
+
countryOption(option) {
|
|
8346
|
+
return index.h("div", { class: "s-product-options-digital-card-wrapper" }, option.details.map((detail) => {
|
|
8347
|
+
return index.h("label", { htmlFor: this.generateUniqueKey(detail.id.toString()), key: detail.id, class: { "s-product-options-digital-card-option": true, "s-product-options-digital-card-option-stock-out": detail.is_out } }, index.h("input", { id: this.generateUniqueKey(detail.id.toString()), type: "radio", class: "s-form-control s-product-options-digital-card-input", value: detail.id, name: this.generateInputName(option.id), disabled: detail.is_out, required: !option.visibility_condition && option.required, onInvalid: (e) => this.invalidHandler(e, option), onChange: e => this.changedHandler(e, option), onClick: () => { this.disableCardValue = false; }, ...(salla.url.is_page("cart") ? { defaultChecked: this.getSelectedDigitalCardOptions(option)?.id === detail.id } : {}) }), index.h("img", { loading: 'lazy', alt: detail.code, height: 24, width: 24, class: "s-product-options-country-flag", src: `https://cdn.assets.salla.network/prod/admin/cp/assets/flags/1x1/${String(detail.code).toLocaleLowerCase()}.svg` }), index.h("span", null, detail.name));
|
|
8348
|
+
}));
|
|
8349
|
+
}
|
|
8350
|
+
get host() { return index.getElement(this); }
|
|
8351
|
+
};
|
|
8352
|
+
SallaProductOptions.style = sallaProductOptionsCss;
|
|
8353
|
+
|
|
6381
8354
|
var PencilRuler = `<!-- Generated by IcoMoon.io -->
|
|
6382
8355
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
6383
8356
|
<title>pencil-ruler</title>
|
|
@@ -6426,11 +8399,11 @@ const SallaProductSizeGuide = class {
|
|
|
6426
8399
|
return index.h("salla-placeholder", { alignment: "center", iconSize: "xl" }, index.h("div", { slot: "title" }, this.placeholder_title), index.h("div", { slot: "description" }, this.placeholder_description));
|
|
6427
8400
|
}
|
|
6428
8401
|
render() {
|
|
6429
|
-
return (index.h("salla-modal", { key: '
|
|
8402
|
+
return (index.h("salla-modal", { key: 'f80606d8b6e1e950c87209ca4e195c92f70dc341', class: "s-product-size-guide-wrapper", id: 'salla-product-size-guide-modal', isLoading: true, "has-skeleton": true, width: "md", ref: modal => this.modal = modal }, index.h("span", { key: '245688c24b70279566b0f7c51c7bf924ca5196c0', slot: 'icon', class: "s-product-size-guide-header-icon", innerHTML: PencilRuler }), index.h("div", { key: '9dc9b4aa8dea0599dbc78f5821e36bc4c600c6aa', slot: "loading" }, index.h("div", { key: 'fca84d9c2c5fa20ac446270c1c68c4ccda16dd77', class: "s-product-size-guide-skeleton" }, index.h("salla-skeleton", { key: '0f036371c9b42314beb4e2c1f308a99e2b068ab8', height: '15px', width: '25%' }), index.h("div", { key: 'a9059b864fddf26b6e15869cab013e793966907e', class: "s-product-size-guide-skeleton-header" }, index.h("salla-skeleton", { key: '34e188b1ff7e0b5e24df84d1b14df2b2255fc9eb', height: '40px' }), index.h("salla-skeleton", { key: '38653491fd73cf4d66cb87658b8121f88130e52e', height: '40px' }), index.h("salla-skeleton", { key: 'a8c3b3cc039fbbb8796c611f4485d889c94e632a', height: '40px' }), index.h("salla-skeleton", { key: '2de2d63a1a56a58f7f1bef92c46843683528ee1a', height: '40px' })), index.h("div", { key: 'cf0b08cb85830fcec4dd82140c89b6d009e1bc74', class: "s-product-size-guide-skeleton-content" }, index.h("salla-skeleton", { key: '402ed4292bb79e839316440ed985b1caed102602', height: '15px', width: '25%' }), index.h("salla-skeleton", { key: '88f0019d79ea72ef7748a5c04b7a8364c1160b92', height: '10px', width: '75%' }), index.h("salla-skeleton", { key: '10d7879c306d7185092c9e9aa0d407d2bb57519e', height: '10px', width: '50%' }), index.h("salla-skeleton", { key: '7b2d00c4c8000083b79d93466ed07828d61b6fbd', height: '10px', width: '75%' }), index.h("salla-skeleton", { key: '5d33b9848d9bccf34bb5f4a93ad99889fe1ee69f', height: '10px', width: '100%' }), index.h("salla-skeleton", { key: '6e49c074a8611a819814d17829466b983a419196', height: '10px', width: '25%' }), index.h("salla-skeleton", { key: '0fb70ed844efeda0d3c2ba348e14d1469a7b279b', height: '10px', width: '60%' }), index.h("salla-skeleton", { key: '5e55cb90aba76662377efccfef4a84fe0f64c341', height: '10px', width: '45%' }), index.h("salla-skeleton", { key: '058b96e3db12454ddfced543d6ecbdf0c38ac3dd', height: '10px', width: '30%' })))), index.h("slot", { key: 'e9eef25bce60cbb1dd48b3d8bc1ebda2305acda0', name: "header" }), !this.hasError && !!this.guides ?
|
|
6430
8403
|
[
|
|
6431
8404
|
index.h("salla-tabs", null, this.guides.map((guide) => index.h("salla-tab-header", { slot: "header", name: guide.name }, index.h("span", null, guide.name))), this.guides.map((guide) => index.h("salla-tab-content", { slot: "content", name: guide.name }, index.h("div", { innerHTML: guide.description }))))
|
|
6432
8405
|
]
|
|
6433
|
-
: this.showPlaceholder(), index.h("slot", { key: '
|
|
8406
|
+
: this.showPlaceholder(), index.h("slot", { key: '6b8bebc72d4a7baea765b1e5a6d4a81862206f94', name: "footer" })));
|
|
6434
8407
|
}
|
|
6435
8408
|
get host() { return index.getElement(this); }
|
|
6436
8409
|
};
|
|
@@ -7423,7 +9396,7 @@ const SallaQuantityInput = class {
|
|
|
7423
9396
|
return this.host;
|
|
7424
9397
|
}
|
|
7425
9398
|
render() {
|
|
7426
|
-
return (index.h(index.Host, { key: '
|
|
9399
|
+
return (index.h(index.Host, { key: '5627ef48310739dc0a112c9c214f78bae9b71bca', class: "s-quantity-input" }, index.h("div", { key: '50040d9cd5bbf38d06d6a13f17a1b4d756f5285d', class: "s-quantity-input-container" }, index.h("button", { key: '334c465e2ac46c3b88e3f89ae3b0754dc3741f69', onClick: () => this.increase(), class: "s-quantity-input-increase-button s-quantity-input-button", type: "button" }, !this.hasIncrementSlot ? index.h("span", { innerHTML: Add }) : '', index.h("slot", { key: '9f41e975e7c47f4cbc3e97dd3f8591b633d9da29', name: "increment-button" })), index.h("input", { key: '6f5bfdeb1804cf98a13f12b966e5fa6582e39557', class: "s-quantity-input-input", ...this.getInputAttributes(), ref: (el) => this.textInput = el, onInput: (event) => this.setValue(event.target.value), min: "1", value: this.quantity }), index.h("button", { key: '583f5edb96bc5a368851eadb5940d79b7afed3be', class: "s-quantity-input-decrease-button s-quantity-input-button", onClick: () => this.decrease(), type: "button" }, !this.hasDecrementSlot ? index.h("span", { innerHTML: Minus }) : '', index.h("slot", { key: '8726d4d616dd6f4fd1348312d3a9c24bf9268146', name: "decrement-button" })))));
|
|
7427
9400
|
}
|
|
7428
9401
|
get host() { return index.getElement(this); }
|
|
7429
9402
|
static get watchers() { return {
|
|
@@ -8323,7 +10296,7 @@ const SallaQuickBuy = class {
|
|
|
8323
10296
|
});
|
|
8324
10297
|
}
|
|
8325
10298
|
render() {
|
|
8326
|
-
return index.h(index.Host, { key: '
|
|
10299
|
+
return index.h(index.Host, { key: '46c3a8b699f4390166d027a0eb2d34451a1dd6f1' }, this.quickBuyButton());
|
|
8327
10300
|
}
|
|
8328
10301
|
quickBuyButton() {
|
|
8329
10302
|
return index.h("apple-pay-button", { locale: salla.config.get('user.language_code'), onClick: () => this.quickBuyHandler(), "data-quick-purchase": "applepay", class: "s-quick-buy-apple-pay", "data-is-applepay": "1", buttonstyle: "black", type: this.type });
|
|
@@ -9371,7 +11344,7 @@ const SallaScopees = class {
|
|
|
9371
11344
|
return salla.onReady();
|
|
9372
11345
|
}
|
|
9373
11346
|
render() {
|
|
9374
|
-
return (index.h(index.Host, { key: '
|
|
11347
|
+
return (index.h(index.Host, { key: '42ac0a93262d5a6bdd602b97fa636b70c2269635' }, index.h("salla-modal", { key: '632eca8b8faa74fd990bc5c024befa11d461568f', ref: modal => this.modal = modal, isClosable: !!(this.isOpenedBefore || (this.selection == 'optional')), class: "s-scopes-modal", isLoading: this.loading, "has-skeleton": true }, this.loading ?
|
|
9375
11348
|
index.h("div", { slot: "loading" }, index.h("div", { class: "s-scopes-skeleton" }, index.h("salla-list-tile", { class: "s-scopes-header" }, index.h("div", { slot: "icon", class: "s-scopes-header-icon" }, index.h("salla-skeleton", { type: "circle" })), index.h("div", { slot: "title", class: "s-scopes-header-title mb-5" }, index.h("salla-skeleton", { height: '15px', width: '50%' })), index.h("div", { slot: "subtitle", class: "s-scopes-header-subtitle" }, index.h("salla-skeleton", { height: '10px' }), index.h("salla-skeleton", { height: '10px', width: '75%' }))), index.h("div", { class: "s-scopes-skeleton-search" }, index.h("salla-skeleton", { height: '10px', width: '50%' }), index.h("salla-skeleton", { height: '30px', width: '100%' })), index.h("div", { class: "s-scopes-skeleton-scopes" }, index.h("salla-skeleton", { height: '10px', width: '30%' }), index.h("salla-skeleton", { height: '10px', width: '25%' }), index.h("salla-skeleton", { height: '10px', width: '30%' }), index.h("salla-skeleton", { height: '10px', width: '25%' }), index.h("salla-skeleton", { height: '10px', width: '30%' }), index.h("salla-skeleton", { height: '10px', width: '25%' }), index.h("salla-skeleton", { height: '10px', width: '30%' }), index.h("salla-skeleton", { height: '10px', width: '25%' })), index.h("div", { class: "s-scopes-skeleton-btn" }, index.h("salla-skeleton", { height: '40px', width: '100%' }))))
|
|
9376
11349
|
:
|
|
9377
11350
|
[index.h("salla-list-tile", { class: this.originalScopesList?.length ? "s-scopes-header block" : "s-hidden" }, index.h("div", { slot: "icon", class: "s-scopes-header-icon", innerHTML: StoreAlt }), index.h("div", { slot: "title", class: "s-scopes-header-title" }, salla.lang.get('blocks.scope.you_are_browse_store_from')), index.h("div", { slot: "subtitle", class: "s-scopes-header-subtitle" }, !!this.selected_scope ? this.selected_scope.name : "")), index.h("div", { class: "s-scopes-wrap" }, !!this.originalScopesList?.length && index.h("h4", { class: "s-scopes-title" }, this.getFormTitle()), this.originalScopesList?.length > this.searchDisplayLimit ?
|
|
@@ -9505,12 +11478,12 @@ const SallaSearch = class {
|
|
|
9505
11478
|
this.inputValue.length < 3 ? this.container.classList.remove('s-search-no-results') : '';
|
|
9506
11479
|
}
|
|
9507
11480
|
render() {
|
|
9508
|
-
const searchContent = index.h("div", { key: '
|
|
9509
|
-
index.h("salla-button", { loading: this.loading, class: { 's-search-action': true, 's-search-action-oval': this.oval }, onClick: () => this.handleActionClick() }, !this.loading && index.h("span", { innerHTML: Search })) : null), index.h("div", { key: '
|
|
11481
|
+
const searchContent = index.h("div", { key: 'fe1ad73a7d7cdc9bfacb43e5c8f1b2d2c5983f9e', class: { 's-search-container': true, 's-search-inline': this.inline }, ref: container => this.container = container }, index.h("div", { key: 'df9c5af32950d9fc1ec30f46054630244fd2e2c1', class: "s-search-input-wrapper" }, index.h("span", { key: 'f4c1788bcd50992364e52388e425cc19c0906ec5', class: "s-search-icon-wrap" }, index.h("span", { key: 'a46da8c6f02e4970c903dc73d3d4a4e107a543f4', class: "s-search-icon", innerHTML: this.loading ? '<i class="s-search-spinner-loader"/>' : Search })), index.h("input", { key: 'af5fff2641e6416f06c51c01e19e007c6ff43e32', type: "search", enterkeyhint: "search", autocomplete: "off", class: "s-search-input", placeholder: salla.lang.get('blocks.header.search_placeholder'), onInput: (e) => this.limitWordsAndSearch(e), onKeyDown: e => this.handleKeyDown(e), ref: input => this.searchInput = input, style: { height: this.height + 'px', borderRadius: this.oval ? this.height / 2 + 'px' : '' } }), this.showAction ?
|
|
11482
|
+
index.h("salla-button", { loading: this.loading, class: { 's-search-action': true, 's-search-action-oval': this.oval }, onClick: () => this.handleActionClick() }, !this.loading && index.h("span", { innerHTML: Search })) : null), index.h("div", { key: 'e742cf41fdf23b37a46324df3bac24abc2c9bf03', class: "s-search-results" }, this.results?.data.map((product) => index.h("a", { href: product.url + '?from=search-bar', class: { "s-search-product": true, 's-search-product-not-available': !product.is_available }, innerHTML: this.productSlot
|
|
9510
11483
|
.replace(/\{name\}/g, product.name)
|
|
9511
11484
|
.replace(/\{price\}/g, product.price ? salla.money(product.price) : '')
|
|
9512
11485
|
.replace(/\{regular_price\}/g, product.is_on_sale && product.regular_price ? salla.money(product.regular_price) : '')
|
|
9513
|
-
.replace(/\{image\}/g, product.image.url) })), index.h("p", { key: '
|
|
11486
|
+
.replace(/\{image\}/g, product.image.url) })), index.h("p", { key: 'bea643f12fa014f6df1dee41a1a8ee8c41022458', ref: el => this.noResults = el, class: "s-search-no-results-placeholder" }, salla.lang.get('common.elements.no_options'))));
|
|
9514
11487
|
return (this.inline ?
|
|
9515
11488
|
index.h("div", { class: "s-search-modal" }, searchContent)
|
|
9516
11489
|
:
|
|
@@ -9553,7 +11526,7 @@ const SallaSkeleton = class {
|
|
|
9553
11526
|
's-skeleton-item': true,
|
|
9554
11527
|
's-skeleton-item-circular': this.type == 'circle',
|
|
9555
11528
|
};
|
|
9556
|
-
return (index.h(index.Host, { key: '
|
|
11529
|
+
return (index.h(index.Host, { key: 'df1344797b9cbe42331625a2a1f432e07d6bd9ef', class: "s-skeleton-wrapper", style: { width: this.width, height: this.height } }, index.h("div", { key: 'b56611551bb2b2bcb02b46240e30f88e2ea7aea5', class: classes }, "\u00A0")));
|
|
9557
11530
|
}
|
|
9558
11531
|
};
|
|
9559
11532
|
SallaSkeleton.style = sallaSkeletonCss;
|
|
@@ -10076,7 +12049,7 @@ const SallaSlider = class {
|
|
|
10076
12049
|
classes += this.verticalThumbs ? ' s-slider-vertical ' : ' s-slider-horizontal ';
|
|
10077
12050
|
classes += this.arrowsCentered ? ' s-slider-v-centered ' : '';
|
|
10078
12051
|
classes += this.gridThumbs ? ' s-slider-with-grid-thumbs ' : '';
|
|
10079
|
-
return (index.h(index.Host, { key: '
|
|
12052
|
+
return (index.h(index.Host, { key: '85e91dde02b7f32655d0ac10e5abb7f9e49d7157', class: 's-slider-wrapper ' + classes }, this.blockTitle || this.showControls ?
|
|
10080
12053
|
index.h("div", { class: "s-slider-block__title" }, this.blockTitle ?
|
|
10081
12054
|
index.h("div", { class: "s-slider-block__title-right" }, index.h("h2", null, this.blockTitle), this.blockSubtitle ? index.h("p", { innerHTML: this.blockSubtitle }) : '')
|
|
10082
12055
|
: '', index.h("div", { class: "s-slider-block__title-left" }, this.displayAllUrl ?
|
|
@@ -10084,7 +12057,7 @@ const SallaSlider = class {
|
|
|
10084
12057
|
: '', this.showControls ?
|
|
10085
12058
|
index.h("div", { class: "s-slider-block__title-nav", dir: "rtl" }, index.h("button", { "aria-label": "Previous Slide", class: "s-slider-prev s-slider-nav-arrow" }, index.h("span", { class: "s-slider-button-icon", innerHTML: this.direction == 'rtl' ? ArrowRightIcon : ArrowLeftIcon })), index.h("button", { "aria-label": "Next Slide", class: "s-slider-next s-slider-nav-arrow" }, index.h("span", { class: "s-slider-button-icon", innerHTML: this.direction == 'rtl' ? ArrowLeftIcon : ArrowRightIcon })))
|
|
10086
12059
|
: ''))
|
|
10087
|
-
: '', index.h("div", { key: '
|
|
12060
|
+
: '', index.h("div", { key: '8842ac56011138fd8456257bff568919c9ce8867', class: "swiper s-slider-container", ref: el => this.sliderContainer = el, dir: this.vertical ? "ltr" : this.direction }, index.h("slot", { key: '17fb40e69031d4c329df9d00fb75443d0ff9ba0c' }), index.h("div", { key: 'b8f42b180a271b4a873d99024251705e9d76adde', class: "swiper-wrapper s-slider-swiper-wrapper", ref: el => this.sliderWrapper = el }, index.h("slot", { key: '82ef4871810000d0b65a24518c6613a6484a2ee9', name: 'items' })), this.pagination ? index.h("div", { class: "swiper-pagination" }) : ''), this.type == 'thumbs' && this.hasThumbSlot ? index.h("div", { class: "s-slider-thumbs" }, index.h("div", { class: "swiper s-slider-thumbs-container", dir: this.getThumbsDirection(), ref: el => this.thumbsSliderContainer = el }, index.h("div", { class: { "s-slider-swiper-wrapper swiper-wrapper": true, "s-slider-grid-thumbs": this.gridThumbs }, ref: el => this.thumbsSliderWrapper = el }, index.h("slot", { name: "thumbs" })), this.showThumbsControls ?
|
|
10088
12061
|
index.h("div", { class: "s-slider-thumbs-nav", dir: "rtl" }, index.h("button", { "aria-label": "Previous Slide", class: "s-slider-thumbs-prev s-slider-nav-arrow" }, index.h("span", { class: "s-slider-button-icon", innerHTML: this.direction == 'rtl' ? ArrowRightIcon : ArrowLeftIcon })), index.h("button", { "aria-label": "Next Slide", class: "s-slider-thumbs-next s-slider-nav-arrow" }, index.h("span", { class: "s-slider-button-icon", innerHTML: this.direction == 'rtl' ? ArrowLeftIcon : ArrowRightIcon })))
|
|
10089
12062
|
: null))
|
|
10090
12063
|
: null));
|
|
@@ -10247,7 +12220,7 @@ const SallaSocialShare = class {
|
|
|
10247
12220
|
window.a2a?.init('page');
|
|
10248
12221
|
}
|
|
10249
12222
|
render() {
|
|
10250
|
-
return (index.h("div", { key: '
|
|
12223
|
+
return (index.h("div", { key: 'e104cbf1051f36e7d1055a96b8d42e0f38b70f21', class: "s-social-share-wrapper" }, index.h("slot", { key: '8519676943448a6b87b1b3df8dd74b78de72aeb9', name: 'widget' }, index.h("salla-button", { key: '0be8b0bf52f046f6818b530430ce1e636fcd36c2', "aria-label": "Share", onClick: () => this.open(), class: "s-social-share-btn", shape: "icon", fill: "outline", color: "light" }, index.h("span", { key: 'e637247fec7fd1a0235a410ca3e28fb4e7eff7f3', innerHTML: this.opened ? Cancel : ShareAlt }))), index.h("ul", { key: '8a378bac1865b26744ad31e6bf7218174b24bdd6', ref: el => this.shareMenu = el, class: "s-social-share-list a2a_kit share", "data-a2a-url": this.url ? this.url : window.location.href, "data-a2a-title": this.urlName ? this.urlName : document.title }, this.platforms.split(',').map(platform => {
|
|
10251
12224
|
return (index.h("li", null, index.h("a", { class: `a2a_button_${platform}`, "aria-label": `Share Via ${platform}` }, this.platformIcons.map((icon) => {
|
|
10252
12225
|
if (icon.name === platform) {
|
|
10253
12226
|
return index.h("span", { class: "s-social-share-icon", innerHTML: icon.icon });
|
|
@@ -10286,7 +12259,7 @@ const SallaTabContent = class {
|
|
|
10286
12259
|
's-tabs-content': true,
|
|
10287
12260
|
's-tabs-content-selected': this.isSelected
|
|
10288
12261
|
};
|
|
10289
|
-
return (index.h("div", { key: '
|
|
12262
|
+
return (index.h("div", { key: '571a30d15d890516a1382ed25239df46de519a12', class: classes }, index.h("slot", { key: '4ceb77d0d6fb15f28e1bb51ec842b7a658ccc160' })));
|
|
10290
12263
|
}
|
|
10291
12264
|
};
|
|
10292
12265
|
SallaTabContent.style = sallaTabContentCss;
|
|
@@ -10345,7 +12318,7 @@ const SallaTabHeader = class {
|
|
|
10345
12318
|
's-tabs-active': this.isSelected,
|
|
10346
12319
|
};
|
|
10347
12320
|
return [
|
|
10348
|
-
index.h("div", { key: '
|
|
12321
|
+
index.h("div", { key: '01eec3d799fd24f75ee29e65447e166057aed846', class: classes, onClick: this.onClick.bind(this) }, index.h("slot", { key: '200d5e89d7bf9cf232c997fa14c0384be65001c1' })),
|
|
10349
12322
|
];
|
|
10350
12323
|
}
|
|
10351
12324
|
};
|
|
@@ -10398,7 +12371,7 @@ const SallaTabs = class {
|
|
|
10398
12371
|
}
|
|
10399
12372
|
render() {
|
|
10400
12373
|
return [
|
|
10401
|
-
index.h("div", { key: '
|
|
12374
|
+
index.h("div", { key: '11dca6efd64c797274f2b71aa10426fbdf08d351', class: "s-tabs" }, index.h("div", { key: '9afd9c6a09728218cddc084c77f417d0249bdfd9', class: "s-tabs-header" }, index.h("slot", { key: 'eef1f2faed6b440c592e51f6d1205e140584b070', name: "header" })), index.h("div", { key: 'adb5bd9c1af2ba78c173eb3fbd5c73c0513ccca5', class: "s-tabs-content-wrapper" }, index.h("slot", { key: 'db9eaa79d095ef71fb1df1ab96ddbb925ec59b40', name: "content" })))
|
|
10402
12375
|
];
|
|
10403
12376
|
}
|
|
10404
12377
|
get host() { return index.getElement(this); }
|
|
@@ -10416,7 +12389,7 @@ const SallaTelInput = class {
|
|
|
10416
12389
|
if (this.TelInput)
|
|
10417
12390
|
return;
|
|
10418
12391
|
try {
|
|
10419
|
-
const telInputModule = await Promise.resolve().then(function () { return require('./index-
|
|
12392
|
+
const telInputModule = await Promise.resolve().then(function () { return require('./index-xI-pRoDr.js'); }).then(function (n) { return n.index; });
|
|
10420
12393
|
this.TelInput = telInputModule.default;
|
|
10421
12394
|
}
|
|
10422
12395
|
catch (error) {
|
|
@@ -10530,7 +12503,7 @@ const SallaTelInput = class {
|
|
|
10530
12503
|
}
|
|
10531
12504
|
}
|
|
10532
12505
|
render() {
|
|
10533
|
-
return (index.h(index.Host, { key: '
|
|
12506
|
+
return (index.h(index.Host, { key: '8dae2336c70ca8da12846544c99eff5150ee3197', class: "s-tel-input" }, index.h("input", { key: '6512ba297a7f1e85f3e6b1a6ba7634c16e57116c', type: "tel", disabled: this.disabled, name: this.name, value: this.phone, onChange: (event) => this.handleCountryInput(event), ref: el => this.phoneInput = el, enterkeyhint: "next", autocomplete: "tel", class: "s-tel-input-control tel-input s-ltr" }), index.h("span", { key: '92def9152e10e06c390e8333048095dcc7613867', class: "s-tel-input-error-msg", ref: el => this.errorMsg = el }), index.h("input", { key: '0a77d8be70d5f9a1e8ac75e444537f0f45fa76d0', type: "hidden", name: "country_code", value: this.countryCode, ref: el => this.countryCodeInput = el, class: "country_code" })));
|
|
10534
12507
|
}
|
|
10535
12508
|
componentDidLoad() {
|
|
10536
12509
|
this.initTelInput();
|
|
@@ -10923,7 +12896,7 @@ const SallaUserProfile = class {
|
|
|
10923
12896
|
if (field.type !== FormFieldTypes.Photo) {
|
|
10924
12897
|
return (index.h("input", { type: field.type, id: `${field.id}`, value: field.value, onChange: event => this.handleFieldChange(`custom_fields[${field.id}]`, event), name: `custom_fields[${field.id}]`, class: "form-input", required: field.required }));
|
|
10925
12898
|
}
|
|
10926
|
-
return (index.h("salla-file-upload", { "instant-upload": true, value: field.value, url: this.getFileUploadUrl(), name: `custom_fields[${field.id}]`, "payload-name": "image", height: "120px", onAdded: data => this.handleOnFileAdded(`custom_fields[${field.id}]`, data) }, index.h("div", { class: "s-user-profile-filepond-placeholder" }, index.h("span", { class: "s-user-profile-filepond-placeholder-icon" }, index.h("i", { innerHTML:
|
|
12899
|
+
return (index.h("salla-file-upload", { "instant-upload": true, value: field.value, url: this.getFileUploadUrl(), name: `custom_fields[${field.id}]`, "payload-name": "image", height: "120px", onAdded: data => this.handleOnFileAdded(`custom_fields[${field.id}]`, data) }, index.h("div", { class: "s-user-profile-filepond-placeholder" }, index.h("span", { class: "s-user-profile-filepond-placeholder-icon" }, index.h("i", { innerHTML: CameraIcon })), index.h("p", { class: "s-user-profile-filepond-placeholder-text" }, this.drag_and_drop_trans), index.h("span", { class: "filepond--label-action" }, this.browse_trans))));
|
|
10927
12900
|
}
|
|
10928
12901
|
// Submit form method
|
|
10929
12902
|
submitForm(event) {
|
|
@@ -11051,13 +13024,17 @@ const SallaUserSettings = class {
|
|
|
11051
13024
|
await salla.profile.delete().finally(() => this.confirmationModal.close());
|
|
11052
13025
|
}
|
|
11053
13026
|
render() {
|
|
11054
|
-
return (index.h(index.Host, { key: '
|
|
13027
|
+
return (index.h(index.Host, { key: '85b2fe2739f6ac3c55939d3cb9c87fc404413e7f', class: "s-user-settings-wrapper" }, this.canHideName && index.h("div", { key: 'e46be8b9cb4898c9b676ee67f0750bb654bda953', class: "s-user-settings-section" }, index.h("salla-list-tile", { key: '48f81d5a9b511c2a8baabab2aab6ad3dcfb98370' }, index.h("div", { key: '9009c4d612aea7e7a6834b90f38d03d8c95bcc84', slot: "icon", class: "s-user-settings-section-icon" }, index.h("span", { key: '03f209e6e1e1adbdb130f9b80aed30f0618dd58c', innerHTML: UserCancel })), index.h("div", { key: 'fb02ca2387806135ac3f074f0a9f30ce4bb325ca', slot: "title", class: "s-user-settings-section-title" }, this.capitalizeText(this.hideMyName)), index.h("div", { key: '1ddbd1144a59745bf26f4650eb5d050a34d42e8f', slot: "subtitle", class: "s-user-settings-section-subtitle" }, this.capitalizeText(this.hideMyNameDesc)), index.h("div", { key: '0ff6163a407a53ff100c8d3235212c167dbb006a', slot: 'action', class: "s-user-settings-section-action" }, index.h("label", { key: '03b817a0bea880c9a2e056d4d8f0fb737dc0e5da', class: "s-toggle" }, index.h("input", { key: 'fcb56427c6d1ae503abdc768358e9ecfa9139dac', class: "s-toggle-input", checked: this.isHiddenName, onChange: (e) => this.toggleSetting('is_hidden_name', e), type: "checkbox" }), index.h("div", { key: 'ff312279ede50b86446d1305217053942d05a603', class: "s-toggle-switcher" }))))), index.h("div", { key: '08cf0045a6f96ae7046d9a7c640e53a5b2cec7dc', class: "s-user-settings-section" }, index.h("salla-list-tile", { key: '1ccbcd93cf4cef91693603b5b05dbc4f3b85dc65' }, index.h("div", { key: 'bf5270f2d2cae798463ab9516c11321e96c461ff', slot: "icon", class: "s-user-settings-section-icon" }, index.h("span", { key: '3bc3927296faa253a8b91710049eca3372fb24aa', innerHTML: Bullhorn })), index.h("div", { key: '60ddca373590545a7fd03498e4ff7306a23b05a9', slot: "title", class: "s-user-settings-section-title" }, this.capitalizeText(this.promotionalMsgs)), index.h("div", { key: '874e81d5e4727160a85bb3381fdfadcd65e774c0', slot: "subtitle", class: "s-user-settings-section-subtitle" }, this.capitalizeText(this.promotionalMsgsDesc)), index.h("div", { key: '6d2aacf7a72c4d25163913eccbb0a3e94595ec75', slot: 'action', class: "s-user-settings-section-action" }, index.h("label", { key: 'cf58459624592b34083afe61a0afc29dea03864e', class: "s-toggle" }, index.h("input", { key: 'b854ce4ca8224c8200623aad0dea4c659d89dee1', class: "s-toggle-input", checked: this.isNotifiable, onChange: (e) => this.toggleSetting('is_notifiable', e), type: "checkbox" }), index.h("div", { key: '785a5765e36056629a23ca53e48715f91c14ee1f', class: "s-toggle-switcher" }))))), index.h("div", { key: '9f58724a8d748809b39874efaa861643a78076eb', class: "s-user-settings-section s-user-settings-section-deactivate-user" }, index.h("salla-list-tile", { key: '12a69027f2822b6fa1e8fb641278932fc2206335' }, index.h("div", { key: '679eec74598612167c77443e5f6977991b333fd7', slot: "icon", class: "s-user-settings-section-icon" }, index.h("span", { key: '0263f8f31ad3e4ca60f2bb4bae910c143f2d36a8', innerHTML: UserOff })), index.h("div", { key: '6c0c17dfbcbb48ae3882b07b58fb0d1245a28cdb', slot: "title", class: "s-user-settings-section-title" }, this.capitalizeText(this.deactivateAccount)), index.h("div", { key: '07389c3b86b3d8e821b8b9c33cf43de1ee6527db', slot: "subtitle", class: "s-user-settings-section-subtitle" }, this.capitalizeText(this.deactivateDesc)), index.h("div", { key: 'e98736162d465c0717550eb8231b120acfafc4f6', slot: 'action', class: "s-user-settings-section-action" }, index.h("salla-button", { key: 'd29c5023b3a35f95c94a06dc87f0e2504b3a6390', fill: "outline", color: "danger", shape: "btn", size: "medium", width: "normal", onClick: () => this.openDeactivateModal() }, this.capitalizeText(this.deactivateAccount))))), index.h("salla-modal", { key: '6f23ca61fe62de261e7d2f616a4d5bf13fba1577', width: "sm", subTitle: this.capitalizeText(this.sorryForLeavingText), ref: modal => this.confirmationModal = modal }, index.h("span", { key: '89073dfc15d4a1349618180c776968012e843556', slot: 'icon', class: "s-user-settings-confirmation-icon", innerHTML: UserOff }), index.h("div", { key: 'f464a56ab783c4ddd51cc40e4d4dbf2f4ae21be2', class: "s-user-settings-confirmation" }, index.h("div", { key: 'e9921faaf8718ba51937006360b11d409bde4e05', class: "s-user-settings-confirmation-warning" }, this.capitalizeText(this.warningText)), index.h("div", { key: '4a71df323e6fa2b86cb85e77af438a51e9c1c5a9', class: "s-user-settings-confirmation-actions" }, index.h("salla-button", { key: '156249d17bdcc25b7c586af416001ec60e8b0f5b', width: "wide", onClick: () => this.confirmationModal.close() }, this.capitalizeText(this.keepAccount)), index.h("salla-button", { key: 'acbe44c04f77f8ccdcaeb90bfb731de399f88fc7', fill: 'outline', loading: this.buttonLoading, width: "wide", onClick: () => this.deleteAccount() }, this.capitalizeText(this.deactivateAccount)))))));
|
|
11055
13028
|
}
|
|
11056
13029
|
};
|
|
11057
13030
|
SallaUserSettings.style = sallaUserSettingsCss;
|
|
11058
13031
|
|
|
13032
|
+
exports.salla_accordion = SallaAccordion;
|
|
13033
|
+
exports.salla_accordion_body = SallaAccordionBody;
|
|
13034
|
+
exports.salla_accordion_head = SallaAccordionHead;
|
|
11059
13035
|
exports.salla_add_product_button = SallaAddProductButton;
|
|
11060
13036
|
exports.salla_alert = SallaAlert;
|
|
13037
|
+
exports.salla_booking_field = SallaBookingField;
|
|
11061
13038
|
exports.salla_bottom_alert = SallaBottomAlert;
|
|
11062
13039
|
exports.salla_breadcrumb = SallaBreadcrumb;
|
|
11063
13040
|
exports.salla_button = SallaButton;
|
|
@@ -11066,6 +13043,7 @@ exports.salla_color_picker = SallaColorPicker;
|
|
|
11066
13043
|
exports.salla_comment_form = SallaCommentForm;
|
|
11067
13044
|
exports.salla_comment_item = SallaCommentItem;
|
|
11068
13045
|
exports.salla_comments = SallaComments;
|
|
13046
|
+
exports.salla_conditional_fields = SallaConditionalFields;
|
|
11069
13047
|
exports.salla_count_down = SallaCountDown;
|
|
11070
13048
|
exports.salla_datetime_picker = SallaDatetimePicker;
|
|
11071
13049
|
exports.salla_drawer = SallaDrawer;
|
|
@@ -11081,10 +13059,16 @@ exports.salla_maintenance_alert = SallaMaintenanceAlert;
|
|
|
11081
13059
|
exports.salla_map = SallaMap;
|
|
11082
13060
|
exports.salla_menu = SallaMenu;
|
|
11083
13061
|
exports.salla_modal = SallaModal;
|
|
13062
|
+
exports.salla_multiple_bundle_product = SallaMultipleBundleProduct;
|
|
13063
|
+
exports.salla_multiple_bundle_product_cart = SallaMultipleBundleProductCart;
|
|
13064
|
+
exports.salla_multiple_bundle_product_details = SallaMultipleBundleProductDetails;
|
|
13065
|
+
exports.salla_multiple_bundle_product_options_modal = SallaMultipleBundleProductOptionsModal;
|
|
13066
|
+
exports.salla_multiple_bundle_product_slider = SallaMultipleBundleProductSlider;
|
|
11084
13067
|
exports.salla_offer_modal = SallaOfferModal;
|
|
11085
13068
|
exports.salla_placeholder = SallaPlaceholder;
|
|
11086
13069
|
exports.salla_product_availability = SallaProductAvailability;
|
|
11087
13070
|
exports.salla_product_card = SallaProductCard;
|
|
13071
|
+
exports.salla_product_options = SallaProductOptions;
|
|
11088
13072
|
exports.salla_product_size_guide = SallaProductSizeGuide;
|
|
11089
13073
|
exports.salla_products_list = SallaProductsList;
|
|
11090
13074
|
exports.salla_products_slider = SallaProductsSlider;
|