@useinsider/guido 3.18.1-beta.280b4e1 → 3.18.1-beta.2e195ed
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/components/Guido.vue.js +3 -3
- package/dist/components/Guido.vue2.js +30 -30
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -11
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +65 -53
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +20 -18
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +47 -0
- package/dist/composables/useCustomInterfaceAppearance.js +56 -48
- package/dist/composables/useHtmlValidator.js +84 -79
- package/dist/composables/useRecommendation.js +21 -18
- package/dist/composables/useStripo.js +30 -30
- package/dist/enums/extensions/recommendationBlock.js +38 -31
- package/dist/extensions/Blocks/Recommendation/block.js +43 -39
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +62 -57
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +84 -52
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +165 -78
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +21 -12
- package/dist/guido.css +1 -1
- package/dist/library.js +13 -15
- package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +9 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +74 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +4 -0
- package/dist/src/library.d.ts +0 -2
- package/dist/src/public/trackingIds.d.ts +2 -6
- package/dist/src/stores/guido-email-editor.d.ts +27 -27
- package/dist/src/stores/onboarding.d.ts +377 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +51 -4
- package/dist/stores/guido-email-editor.js +4 -0
- package/dist/stores/onboarding.js +41 -36
- package/dist/utils/templatePreparation.js +50 -50
- package/package.json +1 -5
- package/dist/public/editorState.js +0 -4
- package/dist/src/public/editorState.d.ts +0 -14
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useConfig as
|
|
5
|
-
import { BlockId as
|
|
6
|
-
import { getMigrationBannerHtml as
|
|
7
|
-
import { Block as
|
|
8
|
-
import { CURRENT_CONFIG_VERSION as
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var y = (l, c, t) => c in l ? D(l, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[c] = t;
|
|
3
|
+
var f = (l, c, t) => y(l, typeof c != "symbol" ? c + "" : c, t);
|
|
4
|
+
import { useConfig as C } from "../../../composables/useConfig.js";
|
|
5
|
+
import { BlockId as b } from "../../../enums/block.js";
|
|
6
|
+
import { getMigrationBannerHtml as A } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as E, BlockCompositionType as S, ModificationDescription as g } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { CURRENT_CONFIG_VERSION as N, PRE_RRS_CONFIG_VERSION as O } from "./constants/defaultConfig.js";
|
|
9
9
|
import { RECOMMENDATION_ID_ATTR as m } from "./constants/selectors.js";
|
|
10
|
-
import { regenerateMobileProductRows as
|
|
11
|
-
import { ensureMobileCssRulesExist as
|
|
10
|
+
import { regenerateMobileProductRows as M } from "./controls/main/utils.js";
|
|
11
|
+
import { ensureMobileCssRulesExist as _, setMobileLayoutOptOut as I, hasMobileLayoutOptOut as w } from "./controls/mobileLayout/cssRules.js";
|
|
12
12
|
import { RecommendationConfigService as s } from "./services/configService.js";
|
|
13
13
|
import { useRecommendationExtensionStore as d } from "./store/recommendation.js";
|
|
14
|
-
import { getDefaultTemplate as
|
|
15
|
-
import { useRecommendationBlockWarning as
|
|
16
|
-
const
|
|
17
|
-
let
|
|
18
|
-
class
|
|
14
|
+
import { getDefaultTemplate as x } from "./templates/grid/template.js";
|
|
15
|
+
import { useRecommendationBlockWarning as H } from "./useRecommendationBlockWarning.js";
|
|
16
|
+
const k = b.Recommendation, u = "recommendation-block-v2", R = "hide-price";
|
|
17
|
+
let B = !1;
|
|
18
|
+
class j extends E {
|
|
19
19
|
constructor() {
|
|
20
20
|
super();
|
|
21
21
|
/**
|
|
22
22
|
* Stores the ID generated in getTemplate() so onCreated() can reuse it.
|
|
23
23
|
* This avoids generating a new (different) ID in onCreated().
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
f(this, "_pendingBlockId", null);
|
|
26
26
|
}
|
|
27
27
|
getId() {
|
|
28
|
-
return
|
|
28
|
+
return k;
|
|
29
29
|
}
|
|
30
30
|
getIcon() {
|
|
31
31
|
return "recommendation-icon";
|
|
32
32
|
}
|
|
33
33
|
getBlockCompositionType() {
|
|
34
|
-
return
|
|
34
|
+
return S.CONTAINER;
|
|
35
35
|
}
|
|
36
36
|
getName() {
|
|
37
37
|
return this.api.translate("Recommendation Block");
|
|
@@ -42,8 +42,8 @@ class W extends b {
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
getSettingsPanelTitleHtml() {
|
|
45
|
-
return
|
|
46
|
-
|
|
45
|
+
return A(
|
|
46
|
+
k,
|
|
47
47
|
this.api.translate("Recommendation Block"),
|
|
48
48
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
|
|
49
49
|
);
|
|
@@ -66,7 +66,7 @@ class W extends b {
|
|
|
66
66
|
*/
|
|
67
67
|
getTemplate() {
|
|
68
68
|
const t = this._generateNextId();
|
|
69
|
-
return this._pendingBlockId = t,
|
|
69
|
+
return this._pendingBlockId = t, x(t);
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
72
|
* Called when a new block is dropped into the template
|
|
@@ -89,23 +89,27 @@ class W extends b {
|
|
|
89
89
|
}
|
|
90
90
|
const i = this._pendingBlockId ?? this._generateNextId();
|
|
91
91
|
this._pendingBlockId = null, this._assignRecommendationId(t, i);
|
|
92
|
-
const { config:
|
|
92
|
+
const n = C().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !s.hasConfig(t), { config: r, wasFreshDrop: a } = s.initializeConfig(
|
|
93
93
|
this.api,
|
|
94
94
|
t,
|
|
95
95
|
{
|
|
96
96
|
recommendationId: i,
|
|
97
|
-
configVersion:
|
|
97
|
+
configVersion: n ? N : O,
|
|
98
|
+
// An RRS block picks a strategy, not an algorithm, and its algorithm control is
|
|
99
|
+
// hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
|
|
100
|
+
// at save for a block the user never configured.
|
|
101
|
+
...o ? { strategy: "" } : {}
|
|
98
102
|
}
|
|
99
|
-
),
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
103
|
+
), p = d();
|
|
104
|
+
if (p.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), a) {
|
|
105
|
+
_(this.api);
|
|
106
|
+
const h = this._getBlockElement(t);
|
|
107
|
+
h && (I(this.api, h, !0), M({
|
|
104
108
|
currentNode: t,
|
|
105
109
|
documentModifier: this.api.getDocumentModifier()
|
|
106
110
|
}));
|
|
107
111
|
}
|
|
108
|
-
|
|
112
|
+
p.patchCurrentBlockConfig({ language: r.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
|
|
109
113
|
}
|
|
110
114
|
/**
|
|
111
115
|
* Called when the document changes or template is loaded
|
|
@@ -127,11 +131,11 @@ class W extends b {
|
|
|
127
131
|
}
|
|
128
132
|
this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
|
|
129
133
|
try {
|
|
130
|
-
|
|
134
|
+
B || (_(this.api), B = !0);
|
|
131
135
|
const e = s.getConfig(t), i = this._getBlockElement(t);
|
|
132
136
|
if (i) {
|
|
133
137
|
const n = !e.mobileLayoutEnabled;
|
|
134
|
-
|
|
138
|
+
w(i) !== n && I(this.api, i, n);
|
|
135
139
|
}
|
|
136
140
|
} catch {
|
|
137
141
|
}
|
|
@@ -161,7 +165,7 @@ class W extends b {
|
|
|
161
165
|
*/
|
|
162
166
|
_warnIfMultipleBlocks() {
|
|
163
167
|
try {
|
|
164
|
-
|
|
168
|
+
H().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
|
|
165
169
|
} catch {
|
|
166
170
|
}
|
|
167
171
|
}
|
|
@@ -211,9 +215,9 @@ class W extends b {
|
|
|
211
215
|
if (!o)
|
|
212
216
|
return;
|
|
213
217
|
let r = -1;
|
|
214
|
-
for (let
|
|
215
|
-
if (n[
|
|
216
|
-
r =
|
|
218
|
+
for (let a = 0; a < n.length; a++)
|
|
219
|
+
if (n[a] === o) {
|
|
220
|
+
r = a;
|
|
217
221
|
break;
|
|
218
222
|
}
|
|
219
223
|
if (r <= 0)
|
|
@@ -293,7 +297,7 @@ class W extends b {
|
|
|
293
297
|
*/
|
|
294
298
|
_stampHidePrice(t, e) {
|
|
295
299
|
const i = this._getBlockElement(t);
|
|
296
|
-
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(
|
|
300
|
+
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(R, String(e)).apply(new g("Stamp hide-price"));
|
|
297
301
|
}
|
|
298
302
|
/**
|
|
299
303
|
* Stamps `hide-price` from config only when the block lacks the attribute —
|
|
@@ -301,7 +305,7 @@ class W extends b {
|
|
|
301
305
|
*/
|
|
302
306
|
_healHidePriceAttr(t) {
|
|
303
307
|
const e = this._getBlockElement(t);
|
|
304
|
-
if (!e || !("getAttribute" in e) || e.getAttribute(
|
|
308
|
+
if (!e || !("getAttribute" in e) || e.getAttribute(R) !== null)
|
|
305
309
|
return;
|
|
306
310
|
const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
|
|
307
311
|
this._stampHidePrice(t, i);
|
|
@@ -338,6 +342,6 @@ class W extends b {
|
|
|
338
342
|
}
|
|
339
343
|
}
|
|
340
344
|
export {
|
|
341
|
-
|
|
342
|
-
|
|
345
|
+
k as BLOCK_ID,
|
|
346
|
+
j as RecommendationBlock
|
|
343
347
|
};
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
var m = Object.defineProperty;
|
|
2
|
-
var C = (
|
|
3
|
-
var
|
|
2
|
+
var C = (g, c, t) => c in g ? m(g, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[c] = t;
|
|
3
|
+
var r = (g, c, t) => C(g, typeof c != "symbol" ? c + "" : c, t);
|
|
4
4
|
import { useConfig as p } from "../../../../../composables/useConfig.js";
|
|
5
5
|
import { ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
6
6
|
import { CommonControl as N } from "../../../common-control.js";
|
|
7
7
|
import { CURRENT_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
|
|
8
8
|
import { RECOMMENDATION_ID_ATTR as I } from "../../constants/selectors.js";
|
|
9
|
-
import { RecommendationConfigService as
|
|
9
|
+
import { RecommendationConfigService as l } from "../../services/configService.js";
|
|
10
10
|
import { useRecommendationExtensionStore as R } from "../../store/recommendation.js";
|
|
11
11
|
import { registerNodeConfigWriter as b } from "../../utils/nodeConfigWriter.js";
|
|
12
12
|
import { AlgorithmControl as T } from "./algorithm.js";
|
|
13
13
|
import { ALGORITHM_CONTROL_ID as ut } from "./algorithm.js";
|
|
14
14
|
import { CurrencyControl as P } from "./currency.js";
|
|
15
|
-
import { CURRENCY_CONTROL_ID as
|
|
15
|
+
import { CURRENCY_CONTROL_ID as gt } from "./currency.js";
|
|
16
16
|
import { FiltersControl as S } from "./filters.js";
|
|
17
|
-
import { FILTERS_CONTROL_ID as
|
|
17
|
+
import { FILTERS_CONTROL_ID as ft } from "./filters.js";
|
|
18
18
|
import { LayoutOrientationControl as O } from "./layoutOrientation.js";
|
|
19
19
|
import { LAYOUT_ORIENTATION_CONTROL_ID as Ct } from "./layoutOrientation.js";
|
|
20
20
|
import { LocaleControl as L } from "./locale.js";
|
|
@@ -31,36 +31,36 @@ import { StrategyControl as w } from "./strategy.js";
|
|
|
31
31
|
import { STRATEGY_CONTROL_ID as Lt } from "./strategy.js";
|
|
32
32
|
import { setCurrencyAttributes as A, getBlockElement as v, isPartnerManagedBlock as x, updateProductContentInPlace as B, regenerateProductRowsWithStyles as U } from "./utils.js";
|
|
33
33
|
import { adjustProductsToSize as kt, formatProductPrice as Dt, getCardComposition as Ft, getCurrentLayout as wt, getMainContainerTbody as At, regenerateMobileProductRows as vt, updatePricesInPlace as xt, updateSingleProductContent as Bt } from "./utils.js";
|
|
34
|
-
import { useDebounceFn as
|
|
35
|
-
const
|
|
34
|
+
import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
35
|
+
const W = "ui-elements-recommendation-block";
|
|
36
36
|
class at extends N {
|
|
37
37
|
constructor() {
|
|
38
38
|
super(...arguments);
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
r(this, "store", R());
|
|
40
|
+
r(this, "storeUnsubscription", () => {
|
|
41
41
|
});
|
|
42
42
|
// blockId -> fingerprint of the node config as it looked at the last sync.
|
|
43
|
-
|
|
43
|
+
r(this, "syncedConfigs", /* @__PURE__ */ new Map());
|
|
44
44
|
// A config change waiting to reach the node config. Deferred so it can ride the
|
|
45
45
|
// re-render's single apply() — one user action must cost one undo press.
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
r(this, "pendingNodeConfigWrite", null);
|
|
47
|
+
r(this, "pendingConfigFlushTimer", null);
|
|
48
48
|
// Sub-control instances for lifecycle management
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
r(this, "algorithmControl", null);
|
|
50
|
+
r(this, "localeControl", null);
|
|
51
|
+
r(this, "currencyControl", null);
|
|
52
|
+
r(this, "productCountControl", null);
|
|
53
|
+
r(this, "productLayoutControl", null);
|
|
54
|
+
r(this, "filtersControl", null);
|
|
55
|
+
r(this, "shuffleControl", null);
|
|
56
|
+
r(this, "pricePlacementControl", null);
|
|
57
|
+
r(this, "layoutOrientationControl", null);
|
|
58
|
+
r(this, "strategyControl", null);
|
|
59
|
+
r(this, "rrsEnabled", !1);
|
|
60
60
|
/**
|
|
61
61
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
r(this, "_debouncedFetchProducts", h(async () => {
|
|
64
64
|
try {
|
|
65
65
|
await this.store.fetchRecommendationProducts();
|
|
66
66
|
} finally {
|
|
@@ -78,7 +78,7 @@ class at extends N {
|
|
|
78
78
|
* count. The store pads products to the configured size, so in-place only
|
|
79
79
|
* fails when the size actually changed.
|
|
80
80
|
*/
|
|
81
|
-
|
|
81
|
+
r(this, "_debouncedRegenerateWithProducts", h(() => {
|
|
82
82
|
const t = this.store.recommendationProducts;
|
|
83
83
|
if (!this.currentNode || !this.api)
|
|
84
84
|
return;
|
|
@@ -99,7 +99,7 @@ class at extends N {
|
|
|
99
99
|
}, 100));
|
|
100
100
|
}
|
|
101
101
|
getId() {
|
|
102
|
-
return
|
|
102
|
+
return W;
|
|
103
103
|
}
|
|
104
104
|
get _subControls() {
|
|
105
105
|
return [
|
|
@@ -142,14 +142,14 @@ class at extends N {
|
|
|
142
142
|
const e = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
|
|
143
143
|
if (!e)
|
|
144
144
|
return;
|
|
145
|
-
const o = this._getRecommendationIdFromNode(t) === null ? null :
|
|
146
|
-
e.classList.toggle("strategy-block",
|
|
145
|
+
const o = this._getRecommendationIdFromNode(t) === null ? null : l.getConfig(t), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _);
|
|
146
|
+
e.classList.toggle("strategy-block", n);
|
|
147
147
|
}
|
|
148
148
|
async onRender() {
|
|
149
149
|
var o;
|
|
150
150
|
b(this.api);
|
|
151
151
|
const t = this._getRecommendationIdFromNode(this.currentNode), e = t ?? this.store.currentRecommendationId;
|
|
152
|
-
if (e !== null && this.store.setCurrentBlock(e), t !== null && this._syncNodeConfigIfChanged(t), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
|
|
152
|
+
if (e !== null && this.store.setCurrentBlock(e), t !== null && this._syncNodeConfigIfChanged(t), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), t !== null && this.strategyControl && (this.strategyControl.api = this.api, this.strategyControl.currentNode = this.currentNode, this.strategyControl.onRender()), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
|
|
153
153
|
this._initializeSubControls();
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
@@ -161,9 +161,9 @@ class at extends N {
|
|
|
161
161
|
const e = this._getRecommendationIdFromNode(t);
|
|
162
162
|
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigIfChanged(e), this._showControlsForBlock(t), e !== null && !((o = this.store.blockStates[e]) != null && o.isInitialized) && this._fetchBlockData(e).then(() => {
|
|
163
163
|
this._initializeSubControls();
|
|
164
|
-
}), this._subControls.forEach((
|
|
164
|
+
}), this._subControls.forEach((n) => {
|
|
165
165
|
var i;
|
|
166
|
-
|
|
166
|
+
n != null && n.api && (n.currentNode = t, (i = n.onTemplateNodeUpdated) == null || i.call(n, t));
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
onDestroy() {
|
|
@@ -203,18 +203,23 @@ class at extends N {
|
|
|
203
203
|
*/
|
|
204
204
|
_syncNodeConfigIfChanged(t) {
|
|
205
205
|
this.pendingNodeConfigWrite && this.pendingNodeConfigWrite.blockId !== t && this._flushPendingNodeConfig();
|
|
206
|
-
const e = JSON.stringify(
|
|
206
|
+
const e = JSON.stringify(l.getConfig(this.currentNode)), o = this.syncedConfigs.get(t);
|
|
207
207
|
this.syncedConfigs.set(t, e), o !== e && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
|
|
208
208
|
}
|
|
209
|
+
/** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
|
|
210
|
+
_isPendingStrategyIdChange() {
|
|
211
|
+
const t = this.pendingNodeConfigWrite;
|
|
212
|
+
return t ? l.getConfig(this.currentNode).strategyId !== t.updates.strategyId : !1;
|
|
213
|
+
}
|
|
209
214
|
_capturePendingNodeConfigWrite() {
|
|
210
215
|
const t = this.store.currentRecommendationId;
|
|
211
216
|
if (!this.currentNode || !this.api || t === null)
|
|
212
217
|
return;
|
|
213
|
-
const { filters: e, strategyId: o, size:
|
|
218
|
+
const { filters: e, strategyId: o, size: n } = this.store.recommendationConfigs;
|
|
214
219
|
this.pendingNodeConfigWrite = {
|
|
215
220
|
blockId: t,
|
|
216
221
|
node: this.currentNode,
|
|
217
|
-
updates: { filters: e, strategyId: o, size:
|
|
222
|
+
updates: { filters: e, strategyId: o, size: n }
|
|
218
223
|
};
|
|
219
224
|
}
|
|
220
225
|
/**
|
|
@@ -229,7 +234,7 @@ class at extends N {
|
|
|
229
234
|
*/
|
|
230
235
|
_stagePendingNodeConfig(t) {
|
|
231
236
|
const e = this.pendingNodeConfigWrite;
|
|
232
|
-
return !e || !this.currentNode ? !1 : (
|
|
237
|
+
return !e || !this.currentNode ? !1 : (l.stageConfig(t, this.currentNode, e.updates), !0);
|
|
233
238
|
}
|
|
234
239
|
/**
|
|
235
240
|
* Arms the guaranteed fallback write, once the product fetch has settled. The
|
|
@@ -253,12 +258,12 @@ class at extends N {
|
|
|
253
258
|
const t = this.pendingNodeConfigWrite;
|
|
254
259
|
if (this.pendingNodeConfigWrite = null, this._clearConfigFlush(), !t || !this.api)
|
|
255
260
|
return;
|
|
256
|
-
const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o =
|
|
257
|
-
JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategyId === t.updates.strategyId && o.size === t.updates.size ||
|
|
261
|
+
const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o = l.getConfig(e);
|
|
262
|
+
JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategyId === t.updates.strategyId && o.size === t.updates.size || l.updateConfig(this.api, e, t.updates, "Update recommendation filters");
|
|
258
263
|
}
|
|
259
264
|
_syncNodeConfigToStore() {
|
|
260
|
-
var
|
|
261
|
-
const t =
|
|
265
|
+
var n;
|
|
266
|
+
const t = l.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
|
|
262
267
|
this.store.patchCurrentBlockConfig({
|
|
263
268
|
strategy: t.strategy,
|
|
264
269
|
strategyId: t.strategyId,
|
|
@@ -300,8 +305,8 @@ class at extends N {
|
|
|
300
305
|
t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
|
|
301
306
|
this.store.fetchRecommendationCreateData(),
|
|
302
307
|
this.store.fetchRecommendationFilters()
|
|
303
|
-
])).forEach((o,
|
|
304
|
-
o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][
|
|
308
|
+
])).forEach((o, n) => {
|
|
309
|
+
o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][n]} failed`, o.reason);
|
|
305
310
|
}), this._applySmartDefaults();
|
|
306
311
|
try {
|
|
307
312
|
await this.store.fetchRecommendationProducts();
|
|
@@ -322,8 +327,8 @@ class at extends N {
|
|
|
322
327
|
_applySmartDefaults() {
|
|
323
328
|
if (!this.currentNode || !this.api)
|
|
324
329
|
return;
|
|
325
|
-
const t =
|
|
326
|
-
let o = null,
|
|
330
|
+
const t = l.getConfig(this.currentNode), e = {};
|
|
331
|
+
let o = null, n = null, i = null;
|
|
327
332
|
if (t.currency.code === a.currency.code) {
|
|
328
333
|
const { currencyList: s } = this.store;
|
|
329
334
|
s.length > 0 && (s.some(
|
|
@@ -338,7 +343,7 @@ class at extends N {
|
|
|
338
343
|
const s = this.store.getActivePredictiveAlgorithms;
|
|
339
344
|
s.length > 0 && (s.some(
|
|
340
345
|
(d) => d.value === a.strategy
|
|
341
|
-
) || (
|
|
346
|
+
) || (n = s[0].value, e.strategy = n));
|
|
342
347
|
}
|
|
343
348
|
if (t.language === a.language) {
|
|
344
349
|
const s = this.store.getLanguages;
|
|
@@ -346,7 +351,7 @@ class at extends N {
|
|
|
346
351
|
(d) => d.value === a.language
|
|
347
352
|
) || (i = s[0].value, e.language = i));
|
|
348
353
|
}
|
|
349
|
-
!o && !
|
|
354
|
+
!o && !n && !i || (l.updateConfig(
|
|
350
355
|
this.api,
|
|
351
356
|
this.currentNode,
|
|
352
357
|
e,
|
|
@@ -367,7 +372,7 @@ class at extends N {
|
|
|
367
372
|
thousandSeparator: a.currency.thousandSeparator
|
|
368
373
|
}
|
|
369
374
|
} : {},
|
|
370
|
-
...
|
|
375
|
+
...n ? { strategy: n } : {},
|
|
371
376
|
...i ? { language: i } : {}
|
|
372
377
|
}, { triggerRefetch: !1 }));
|
|
373
378
|
}
|
|
@@ -381,8 +386,8 @@ class at extends N {
|
|
|
381
386
|
const o = e.getAttribute(I);
|
|
382
387
|
if (!o)
|
|
383
388
|
return null;
|
|
384
|
-
const
|
|
385
|
-
return Number.isNaN(
|
|
389
|
+
const n = parseInt(o);
|
|
390
|
+
return Number.isNaN(n) ? null : n;
|
|
386
391
|
}
|
|
387
392
|
/**
|
|
388
393
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -399,27 +404,27 @@ class at extends N {
|
|
|
399
404
|
*/
|
|
400
405
|
_listenStateUpdates() {
|
|
401
406
|
const { store: t } = this;
|
|
402
|
-
let e = t.recommendationProducts, o = t.$state.configVersion,
|
|
407
|
+
let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
|
|
403
408
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
404
409
|
const i = t.currentRecommendationId;
|
|
405
|
-
if (i !==
|
|
406
|
-
|
|
410
|
+
if (i !== n) {
|
|
411
|
+
n = i, e = t.recommendationProducts, o = t.$state.configVersion;
|
|
407
412
|
return;
|
|
408
413
|
}
|
|
409
414
|
const s = t.$state.configVersion;
|
|
410
|
-
s !== o && (o = s, this._capturePendingNodeConfigWrite(), this._debouncedFetchProducts());
|
|
411
|
-
const u = t.recommendationProducts, d = u !== e,
|
|
412
|
-
d &&
|
|
415
|
+
s !== o && (o = s, this._capturePendingNodeConfigWrite(), this._isPendingStrategyIdChange() && this._flushPendingNodeConfig(), this._debouncedFetchProducts());
|
|
416
|
+
const u = t.recommendationProducts, d = u !== e, f = Array.isArray(u) && u.length > 0;
|
|
417
|
+
d && f && (e = u, this._debouncedRegenerateWithProducts());
|
|
413
418
|
});
|
|
414
419
|
}
|
|
415
420
|
}
|
|
416
421
|
export {
|
|
417
422
|
ut as ALGORITHM_CONTROL_ID,
|
|
418
423
|
T as AlgorithmControl,
|
|
419
|
-
|
|
420
|
-
|
|
424
|
+
W as CONTROL_BLOCK_ID,
|
|
425
|
+
gt as CURRENCY_CONTROL_ID,
|
|
421
426
|
P as CurrencyControl,
|
|
422
|
-
|
|
427
|
+
ft as FILTERS_CONTROL_ID,
|
|
423
428
|
S as FiltersControl,
|
|
424
429
|
Ct as LAYOUT_ORIENTATION_CONTROL_ID,
|
|
425
430
|
yt as LOCALE_CONTROL_ID,
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { ACADEMY_LINKS as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var S = (o, n, t) => n in o ? u(o, n, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[n] = t;
|
|
3
|
+
var r = (o, n, t) => S(o, typeof n != "symbol" ? n + "" : n, t);
|
|
4
|
+
import { ACADEMY_LINKS as _ } from "../../../../../enums/academy.js";
|
|
5
|
+
import { useOnboardingStore as f } from "../../../../../stores/onboarding.js";
|
|
6
|
+
import { CommonControl as v } from "../../../common-control.js";
|
|
7
|
+
import { CURRENT_CONFIG_VERSION as b } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as h } from "../../services/configService.js";
|
|
9
|
+
import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
|
|
10
|
+
const k = "recommendation-strategy-control";
|
|
11
|
+
class I extends v {
|
|
9
12
|
constructor() {
|
|
10
13
|
super(...arguments);
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
r(this, "store", C());
|
|
15
|
+
r(this, "onboardingStore", f());
|
|
16
|
+
r(this, "storeUnsubscription", () => {
|
|
13
17
|
});
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
r(this, "listeners", []);
|
|
19
|
+
r(this, "lastPaintedState", null);
|
|
16
20
|
}
|
|
17
21
|
getId() {
|
|
18
|
-
return
|
|
22
|
+
return k;
|
|
19
23
|
}
|
|
20
24
|
getTemplate() {
|
|
21
25
|
const t = this.api.translate(
|
|
@@ -23,21 +27,34 @@ class f extends h {
|
|
|
23
27
|
), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
|
|
24
28
|
return `
|
|
25
29
|
<div class="strategy-control-container">
|
|
26
|
-
<div
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
</p>
|
|
30
|
+
<div data-strategy-loading-state>
|
|
31
|
+
<div class="strategy-control-header">
|
|
32
|
+
<span class="guido-skeleton guido-skeleton--strategy-title"></span>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="strategy-control-description-row">
|
|
35
|
+
<span class="guido-skeleton guido-skeleton--strategy-description"></span>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="strategy-control-skeleton-row">
|
|
38
|
+
<span class="guido-skeleton guido-skeleton--strategy-cta"></span>
|
|
39
|
+
<span class="guido-skeleton guido-skeleton--strategy-cta"></span>
|
|
40
|
+
</div>
|
|
38
41
|
</div>
|
|
39
|
-
<div data-strategy-
|
|
40
|
-
|
|
42
|
+
<div data-strategy-content style="display: none;">
|
|
43
|
+
<div class="strategy-control-header">
|
|
44
|
+
<h3 class="strategy-control-title">${this.api.translate("Recommendation Strategy")}</h3>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="strategy-control-description-row">
|
|
47
|
+
<p class="strategy-control-description">
|
|
48
|
+
${t}
|
|
49
|
+
${e}
|
|
50
|
+
<a
|
|
51
|
+
href="${_.EMAIL_RECOMMENDATION_BLOCK}"
|
|
52
|
+
target="_blank"
|
|
53
|
+
rel="noopener noreferrer">${a}</a>.
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
<div data-strategy-empty-state style="display: none;">
|
|
57
|
+
${this._GuTwoColumns([
|
|
41
58
|
this._GuButton({
|
|
42
59
|
name: "assignStrategy",
|
|
43
60
|
label: this.api.translate("Assign Strategy"),
|
|
@@ -48,26 +65,28 @@ class f extends h {
|
|
|
48
65
|
name: "createStrategy",
|
|
49
66
|
label: this.api.translate("Create New Strategy"),
|
|
50
67
|
id: "guido__btn-create-strategy",
|
|
51
|
-
className: "strategy-control-cta primary"
|
|
52
|
-
disabled: !0
|
|
68
|
+
className: "strategy-control-cta primary"
|
|
53
69
|
})
|
|
54
70
|
], "strategy-control-cta-row")}
|
|
55
|
-
</div>
|
|
56
|
-
<div data-strategy-assigned-state style="display: none;">
|
|
57
|
-
<div class="strategy-control-name-band">
|
|
58
|
-
<span class="strategy-control-name" data-strategy-name></span>
|
|
59
71
|
</div>
|
|
60
|
-
<div
|
|
61
|
-
|
|
72
|
+
<div data-strategy-assigned-state style="display: none;">
|
|
73
|
+
<div class="strategy-control-name-band">
|
|
74
|
+
<span class="strategy-control-name" data-strategy-name></span>
|
|
75
|
+
<span
|
|
76
|
+
class="guido-skeleton guido-skeleton--strategy-name" data-strategy-name-skeleton></span>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="strategy-control-actions">
|
|
79
|
+
${this._strategyAction({
|
|
62
80
|
id: "guido__btn-change-strategy",
|
|
63
81
|
label: this.api.translate("Change"),
|
|
64
82
|
modifier: "change"
|
|
65
83
|
})}
|
|
66
|
-
|
|
84
|
+
${this._strategyAction({
|
|
67
85
|
id: "guido__btn-remove-strategy",
|
|
68
86
|
label: this.api.translate("Remove"),
|
|
69
87
|
modifier: "remove"
|
|
70
88
|
})}
|
|
89
|
+
</div>
|
|
71
90
|
</div>
|
|
72
91
|
</div>
|
|
73
92
|
</div>
|
|
@@ -84,41 +103,54 @@ class f extends h {
|
|
|
84
103
|
`;
|
|
85
104
|
}
|
|
86
105
|
onRender() {
|
|
87
|
-
this._teardown(), this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
106
|
+
this._teardown(), this.store.strategyPanelOpen = !0, this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
88
107
|
this._renderState();
|
|
89
|
-
}), this.store.recommendationConfigs.strategyId && !this.store.
|
|
108
|
+
}), this.store.recommendationConfigs.strategyId && !this.store.strategiesFetched && this.store.fetchStrategies().catch(() => {
|
|
90
109
|
});
|
|
91
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Whether the document itself says this block has no strategy.
|
|
113
|
+
*
|
|
114
|
+
* Read the node, not the store: when the main control cannot resolve the block id off the
|
|
115
|
+
* node it never syncs the persisted config, so the store still holds defaults (empty
|
|
116
|
+
* strategyId) for an assigned block.
|
|
117
|
+
*/
|
|
118
|
+
_isNodeUnassigned() {
|
|
119
|
+
if (!h.hasConfig(this.currentNode))
|
|
120
|
+
return !1;
|
|
121
|
+
const t = h.getConfig(this.currentNode);
|
|
122
|
+
return !t.strategyId && (t.configVersion ?? 0) >= b;
|
|
123
|
+
}
|
|
92
124
|
onDestroy() {
|
|
93
125
|
this._teardown();
|
|
94
126
|
}
|
|
95
127
|
_teardown() {
|
|
96
|
-
this.storeUnsubscription(), this.storeUnsubscription = () => {
|
|
128
|
+
this.store.strategyPanelOpen = !1, this.storeUnsubscription(), this.storeUnsubscription = () => {
|
|
97
129
|
}, this.lastPaintedState = null, this.listeners.forEach(({ element: t, handler: e }) => t.removeEventListener("click", e)), this.listeners = [];
|
|
98
130
|
}
|
|
99
131
|
_setupButtonListeners() {
|
|
100
132
|
const t = this.getContainer();
|
|
101
133
|
if (!t)
|
|
102
134
|
return;
|
|
103
|
-
const e = (a,
|
|
104
|
-
const
|
|
105
|
-
|
|
135
|
+
const e = (a, i) => {
|
|
136
|
+
const s = t.querySelector(a);
|
|
137
|
+
s && (s.addEventListener("click", i), this.listeners.push({ element: s, handler: i }));
|
|
106
138
|
};
|
|
107
|
-
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal());
|
|
139
|
+
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-create-strategy", () => this.store.openStrategyCreation()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal());
|
|
108
140
|
}
|
|
109
141
|
_renderState() {
|
|
110
|
-
var
|
|
111
|
-
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((
|
|
112
|
-
if (
|
|
142
|
+
var p;
|
|
143
|
+
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((p = this.store.assignedStrategy) == null ? void 0 : p.name) ?? "" : "", a = !!t && !e && (this.store.strategiesLoading || !this.store.strategiesSettled), i = `${t}\0${e}\0${a}`;
|
|
144
|
+
if (i === this.lastPaintedState)
|
|
113
145
|
return;
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
146
|
+
const s = this.getContainer();
|
|
147
|
+
if (!s)
|
|
116
148
|
return;
|
|
117
|
-
const
|
|
118
|
-
!
|
|
149
|
+
const c = s.querySelector("[data-strategy-empty-state]"), g = s.querySelector("[data-strategy-assigned-state]"), l = s.querySelector("[data-strategy-loading-state]"), y = s.querySelector("[data-strategy-content]"), d = s.querySelector("[data-strategy-name]"), m = s.querySelector("[data-strategy-name-skeleton]");
|
|
150
|
+
!c || !g || (l && (l.style.display = "none"), y && (y.style.display = ""), c.style.display = t ? "none" : "", g.style.display = t ? "" : "none", !t && this._isNodeUnassigned() && this.onboardingStore.startOnboarding("recommendationStrategyOnboarding"), d && (d.style.display = a ? "none" : "", t && !a && (d.textContent = e || `#${t}`)), m && (m.style.display = a ? "block" : "none"), this.lastPaintedState = i);
|
|
119
151
|
}
|
|
120
152
|
}
|
|
121
153
|
export {
|
|
122
|
-
|
|
123
|
-
|
|
154
|
+
k as STRATEGY_CONTROL_ID,
|
|
155
|
+
I as StrategyControl
|
|
124
156
|
};
|