@salla.sa/twilight-components 2.14.271 → 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-DZKo1pV9.js → filepond-B6LUaQ9F.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-Ddu0-eEg.js → filepond-plugin-file-poster-DlB67Vv3.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-B2VId_n-.js → filepond-plugin-file-validate-size-D7kuqaEC.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-lGUMFCde.js → filepond-plugin-file-validate-type-CliXp1Qt.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-BlEvC0bv.js → filepond-plugin-image-edit-BRIZbIyN.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-C9yPmasn.js → filepond-plugin-image-exif-orientation-bFbWHyQs.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-BPQ9o2YT.js → filepond-plugin-image-preview-24nxaVX6.js} +1 -1
- package/dist/cjs/{index-DpqjX7F3.js → index-BpUrZ_-D.js} +136 -26
- package/dist/cjs/{index-4c5cqxT-.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 -121
- 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-login-modal/salla-login-modal.js +0 -1
- 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-login-modal.js +0 -1
- 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-DbqR2fSR.js → filepond-C8M-qAIs.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-oSU_je8q.js → filepond-plugin-file-poster-UfHq-uvl.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-DBNbjpCq.js → filepond-plugin-file-validate-size-DZ15xnJZ.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-FNihY0D1.js → filepond-plugin-file-validate-type-CWR9opI0.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-BvLwmvqS.js → filepond-plugin-image-edit-XbR1h-bg.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-CzDuHCvL.js → filepond-plugin-image-exif-orientation-cSRDvvXQ.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-OJew5tLP.js → filepond-plugin-image-preview-B-SvzNFg.js} +1 -1
- package/dist/esm/{index-DFnMPSip.js → index-Q_DltBmK.js} +1 -1
- package/dist/esm/{index-DXrQDmAN.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 -112
- 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-11c1fc02.entry.js → p-00d8544c.entry.js} +1 -1
- package/dist/twilight/{p-c87e16b6.entry.js → p-06d126b6.entry.js} +1 -1
- package/dist/twilight/{p-adc5a167.entry.js → p-1cc68ef5.entry.js} +1 -1
- package/dist/twilight/{p-yWcVqMiP.js → p-1ekWkYOJ.js} +1 -1
- package/dist/twilight/p-21b37923.entry.js +4 -0
- package/dist/twilight/{p-c2f0f504.entry.js → p-263b9b06.entry.js} +1 -1
- package/dist/twilight/{p-c0450f72.entry.js → p-2787ff9f.entry.js} +1 -1
- package/dist/twilight/p-3c1484b9.entry.js +11 -0
- package/dist/twilight/{p-6ed0de44.entry.js → p-5057b400.entry.js} +1 -1
- package/dist/twilight/{p-5c67f412.entry.js → p-5278b873.entry.js} +1 -1
- package/dist/twilight/{p-1d1672e8.entry.js → p-56f7a2ba.entry.js} +1 -1
- package/dist/twilight/{p-5aa17da1.entry.js → p-697db5c6.entry.js} +1 -1
- package/dist/twilight/{p-81131b67.entry.js → p-73a8296a.entry.js} +1 -1
- package/dist/twilight/{p-93b26c0b.entry.js → p-7603a820.entry.js} +1 -1
- package/dist/twilight/{p-86f00281.entry.js → p-7c8d7ca3.entry.js} +1 -1
- package/dist/twilight/{p-62312d5b.entry.js → p-80a07063.entry.js} +1 -1
- package/dist/twilight/{p-e987bf56.entry.js → p-82c156ab.entry.js} +1 -1
- package/dist/twilight/{p-fed06a9f.entry.js → p-8380c411.entry.js} +1 -1
- package/dist/twilight/{p-906ec5e3.entry.js → p-946e5649.entry.js} +1 -1
- package/dist/twilight/{p-01b67a23.entry.js → p-9bcd9c87.entry.js} +1 -1
- package/dist/twilight/p-9c477fdf.entry.js +4 -0
- package/dist/twilight/{p-B3DRwtQ_.js → p-B-nQtFTN.js} +1 -1
- package/dist/twilight/{p-BeXdXg7Q.js → p-BI2zk2yo.js} +1 -1
- package/dist/twilight/{p-E9O3bnHS.js → p-BRD27esZ.js} +1 -1
- package/dist/twilight/{p-MbgAyDn3.js → p-CUYEEJ4c.js} +1 -1
- package/dist/twilight/{p-BvKpNEUI.js → p-DUvdNUoC.js} +1 -1
- package/dist/twilight/{p-C3joUrVg.js → p-DhR67rwu.js} +1 -1
- package/dist/twilight/p-a01dd6b7.entry.js +4 -0
- package/dist/twilight/{p-849be825.entry.js → p-a3e000ef.entry.js} +1 -1
- package/dist/twilight/{p-0e18add0.entry.js → p-a6c14a64.entry.js} +1 -1
- package/dist/twilight/p-b0b79820.entry.js +4 -0
- package/dist/twilight/{p-57e8c6b5.entry.js → p-b5581886.entry.js} +1 -1
- package/dist/twilight/p-b81437f4.entry.js +4 -0
- package/dist/twilight/{p-591043a2.entry.js → p-bf010154.entry.js} +1 -1
- package/dist/twilight/{p-d3022e35.entry.js → p-c0388251.entry.js} +1 -1
- package/dist/twilight/{p-a71a3922.entry.js → p-c9ab361e.entry.js} +1 -1
- package/dist/twilight/{p-d8e500cc.entry.js → p-ed85bc00.entry.js} +1 -1
- package/dist/twilight/p-f7863a58.entry.js +4 -0
- package/dist/twilight/{p-DXrQDmAN.js → p-gLeBNvS1.js} +2 -2
- package/dist/twilight/{p-BQuXdlAk.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-DfTgypwp.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-i4_OI7UA.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-137e1751.entry.js +0 -4
- package/dist/twilight/p-18cd5d66.entry.js +0 -4
- package/dist/twilight/p-36b30807.entry.js +0 -4
- package/dist/twilight/p-6159654b.entry.js +0 -4
- package/dist/twilight/p-9d9e5493.entry.js +0 -4
- package/dist/twilight/p-C6jIkM-X.js +0 -4
- package/dist/twilight/p-CqZlwzcH.js +0 -4
- package/dist/twilight/p-DfeagqF1.js +0 -4
- package/dist/twilight/p-affed6bd.entry.js +0 -11
- package/dist/twilight/p-cfbd199f.entry.js +0 -4
- package/dist/twilight/p-d060275b.entry.js +0 -4
- package/dist/twilight/p-e162d003.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
|
|
@@ -4538,7 +4957,6 @@ const SallaLoginModal = class {
|
|
|
4538
4957
|
catch (error) {
|
|
4539
4958
|
Salla.log('Error on assign');
|
|
4540
4959
|
}
|
|
4541
|
-
await Salla.cart.api.assign();
|
|
4542
4960
|
withCartReset && Salla.cart.reset();
|
|
4543
4961
|
!Salla.auth.api.isSessionless() && await Salla.auth.api.request('auth/jwt');
|
|
4544
4962
|
setTimeout(() => window.location.reload(), 100);
|
|
@@ -5861,83 +6279,861 @@ const SallaModal = class {
|
|
|
5861
6279
|
};
|
|
5862
6280
|
SallaModal.style = sallaModalCss;
|
|
5863
6281
|
|
|
5864
|
-
|
|
5865
|
-
<title>tag</title>
|
|
5866
|
-
<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>
|
|
5867
|
-
</svg>
|
|
5868
|
-
`;
|
|
6282
|
+
const sallaMultipleBundleProductCss = ":host{display:block}";
|
|
5869
6283
|
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
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;
|
|
5876
6342
|
|
|
5877
|
-
const
|
|
6343
|
+
const sallaMultipleBundleProductCartCss = "";
|
|
5878
6344
|
|
|
5879
|
-
const
|
|
6345
|
+
const SallaMultipleBundleProductCart = class {
|
|
5880
6346
|
constructor(hostRef) {
|
|
5881
6347
|
index.registerInstance(this, hostRef);
|
|
5882
|
-
this.
|
|
5883
|
-
this.
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
salla.log('User selected to don\'t show this offer again.');
|
|
5897
|
-
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());
|
|
5898
6362
|
}
|
|
5899
|
-
|
|
5900
|
-
});
|
|
6363
|
+
}
|
|
5901
6364
|
}
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
* @param offer - The offer being viewed in the modal
|
|
5905
|
-
*/
|
|
5906
|
-
emitPromotionViewed(offer) {
|
|
5907
|
-
if (!offer)
|
|
5908
|
-
return;
|
|
5909
|
-
salla.event.emit('promotion::viewed', [{
|
|
5910
|
-
id: offer.id?.toString(),
|
|
5911
|
-
creative: offer.message,
|
|
5912
|
-
name: offer.name,
|
|
5913
|
-
position: `${this.offer_type}_offer_modal`
|
|
5914
|
-
}]);
|
|
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" })));
|
|
5915
6367
|
}
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
*/
|
|
5920
|
-
emitPromotionClicked(offer) {
|
|
5921
|
-
if (!offer)
|
|
5922
|
-
return;
|
|
5923
|
-
salla.event.emit('promotion::clicked', [{
|
|
5924
|
-
id: offer.id?.toString(),
|
|
5925
|
-
creative: offer.message,
|
|
5926
|
-
name: offer.name,
|
|
5927
|
-
position: `${this.offer_type}_offer_modal`
|
|
5928
|
-
}]);
|
|
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))))));
|
|
5929
6371
|
}
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
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]))
|
|
5941
7137
|
.catch(e => {
|
|
5942
7138
|
this.hasError = true;
|
|
5943
7139
|
this.errorMessage = e.response?.data?.error?.message || e.response?.data;
|
|
@@ -6032,7 +7228,7 @@ const SallaOfferModal = class {
|
|
|
6032
7228
|
// '</div>';
|
|
6033
7229
|
// }
|
|
6034
7230
|
render() {
|
|
6035
|
-
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
|
|
6036
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 ?
|
|
6037
7233
|
index.h("p", { class: "s-offer-modal-expiry" }, salla.lang.get('pages.products.offer_expires_in'), " ", this.offer.formatted_date)
|
|
6038
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'))),
|
|
@@ -6081,7 +7277,7 @@ const SallaPlaceholder = class {
|
|
|
6081
7277
|
};
|
|
6082
7278
|
}
|
|
6083
7279
|
render() {
|
|
6084
|
-
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'))))));
|
|
6085
7281
|
}
|
|
6086
7282
|
};
|
|
6087
7283
|
SallaPlaceholder.style = sallaPlaceholderCss;
|
|
@@ -6223,7 +7419,7 @@ const SallaProductAvailability = class {
|
|
|
6223
7419
|
field.nextElementSibling['innerText'] = '* ' + errorMsg;
|
|
6224
7420
|
}
|
|
6225
7421
|
render() {
|
|
6226
|
-
return (index.h(index.Host, { key: '
|
|
7422
|
+
return (index.h(index.Host, { key: '631de4fa7186561daed53943f2ece491a8dbe934', class: "s-product-availability-wrap" }, this.isSubscribed || this.isVisitorSubscribed
|
|
6227
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'))
|
|
6228
7424
|
:
|
|
6229
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()));
|
|
@@ -6339,14 +7535,14 @@ const SallaProductCard = class {
|
|
|
6339
7535
|
's-product-card-out-of-stock': this.productData?.is_out_of_stock,
|
|
6340
7536
|
};
|
|
6341
7537
|
const hrefProp = this.productData?.url ? { href: this.productData.url, title: `Learn more about ${this.productData?.name}` } : {};
|
|
6342
|
-
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)
|
|
6343
7539
|
? 'contain'
|
|
6344
7540
|
: this.fitImageHeight
|
|
6345
7541
|
? this.fitImageHeight
|
|
6346
|
-
: '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: '
|
|
6347
|
-
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 ?
|
|
6348
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" })))
|
|
6349
|
-
: '', 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 ?
|
|
6350
7546
|
index.h("p", { class: "s-product-card-content-subtitle" }, this.productData?.subtitle)
|
|
6351
7547
|
: ''), this.productData?.donation && !this.minimal && !this.fullImage ?
|
|
6352
7548
|
[index.h("salla-progress-bar", { donation: this.productData?.donation }), index.h("div", { class: "s-product-card-donation-input" }, this.productData?.donation?.can_donate ?
|
|
@@ -6355,7 +7551,7 @@ const SallaProductCard = class {
|
|
|
6355
7551
|
this.addBtn.donatingAmount = e.target.value;
|
|
6356
7552
|
}, id: "donation-amount", name: "donating_amount", class: "s-form-control", placeholder: this.donationAmount })]
|
|
6357
7553
|
: '')]
|
|
6358
|
-
: '', 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 ?
|
|
6359
7555
|
index.h("div", { class: "s-product-card-rating" }, index.h("span", { innerHTML: Rate }), index.h("span", null, this.productData.rating.stars))
|
|
6360
7556
|
: ''), this.isSpecial && this.productData.discount_ends
|
|
6361
7557
|
? index.h("salla-count-down", { date: this.formatDate(this.productData.discount_ends), "end-of-day": true, boxed: true, labeled: true })
|
|
@@ -6379,6 +7575,782 @@ const SallaProductCard = class {
|
|
|
6379
7575
|
};
|
|
6380
7576
|
SallaProductCard.style = sallaProductCardCss;
|
|
6381
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
|
+
|
|
6382
8354
|
var PencilRuler = `<!-- Generated by IcoMoon.io -->
|
|
6383
8355
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
6384
8356
|
<title>pencil-ruler</title>
|
|
@@ -6427,11 +8399,11 @@ const SallaProductSizeGuide = class {
|
|
|
6427
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));
|
|
6428
8400
|
}
|
|
6429
8401
|
render() {
|
|
6430
|
-
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 ?
|
|
6431
8403
|
[
|
|
6432
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 }))))
|
|
6433
8405
|
]
|
|
6434
|
-
: this.showPlaceholder(), index.h("slot", { key: '
|
|
8406
|
+
: this.showPlaceholder(), index.h("slot", { key: '6b8bebc72d4a7baea765b1e5a6d4a81862206f94', name: "footer" })));
|
|
6435
8407
|
}
|
|
6436
8408
|
get host() { return index.getElement(this); }
|
|
6437
8409
|
};
|
|
@@ -7424,7 +9396,7 @@ const SallaQuantityInput = class {
|
|
|
7424
9396
|
return this.host;
|
|
7425
9397
|
}
|
|
7426
9398
|
render() {
|
|
7427
|
-
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" })))));
|
|
7428
9400
|
}
|
|
7429
9401
|
get host() { return index.getElement(this); }
|
|
7430
9402
|
static get watchers() { return {
|
|
@@ -8324,7 +10296,7 @@ const SallaQuickBuy = class {
|
|
|
8324
10296
|
});
|
|
8325
10297
|
}
|
|
8326
10298
|
render() {
|
|
8327
|
-
return index.h(index.Host, { key: '
|
|
10299
|
+
return index.h(index.Host, { key: '46c3a8b699f4390166d027a0eb2d34451a1dd6f1' }, this.quickBuyButton());
|
|
8328
10300
|
}
|
|
8329
10301
|
quickBuyButton() {
|
|
8330
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 });
|
|
@@ -9372,7 +11344,7 @@ const SallaScopees = class {
|
|
|
9372
11344
|
return salla.onReady();
|
|
9373
11345
|
}
|
|
9374
11346
|
render() {
|
|
9375
|
-
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 ?
|
|
9376
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%' }))))
|
|
9377
11349
|
:
|
|
9378
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 ?
|
|
@@ -9506,12 +11478,12 @@ const SallaSearch = class {
|
|
|
9506
11478
|
this.inputValue.length < 3 ? this.container.classList.remove('s-search-no-results') : '';
|
|
9507
11479
|
}
|
|
9508
11480
|
render() {
|
|
9509
|
-
const searchContent = index.h("div", { key: '
|
|
9510
|
-
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
|
|
9511
11483
|
.replace(/\{name\}/g, product.name)
|
|
9512
11484
|
.replace(/\{price\}/g, product.price ? salla.money(product.price) : '')
|
|
9513
11485
|
.replace(/\{regular_price\}/g, product.is_on_sale && product.regular_price ? salla.money(product.regular_price) : '')
|
|
9514
|
-
.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'))));
|
|
9515
11487
|
return (this.inline ?
|
|
9516
11488
|
index.h("div", { class: "s-search-modal" }, searchContent)
|
|
9517
11489
|
:
|
|
@@ -9554,7 +11526,7 @@ const SallaSkeleton = class {
|
|
|
9554
11526
|
's-skeleton-item': true,
|
|
9555
11527
|
's-skeleton-item-circular': this.type == 'circle',
|
|
9556
11528
|
};
|
|
9557
|
-
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")));
|
|
9558
11530
|
}
|
|
9559
11531
|
};
|
|
9560
11532
|
SallaSkeleton.style = sallaSkeletonCss;
|
|
@@ -10077,7 +12049,7 @@ const SallaSlider = class {
|
|
|
10077
12049
|
classes += this.verticalThumbs ? ' s-slider-vertical ' : ' s-slider-horizontal ';
|
|
10078
12050
|
classes += this.arrowsCentered ? ' s-slider-v-centered ' : '';
|
|
10079
12051
|
classes += this.gridThumbs ? ' s-slider-with-grid-thumbs ' : '';
|
|
10080
|
-
return (index.h(index.Host, { key: '
|
|
12052
|
+
return (index.h(index.Host, { key: '85e91dde02b7f32655d0ac10e5abb7f9e49d7157', class: 's-slider-wrapper ' + classes }, this.blockTitle || this.showControls ?
|
|
10081
12053
|
index.h("div", { class: "s-slider-block__title" }, this.blockTitle ?
|
|
10082
12054
|
index.h("div", { class: "s-slider-block__title-right" }, index.h("h2", null, this.blockTitle), this.blockSubtitle ? index.h("p", { innerHTML: this.blockSubtitle }) : '')
|
|
10083
12055
|
: '', index.h("div", { class: "s-slider-block__title-left" }, this.displayAllUrl ?
|
|
@@ -10085,7 +12057,7 @@ const SallaSlider = class {
|
|
|
10085
12057
|
: '', this.showControls ?
|
|
10086
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 })))
|
|
10087
12059
|
: ''))
|
|
10088
|
-
: '', 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 ?
|
|
10089
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 })))
|
|
10090
12062
|
: null))
|
|
10091
12063
|
: null));
|
|
@@ -10248,7 +12220,7 @@ const SallaSocialShare = class {
|
|
|
10248
12220
|
window.a2a?.init('page');
|
|
10249
12221
|
}
|
|
10250
12222
|
render() {
|
|
10251
|
-
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 => {
|
|
10252
12224
|
return (index.h("li", null, index.h("a", { class: `a2a_button_${platform}`, "aria-label": `Share Via ${platform}` }, this.platformIcons.map((icon) => {
|
|
10253
12225
|
if (icon.name === platform) {
|
|
10254
12226
|
return index.h("span", { class: "s-social-share-icon", innerHTML: icon.icon });
|
|
@@ -10287,7 +12259,7 @@ const SallaTabContent = class {
|
|
|
10287
12259
|
's-tabs-content': true,
|
|
10288
12260
|
's-tabs-content-selected': this.isSelected
|
|
10289
12261
|
};
|
|
10290
|
-
return (index.h("div", { key: '
|
|
12262
|
+
return (index.h("div", { key: '571a30d15d890516a1382ed25239df46de519a12', class: classes }, index.h("slot", { key: '4ceb77d0d6fb15f28e1bb51ec842b7a658ccc160' })));
|
|
10291
12263
|
}
|
|
10292
12264
|
};
|
|
10293
12265
|
SallaTabContent.style = sallaTabContentCss;
|
|
@@ -10346,7 +12318,7 @@ const SallaTabHeader = class {
|
|
|
10346
12318
|
's-tabs-active': this.isSelected,
|
|
10347
12319
|
};
|
|
10348
12320
|
return [
|
|
10349
|
-
index.h("div", { key: '
|
|
12321
|
+
index.h("div", { key: '01eec3d799fd24f75ee29e65447e166057aed846', class: classes, onClick: this.onClick.bind(this) }, index.h("slot", { key: '200d5e89d7bf9cf232c997fa14c0384be65001c1' })),
|
|
10350
12322
|
];
|
|
10351
12323
|
}
|
|
10352
12324
|
};
|
|
@@ -10399,7 +12371,7 @@ const SallaTabs = class {
|
|
|
10399
12371
|
}
|
|
10400
12372
|
render() {
|
|
10401
12373
|
return [
|
|
10402
|
-
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" })))
|
|
10403
12375
|
];
|
|
10404
12376
|
}
|
|
10405
12377
|
get host() { return index.getElement(this); }
|
|
@@ -10417,7 +12389,7 @@ const SallaTelInput = class {
|
|
|
10417
12389
|
if (this.TelInput)
|
|
10418
12390
|
return;
|
|
10419
12391
|
try {
|
|
10420
|
-
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; });
|
|
10421
12393
|
this.TelInput = telInputModule.default;
|
|
10422
12394
|
}
|
|
10423
12395
|
catch (error) {
|
|
@@ -10531,7 +12503,7 @@ const SallaTelInput = class {
|
|
|
10531
12503
|
}
|
|
10532
12504
|
}
|
|
10533
12505
|
render() {
|
|
10534
|
-
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" })));
|
|
10535
12507
|
}
|
|
10536
12508
|
componentDidLoad() {
|
|
10537
12509
|
this.initTelInput();
|
|
@@ -10924,7 +12896,7 @@ const SallaUserProfile = class {
|
|
|
10924
12896
|
if (field.type !== FormFieldTypes.Photo) {
|
|
10925
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 }));
|
|
10926
12898
|
}
|
|
10927
|
-
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))));
|
|
10928
12900
|
}
|
|
10929
12901
|
// Submit form method
|
|
10930
12902
|
submitForm(event) {
|
|
@@ -11052,13 +13024,17 @@ const SallaUserSettings = class {
|
|
|
11052
13024
|
await salla.profile.delete().finally(() => this.confirmationModal.close());
|
|
11053
13025
|
}
|
|
11054
13026
|
render() {
|
|
11055
|
-
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)))))));
|
|
11056
13028
|
}
|
|
11057
13029
|
};
|
|
11058
13030
|
SallaUserSettings.style = sallaUserSettingsCss;
|
|
11059
13031
|
|
|
13032
|
+
exports.salla_accordion = SallaAccordion;
|
|
13033
|
+
exports.salla_accordion_body = SallaAccordionBody;
|
|
13034
|
+
exports.salla_accordion_head = SallaAccordionHead;
|
|
11060
13035
|
exports.salla_add_product_button = SallaAddProductButton;
|
|
11061
13036
|
exports.salla_alert = SallaAlert;
|
|
13037
|
+
exports.salla_booking_field = SallaBookingField;
|
|
11062
13038
|
exports.salla_bottom_alert = SallaBottomAlert;
|
|
11063
13039
|
exports.salla_breadcrumb = SallaBreadcrumb;
|
|
11064
13040
|
exports.salla_button = SallaButton;
|
|
@@ -11067,6 +13043,7 @@ exports.salla_color_picker = SallaColorPicker;
|
|
|
11067
13043
|
exports.salla_comment_form = SallaCommentForm;
|
|
11068
13044
|
exports.salla_comment_item = SallaCommentItem;
|
|
11069
13045
|
exports.salla_comments = SallaComments;
|
|
13046
|
+
exports.salla_conditional_fields = SallaConditionalFields;
|
|
11070
13047
|
exports.salla_count_down = SallaCountDown;
|
|
11071
13048
|
exports.salla_datetime_picker = SallaDatetimePicker;
|
|
11072
13049
|
exports.salla_drawer = SallaDrawer;
|
|
@@ -11082,10 +13059,16 @@ exports.salla_maintenance_alert = SallaMaintenanceAlert;
|
|
|
11082
13059
|
exports.salla_map = SallaMap;
|
|
11083
13060
|
exports.salla_menu = SallaMenu;
|
|
11084
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;
|
|
11085
13067
|
exports.salla_offer_modal = SallaOfferModal;
|
|
11086
13068
|
exports.salla_placeholder = SallaPlaceholder;
|
|
11087
13069
|
exports.salla_product_availability = SallaProductAvailability;
|
|
11088
13070
|
exports.salla_product_card = SallaProductCard;
|
|
13071
|
+
exports.salla_product_options = SallaProductOptions;
|
|
11089
13072
|
exports.salla_product_size_guide = SallaProductSizeGuide;
|
|
11090
13073
|
exports.salla_products_list = SallaProductsList;
|
|
11091
13074
|
exports.salla_products_slider = SallaProductsSlider;
|