@useinsider/guido 3.21.0-beta.27e5667 → 3.21.0-beta.387b29d
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/extensions/Blocks/Recommendation/block.js +136 -166
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +31 -48
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -7
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -9
- package/package.json +2 -2
|
@@ -1,44 +1,43 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useConfig as
|
|
1
|
+
var B = Object.defineProperty;
|
|
2
|
+
var b = (a, l, t) => l in a ? B(a, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[l] = t;
|
|
3
|
+
var d = (a, l, t) => b(a, typeof l != "symbol" ? l + "" : l, t);
|
|
4
|
+
import { useConfig as g } from "../../../composables/useConfig.js";
|
|
5
5
|
import { BlockId as C } from "../../../enums/block.js";
|
|
6
|
-
import { getMigrationBannerHtml as
|
|
7
|
-
import { Block as
|
|
8
|
-
import { CURRENT_CONFIG_VERSION as
|
|
9
|
-
import { RECOMMENDATION_ID_ATTR as
|
|
10
|
-
import { regenerateMobileProductRows as
|
|
11
|
-
import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as
|
|
12
|
-
import { RecommendationConfigService as
|
|
13
|
-
import { useRecommendationExtensionStore as
|
|
14
|
-
import { getDefaultTemplate as
|
|
15
|
-
import { useRecommendationBlockWarning as
|
|
16
|
-
import { registerNodeConfigWriter as
|
|
17
|
-
import {
|
|
18
|
-
const
|
|
19
|
-
let
|
|
20
|
-
class
|
|
6
|
+
import { getMigrationBannerHtml as A } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as E, BlockCompositionType as S, ModificationDescription as p } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { CURRENT_CONFIG_VERSION as N, PRE_RRS_CONFIG_VERSION as w } from "./constants/defaultConfig.js";
|
|
9
|
+
import { RECOMMENDATION_ID_ATTR as m } from "./constants/selectors.js";
|
|
10
|
+
import { regenerateMobileProductRows as M } from "./controls/main/utils.js";
|
|
11
|
+
import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as R, hasMobileLayoutOptOut as O } from "./controls/mobileLayout/cssRules.js";
|
|
12
|
+
import { RecommendationConfigService as s } from "./services/configService.js";
|
|
13
|
+
import { useRecommendationExtensionStore as h } from "./store/recommendation.js";
|
|
14
|
+
import { getDefaultTemplate as x } from "./templates/grid/template.js";
|
|
15
|
+
import { useRecommendationBlockWarning as T } from "./useRecommendationBlockWarning.js";
|
|
16
|
+
import { registerNodeConfigWriter as H } from "./utils/nodeConfigWriter.js";
|
|
17
|
+
import { refreshDuplicatedStrategyBlocks as $ } from "./utils/strategyCommit.js";
|
|
18
|
+
const k = C.Recommendation, u = "recommendation-block-v2", D = "hide-price";
|
|
19
|
+
let y = !1;
|
|
20
|
+
class Y extends E {
|
|
21
21
|
constructor() {
|
|
22
22
|
super();
|
|
23
23
|
/**
|
|
24
24
|
* Stores the ID generated in getTemplate() so onCreated() can reuse it.
|
|
25
25
|
* This avoids generating a new (different) ID in onCreated().
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
d(this, "_pendingBlockId", null);
|
|
28
28
|
/** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
|
|
29
|
-
|
|
29
|
+
d(this, "_resetSourceIds", /* @__PURE__ */ new Set());
|
|
30
30
|
/** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
|
|
31
|
-
|
|
32
|
-
m(this, "_arrivedNodes", []);
|
|
31
|
+
d(this, "_unsettledDuplicateIds", /* @__PURE__ */ new Set());
|
|
33
32
|
}
|
|
34
33
|
getId() {
|
|
35
|
-
return
|
|
34
|
+
return k;
|
|
36
35
|
}
|
|
37
36
|
getIcon() {
|
|
38
37
|
return "recommendation-icon";
|
|
39
38
|
}
|
|
40
39
|
getBlockCompositionType() {
|
|
41
|
-
return
|
|
40
|
+
return S.CONTAINER;
|
|
42
41
|
}
|
|
43
42
|
getName() {
|
|
44
43
|
return this.api.translate("Recommendation Block");
|
|
@@ -49,8 +48,8 @@ class Z extends S {
|
|
|
49
48
|
);
|
|
50
49
|
}
|
|
51
50
|
getSettingsPanelTitleHtml() {
|
|
52
|
-
return
|
|
53
|
-
|
|
51
|
+
return A(
|
|
52
|
+
k,
|
|
54
53
|
this.api.translate("Recommendation Block"),
|
|
55
54
|
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.")
|
|
56
55
|
);
|
|
@@ -72,8 +71,8 @@ class Z extends S {
|
|
|
72
71
|
* attribute and overwrites dynamically added classes via setAttribute.
|
|
73
72
|
*/
|
|
74
73
|
getTemplate() {
|
|
75
|
-
const
|
|
76
|
-
return this._pendingBlockId =
|
|
74
|
+
const t = this._generateNextId();
|
|
75
|
+
return this._pendingBlockId = t, x(t);
|
|
77
76
|
}
|
|
78
77
|
/**
|
|
79
78
|
* Called when a new block is dropped into the template
|
|
@@ -82,49 +81,42 @@ class Z extends S {
|
|
|
82
81
|
* and assigns the recommendation-id attribute + initializes configuration.
|
|
83
82
|
* @param node - The newly created block node
|
|
84
83
|
*/
|
|
85
|
-
onCreated(
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
if (this._detectDuplicate(
|
|
89
|
-
this._handleDuplicate(
|
|
84
|
+
onCreated(t) {
|
|
85
|
+
const e = this._getRecommendationId(t);
|
|
86
|
+
if (e !== null && e > 0) {
|
|
87
|
+
if (this._detectDuplicate(e)) {
|
|
88
|
+
this._handleDuplicate(t, e), this._scheduleArrivalReset(t);
|
|
90
89
|
return;
|
|
91
90
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (h && this._detectDuplicate(t)) {
|
|
96
|
-
this._handleDuplicate(e, t);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
this._queueArrivalRefresh(e);
|
|
100
|
-
}
|
|
101
|
-
}, 0), this._scheduleArrivalReset(e);
|
|
91
|
+
this._pendingBlockId === null && setTimeout(() => {
|
|
92
|
+
this._getBlockElement(t) && this._detectDuplicate(e) && this._handleDuplicate(t, e);
|
|
93
|
+
}, 0), this._scheduleArrivalReset(t);
|
|
102
94
|
return;
|
|
103
95
|
}
|
|
104
96
|
const i = this._pendingBlockId ?? this._generateNextId();
|
|
105
|
-
this._pendingBlockId = null, this._assignRecommendationId(
|
|
106
|
-
const
|
|
97
|
+
this._pendingBlockId = null, this._assignRecommendationId(t, i);
|
|
98
|
+
const n = g().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !s.hasConfig(t), { config: r, wasFreshDrop: c } = s.initializeConfig(
|
|
107
99
|
this.api,
|
|
108
|
-
|
|
100
|
+
t,
|
|
109
101
|
{
|
|
110
102
|
recommendationId: i,
|
|
111
|
-
configVersion:
|
|
112
|
-
...
|
|
103
|
+
configVersion: n ? N : w,
|
|
104
|
+
...o ? { partnerName: g().partnerName.value } : {},
|
|
113
105
|
// An RRS block picks a strategy, not an algorithm, and its algorithm control is
|
|
114
106
|
// hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
|
|
115
107
|
// at save for a block the user never configured.
|
|
116
|
-
...
|
|
108
|
+
...o ? { strategy: "" } : {}
|
|
117
109
|
}
|
|
118
|
-
),
|
|
119
|
-
if (
|
|
110
|
+
), f = h();
|
|
111
|
+
if (f.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), c) {
|
|
120
112
|
I(this.api);
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
currentNode:
|
|
113
|
+
const _ = this._getBlockElement(t);
|
|
114
|
+
_ && (R(this.api, _, !0), M({
|
|
115
|
+
currentNode: t,
|
|
124
116
|
documentModifier: this.api.getDocumentModifier()
|
|
125
117
|
}));
|
|
126
118
|
}
|
|
127
|
-
|
|
119
|
+
f.patchCurrentBlockConfig({ language: r.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
|
|
128
120
|
}
|
|
129
121
|
/**
|
|
130
122
|
* Called when the document changes or template is loaded
|
|
@@ -133,24 +125,24 @@ class Z extends S {
|
|
|
133
125
|
* and assigns recommendation-id to legacy blocks that lack one.
|
|
134
126
|
* @param node - The block node that may need migration
|
|
135
127
|
*/
|
|
136
|
-
onDocumentChanged(
|
|
137
|
-
if (!(!
|
|
138
|
-
if (!this._getRecommendationId(
|
|
139
|
-
const
|
|
140
|
-
this._assignRecommendationId(
|
|
128
|
+
onDocumentChanged(t) {
|
|
129
|
+
if (!(!t || !("getNodeConfig" in t))) {
|
|
130
|
+
if (!this._getRecommendationId(t)) {
|
|
131
|
+
const e = this._generateNextId();
|
|
132
|
+
this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
|
|
141
133
|
this.api,
|
|
142
|
-
|
|
143
|
-
{ recommendationId:
|
|
134
|
+
t,
|
|
135
|
+
{ recommendationId: e },
|
|
144
136
|
"Assign recommendation ID to legacy block"
|
|
145
137
|
);
|
|
146
138
|
}
|
|
147
|
-
this._healLingeringDuplicate(
|
|
139
|
+
this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
|
|
148
140
|
try {
|
|
149
|
-
|
|
150
|
-
const
|
|
141
|
+
y || (I(this.api), y = !0);
|
|
142
|
+
const e = s.getConfig(t), i = this._getBlockElement(t);
|
|
151
143
|
if (i) {
|
|
152
|
-
const
|
|
153
|
-
O(i) !==
|
|
144
|
+
const n = !e.mobileLayoutEnabled;
|
|
145
|
+
O(i) !== n && R(this.api, i, n);
|
|
154
146
|
}
|
|
155
147
|
} catch {
|
|
156
148
|
}
|
|
@@ -162,9 +154,9 @@ class Z extends S {
|
|
|
162
154
|
* Cleans up the per-block state from the Pinia store.
|
|
163
155
|
* @param node - The block node being deleted
|
|
164
156
|
*/
|
|
165
|
-
onDelete(
|
|
166
|
-
const
|
|
167
|
-
|
|
157
|
+
onDelete(t) {
|
|
158
|
+
const e = this._getRecommendationId(t);
|
|
159
|
+
e && h().removeBlockState(e);
|
|
168
160
|
}
|
|
169
161
|
/**
|
|
170
162
|
* Warns (dark advisory toaster) when the design holds more than one live
|
|
@@ -180,7 +172,7 @@ class Z extends S {
|
|
|
180
172
|
*/
|
|
181
173
|
_warnIfMultipleBlocks() {
|
|
182
174
|
try {
|
|
183
|
-
|
|
175
|
+
T().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
|
|
184
176
|
} catch {
|
|
185
177
|
}
|
|
186
178
|
}
|
|
@@ -189,21 +181,21 @@ class Z extends S {
|
|
|
189
181
|
* in the document and finding the maximum existing ID + 1.
|
|
190
182
|
*/
|
|
191
183
|
_generateNextId() {
|
|
192
|
-
let
|
|
193
|
-
const
|
|
184
|
+
let t = 0;
|
|
185
|
+
const e = /* @__PURE__ */ new Set();
|
|
194
186
|
try {
|
|
195
187
|
const i = this.api.getDocumentRoot();
|
|
196
|
-
i && "querySelectorAll" in i && i.querySelectorAll(`.${
|
|
197
|
-
if ("getAttribute" in
|
|
198
|
-
const
|
|
199
|
-
|
|
188
|
+
i && "querySelectorAll" in i && i.querySelectorAll(`.${u}`).forEach((o) => {
|
|
189
|
+
if ("getAttribute" in o) {
|
|
190
|
+
const r = o.getAttribute(m), c = r ? parseInt(r) : 0;
|
|
191
|
+
e.add(c), c > t && (t = c);
|
|
200
192
|
}
|
|
201
193
|
});
|
|
202
194
|
} catch {
|
|
203
195
|
}
|
|
204
196
|
return this._unsettledDuplicateIds.forEach((i) => {
|
|
205
|
-
|
|
206
|
-
}), Math.max(
|
|
197
|
+
e.has(i) && this._unsettledDuplicateIds.delete(i);
|
|
198
|
+
}), Math.max(t, ...this._unsettledDuplicateIds) + 1;
|
|
207
199
|
}
|
|
208
200
|
/**
|
|
209
201
|
* Drops the "already fetched" claims of a block that arrived holding a baked id
|
|
@@ -212,34 +204,12 @@ class Z extends S {
|
|
|
212
204
|
* Deferred a tick: the collision handlers rename a sibling first, and either sibling can be
|
|
213
205
|
* the renamed one depending on where the module was dropped (SD-149916).
|
|
214
206
|
*/
|
|
215
|
-
_scheduleArrivalReset(
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
207
|
+
_scheduleArrivalReset(t) {
|
|
208
|
+
g().isFeatureEnabled("reusableRecommendationStrategy") && setTimeout(() => {
|
|
209
|
+
const e = this._getRecommendationId(t);
|
|
210
|
+
e !== null && e > 0 && !this._resetSourceIds.delete(e) && h().resetArrivedBlock(e);
|
|
219
211
|
}, 0);
|
|
220
212
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Re-reads the strategy of a block that arrived with saved cards, without waiting for a click. Stripo
|
|
223
|
-
* creates every block of an opened template or dropped module, so arrivals of one tick refresh together.
|
|
224
|
-
*/
|
|
225
|
-
_queueArrivalRefresh(e) {
|
|
226
|
-
u().isFeatureEnabled("reusableRecommendationStrategy") && (this._arrivedNodes.push(e) > 1 || setTimeout(() => {
|
|
227
|
-
const t = this._arrivedNodes;
|
|
228
|
-
this._arrivedNodes = [];
|
|
229
|
-
try {
|
|
230
|
-
this._refreshArrivedBlocks(t);
|
|
231
|
-
} catch (i) {
|
|
232
|
-
console.error("[recommendation] refreshing an arrived strategy failed", i);
|
|
233
|
-
}
|
|
234
|
-
}, 0));
|
|
235
|
-
}
|
|
236
|
-
_refreshArrivedBlocks(e) {
|
|
237
|
-
const t = e.flatMap((i) => {
|
|
238
|
-
const r = this._getRecommendationId(i), n = this._getBlockElement(i);
|
|
239
|
-
return r && n ? [{ id: r, config: o.getConfig(n) }] : [];
|
|
240
|
-
});
|
|
241
|
-
R(this.api), H(t).catch((i) => console.error("[recommendation] refreshing an arrived strategy failed", i));
|
|
242
|
-
}
|
|
243
213
|
/**
|
|
244
214
|
* Heals a duplicate that slipped past the create-time `_detectDuplicate`
|
|
245
215
|
* scan (or that was persisted by an older template before SD-142352).
|
|
@@ -252,49 +222,49 @@ class Z extends S {
|
|
|
252
222
|
* yanking the user's current selection mid-edit when the heal fires from
|
|
253
223
|
* `onDocumentChanged`.
|
|
254
224
|
*/
|
|
255
|
-
_healLingeringDuplicate(
|
|
256
|
-
const
|
|
257
|
-
if (!(
|
|
225
|
+
_healLingeringDuplicate(t) {
|
|
226
|
+
const e = this._getRecommendationId(t);
|
|
227
|
+
if (!(e === null || e <= 0))
|
|
258
228
|
try {
|
|
259
229
|
const i = this.api.getDocumentRoot();
|
|
260
230
|
if (!i || !("querySelectorAll" in i))
|
|
261
231
|
return;
|
|
262
|
-
const
|
|
263
|
-
`.${
|
|
232
|
+
const n = i.querySelectorAll(
|
|
233
|
+
`.${u}[${m}="${e}"]`
|
|
264
234
|
);
|
|
265
|
-
if (
|
|
235
|
+
if (n.length <= 1)
|
|
266
236
|
return;
|
|
267
|
-
const
|
|
268
|
-
if (!
|
|
237
|
+
const o = this._getBlockElement(t);
|
|
238
|
+
if (!o)
|
|
269
239
|
return;
|
|
270
|
-
let
|
|
271
|
-
for (let
|
|
272
|
-
if (
|
|
273
|
-
|
|
240
|
+
let r = -1;
|
|
241
|
+
for (let c = 0; c < n.length; c++)
|
|
242
|
+
if (n[c] === o) {
|
|
243
|
+
r = c;
|
|
274
244
|
break;
|
|
275
245
|
}
|
|
276
|
-
if (
|
|
246
|
+
if (r <= 0)
|
|
277
247
|
return;
|
|
278
|
-
this._reassignDuplicateId(
|
|
248
|
+
this._reassignDuplicateId(t, e);
|
|
279
249
|
} catch {
|
|
280
250
|
}
|
|
281
251
|
}
|
|
282
252
|
/** True when another block already holds the same id — Stripo's duplication signal. */
|
|
283
|
-
_detectDuplicate(
|
|
253
|
+
_detectDuplicate(t) {
|
|
284
254
|
try {
|
|
285
|
-
const
|
|
286
|
-
if (
|
|
287
|
-
return
|
|
288
|
-
`.${
|
|
255
|
+
const e = this.api.getDocumentRoot();
|
|
256
|
+
if (e && "querySelectorAll" in e)
|
|
257
|
+
return e.querySelectorAll(
|
|
258
|
+
`.${u}[${m}="${t}"]`
|
|
289
259
|
).length > 1;
|
|
290
260
|
} catch {
|
|
291
261
|
}
|
|
292
262
|
return !1;
|
|
293
263
|
}
|
|
294
264
|
/** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
|
|
295
|
-
_handleDuplicate(
|
|
296
|
-
const i = this._reassignDuplicateId(
|
|
297
|
-
|
|
265
|
+
_handleDuplicate(t, e) {
|
|
266
|
+
const i = this._reassignDuplicateId(t, e), n = h();
|
|
267
|
+
n.cloneBlockState(e, i), n.setCurrentBlock(i), g().isFeatureEnabled("reusableRecommendationStrategy") && (this._resetSourceIds.add(e), H(this.api), $(e, i, s.getConfig(t)).catch((o) => console.error("[recommendation] refreshing a duplicated strategy failed", o))), this._warnIfMultipleBlocks();
|
|
298
268
|
}
|
|
299
269
|
/**
|
|
300
270
|
* Core id-reassignment for a duplicated block: rewrites the DOM
|
|
@@ -307,13 +277,13 @@ class Z extends S {
|
|
|
307
277
|
* effects so older bug-affected templates can self-repair without
|
|
308
278
|
* disturbing the user's current selection).
|
|
309
279
|
*/
|
|
310
|
-
_reassignDuplicateId(
|
|
311
|
-
const i = this._generateNextId(),
|
|
312
|
-
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(
|
|
280
|
+
_reassignDuplicateId(t, e) {
|
|
281
|
+
const i = this._generateNextId(), n = this._getBlockElement(t);
|
|
282
|
+
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), s.hasConfig(t) && s.updateConfig(
|
|
313
283
|
this.api,
|
|
314
|
-
|
|
284
|
+
t,
|
|
315
285
|
{ recommendationId: i },
|
|
316
|
-
`Reassign recommendation ID on duplicate (was ${
|
|
286
|
+
`Reassign recommendation ID on duplicate (was ${e})`
|
|
317
287
|
), i;
|
|
318
288
|
}
|
|
319
289
|
/**
|
|
@@ -323,12 +293,12 @@ class Z extends S {
|
|
|
323
293
|
* the source's class would both leak stylistic edits across blocks and
|
|
324
294
|
* cause the mail render to apply the source block's config to the clone.
|
|
325
295
|
*/
|
|
326
|
-
_reassignInstanceClass(
|
|
327
|
-
if (!("getAttribute" in
|
|
296
|
+
_reassignInstanceClass(t, e, i) {
|
|
297
|
+
if (!("getAttribute" in t))
|
|
328
298
|
return;
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
`Reassign recommendation instance class ${
|
|
299
|
+
const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, r = this.api.getDocumentModifier();
|
|
300
|
+
r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new p(
|
|
301
|
+
`Reassign recommendation instance class ${n} -> ${o}`
|
|
332
302
|
));
|
|
333
303
|
}
|
|
334
304
|
/**
|
|
@@ -337,64 +307,64 @@ class Z extends S {
|
|
|
337
307
|
* HTML by getTemplate(), since Stripo's Angular rendering overwrites dynamically
|
|
338
308
|
* added classes via setAttribute.
|
|
339
309
|
*/
|
|
340
|
-
_assignRecommendationId(
|
|
341
|
-
const i = this._getBlockElement(
|
|
310
|
+
_assignRecommendationId(t, e) {
|
|
311
|
+
const i = this._getBlockElement(t);
|
|
342
312
|
if (!i)
|
|
343
313
|
return;
|
|
344
|
-
const
|
|
345
|
-
|
|
314
|
+
const n = this.api.getDocumentModifier();
|
|
315
|
+
n.modifyHtml(i).setAttribute(m, e.toString()), n.apply(new p(`Assign recommendation ID ${e}`));
|
|
346
316
|
}
|
|
347
317
|
/**
|
|
348
318
|
* Stamps the `hide-price` attribute (read by email-service at send time) on
|
|
349
319
|
* the block element from the config flag.
|
|
350
320
|
*/
|
|
351
|
-
_stampHidePrice(
|
|
352
|
-
const i = this._getBlockElement(
|
|
353
|
-
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(
|
|
321
|
+
_stampHidePrice(t, e) {
|
|
322
|
+
const i = this._getBlockElement(t);
|
|
323
|
+
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(D, String(e)).apply(new p("Stamp hide-price"));
|
|
354
324
|
}
|
|
355
325
|
/**
|
|
356
326
|
* Stamps `hide-price` from config only when the block lacks the attribute —
|
|
357
327
|
* heals templates saved before this feature without dirtying current ones.
|
|
358
328
|
*/
|
|
359
|
-
_healHidePriceAttr(
|
|
360
|
-
const
|
|
361
|
-
if (!
|
|
329
|
+
_healHidePriceAttr(t) {
|
|
330
|
+
const e = this._getBlockElement(t);
|
|
331
|
+
if (!e || !("getAttribute" in e) || e.getAttribute(D) !== null)
|
|
362
332
|
return;
|
|
363
|
-
const { priceHideIfSameAsDiscounted: i } =
|
|
364
|
-
this._stampHidePrice(
|
|
333
|
+
const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
|
|
334
|
+
this._stampHidePrice(t, i);
|
|
365
335
|
}
|
|
366
336
|
/**
|
|
367
337
|
* Gets the recommendation-id from a block node
|
|
368
338
|
*/
|
|
369
|
-
_getRecommendationId(
|
|
370
|
-
const
|
|
371
|
-
if (!
|
|
339
|
+
_getRecommendationId(t) {
|
|
340
|
+
const e = this._getBlockElement(t);
|
|
341
|
+
if (!e || !("getAttribute" in e))
|
|
372
342
|
return null;
|
|
373
|
-
const i =
|
|
343
|
+
const i = e.getAttribute(m);
|
|
374
344
|
if (!i)
|
|
375
345
|
return null;
|
|
376
|
-
const
|
|
377
|
-
return Number.isNaN(
|
|
346
|
+
const n = parseInt(i);
|
|
347
|
+
return Number.isNaN(n) ? null : n;
|
|
378
348
|
}
|
|
379
349
|
/**
|
|
380
350
|
* Gets the block element (the element with BLOCK_CLASS)
|
|
381
351
|
*/
|
|
382
|
-
_getBlockElement(
|
|
383
|
-
if ("getAttribute" in
|
|
384
|
-
const
|
|
385
|
-
if (
|
|
386
|
-
return
|
|
352
|
+
_getBlockElement(t) {
|
|
353
|
+
if ("getAttribute" in t) {
|
|
354
|
+
const e = t.getAttribute("class");
|
|
355
|
+
if (e && e.includes(u))
|
|
356
|
+
return t;
|
|
387
357
|
}
|
|
388
|
-
return "querySelector" in
|
|
358
|
+
return "querySelector" in t ? t.querySelector(`.${u}`) ?? null : null;
|
|
389
359
|
}
|
|
390
360
|
/**
|
|
391
361
|
* Migrate configuration from legacy format
|
|
392
362
|
*/
|
|
393
|
-
_migrateFromLegacy(
|
|
394
|
-
|
|
363
|
+
_migrateFromLegacy(t) {
|
|
364
|
+
s.migrateFromDataAttributes(this.api, t);
|
|
395
365
|
}
|
|
396
366
|
}
|
|
397
367
|
export {
|
|
398
|
-
|
|
399
|
-
|
|
368
|
+
k as BLOCK_ID,
|
|
369
|
+
Y as RecommendationBlock
|
|
400
370
|
};
|
|
@@ -1,60 +1,43 @@
|
|
|
1
|
-
import { useRecommendationExtensionStore as
|
|
2
|
-
import { refreshBlockOutsidePanel as
|
|
3
|
-
import { toBlockUrlConfig as
|
|
4
|
-
import { commitBlockChangeOutsidePanel as
|
|
5
|
-
function
|
|
6
|
-
const r = JSON.stringify(
|
|
7
|
-
return
|
|
1
|
+
import { useRecommendationExtensionStore as g } from "../store/recommendation.js";
|
|
2
|
+
import { refreshBlockOutsidePanel as y } from "./blockRefresh.js";
|
|
3
|
+
import { toBlockUrlConfig as a } from "./blockUrlConfig.js";
|
|
4
|
+
import { commitBlockChangeOutsidePanel as l, readBlockNodeConfigs as S } from "./nodeConfigWriter.js";
|
|
5
|
+
function d(e, t) {
|
|
6
|
+
const r = JSON.stringify(a(t));
|
|
7
|
+
return S(e).find((o) => JSON.stringify(a(o)) !== r) ?? t;
|
|
8
8
|
}
|
|
9
|
-
async function
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
async function p(e, t, r) {
|
|
10
|
+
const o = g(), s = [e, t];
|
|
11
|
+
(/* @__PURE__ */ new Map([[e, d(e, r)], [t, r]])).forEach((n, i) => {
|
|
12
|
+
var m;
|
|
13
|
+
(!!n.strategyId || i === t) && ((m = o.blockStates[i]) == null ? void 0 : m.recommendationConfigs.strategyId) !== n.strategyId && o.seedBlockUrlConfig(i, a(n));
|
|
14
|
+
}), o.resetArrivedBlock(t), await Promise.all(s.map(async (n) => {
|
|
15
|
+
if (!await o.refreshStrategyBlock(n))
|
|
13
16
|
return;
|
|
14
|
-
const { recommendationConfigs:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{ size:
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const { recommendationConfigs: i, recommendationProducts: f } = o.blockStates[n];
|
|
18
|
+
l(
|
|
19
|
+
n,
|
|
20
|
+
{ size: i.size },
|
|
21
|
+
f,
|
|
22
|
+
"Refresh duplicated recommendation strategy"
|
|
20
23
|
);
|
|
21
24
|
}));
|
|
22
25
|
}
|
|
23
|
-
async function
|
|
24
|
-
|
|
25
|
-
(/* @__PURE__ */ new Map([[o, S(o, r)], [t, r]])).forEach((a, f) => {
|
|
26
|
-
var g;
|
|
27
|
-
(!!a.strategyId || f === t) && ((g = n.blockStates[f]) == null ? void 0 : g.recommendationConfigs.strategyId) !== a.strategyId && n.seedBlockUrlConfig(f, i(a));
|
|
28
|
-
}), n.resetArrivedBlock(t), await m(e, "Refresh duplicated recommendation strategy");
|
|
29
|
-
}
|
|
30
|
-
async function k(o) {
|
|
31
|
-
const t = c(), r = o.filter(({ config: e }) => !!e.strategyId);
|
|
32
|
-
if (!r.length)
|
|
33
|
-
return;
|
|
34
|
-
r.forEach(({ id: e, config: s }) => t.seedBlockUrlConfig(e, i(s))), t.invalidateStrategies();
|
|
35
|
-
const n = new Map(r.map(({ id: e, config: s }) => [e, s.size]));
|
|
36
|
-
await m(
|
|
37
|
-
r.map(({ id: e }) => e),
|
|
38
|
-
"Refresh recommendation strategy",
|
|
39
|
-
(e, s) => s !== n.get(e)
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
async function O(o, t) {
|
|
43
|
-
if (!c().blockStates[o])
|
|
26
|
+
async function k(e, t) {
|
|
27
|
+
if (!g().blockStates[e])
|
|
44
28
|
return !1;
|
|
45
|
-
const r = await
|
|
46
|
-
pickUpdates: ({ strategyId:
|
|
47
|
-
strategyId:
|
|
48
|
-
strategy:
|
|
49
|
-
size:
|
|
50
|
-
configVersion:
|
|
29
|
+
const r = await y(e, {
|
|
30
|
+
pickUpdates: ({ strategyId: o, strategy: s, size: c, nodeConfigVersion: n }) => ({
|
|
31
|
+
strategyId: o,
|
|
32
|
+
strategy: s,
|
|
33
|
+
size: c,
|
|
34
|
+
configVersion: n
|
|
51
35
|
}),
|
|
52
36
|
description: t
|
|
53
37
|
});
|
|
54
|
-
return r || console.error("[recommendation] strategy change did not reach a node", { blockId:
|
|
38
|
+
return r || console.error("[recommendation] strategy change did not reach a node", { blockId: e }), r;
|
|
55
39
|
}
|
|
56
40
|
export {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
C as refreshDuplicatedStrategyBlocks
|
|
41
|
+
k as commitStrategyChange,
|
|
42
|
+
p as refreshDuplicatedStrategyBlocks
|
|
60
43
|
};
|
|
@@ -19,7 +19,6 @@ export declare class RecommendationBlock extends Block {
|
|
|
19
19
|
private _resetSourceIds;
|
|
20
20
|
/** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
|
|
21
21
|
private _unsettledDuplicateIds;
|
|
22
|
-
private _arrivedNodes;
|
|
23
22
|
constructor();
|
|
24
23
|
getId(): string;
|
|
25
24
|
getIcon(): string;
|
|
@@ -86,12 +85,6 @@ export declare class RecommendationBlock extends Block {
|
|
|
86
85
|
* the renamed one depending on where the module was dropped (SD-149916).
|
|
87
86
|
*/
|
|
88
87
|
private _scheduleArrivalReset;
|
|
89
|
-
/**
|
|
90
|
-
* Re-reads the strategy of a block that arrived with saved cards, without waiting for a click. Stripo
|
|
91
|
-
* creates every block of an opened template or dropped module, so arrivals of one tick refresh together.
|
|
92
|
-
*/
|
|
93
|
-
private _queueArrivalRefresh;
|
|
94
|
-
private _refreshArrivedBlocks;
|
|
95
88
|
/**
|
|
96
89
|
* Heals a duplicate that slipped past the create-time `_detectDuplicate`
|
|
97
90
|
* scan (or that was persisted by an older template before SD-142352).
|
|
@@ -5,15 +5,6 @@ import type { RecommendationNodeConfig } from '../types/nodeConfig';
|
|
|
5
5
|
* @param config - the arriving block's persisted config; seeds either block its store entry does not match
|
|
6
6
|
*/
|
|
7
7
|
export declare function refreshDuplicatedStrategyBlocks(sourceId: number, duplicateId: number, config: RecommendationNodeConfig): Promise<void>;
|
|
8
|
-
/**
|
|
9
|
-
* Re-reads the strategy of blocks that arrived from a saved template or module, so the panel and
|
|
10
|
-
* preview show a strategy edited since the design was saved without selecting the block.
|
|
11
|
-
* @param blocks - each block's id with its persisted config, the truth its store entry is seeded from
|
|
12
|
-
*/
|
|
13
|
-
export declare function refreshArrivedStrategyBlocks(blocks: {
|
|
14
|
-
id: number;
|
|
15
|
-
config: RecommendationNodeConfig;
|
|
16
|
-
}[]): Promise<void>;
|
|
17
8
|
/**
|
|
18
9
|
* Writes a strategy change and its products straight to the document, without the settings panel.
|
|
19
10
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.21.0-beta.
|
|
3
|
+
"version": "3.21.0-beta.387b29d",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@stripoinc/ui-editor-extensions": "3.11.0",
|
|
56
56
|
"@useinsider/design-system-organisms": "0.0.3-beta.d816f06",
|
|
57
|
-
"@useinsider/design-system-vue": "2.
|
|
57
|
+
"@useinsider/design-system-vue": "2.5.0",
|
|
58
58
|
"@vueuse/core": "11.3.0",
|
|
59
59
|
"lodash-es": "4.17.21",
|
|
60
60
|
"pinia": "2.3.1",
|