@useinsider/guido 3.19.0-beta.c8d2be8 → 3.19.0-beta.cac604e
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/@types/config/schemas.js +104 -91
- package/dist/components/organisms/header/EditorActions.vue.js +4 -4
- package/dist/components/organisms/header/EditorActions.vue2.js +23 -25
- package/dist/composables/useActionsApi.js +52 -47
- package/dist/composables/useCodeEditorApi.js +23 -9
- package/dist/composables/useHttp.js +44 -55
- package/dist/composables/useTranslations.js +3 -2
- package/dist/composables/useVersionHistoryApi.js +33 -24
- package/dist/extensions/Blocks/Recommendation/block.js +88 -53
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +45 -38
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +72 -49
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +42 -22
- package/dist/extensions/Blocks/Recommendation/utils/partnerScope.js +26 -0
- package/dist/guido.css +1 -1
- package/dist/src/@types/config/schemas.d.ts +16 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +5 -0
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/partnerScope.d.ts +27 -0
- package/dist/src/stores/config.d.ts +20 -0
- package/dist/src/utils/stripoEditorApi.d.ts +4 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +9 -0
- package/dist/stores/unsubscribe.js +3 -3
- package/dist/utils/stripoEditorApi.js +11 -0
- package/package.json +2 -1
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var i = (
|
|
4
|
-
import { useLegacyStrategyConversion as
|
|
5
|
-
import { ACADEMY_LINKS as
|
|
6
|
-
import { useOnboardingStore as
|
|
7
|
-
import { CommonControl as
|
|
8
|
-
import { RRS_CONFIG_VERSION as
|
|
9
|
-
import { RecommendationConfigService as
|
|
10
|
-
import { useRecommendationExtensionStore as
|
|
11
|
-
const
|
|
12
|
-
class
|
|
1
|
+
var w = Object.defineProperty;
|
|
2
|
+
var N = (l, o, t) => o in l ? w(l, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[o] = t;
|
|
3
|
+
var i = (l, o, t) => N(l, typeof o != "symbol" ? o + "" : o, t);
|
|
4
|
+
import { useLegacyStrategyConversion as L } from "../../../../../composables/useLegacyStrategyConversion.js";
|
|
5
|
+
import { ACADEMY_LINKS as $ } from "../../../../../enums/academy.js";
|
|
6
|
+
import { useOnboardingStore as A } from "../../../../../stores/onboarding.js";
|
|
7
|
+
import { CommonControl as R } from "../../../common-control.js";
|
|
8
|
+
import { RRS_CONFIG_VERSION as E } from "../../constants/defaultConfig.js";
|
|
9
|
+
import { RecommendationConfigService as C } from "../../services/configService.js";
|
|
10
|
+
import { useRecommendationExtensionStore as O } from "../../store/recommendation.js";
|
|
11
|
+
const I = "recommendation-strategy-control";
|
|
12
|
+
class P extends R {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
|
-
i(this, "store",
|
|
16
|
-
i(this, "onboardingStore",
|
|
17
|
-
i(this, "legacyConversion",
|
|
15
|
+
i(this, "store", O());
|
|
16
|
+
i(this, "onboardingStore", A());
|
|
17
|
+
i(this, "legacyConversion", L());
|
|
18
18
|
i(this, "storeUnsubscription", () => {
|
|
19
19
|
});
|
|
20
20
|
i(this, "listeners", []);
|
|
21
21
|
i(this, "lastPaintedState", null);
|
|
22
22
|
}
|
|
23
23
|
getId() {
|
|
24
|
-
return
|
|
24
|
+
return I;
|
|
25
25
|
}
|
|
26
26
|
getTemplate() {
|
|
27
27
|
const t = this.api.translate(
|
|
28
28
|
"You can assign a recommendation strategy by selecting an existing one or creating a new one to show specific content."
|
|
29
|
-
), e = this.api.translate("For more information, you can"),
|
|
29
|
+
), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy"), r = this.api.translate("Legacy Strategy"), s = this.api.translate(
|
|
30
30
|
"Note that this is an older version of the Recommendation Strategy. We recommend you update it to the new Recommendation Strategy for an improved experience."
|
|
31
|
+
), g = this.api.translate(
|
|
32
|
+
"The recommendation strategy used in the recommendation block is no longer available. You can assign a different strategy to it."
|
|
31
33
|
);
|
|
32
34
|
return `
|
|
33
35
|
<div class="strategy-control-container">
|
|
@@ -52,9 +54,9 @@ class M extends A {
|
|
|
52
54
|
${t}
|
|
53
55
|
${e}
|
|
54
56
|
<a
|
|
55
|
-
href="${
|
|
57
|
+
href="${$.EMAIL_RECOMMENDATION_BLOCK}"
|
|
56
58
|
target="_blank"
|
|
57
|
-
rel="noopener noreferrer">${
|
|
59
|
+
rel="noopener noreferrer">${a}</a>.
|
|
58
60
|
</p>
|
|
59
61
|
</div>
|
|
60
62
|
<div data-strategy-empty-state style="display: none;">
|
|
@@ -71,16 +73,37 @@ class M extends A {
|
|
|
71
73
|
id: "guido__btn-create-strategy",
|
|
72
74
|
className: "strategy-control-cta primary"
|
|
73
75
|
})
|
|
76
|
+
], "strategy-control-cta-row")}
|
|
77
|
+
</div>
|
|
78
|
+
<div data-strategy-unavailable-state style="display: none;">
|
|
79
|
+
<div class="strategy-control-notice-row">
|
|
80
|
+
<div class="strategy-control-notice strategy-control-notice--error" role="alert">
|
|
81
|
+
<p class="strategy-control-notice-text">${g}</p>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
${this._GuTwoColumns([
|
|
85
|
+
this._GuButton({
|
|
86
|
+
name: "assignUnavailableStrategy",
|
|
87
|
+
label: this.api.translate("Assign Strategy"),
|
|
88
|
+
id: "guido__btn-assign-unavailable-strategy",
|
|
89
|
+
className: "strategy-control-cta on"
|
|
90
|
+
}),
|
|
91
|
+
this._GuButton({
|
|
92
|
+
name: "createUnavailableStrategy",
|
|
93
|
+
label: this.api.translate("Create New Strategy"),
|
|
94
|
+
id: "guido__btn-create-unavailable-strategy",
|
|
95
|
+
className: "strategy-control-cta primary"
|
|
96
|
+
})
|
|
74
97
|
], "strategy-control-cta-row")}
|
|
75
98
|
</div>
|
|
76
99
|
<div data-strategy-legacy-state style="display: none;">
|
|
77
100
|
<div class="strategy-control-notice-row">
|
|
78
101
|
<div class="strategy-control-notice">
|
|
79
|
-
<p class="strategy-control-notice-text">${
|
|
102
|
+
<p class="strategy-control-notice-text">${s}</p>
|
|
80
103
|
</div>
|
|
81
104
|
</div>
|
|
82
105
|
<div class="strategy-control-name-band">
|
|
83
|
-
<span class="strategy-control-name">${
|
|
106
|
+
<span class="strategy-control-name">${r}</span>
|
|
84
107
|
${this._strategyAction({
|
|
85
108
|
id: "guido__btn-update-legacy-strategy",
|
|
86
109
|
label: this.api.translate("Update"),
|
|
@@ -123,12 +146,12 @@ class M extends A {
|
|
|
123
146
|
</div>
|
|
124
147
|
`;
|
|
125
148
|
}
|
|
126
|
-
_strategyAction({ id: t, label: e, modifier:
|
|
149
|
+
_strategyAction({ id: t, label: e, modifier: a }) {
|
|
127
150
|
return `
|
|
128
151
|
<button
|
|
129
152
|
id="${t}"
|
|
130
153
|
type="button"
|
|
131
|
-
class="strategy-control-action strategy-control-action--${
|
|
154
|
+
class="strategy-control-action strategy-control-action--${a}">
|
|
132
155
|
<span>${e}</span>
|
|
133
156
|
</button>
|
|
134
157
|
`;
|
|
@@ -136,8 +159,8 @@ class M extends A {
|
|
|
136
159
|
onRender() {
|
|
137
160
|
this._teardown(), this.store.strategyPanelOpen = !0, this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
138
161
|
this._renderState();
|
|
139
|
-
}), this.store.recommendationConfigs.strategyId && !this.store.
|
|
140
|
-
});
|
|
162
|
+
}), this.store.recommendationConfigs.strategyId && !this.store.strategiesLoading && (this.store.invalidateStrategies(), this.store.fetchStrategies().catch(() => {
|
|
163
|
+
}));
|
|
141
164
|
}
|
|
142
165
|
/**
|
|
143
166
|
* Whether the document itself says this block has no strategy.
|
|
@@ -147,10 +170,10 @@ class M extends A {
|
|
|
147
170
|
* strategyId) for an assigned block.
|
|
148
171
|
*/
|
|
149
172
|
_isNodeUnassigned() {
|
|
150
|
-
if (!
|
|
173
|
+
if (!C.hasConfig(this.currentNode))
|
|
151
174
|
return !1;
|
|
152
|
-
const t =
|
|
153
|
-
return !t.strategyId && (t.configVersion ?? 0) >=
|
|
175
|
+
const t = C.getConfig(this.currentNode);
|
|
176
|
+
return !t.strategyId && (t.configVersion ?? 0) >= E;
|
|
154
177
|
}
|
|
155
178
|
onDestroy() {
|
|
156
179
|
this._teardown();
|
|
@@ -163,37 +186,37 @@ class M extends A {
|
|
|
163
186
|
const t = this.getContainer();
|
|
164
187
|
if (!t)
|
|
165
188
|
return;
|
|
166
|
-
const e = (
|
|
167
|
-
const
|
|
168
|
-
|
|
189
|
+
const e = (a, r) => {
|
|
190
|
+
const s = t.querySelector(a);
|
|
191
|
+
s && (s.addEventListener("click", r), this.listeners.push({ element: s, handler: r }));
|
|
169
192
|
};
|
|
170
|
-
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-change-legacy-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-remove-legacy-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-update-legacy-strategy", () => {
|
|
193
|
+
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-create-strategy", () => this.store.openStrategyCreation()), e("#guido__btn-assign-unavailable-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-create-unavailable-strategy", () => this.store.openStrategyCreation()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-legacy-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-remove-legacy-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-update-legacy-strategy", () => {
|
|
171
194
|
this.legacyConversion.convertLegacyStrategy();
|
|
172
195
|
});
|
|
173
196
|
}
|
|
174
197
|
_renderState() {
|
|
175
|
-
var
|
|
176
|
-
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((
|
|
177
|
-
if (
|
|
198
|
+
var f;
|
|
199
|
+
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((f = this.store.assignedStrategy) == null ? void 0 : f.name) ?? "" : "", a = !!t && !e && (this.store.strategiesLoading || !this.store.strategiesSettled), r = !!t && !e && !a && this.store.strategiesFetched, s = this.store.legacyConversionLoading, g = this.store.isLegacyStrategyBlock, p = [t, e, a, r, s, g].join("\0");
|
|
200
|
+
if (p === this.lastPaintedState)
|
|
178
201
|
return;
|
|
179
|
-
const
|
|
180
|
-
if (!
|
|
202
|
+
const n = this.getContainer();
|
|
203
|
+
if (!n)
|
|
181
204
|
return;
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
205
|
+
const y = n.querySelector("[data-strategy-empty-state]"), u = n.querySelector("[data-strategy-assigned-state]"), c = n.querySelector("[data-strategy-legacy-state]"), h = n.querySelector("[data-strategy-unavailable-state]"), v = n.querySelector("[data-strategy-loading-state]"), b = n.querySelector("[data-strategy-content]"), m = n.querySelector("[data-strategy-name]"), _ = n.querySelector("[data-strategy-name-skeleton]");
|
|
206
|
+
if (!y || !u || !c || !h)
|
|
184
207
|
return;
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
[
|
|
188
|
-
|
|
189
|
-
}),
|
|
190
|
-
|
|
191
|
-
}),
|
|
208
|
+
v && (v.style.display = "none"), b && (b.style.display = "");
|
|
209
|
+
const k = t ? r ? h : u : g ? c : y;
|
|
210
|
+
[y, u, c, h].forEach((d) => {
|
|
211
|
+
d.style.display = d === k ? "" : "none";
|
|
212
|
+
}), c.querySelectorAll("button").forEach((d) => {
|
|
213
|
+
d.disabled = s;
|
|
214
|
+
}), c.classList.toggle("is-converting", s), !t && this._isNodeUnassigned() && this.onboardingStore.startOnboarding("recommendationStrategyOnboarding");
|
|
192
215
|
const S = this.store.currentRecommendationId;
|
|
193
|
-
|
|
216
|
+
g && S !== null && this.store.blockStates[S] && this.onboardingStore.startOnboarding("recommendationLegacyStrategyOnboarding"), m && (m.style.display = a ? "none" : "", t && !a && (m.textContent = e || `#${t}`)), _ && (_.style.display = a ? "block" : "none"), this.lastPaintedState = p;
|
|
194
217
|
}
|
|
195
218
|
}
|
|
196
219
|
export {
|
|
197
|
-
|
|
198
|
-
|
|
220
|
+
I as STRATEGY_CONTROL_ID,
|
|
221
|
+
P as StrategyControl
|
|
199
222
|
};
|
|
@@ -3,7 +3,7 @@ import { useTranslations as L } from "../../../../composables/useTranslations.js
|
|
|
3
3
|
import { getRecommendationFeedSourceMaps as F, strategyEditPath as U, URLS as E, getOperatorOptions as N, PriceAttributes as M } from "../../../../enums/extensions/recommendationBlock.js";
|
|
4
4
|
import { ToasterTypeOptions as A } from "../../../../enums/toaster.js";
|
|
5
5
|
import { useRecommendationApi as T } from "../../../../services/recommendationApi.js";
|
|
6
|
-
import { useConfigStore as
|
|
6
|
+
import { useConfigStore as R } from "../../../../stores/config.js";
|
|
7
7
|
import { defineStore as B } from "pinia";
|
|
8
8
|
import "../constants/selectors.js";
|
|
9
9
|
import { DEFAULT_MOBILE_CARDS_IN_ROW as O, DEFAULT_CARDS_IN_ROW as z } from "../constants/layout.js";
|
|
@@ -12,11 +12,11 @@ import { getDefaultProducts as w } from "../templates/utils.js";
|
|
|
12
12
|
import { generateCompleteFilterQuery as P } from "../utils/filterUtil.js";
|
|
13
13
|
import { isLegacyStrategyConfig as j } from "../utils/legacyStrategyMigration.js";
|
|
14
14
|
import { getPartnerRecommendationParams as $ } from "../utils/partnerCustomizations.js";
|
|
15
|
-
import { sanitizeProductIds as
|
|
16
|
-
import { isFilterValid as
|
|
15
|
+
import { sanitizeProductIds as K } from "../utils/productIds.js";
|
|
16
|
+
import { isFilterValid as q } from "../validation/filterSchema.js";
|
|
17
17
|
import { getInvalidFields as H, isConfigValid as J } from "../validation/requiredFields.js";
|
|
18
18
|
const m = T();
|
|
19
|
-
let S = null, p = null, y = null,
|
|
19
|
+
let S = null, p = null, y = null, b = "", k = null, I = 0;
|
|
20
20
|
const g = /* @__PURE__ */ new Map();
|
|
21
21
|
let l = null;
|
|
22
22
|
function _() {
|
|
@@ -45,7 +45,7 @@ function _() {
|
|
|
45
45
|
// that default is what reached buildCampaignUrl and baked a most-popular feed URL
|
|
46
46
|
// for a block the user never configured (SD-149916). Legacy blocks still get their real
|
|
47
47
|
// algorithm from the node-config sync or the save-time seed.
|
|
48
|
-
strategy:
|
|
48
|
+
strategy: R().isFeatureEnabled("reusableRecommendationStrategy") ? "" : "mostPopular",
|
|
49
49
|
strategyId: "",
|
|
50
50
|
nodeConfigVersion: C,
|
|
51
51
|
textTrimming: !0,
|
|
@@ -119,7 +119,7 @@ const Q = () => ({
|
|
|
119
119
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
|
|
120
120
|
},
|
|
121
121
|
isLegacyStrategyBlock() {
|
|
122
|
-
return
|
|
122
|
+
return R().isFeatureEnabled("reusableRecommendationStrategy") && j(this.recommendationConfigs);
|
|
123
123
|
},
|
|
124
124
|
legacyConversionLoading(t) {
|
|
125
125
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyConversionLoading ?? !1 : !1;
|
|
@@ -234,7 +234,7 @@ const Q = () => ({
|
|
|
234
234
|
const r = this.blockStates[t];
|
|
235
235
|
if (r) {
|
|
236
236
|
const o = structuredClone(r);
|
|
237
|
-
o.recommendationConfigs.id = e, o.recommendationConfigs.strategyId &&
|
|
237
|
+
o.recommendationConfigs.id = e, o.recommendationConfigs.strategyId && R().isFeatureEnabled("reusableRecommendationStrategy") && (o.isInitialized = !1, o.syncedConfigFingerprint = null), this.blockStates = {
|
|
238
238
|
...this.blockStates,
|
|
239
239
|
[e]: o
|
|
240
240
|
};
|
|
@@ -380,31 +380,50 @@ const Q = () => ({
|
|
|
380
380
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
|
|
381
381
|
},
|
|
382
382
|
async fetchStrategies() {
|
|
383
|
-
for (;
|
|
383
|
+
for (; k; )
|
|
384
384
|
try {
|
|
385
|
-
await
|
|
385
|
+
await k;
|
|
386
386
|
} catch {
|
|
387
387
|
}
|
|
388
388
|
if (this.strategiesFetched)
|
|
389
389
|
return;
|
|
390
|
-
const t =
|
|
390
|
+
const t = I, e = (async () => {
|
|
391
391
|
this.strategiesLoading = !0;
|
|
392
392
|
try {
|
|
393
393
|
const r = await m.fetchRecommendationStrategies();
|
|
394
|
-
if (t !==
|
|
394
|
+
if (t !== I)
|
|
395
395
|
return;
|
|
396
396
|
this.strategies = r, this.strategiesFetched = !0;
|
|
397
397
|
} finally {
|
|
398
|
-
this.strategiesLoading = !1, t ===
|
|
398
|
+
this.strategiesLoading = !1, t === I && (this.strategiesSettled = !0);
|
|
399
399
|
}
|
|
400
400
|
})();
|
|
401
|
-
|
|
401
|
+
k = e;
|
|
402
402
|
try {
|
|
403
403
|
await e;
|
|
404
404
|
} finally {
|
|
405
|
-
|
|
405
|
+
k = null;
|
|
406
406
|
}
|
|
407
407
|
},
|
|
408
|
+
/**
|
|
409
|
+
* Drops what the store still holds for a block whose account-scoped config was just
|
|
410
|
+
* reset in the document (SD-151945), so the panel re-seeds from the emptied node.
|
|
411
|
+
*/
|
|
412
|
+
resetPartnerScopedConfig(t) {
|
|
413
|
+
const e = t.toString();
|
|
414
|
+
if (this.recommendationCampaignUrls[e] !== void 0) {
|
|
415
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
416
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
417
|
+
}
|
|
418
|
+
const r = this.blockStates[t];
|
|
419
|
+
r && (r.recommendationConfigs = {
|
|
420
|
+
...r.recommendationConfigs,
|
|
421
|
+
strategyId: "",
|
|
422
|
+
strategy: "",
|
|
423
|
+
filters: [],
|
|
424
|
+
productIds: []
|
|
425
|
+
}, r.isInitialized = !1, r.syncedConfigFingerprint = null, this.currentRecommendationId === t && this.configVersion++);
|
|
426
|
+
},
|
|
408
427
|
/**
|
|
409
428
|
* Clears what a block inherited from the id it arrived holding, so the panel fetches for it.
|
|
410
429
|
* A re-dropped saved module can keep the source's id — and its "already fetched" entry —
|
|
@@ -416,7 +435,7 @@ const Q = () => ({
|
|
|
416
435
|
}));
|
|
417
436
|
},
|
|
418
437
|
invalidateStrategies() {
|
|
419
|
-
this.strategiesFetched = !1, this.strategiesSettled = !1,
|
|
438
|
+
this.strategiesFetched = !1, this.strategiesSettled = !1, I += 1;
|
|
420
439
|
},
|
|
421
440
|
/**
|
|
422
441
|
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
@@ -503,6 +522,7 @@ const Q = () => ({
|
|
|
503
522
|
this.blockStates[r].legacyConversionLoading = !0;
|
|
504
523
|
try {
|
|
505
524
|
const n = await m.migrateLegacyStrategy(t, e);
|
|
525
|
+
this.invalidateStrategies();
|
|
506
526
|
try {
|
|
507
527
|
await this.fetchStrategies();
|
|
508
528
|
} catch (o) {
|
|
@@ -606,7 +626,7 @@ const Q = () => ({
|
|
|
606
626
|
const n = [...e.recommendationConfigs.filters];
|
|
607
627
|
n[r] = {
|
|
608
628
|
...t,
|
|
609
|
-
isValid:
|
|
629
|
+
isValid: q(t)
|
|
610
630
|
}, e.recommendationConfigs.filters = n;
|
|
611
631
|
}
|
|
612
632
|
},
|
|
@@ -670,22 +690,22 @@ const Q = () => ({
|
|
|
670
690
|
const t = [
|
|
671
691
|
this.currentRecommendationId,
|
|
672
692
|
this.configVersion,
|
|
673
|
-
|
|
693
|
+
I
|
|
674
694
|
].join(":");
|
|
675
|
-
if (y &&
|
|
695
|
+
if (y && b === t) {
|
|
676
696
|
await y;
|
|
677
697
|
return;
|
|
678
698
|
}
|
|
679
|
-
|
|
699
|
+
b = t, y = this._doFetchProducts();
|
|
680
700
|
try {
|
|
681
701
|
await y;
|
|
682
702
|
} finally {
|
|
683
|
-
|
|
703
|
+
b === t && (y = null, b = "");
|
|
684
704
|
}
|
|
685
705
|
},
|
|
686
706
|
async _doFetchProducts() {
|
|
687
707
|
var h;
|
|
688
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n =
|
|
708
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = R();
|
|
689
709
|
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
690
710
|
await this._doFetchStrategyProducts(t);
|
|
691
711
|
return;
|
|
@@ -705,7 +725,7 @@ const Q = () => ({
|
|
|
705
725
|
details: !0,
|
|
706
726
|
campaignId: n.variationId
|
|
707
727
|
};
|
|
708
|
-
r.strategy === "manualMerchandising" ? c.productId =
|
|
728
|
+
r.strategy === "manualMerchandising" ? c.productId = K(r.productIds) : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), a && (c.filter = a), r.shuffleProducts && (c.shuffle = !0), Object.assign(
|
|
709
729
|
c,
|
|
710
730
|
$(n.partnerName, r.strategy)
|
|
711
731
|
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ATTR_CUSTOM_PREFIX as f, RECOMMENDATION_ID_ATTR as o } from "../constants/selectors.js";
|
|
2
|
+
const s = new RegExp(`\\s${o}="(\\d+)"`, "g");
|
|
3
|
+
function u(t) {
|
|
4
|
+
if (typeof t == "string")
|
|
5
|
+
return t.trim() !== "";
|
|
6
|
+
if (t && typeof t == "object" && "strategyId" in t) {
|
|
7
|
+
const { strategyId: r } = t;
|
|
8
|
+
return (typeof r == "string" || typeof r == "number") && String(r).trim() !== "";
|
|
9
|
+
}
|
|
10
|
+
return !1;
|
|
11
|
+
}
|
|
12
|
+
function a(t) {
|
|
13
|
+
return new Set([...t.matchAll(s)].map((r) => Number(r[1])));
|
|
14
|
+
}
|
|
15
|
+
function g({ config: t, blockId: r, partnerName: e, campaignUrls: n, loadedIds: i }) {
|
|
16
|
+
return e ? t.partnerName ? t.partnerName !== e : !t.strategyId || !n || !i.has(r) ? !1 : !u(n[String(r)]) : !1;
|
|
17
|
+
}
|
|
18
|
+
function p(t) {
|
|
19
|
+
return t.filter((r) => !r.startsWith(f));
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
g as carriesForeignPartnerConfig,
|
|
23
|
+
u as isDefinedCampaignUrl,
|
|
24
|
+
a as loadedRecommendationIds,
|
|
25
|
+
p as withoutCustomAttributes
|
|
26
|
+
};
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-
|
|
1
|
+
@charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-c61cc8ea]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-36867e2e]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-36867e2e]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-36867e2e]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-19d8cb42] .vueperslides__bullets,[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}.legacy-strategy-updated-modal[data-v-da2225a1]{position:relative;z-index:145}
|
|
@@ -278,6 +278,14 @@ export declare const TemplateSchema: v.ObjectSchema<{
|
|
|
278
278
|
* mount. Non-numbers still fail, like every other field in this schema.
|
|
279
279
|
*/
|
|
280
280
|
readonly trackIdCounter: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, number>]>, 0>;
|
|
281
|
+
/**
|
|
282
|
+
* The variation's saved `recommendationCampaignUrls`, keyed by block id. A block
|
|
283
|
+
* that still names a strategy but has no entry here had it dropped by a
|
|
284
|
+
* cross-account duplicate, so Guido resets it on load (SD-151945). Omit it and
|
|
285
|
+
* that check is off, and so is any non-object value such as `null`, because a reset
|
|
286
|
+
* cannot be undone. Hosts send `[]` for an empty map.
|
|
287
|
+
*/
|
|
288
|
+
readonly recommendationCampaignUrls: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<unknown, Record<string, unknown> | undefined>]>, undefined>;
|
|
281
289
|
/** Migration-only inputs (legacy block configs) */
|
|
282
290
|
readonly migration: v.OptionalSchema<v.ObjectSchema<{
|
|
283
291
|
/**
|
|
@@ -701,6 +709,14 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
|
|
|
701
709
|
* mount. Non-numbers still fail, like every other field in this schema.
|
|
702
710
|
*/
|
|
703
711
|
readonly trackIdCounter: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, number>]>, 0>;
|
|
712
|
+
/**
|
|
713
|
+
* The variation's saved `recommendationCampaignUrls`, keyed by block id. A block
|
|
714
|
+
* that still names a strategy but has no entry here had it dropped by a
|
|
715
|
+
* cross-account duplicate, so Guido resets it on load (SD-151945). Omit it and
|
|
716
|
+
* that check is off, and so is any non-object value such as `null`, because a reset
|
|
717
|
+
* cannot be undone. Hosts send `[]` for an empty map.
|
|
718
|
+
*/
|
|
719
|
+
readonly recommendationCampaignUrls: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<unknown, Record<string, unknown> | undefined>]>, undefined>;
|
|
704
720
|
/** Migration-only inputs (legacy block configs) */
|
|
705
721
|
readonly migration: v.OptionalSchema<v.ObjectSchema<{
|
|
706
722
|
/**
|
|
@@ -43,6 +43,7 @@ export declare const useConfig: () => {
|
|
|
43
43
|
selectedUnsubscribePages: number[];
|
|
44
44
|
forceRecreate: boolean;
|
|
45
45
|
trackIdCounter: number;
|
|
46
|
+
recommendationCampaignUrls?: Record<string, unknown> | undefined;
|
|
46
47
|
migration: {
|
|
47
48
|
recommendationConfigs: {
|
|
48
49
|
[x: string]: {
|
|
@@ -180,6 +181,7 @@ export declare const useConfig: () => {
|
|
|
180
181
|
selectedUnsubscribePages: number[];
|
|
181
182
|
forceRecreate: boolean;
|
|
182
183
|
trackIdCounter: number;
|
|
184
|
+
recommendationCampaignUrls?: Record<string, unknown> | undefined;
|
|
183
185
|
migration: {
|
|
184
186
|
recommendationConfigs: {
|
|
185
187
|
[x: string]: {
|
|
@@ -137,6 +137,12 @@ export declare class RecommendationBlock extends Block {
|
|
|
137
137
|
* heals templates saved before this feature without dirtying current ones.
|
|
138
138
|
*/
|
|
139
139
|
private _healHidePriceAttr;
|
|
140
|
+
/**
|
|
141
|
+
* Empties a block copied in from another account: its strategy and attribute types
|
|
142
|
+
* are account-scoped and would not resolve here (SD-151945). Layout, locale and
|
|
143
|
+
* currency stay. The write stamps the current account, so the next pass is a no-op.
|
|
144
|
+
*/
|
|
145
|
+
private _resetForeignPartnerConfig;
|
|
140
146
|
/**
|
|
141
147
|
* Gets the recommendation-id from a block node
|
|
142
148
|
*/
|
|
@@ -543,6 +543,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
543
543
|
openRemoveStrategyModal(): void;
|
|
544
544
|
closeRemoveStrategyModal(): void;
|
|
545
545
|
fetchStrategies(): Promise<void>;
|
|
546
|
+
/**
|
|
547
|
+
* Drops what the store still holds for a block whose account-scoped config was just
|
|
548
|
+
* reset in the document (SD-151945), so the panel re-seeds from the emptied node.
|
|
549
|
+
*/
|
|
550
|
+
resetPartnerScopedConfig(id: number): void;
|
|
546
551
|
/**
|
|
547
552
|
* Clears what a block inherited from the id it arrived holding, so the panel fetches for it.
|
|
548
553
|
* A re-dropped saved module can keep the source's id — and its "already fetched" entry —
|
|
@@ -83,6 +83,12 @@ export interface RecommendationNodeConfig {
|
|
|
83
83
|
*/
|
|
84
84
|
filters: Filter[];
|
|
85
85
|
strategyId: string;
|
|
86
|
+
/**
|
|
87
|
+
* Account (`config.partner.name`) that last wrote the strategy config. Strategy ids and
|
|
88
|
+
* attribute types are account-scoped, so a block opened under another account is reset.
|
|
89
|
+
* Absent on blocks saved before SD-151945.
|
|
90
|
+
*/
|
|
91
|
+
partnerName?: string;
|
|
86
92
|
/**
|
|
87
93
|
* Layout orientation
|
|
88
94
|
* - 'grid': Products in a grid, attributes aligned across products
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RecommendationNodeConfig } from '../types/nodeConfig';
|
|
2
|
+
/**
|
|
3
|
+
* Mirrors the backend's `RecommendationCampaignUrls::isDefined`: a legacy feed URL
|
|
4
|
+
* string or an entry that names a strategy.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isDefinedCampaignUrl(value: unknown): boolean;
|
|
7
|
+
/** Recommendation block ids present in the HTML the host loaded the editor with. */
|
|
8
|
+
export declare function loadedRecommendationIds(html: string): Set<number>;
|
|
9
|
+
export interface PartnerScopeInputs {
|
|
10
|
+
config: Pick<RecommendationNodeConfig, 'strategyId' | 'partnerName'>;
|
|
11
|
+
blockId: number;
|
|
12
|
+
partnerName: string;
|
|
13
|
+
/** `undefined` when the host does not pass the map — the unstamped check is then off. */
|
|
14
|
+
campaignUrls: Record<string, unknown> | undefined;
|
|
15
|
+
loadedIds: Set<number>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Whether a block carries another account's strategy config (SD-151945).
|
|
19
|
+
*
|
|
20
|
+
* A stamped block is judged by its stamp. An unstamped one predates the stamp, so it
|
|
21
|
+
* falls back to the backend's own signal: a cross-account duplicate drops the block's
|
|
22
|
+
* strategy entry from the campaign URL map but leaves the HTML untouched. That check
|
|
23
|
+
* only holds for blocks the host loaded, whose map entry the host actually sent — a
|
|
24
|
+
* saved module or a clone arrives under an id the map never had.
|
|
25
|
+
*/
|
|
26
|
+
export declare function carriesForeignPartnerConfig({ config, blockId, partnerName, campaignUrls, loadedIds }: PartnerScopeInputs): boolean;
|
|
27
|
+
export declare function withoutCustomAttributes(composition: string[]): string[];
|