@useinsider/guido 3.16.0 → 3.17.0-beta.3e9d6e7
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/README.md +1 -0
- package/dist/@types/config/schemas.js +12 -6
- package/dist/components/Guido.vue.js +6 -6
- package/dist/components/Guido.vue2.js +63 -61
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +18 -0
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +67 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue2.js +55 -0
- package/dist/composables/useCustomInterfaceAppearance.js +19 -16
- package/dist/composables/useRecommendation.js +43 -35
- package/dist/composables/useStripo.js +30 -29
- package/dist/config/migrator/itemsBlockMigrator.js +1 -1
- package/dist/config/migrator/recommendationMigrator.js +6 -4
- package/dist/enums/date.js +4 -3
- package/dist/enums/extensions/recommendationBlock.js +25 -23
- package/dist/enums/recommendation.js +17 -17
- package/dist/extensions/Blocks/Items/enums/productEnums.js +45 -45
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +13 -11
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +37 -26
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +115 -87
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +132 -0
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +198 -51
- package/dist/extensions/Blocks/Recommendation/utils/productIds.js +6 -0
- package/dist/extensions/Blocks/common-control.js +22 -19
- package/dist/guido.css +1 -1
- package/dist/node_modules/@useinsider/design-system-organisms/dist/index-Dc9AygoZ.js +526 -0
- package/dist/node_modules/@useinsider/design-system-organisms/dist/index.js +9345 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InAccordion.js +174 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBasicTextInput.js +381 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBox.js +236 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBulkActions.js +70 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InButton.js +350 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InButtonV2.js +371 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InCheckBox.js +152 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InChips.js +141 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InCustomDropDown.js +1047 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDataTableV2.js +96050 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDatePicker.js +2042 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDrawer.js +166 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDropDown.js +1098 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InIcons.js +55 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InInfoBox.js +265 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InLinks.js +184 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InLoading.js +50 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InModals.js +453 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InNoData.js +145 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InOnPageMessage.js +176 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InProgress.js +266 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InRadioButton.js +114 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSegments.js +200 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSelect.js +451 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSkeleton.js +49 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InStatusText.js +119 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTabs.js +4309 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTagsText.js +129 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTextInput.js +503 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InToasts.js +253 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InToggle.js +107 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTooltip.js +134 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTooltipV2.js +464 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/_commonjsHelpers.BItOPCY9.js +28 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/_plugin-vue2_normalizer.WQT2Fc8L.js +23 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/clickOutside.qP9M0QCm.js +29 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/helpers.CgHNyjAJ.js +109 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/index.Bw_06igr.js +2339 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/localLocalesMixin.DYMhydo2.js +16 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/useLocalLocales.Ckuhy7d-.js +17 -0
- package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/vue-property-decorator.BtlM7Epa.js +188 -0
- package/dist/services/recommendationApi.js +77 -28
- package/dist/src/@types/config/schemas.d.ts +12 -0
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
- package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBox.vue.d.ts +24 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useRecommendation.d.ts +1 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +12 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +37 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +210 -10
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +6 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
- package/dist/src/mock/api/recommendation-strategies.d.ts +43 -0
- package/dist/src/services/recommendationApi.d.ts +4 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +171 -0
- package/dist/utils/dateUtil.js +23 -10
- package/dist/utils/templatePreparation.js +37 -34
- package/package.json +2 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as
|
|
1
|
+
import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as a } from "./layout.js";
|
|
2
2
|
import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as i, ATTR_PRODUCT_BUTTON as I } from "./selectors.js";
|
|
3
|
-
const
|
|
3
|
+
const C = {
|
|
4
4
|
code: "USD",
|
|
5
5
|
symbol: "USD",
|
|
6
6
|
alignment: "after",
|
|
7
7
|
decimalCount: 2,
|
|
8
8
|
decimalSeparator: ".",
|
|
9
9
|
thousandSeparator: ","
|
|
10
|
-
},
|
|
10
|
+
}, D = {
|
|
11
11
|
textBefore: "",
|
|
12
12
|
textAfter: ""
|
|
13
|
-
},
|
|
13
|
+
}, O = {
|
|
14
14
|
textBefore: "",
|
|
15
15
|
textAfter: ""
|
|
16
16
|
}, A = [
|
|
@@ -36,11 +36,13 @@ const D = {
|
|
|
36
36
|
size: "6",
|
|
37
37
|
shuffleProducts: !1,
|
|
38
38
|
language: "en_US",
|
|
39
|
-
currency:
|
|
39
|
+
currency: C,
|
|
40
40
|
filters: [],
|
|
41
|
+
// Version NOT bumped: mergeWithDefaults() backfills '' for older configs.
|
|
42
|
+
strategyId: "",
|
|
41
43
|
// Layout
|
|
42
44
|
layout: "grid",
|
|
43
|
-
cardsInRow:
|
|
45
|
+
cardsInRow: a,
|
|
44
46
|
mobileCardsInRow: e,
|
|
45
47
|
mobileLayoutEnabled: !1,
|
|
46
48
|
previousMobileCardsInRow: e,
|
|
@@ -52,8 +54,8 @@ const D = {
|
|
|
52
54
|
composition: A,
|
|
53
55
|
visibility: c,
|
|
54
56
|
// Element settings
|
|
55
|
-
omnibusPrice:
|
|
56
|
-
omnibusDiscount:
|
|
57
|
+
omnibusPrice: D,
|
|
58
|
+
omnibusDiscount: O,
|
|
57
59
|
textTrimming: !1,
|
|
58
60
|
// Price placement (block-level, affects all cards)
|
|
59
61
|
// Default ON = current stacked look, so existing templates are unaffected.
|
|
@@ -71,10 +73,10 @@ const D = {
|
|
|
71
73
|
export {
|
|
72
74
|
m as CURRENT_CONFIG_VERSION,
|
|
73
75
|
A as DEFAULT_COMPOSITION,
|
|
74
|
-
|
|
76
|
+
C as DEFAULT_CURRENCY,
|
|
75
77
|
l as DEFAULT_NODE_CONFIG,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
O as DEFAULT_OMNIBUS_DISCOUNT,
|
|
79
|
+
D as DEFAULT_OMNIBUS_PRICE,
|
|
78
80
|
c as DEFAULT_VISIBILITY,
|
|
79
81
|
N as EXCLUDED_ALGORITHM_IDS
|
|
80
82
|
};
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { UEAttr as
|
|
5
|
-
import { CommonControl as
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var h = (r, s, t) => s in r ? d(r, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[s] = t;
|
|
3
|
+
var c = (r, s, t) => h(r, typeof s != "symbol" ? s + "" : s, t);
|
|
4
|
+
import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as g } from "../../../common-control.js";
|
|
6
6
|
import { RecommendationConfigService as n } from "../../services/configService.js";
|
|
7
7
|
import { useRecommendationExtensionStore as m } from "../../store/recommendation.js";
|
|
8
|
-
import { mapLegacyStrategy as
|
|
9
|
-
const
|
|
8
|
+
import { mapLegacyStrategy as u } from "../../utils/legacyStrategyMap.js";
|
|
9
|
+
const p = "recommendation-algorithm-control", i = {
|
|
10
10
|
ALGORITHM: "strategy",
|
|
11
11
|
PRODUCT_IDS: "productIds"
|
|
12
12
|
};
|
|
13
|
-
class R extends
|
|
13
|
+
class R extends g {
|
|
14
14
|
constructor() {
|
|
15
15
|
super(...arguments);
|
|
16
16
|
// Store is used ONLY for API-fetched data (algorithms list), not for config
|
|
17
|
-
|
|
17
|
+
c(this, "store", m());
|
|
18
18
|
}
|
|
19
19
|
getId() {
|
|
20
|
-
return
|
|
20
|
+
return p;
|
|
21
21
|
}
|
|
22
22
|
getTemplate() {
|
|
23
23
|
return `
|
|
@@ -46,11 +46,10 @@ class R extends d {
|
|
|
46
46
|
super.onTemplateNodeUpdated(t), this._initializeSelectItems(), this._setFormValues();
|
|
47
47
|
}
|
|
48
48
|
_setFormValues() {
|
|
49
|
-
const t = n.getConfig(this.currentNode), e =
|
|
50
|
-
this._setProductIdsVisibility(e)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
49
|
+
const t = n.getConfig(this.currentNode), e = u(t.strategy) ?? t.strategy;
|
|
50
|
+
this._setProductIdsVisibility(e);
|
|
51
|
+
const o = { [i.ALGORITHM]: e }, a = t.productIds.join(",");
|
|
52
|
+
this.api.getValues()[i.PRODUCT_IDS] !== a && (o[i.PRODUCT_IDS] = a), this.api.updateValues(o);
|
|
54
53
|
}
|
|
55
54
|
_initializeSelectItems() {
|
|
56
55
|
var e;
|
|
@@ -59,35 +58,47 @@ class R extends d {
|
|
|
59
58
|
try {
|
|
60
59
|
this.api.setUIEAttribute(
|
|
61
60
|
i.ALGORITHM,
|
|
62
|
-
|
|
61
|
+
l.SELECTPICKER.items,
|
|
63
62
|
t
|
|
64
63
|
);
|
|
65
|
-
} catch (
|
|
66
|
-
console.warn("[AlgorithmControl] Failed to set algorithm options:",
|
|
64
|
+
} catch (o) {
|
|
65
|
+
console.warn("[AlgorithmControl] Failed to set algorithm options:", o);
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
_setProductIdsVisibility(t) {
|
|
70
|
-
const
|
|
71
|
-
this.api.setVisibility(i.PRODUCT_IDS,
|
|
69
|
+
const o = (t ?? n.getConfig(this.currentNode).strategy) === "manualMerchandising";
|
|
70
|
+
this.api.setVisibility(i.PRODUCT_IDS, o), this.api.setVisibility(`${i.PRODUCT_IDS}_label`, o);
|
|
72
71
|
}
|
|
73
72
|
_onAlgorithmChange(t) {
|
|
74
|
-
|
|
73
|
+
if (!this.currentNode)
|
|
74
|
+
return;
|
|
75
|
+
const e = n.getConfig(this.currentNode);
|
|
76
|
+
if (e.strategy === t) {
|
|
77
|
+
this.store.recommendationConfigs.strategy !== t && this.store.patchCurrentBlockConfig({ strategy: e.strategy, filters: e.filters });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
n.updateConfig(
|
|
75
81
|
this.api,
|
|
76
82
|
this.currentNode,
|
|
77
83
|
{ strategy: t },
|
|
78
84
|
`Changed algorithm to ${t}`
|
|
79
|
-
), this.store.patchCurrentBlockConfig({ strategy: t }), this._setProductIdsVisibility(t)
|
|
85
|
+
), this.store.patchCurrentBlockConfig({ strategy: t }), this._setProductIdsVisibility(t);
|
|
80
86
|
}
|
|
81
87
|
_onProductIdsChange(t) {
|
|
82
88
|
if (!this.currentNode)
|
|
83
89
|
return;
|
|
84
|
-
const e =
|
|
90
|
+
const e = n.getConfig(this.currentNode);
|
|
91
|
+
if (e.productIds.join(",") === t) {
|
|
92
|
+
this.store.recommendationConfigs.productIds.join(",") !== t && this.store.patchCurrentBlockConfig({ productIds: e.productIds, filters: e.filters });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const o = t === "" ? [] : t.split(",");
|
|
85
96
|
n.updateConfig(
|
|
86
97
|
this.api,
|
|
87
98
|
this.currentNode,
|
|
88
|
-
{ productIds:
|
|
99
|
+
{ productIds: o },
|
|
89
100
|
"Updated product IDs"
|
|
90
|
-
), this.store.patchCurrentBlockConfig({ productIds:
|
|
101
|
+
), this.store.patchCurrentBlockConfig({ productIds: o });
|
|
91
102
|
}
|
|
92
103
|
_listenToFormUpdates() {
|
|
93
104
|
this.api.onValueChanged(i.ALGORITHM, (t) => {
|
|
@@ -98,6 +109,6 @@ class R extends d {
|
|
|
98
109
|
}
|
|
99
110
|
}
|
|
100
111
|
export {
|
|
101
|
-
|
|
112
|
+
p as ALGORITHM_CONTROL_ID,
|
|
102
113
|
R as AlgorithmControl
|
|
103
114
|
};
|
|
@@ -1,36 +1,39 @@
|
|
|
1
1
|
var f = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var s = (d,
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
var g = (d, a, t) => a in d ? f(d, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[a] = t;
|
|
3
|
+
var s = (d, a, t) => g(d, typeof a != "symbol" ? a + "" : a, t);
|
|
4
|
+
import { useConfig as p } from "../../../../../composables/useConfig.js";
|
|
5
|
+
import { CommonControl as y } from "../../../common-control.js";
|
|
6
|
+
import { DEFAULT_NODE_CONFIG as l } from "../../constants/defaultConfig.js";
|
|
6
7
|
import { RecommendationConfigService as m } from "../../services/configService.js";
|
|
7
|
-
import { useRecommendationExtensionStore as
|
|
8
|
-
import { AlgorithmControl as
|
|
9
|
-
import { ALGORITHM_CONTROL_ID as
|
|
8
|
+
import { useRecommendationExtensionStore as N } from "../../store/recommendation.js";
|
|
9
|
+
import { AlgorithmControl as I } from "./algorithm.js";
|
|
10
|
+
import { ALGORITHM_CONTROL_ID as nt } from "./algorithm.js";
|
|
10
11
|
import { CurrencyControl as R } from "./currency.js";
|
|
11
|
-
import { CURRENCY_CONTROL_ID as
|
|
12
|
-
import { FiltersControl as
|
|
13
|
-
import { FILTERS_CONTROL_ID as
|
|
14
|
-
import { LayoutOrientationControl as
|
|
15
|
-
import { LAYOUT_ORIENTATION_CONTROL_ID as
|
|
16
|
-
import { LocaleControl as
|
|
17
|
-
import { LOCALE_CONTROL_ID as
|
|
18
|
-
import { PricePlacementControl as
|
|
19
|
-
import { PRICE_PLACEMENT_CONTROL_ID as
|
|
12
|
+
import { CURRENCY_CONTROL_ID as st } from "./currency.js";
|
|
13
|
+
import { FiltersControl as T } from "./filters.js";
|
|
14
|
+
import { FILTERS_CONTROL_ID as at } from "./filters.js";
|
|
15
|
+
import { LayoutOrientationControl as b } from "./layoutOrientation.js";
|
|
16
|
+
import { LAYOUT_ORIENTATION_CONTROL_ID as ut } from "./layoutOrientation.js";
|
|
17
|
+
import { LocaleControl as _ } from "./locale.js";
|
|
18
|
+
import { LOCALE_CONTROL_ID as mt } from "./locale.js";
|
|
19
|
+
import { PricePlacementControl as O } from "./pricePlacement.js";
|
|
20
|
+
import { PRICE_PLACEMENT_CONTROL_ID as Ct } from "./pricePlacement.js";
|
|
20
21
|
import { ProductCountControl as P } from "./productCount.js";
|
|
21
|
-
import { PRODUCT_COUNT_CONTROL_ID as
|
|
22
|
-
import { ProductLayoutControl as
|
|
23
|
-
import { PRODUCT_LAYOUT_CONTROL_ID as
|
|
22
|
+
import { PRODUCT_COUNT_CONTROL_ID as gt } from "./productCount.js";
|
|
23
|
+
import { ProductLayoutControl as S } from "./productLayout.js";
|
|
24
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as yt } from "./productLayout.js";
|
|
24
25
|
import { ShuffleControl as L } from "./shuffle.js";
|
|
25
|
-
import { SHUFFLE_CONTROL_ID as
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { SHUFFLE_CONTROL_ID as It } from "./shuffle.js";
|
|
27
|
+
import { StrategyControl as k } from "./strategy.js";
|
|
28
|
+
import { STRATEGY_CONTROL_ID as Tt } from "./strategy.js";
|
|
29
|
+
import { setCurrencyAttributes as D, getBlockElement as E, isPartnerManagedBlock as v, updateProductContentInPlace as A, regenerateProductRowsWithStyles as w } from "./utils.js";
|
|
30
|
+
import { adjustProductsToSize as _t, formatProductPrice as Ot, getCardComposition as Pt, getCurrentLayout as St, regenerateMobileProductRows as Lt, updatePricesInPlace as kt, updateSingleProductContent as Dt } from "./utils.js";
|
|
28
31
|
import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
29
|
-
const
|
|
30
|
-
class
|
|
32
|
+
const x = "recommendation-id", B = "ui-elements-recommendation-block";
|
|
33
|
+
class et extends y {
|
|
31
34
|
constructor() {
|
|
32
35
|
super(...arguments);
|
|
33
|
-
s(this, "store",
|
|
36
|
+
s(this, "store", N());
|
|
34
37
|
s(this, "storeUnsubscription", () => {
|
|
35
38
|
});
|
|
36
39
|
s(this, "syncedBlockIds", /* @__PURE__ */ new Set());
|
|
@@ -44,6 +47,7 @@ class Q extends g {
|
|
|
44
47
|
s(this, "shuffleControl", null);
|
|
45
48
|
s(this, "pricePlacementControl", null);
|
|
46
49
|
s(this, "layoutOrientationControl", null);
|
|
50
|
+
s(this, "strategyControl", null);
|
|
47
51
|
/**
|
|
48
52
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
49
53
|
*/
|
|
@@ -63,14 +67,14 @@ class Q extends g {
|
|
|
63
67
|
*/
|
|
64
68
|
s(this, "_debouncedRegenerateWithProducts", h(() => {
|
|
65
69
|
const t = this.store.recommendationProducts;
|
|
66
|
-
if (!this.currentNode || !this.api ||
|
|
70
|
+
if (!this.currentNode || !this.api || v(this.currentNode))
|
|
67
71
|
return;
|
|
68
72
|
const e = this.api.getDocumentModifier();
|
|
69
|
-
|
|
73
|
+
A({
|
|
70
74
|
currentNode: this.currentNode,
|
|
71
75
|
documentModifier: e,
|
|
72
76
|
products: t
|
|
73
|
-
}) ||
|
|
77
|
+
}) || w({
|
|
74
78
|
currentNode: this.currentNode,
|
|
75
79
|
documentModifier: e,
|
|
76
80
|
products: t
|
|
@@ -78,10 +82,11 @@ class Q extends g {
|
|
|
78
82
|
}, 100));
|
|
79
83
|
}
|
|
80
84
|
getId() {
|
|
81
|
-
return
|
|
85
|
+
return B;
|
|
82
86
|
}
|
|
83
87
|
getTemplate() {
|
|
84
|
-
|
|
88
|
+
const t = p().isFeatureEnabled("reusableRecommendationStrategy");
|
|
89
|
+
return this.algorithmControl = t ? null : new I(), this.localeControl = new _(), this.currencyControl = new R(), this.productCountControl = t ? null : new P(), this.productLayoutControl = new S(), this.filtersControl = t ? null : new T(), this.shuffleControl = t ? null : new L(), this.pricePlacementControl = new O(), this.layoutOrientationControl = new b(), this.strategyControl = t ? new k() : null, [
|
|
85
90
|
this.algorithmControl,
|
|
86
91
|
this.localeControl,
|
|
87
92
|
this.currencyControl,
|
|
@@ -90,10 +95,20 @@ class Q extends g {
|
|
|
90
95
|
this.filtersControl,
|
|
91
96
|
this.shuffleControl,
|
|
92
97
|
this.pricePlacementControl,
|
|
93
|
-
this.layoutOrientationControl
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
this.layoutOrientationControl,
|
|
99
|
+
this.strategyControl
|
|
100
|
+
].forEach((o) => {
|
|
101
|
+
o && (o.api = this.api);
|
|
102
|
+
}), t ? `
|
|
103
|
+
<div class="recommendation-controls-container">
|
|
104
|
+
${this.strategyControl.getTemplate()}
|
|
105
|
+
${this.layoutOrientationControl.getTemplate()}
|
|
106
|
+
${this.localeControl.getTemplate()}
|
|
107
|
+
${this.currencyControl.getTemplate()}
|
|
108
|
+
${this.pricePlacementControl.getTemplate()}
|
|
109
|
+
${this.productLayoutControl.getTemplate()}
|
|
110
|
+
</div>
|
|
111
|
+
` : `
|
|
97
112
|
<div class="recommendation-controls-container">
|
|
98
113
|
${this.layoutOrientationControl.getTemplate()}
|
|
99
114
|
${this.productCountControl.getTemplate()}
|
|
@@ -131,7 +146,8 @@ class Q extends g {
|
|
|
131
146
|
this.productLayoutControl,
|
|
132
147
|
this.filtersControl,
|
|
133
148
|
this.shuffleControl,
|
|
134
|
-
this.pricePlacementControl
|
|
149
|
+
this.pricePlacementControl,
|
|
150
|
+
this.strategyControl
|
|
135
151
|
].forEach((n) => {
|
|
136
152
|
var i;
|
|
137
153
|
n != null && n.api && (n.currentNode = t, (i = n.onTemplateNodeUpdated) == null || i.call(n, t));
|
|
@@ -147,7 +163,8 @@ class Q extends g {
|
|
|
147
163
|
this.productLayoutControl,
|
|
148
164
|
this.filtersControl,
|
|
149
165
|
this.shuffleControl,
|
|
150
|
-
this.pricePlacementControl
|
|
166
|
+
this.pricePlacementControl,
|
|
167
|
+
this.strategyControl
|
|
151
168
|
].forEach((e) => {
|
|
152
169
|
var o;
|
|
153
170
|
return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
|
|
@@ -167,7 +184,8 @@ class Q extends g {
|
|
|
167
184
|
this.productLayoutControl,
|
|
168
185
|
this.filtersControl,
|
|
169
186
|
this.shuffleControl,
|
|
170
|
-
this.pricePlacementControl
|
|
187
|
+
this.pricePlacementControl,
|
|
188
|
+
this.strategyControl
|
|
171
189
|
].forEach((e) => {
|
|
172
190
|
var o;
|
|
173
191
|
e && (e.api = this.api, e.currentNode = this.currentNode, (o = e.onRender) == null || o.call(e));
|
|
@@ -189,6 +207,7 @@ class Q extends g {
|
|
|
189
207
|
const t = m.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
|
|
190
208
|
this.store.patchCurrentBlockConfig({
|
|
191
209
|
strategy: t.strategy,
|
|
210
|
+
strategyId: t.strategyId,
|
|
192
211
|
language: t.language,
|
|
193
212
|
size: t.size,
|
|
194
213
|
productIds: t.productIds,
|
|
@@ -251,26 +270,26 @@ class Q extends g {
|
|
|
251
270
|
return;
|
|
252
271
|
const t = m.getConfig(this.currentNode), e = {};
|
|
253
272
|
let o = null, r = null, n = null;
|
|
254
|
-
if (t.currency.code ===
|
|
273
|
+
if (t.currency.code === l.currency.code) {
|
|
255
274
|
const { currencyList: i } = this.store;
|
|
256
275
|
i.length > 0 && (i.some(
|
|
257
|
-
(u) => u.value === `price.${
|
|
276
|
+
(u) => u.value === `price.${l.currency.code}`
|
|
258
277
|
) || (o = i[0].value.replace("price.", ""), e.currency = {
|
|
259
|
-
...
|
|
278
|
+
...l.currency,
|
|
260
279
|
code: o,
|
|
261
280
|
symbol: o
|
|
262
281
|
}));
|
|
263
282
|
}
|
|
264
|
-
if (t.strategy ===
|
|
283
|
+
if (t.strategy === l.strategy) {
|
|
265
284
|
const i = this.store.getActivePredictiveAlgorithms;
|
|
266
285
|
i.length > 0 && (i.some(
|
|
267
|
-
(u) => u.value ===
|
|
286
|
+
(u) => u.value === l.strategy
|
|
268
287
|
) || (r = i[0].value, e.strategy = r));
|
|
269
288
|
}
|
|
270
|
-
if (t.language ===
|
|
289
|
+
if (t.language === l.language) {
|
|
271
290
|
const i = this.store.getLanguages;
|
|
272
291
|
i.length > 0 && (i.some(
|
|
273
|
-
(u) => u.value ===
|
|
292
|
+
(u) => u.value === l.language
|
|
274
293
|
) || (n = i[0].value, e.language = n));
|
|
275
294
|
}
|
|
276
295
|
!o && !r && !n || (m.updateConfig(
|
|
@@ -278,7 +297,7 @@ class Q extends g {
|
|
|
278
297
|
this.currentNode,
|
|
279
298
|
e,
|
|
280
299
|
"Applied smart defaults"
|
|
281
|
-
), o && e.currency &&
|
|
300
|
+
), o && e.currency && D({
|
|
282
301
|
currentNode: this.currentNode,
|
|
283
302
|
documentModifier: this.api.getDocumentModifier(),
|
|
284
303
|
currency: e.currency
|
|
@@ -288,10 +307,10 @@ class Q extends g {
|
|
|
288
307
|
name: o,
|
|
289
308
|
value: o,
|
|
290
309
|
symbol: o,
|
|
291
|
-
alignment:
|
|
292
|
-
decimalCount:
|
|
293
|
-
decimalSeparator:
|
|
294
|
-
thousandSeparator:
|
|
310
|
+
alignment: l.currency.alignment === "before" ? "0" : "1",
|
|
311
|
+
decimalCount: l.currency.decimalCount.toString(),
|
|
312
|
+
decimalSeparator: l.currency.decimalSeparator,
|
|
313
|
+
thousandSeparator: l.currency.thousandSeparator
|
|
295
314
|
}
|
|
296
315
|
} : {},
|
|
297
316
|
...r ? { strategy: r } : {},
|
|
@@ -302,10 +321,10 @@ class Q extends g {
|
|
|
302
321
|
* Reads the recommendation-id attribute from the block element within the node
|
|
303
322
|
*/
|
|
304
323
|
_getRecommendationIdFromNode(t) {
|
|
305
|
-
const e =
|
|
324
|
+
const e = E(t);
|
|
306
325
|
if (!e || !("getAttribute" in e))
|
|
307
326
|
return null;
|
|
308
|
-
const o = e.getAttribute(
|
|
327
|
+
const o = e.getAttribute(x);
|
|
309
328
|
if (!o)
|
|
310
329
|
return null;
|
|
311
330
|
const r = parseInt(o);
|
|
@@ -335,57 +354,66 @@ class Q extends g {
|
|
|
335
354
|
}
|
|
336
355
|
const i = t.$state.configVersion;
|
|
337
356
|
i !== o && (o = i, this._persistFiltersToNodeConfig(), this._debouncedFetchProducts());
|
|
338
|
-
const
|
|
339
|
-
u && C && (e =
|
|
357
|
+
const c = t.recommendationProducts, u = c !== e, C = Array.isArray(c) && c.length > 0;
|
|
358
|
+
u && C && (e = c, this._debouncedRegenerateWithProducts());
|
|
340
359
|
});
|
|
341
360
|
}
|
|
342
361
|
/**
|
|
343
|
-
* Persists the current filter state from Pinia store to the
|
|
344
|
-
* This ensures
|
|
362
|
+
* Persists the current filter + strategy state from Pinia store to the
|
|
363
|
+
* Stripo node config. This ensures they survive template save/reload cycles
|
|
364
|
+
* (strategyId must be in esd-ext-config before any save — SD-149105).
|
|
365
|
+
*
|
|
366
|
+
* `size` rides along because assigning a strategy overwrites it in the
|
|
367
|
+
* store only. Without this write, `_syncNodeConfigToStore` re-seeds the
|
|
368
|
+
* store from the stale node config on the next panel open, and a block
|
|
369
|
+
* whose saved HTML has the strategy's slot count gets rebuilt against the
|
|
370
|
+
* old one — resetting migrator-applied per-element styles.
|
|
345
371
|
*/
|
|
346
372
|
_persistFiltersToNodeConfig() {
|
|
347
373
|
if (!this.currentNode || !this.api)
|
|
348
374
|
return;
|
|
349
|
-
const { filters: t } = this.store.recommendationConfigs;
|
|
350
|
-
m.updateConfig(
|
|
375
|
+
const { filters: t, strategyId: e, size: o } = this.store.recommendationConfigs, r = m.getConfig(this.currentNode);
|
|
376
|
+
JSON.stringify(r.filters) === JSON.stringify(t) && r.strategyId === e && r.size === o || m.updateConfig(
|
|
351
377
|
this.api,
|
|
352
378
|
this.currentNode,
|
|
353
|
-
{ filters: t },
|
|
379
|
+
{ filters: t, strategyId: e, size: o },
|
|
354
380
|
"Update recommendation filters"
|
|
355
381
|
);
|
|
356
382
|
}
|
|
357
383
|
}
|
|
358
384
|
export {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
385
|
+
nt as ALGORITHM_CONTROL_ID,
|
|
386
|
+
I as AlgorithmControl,
|
|
387
|
+
B as CONTROL_BLOCK_ID,
|
|
388
|
+
st as CURRENCY_CONTROL_ID,
|
|
363
389
|
R as CurrencyControl,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
390
|
+
at as FILTERS_CONTROL_ID,
|
|
391
|
+
T as FiltersControl,
|
|
392
|
+
ut as LAYOUT_ORIENTATION_CONTROL_ID,
|
|
393
|
+
mt as LOCALE_CONTROL_ID,
|
|
394
|
+
b as LayoutOrientationControl,
|
|
395
|
+
_ as LocaleControl,
|
|
396
|
+
Ct as PRICE_PLACEMENT_CONTROL_ID,
|
|
397
|
+
gt as PRODUCT_COUNT_CONTROL_ID,
|
|
398
|
+
yt as PRODUCT_LAYOUT_CONTROL_ID,
|
|
399
|
+
O as PricePlacementControl,
|
|
374
400
|
P as ProductCountControl,
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
401
|
+
S as ProductLayoutControl,
|
|
402
|
+
et as RecommendationBlockControl,
|
|
403
|
+
It as SHUFFLE_CONTROL_ID,
|
|
404
|
+
Tt as STRATEGY_CONTROL_ID,
|
|
378
405
|
L as ShuffleControl,
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
406
|
+
k as StrategyControl,
|
|
407
|
+
_t as adjustProductsToSize,
|
|
408
|
+
Ot as formatProductPrice,
|
|
409
|
+
E as getBlockElement,
|
|
410
|
+
Pt as getCardComposition,
|
|
411
|
+
St as getCurrentLayout,
|
|
412
|
+
v as isPartnerManagedBlock,
|
|
413
|
+
Lt as regenerateMobileProductRows,
|
|
414
|
+
w as regenerateProductRowsWithStyles,
|
|
415
|
+
D as setCurrencyAttributes,
|
|
416
|
+
kt as updatePricesInPlace,
|
|
417
|
+
A as updateProductContentInPlace,
|
|
418
|
+
Dt as updateSingleProductContent
|
|
391
419
|
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var l = (n, a, t) => a in n ? d(n, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[a] = t;
|
|
3
|
+
var o = (n, a, t) => l(n, typeof a != "symbol" ? a + "" : a, t);
|
|
4
|
+
import { CommonControl as g } from "../../../common-control.js";
|
|
5
|
+
import { useRecommendationExtensionStore as y } from "../../store/recommendation.js";
|
|
6
|
+
const h = "recommendation-strategy-control", m = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block";
|
|
7
|
+
class b extends g {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
o(this, "store", y());
|
|
11
|
+
o(this, "storeUnsubscription", () => {
|
|
12
|
+
});
|
|
13
|
+
o(this, "listeners", []);
|
|
14
|
+
}
|
|
15
|
+
getId() {
|
|
16
|
+
return h;
|
|
17
|
+
}
|
|
18
|
+
getTemplate() {
|
|
19
|
+
const t = this.api.translate(
|
|
20
|
+
"You can assign a recommendation strategy by selecting an existing one or creating a new one to show specific content."
|
|
21
|
+
), e = this.api.translate("For more information, you can"), s = this.api.translate("visit Academy");
|
|
22
|
+
return `
|
|
23
|
+
<div class="strategy-control-container">
|
|
24
|
+
<!-- A section heading, not a field label: the ue-label element renders
|
|
25
|
+
the panel's 13px field styling and the design asks for a 16px/600
|
|
26
|
+
heading. Kept outside a .container so the editor draws no rule. -->
|
|
27
|
+
<div class="strategy-control-header">
|
|
28
|
+
<h3 class="strategy-control-title">${this.api.translate("Recommendation Strategy")}</h3>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="strategy-control-description-row">
|
|
31
|
+
<p class="strategy-control-description">
|
|
32
|
+
${t}
|
|
33
|
+
${e}
|
|
34
|
+
<!-- cspell:disable-next-line -->
|
|
35
|
+
<a href="${m}" target="_blank" rel="noopener noreferrer">${s}</a>.
|
|
36
|
+
</p>
|
|
37
|
+
</div>
|
|
38
|
+
<div data-strategy-empty-state>
|
|
39
|
+
${this._GuTwoColumns([
|
|
40
|
+
this._GuButton({
|
|
41
|
+
name: "assignStrategy",
|
|
42
|
+
label: this.api.translate("Assign Strategy"),
|
|
43
|
+
id: "guido__btn-assign-strategy",
|
|
44
|
+
className: "strategy-control-cta accent"
|
|
45
|
+
}),
|
|
46
|
+
// Create round-trip ships in a later phase. Disabled, not dimmed:
|
|
47
|
+
// the design keeps it at full contrast.
|
|
48
|
+
this._GuButton({
|
|
49
|
+
name: "createStrategy",
|
|
50
|
+
label: this.api.translate("Create New Strategy"),
|
|
51
|
+
id: "guido__btn-create-strategy",
|
|
52
|
+
className: "strategy-control-cta primary",
|
|
53
|
+
disabled: !0
|
|
54
|
+
})
|
|
55
|
+
], "strategy-control-cta-row")}
|
|
56
|
+
</div>
|
|
57
|
+
<div data-strategy-assigned-state style="display: none;">
|
|
58
|
+
<!-- The name band bleeds to the panel edges, so it is a sibling of the
|
|
59
|
+
actions row rather than sharing its 16px inset. -->
|
|
60
|
+
<div class="strategy-control-name-band">
|
|
61
|
+
<span class="strategy-control-name" data-strategy-name></span>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="strategy-control-actions">
|
|
64
|
+
${this._strategyAction({
|
|
65
|
+
id: "guido__btn-change-strategy",
|
|
66
|
+
label: this.api.translate("Change"),
|
|
67
|
+
modifier: "change"
|
|
68
|
+
})}
|
|
69
|
+
${this._strategyAction({
|
|
70
|
+
id: "guido__btn-remove-strategy",
|
|
71
|
+
label: this.api.translate("Remove"),
|
|
72
|
+
modifier: "remove"
|
|
73
|
+
})}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Change / Remove are icon+text actions in the design, not buttons — and
|
|
81
|
+
* `ue-button` cannot pair a caption with an arbitrary icon, so these are
|
|
82
|
+
* plain elements. Click wiring is by id, which works on any element.
|
|
83
|
+
*
|
|
84
|
+
* The icon is a CSS mask, not inline SVG: Stripo re-creates the control's
|
|
85
|
+
* markup through Angular, which rebuilds `<svg>` outside the SVG namespace
|
|
86
|
+
* (the view-box attribute comes back lowercased) and it never paints.
|
|
87
|
+
*/
|
|
88
|
+
_strategyAction({ id: t, label: e, modifier: s }) {
|
|
89
|
+
return `
|
|
90
|
+
<button
|
|
91
|
+
id="${t}"
|
|
92
|
+
type="button"
|
|
93
|
+
class="strategy-control-action strategy-control-action--${s}">
|
|
94
|
+
<span>${e}</span>
|
|
95
|
+
</button>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
onRender() {
|
|
99
|
+
this._teardown(), this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
100
|
+
this._renderState();
|
|
101
|
+
}), this.store.recommendationConfigs.strategyId && !this.store.strategies.length && this.store.fetchStrategies().catch(() => {
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
onDestroy() {
|
|
105
|
+
this._teardown();
|
|
106
|
+
}
|
|
107
|
+
_teardown() {
|
|
108
|
+
this.storeUnsubscription(), this.storeUnsubscription = () => {
|
|
109
|
+
}, this.listeners.forEach(({ element: t, handler: e }) => t.removeEventListener("click", e)), this.listeners = [];
|
|
110
|
+
}
|
|
111
|
+
_setupButtonListeners() {
|
|
112
|
+
const t = (e, s) => {
|
|
113
|
+
const r = this.getContainer().querySelector(e);
|
|
114
|
+
r && (r.addEventListener("click", s), this.listeners.push({ element: r, handler: s }));
|
|
115
|
+
};
|
|
116
|
+
t("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), t("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), t("#guido__btn-remove-strategy", () => this.store.removeStrategy());
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Toggles empty vs assigned state from the store's current block config.
|
|
120
|
+
* Display name comes from the listing; falls back to the raw id while the
|
|
121
|
+
* listing loads (or when the strategy is no longer listed).
|
|
122
|
+
*/
|
|
123
|
+
_renderState() {
|
|
124
|
+
var c;
|
|
125
|
+
const t = this.getContainer(), e = t.querySelector("[data-strategy-empty-state]"), s = t.querySelector("[data-strategy-assigned-state]"), r = t.querySelector("[data-strategy-name]"), { strategyId: i } = this.store.recommendationConfigs;
|
|
126
|
+
!e || !s || (e.style.display = i ? "none" : "", s.style.display = i ? "" : "none", r && i && (r.textContent = ((c = this.store.assignedStrategy) == null ? void 0 : c.name) ?? `#${i}`));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
h as STRATEGY_CONTROL_ID,
|
|
131
|
+
b as StrategyControl
|
|
132
|
+
};
|