@useinsider/guido 3.3.1-beta.11641c6 → 3.4.0-beta.14fc097
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 +1 -1
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +42 -40
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +9 -11
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +70 -35
- package/dist/components/organisms/header/MiddleSlot.vue.js +7 -7
- package/dist/composables/useCortexBlueprintBridge.js +66 -0
- package/dist/composables/useEmailTemplateApplier.js +41 -0
- package/dist/composables/useGuidoStateBridge.js +48 -0
- package/dist/composables/useHtmlValidator.js +53 -47
- package/dist/composables/useResponsivePreview.js +1 -1
- package/dist/config/migrator/radioButtonMigrator.js +30 -29
- package/dist/enums/extensions/recommendationBlock.js +33 -32
- package/dist/extensions/Blocks/RadioButton/template.js +6 -6
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +30 -21
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +3 -3
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +3 -3
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +25 -12
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +33 -0
- package/dist/guido.css +1 -1
- package/dist/node_modules/valibot/dist/index.js +252 -329
- package/dist/package.json.js +1 -1
- package/dist/services/unsubscribeApi.js +6 -6
- package/dist/src/composables/useCortexBlueprintBridge.d.ts +25 -0
- package/dist/src/composables/useEmailTemplateApplier.d.ts +21 -0
- package/dist/src/composables/useGuidoStateBridge.d.ts +22 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -0
- package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +7 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/filterUtil.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +21 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.test.d.ts +1 -0
- package/dist/src/stores/guido-email-editor.d.ts +41 -0
- package/dist/stores/guido-email-editor.js +20 -0
- package/package.json +5 -4
|
@@ -1,54 +1,56 @@
|
|
|
1
|
-
import { useConfig as
|
|
2
|
-
import { TemplateTypes as
|
|
3
|
-
import { DISPLAY_CONDITIONS_REGEX as
|
|
1
|
+
import { useConfig as V } from "./useConfig.js";
|
|
2
|
+
import { TemplateTypes as H } from "../enums/defaults.js";
|
|
3
|
+
import { DISPLAY_CONDITIONS_REGEX as P, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as G, CampaignCouldNotBeSavedKey as M, CanNotMakeAnyChangesForRunningKey as $ } from "../enums/html-validator.js";
|
|
4
4
|
import { ToasterTypeOptions as c } from "../enums/toaster.js";
|
|
5
|
-
import { itemsBlockDynamicVariables as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
import { itemsBlockDynamicVariables as j } from "../extensions/Blocks/Items/enums/productEnums.js";
|
|
6
|
+
import { useRecommendationExtensionStore as q } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
7
|
+
import { RecommendationRequiredFieldsKey as X } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
|
|
8
|
+
import { useRecommendationStore as K } from "../stores/recommendation.js";
|
|
9
|
+
import { base64EncodeWithSpecialChars as z } from "../utils/base64.js";
|
|
10
|
+
import { useHttp as U } from "./useHttp.js";
|
|
11
|
+
import { useToaster as Y } from "./useToaster.js";
|
|
12
|
+
import { useTranslations as Z } from "./useTranslations.js";
|
|
13
|
+
const J = /recommendation-id="(\d+)"/g;
|
|
14
|
+
function Q(a) {
|
|
15
|
+
return [...a.matchAll(J)].map((u) => u[1]);
|
|
14
16
|
}
|
|
15
|
-
function
|
|
17
|
+
function ee(a, u) {
|
|
16
18
|
return u.some((d) => a.startsWith(`${d}_`));
|
|
17
19
|
}
|
|
18
|
-
const
|
|
19
|
-
var
|
|
20
|
-
const { showToaster: a } =
|
|
20
|
+
const ge = () => {
|
|
21
|
+
var h, v;
|
|
22
|
+
const { showToaster: a } = Y(), { post: u } = U(), { config: d } = V(), r = Z(), p = K(), f = q(), y = ((v = (h = d.value) == null ? void 0 : h.partner) == null ? void 0 : v.messageType) === H.transactional, w = async (e) => {
|
|
21
23
|
const t = await u(
|
|
22
24
|
"/newsletter/template-library/check-template-html-body",
|
|
23
|
-
{ html:
|
|
25
|
+
{ html: z(e) }
|
|
24
26
|
), { status: n, message: l } = t.data;
|
|
25
27
|
return n || a({
|
|
26
28
|
type: c.Alert,
|
|
27
29
|
message: n === void 0 ? l : r("newsletter.invalid-url-link-for-toaster")
|
|
28
|
-
}), r(
|
|
30
|
+
}), r(M), l === r($) && a({
|
|
29
31
|
type: c.Alert,
|
|
30
32
|
message: r("newsletter.already-in-progress")
|
|
31
33
|
}), n;
|
|
32
|
-
},
|
|
34
|
+
}, S = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), E = (e) => ["if", "endif"].includes(e.toLowerCase()), A = (e, s) => {
|
|
33
35
|
const t = e.match(/({%(.*?)%})/g);
|
|
34
36
|
let n = !0;
|
|
35
|
-
return t !== null && !
|
|
37
|
+
return t !== null && !y && t.forEach((l) => {
|
|
36
38
|
const o = l.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
|
|
37
39
|
if (o && o.length > 0) {
|
|
38
40
|
const [i] = o;
|
|
39
|
-
|
|
41
|
+
S(i) && !s.includes(i) && (a({
|
|
40
42
|
type: c.Warning,
|
|
41
43
|
message: r("custom-fields.invalid-custom-fields")
|
|
42
44
|
}), n = !1);
|
|
43
45
|
}
|
|
44
46
|
}), n;
|
|
45
|
-
},
|
|
46
|
-
const n = t ? await
|
|
47
|
-
return
|
|
48
|
-
},
|
|
47
|
+
}, k = async (e, s, t) => {
|
|
48
|
+
const n = t ? await w(e) : !0;
|
|
49
|
+
return A(e, s) && n;
|
|
50
|
+
}, x = (e) => e.length > 0 ? !0 : (a({
|
|
49
51
|
type: c.Warning,
|
|
50
52
|
message: r("newsletter.html-content-is-empty")
|
|
51
|
-
}), !1),
|
|
53
|
+
}), !1), I = (e) => {
|
|
52
54
|
const s = (e.match(/{/gm) || []).length, t = (e.match(/}/gm) || []).length;
|
|
53
55
|
return s > t && a({
|
|
54
56
|
type: c.Warning,
|
|
@@ -57,19 +59,19 @@ const ce = () => {
|
|
|
57
59
|
type: c.Warning,
|
|
58
60
|
message: r("custom-fields.missing-opening-braces")
|
|
59
61
|
}), s === t;
|
|
60
|
-
},
|
|
62
|
+
}, F = (e) => {
|
|
61
63
|
const s = e.match(/{{\s*(\w+\s+((\w+\|\w+)|(\w+)))\s*}}/gm) === null;
|
|
62
64
|
return s || a({
|
|
63
65
|
type: c.Warning,
|
|
64
66
|
message: r("custom-fields.invalid-custom-fields")
|
|
65
67
|
}), s;
|
|
66
|
-
},
|
|
68
|
+
}, R = (e, s) => {
|
|
67
69
|
const t = e.match(/{{([a-zA-Z0-9_\s]*)}}/gm);
|
|
68
|
-
if (t && !
|
|
69
|
-
const n = new Set(s.map((i) => i.toLowerCase())), l =
|
|
70
|
+
if (t && !y) {
|
|
71
|
+
const n = new Set(s.map((i) => i.toLowerCase())), l = Q(e), o = [];
|
|
70
72
|
if (t.forEach((i) => {
|
|
71
73
|
const m = i.slice(2, -2).trim().toLowerCase();
|
|
72
|
-
(!n.has(m) || m === "") && !
|
|
74
|
+
(!n.has(m) || m === "") && !ee(m, l) && o.push(m);
|
|
73
75
|
}), o.length > 0) {
|
|
74
76
|
const i = `
|
|
75
77
|
<ul>
|
|
@@ -83,22 +85,22 @@ const ce = () => {
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
return !0;
|
|
86
|
-
},
|
|
88
|
+
}, T = (e) => {
|
|
87
89
|
const s = e.match(/{%(.*?)%}/g), t = [];
|
|
88
90
|
let n = !0;
|
|
89
91
|
if (s && s.forEach((l) => {
|
|
90
|
-
const o = l.match(
|
|
92
|
+
const o = l.match(P), i = l.match(G), m = (o == null ? void 0 : o.join("")) || "";
|
|
91
93
|
(!o || l !== m) && !i && (a({
|
|
92
94
|
type: c.Alert,
|
|
93
95
|
message: r("newsletter.display-conditions-invalid-syntax")
|
|
94
|
-
}), n = !1), o && o.forEach((
|
|
95
|
-
|
|
96
|
+
}), n = !1), o && o.forEach((g) => {
|
|
97
|
+
g.trim() === "=" && (a({
|
|
96
98
|
type: c.Alert,
|
|
97
99
|
message: r("custom-conditions.wrong-equality-operators")
|
|
98
100
|
}), n = !1);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const C = g.match(/^[a-zA-Z]*$/g);
|
|
102
|
+
C && C.forEach((b) => {
|
|
103
|
+
E(b) && t.push(b);
|
|
102
104
|
});
|
|
103
105
|
});
|
|
104
106
|
}), t.length) {
|
|
@@ -109,25 +111,28 @@ const ce = () => {
|
|
|
109
111
|
}), n = !1);
|
|
110
112
|
}
|
|
111
113
|
return n;
|
|
112
|
-
},
|
|
114
|
+
}, B = (e) => {
|
|
113
115
|
const s = (e.match(/{% /gm) || []).length, t = (e.match(/ %}/gm) || []).length, n = s === t;
|
|
114
116
|
return n || a({
|
|
115
117
|
type: c.Warning,
|
|
116
118
|
message: r("custom-conditions.no-space-after-braces")
|
|
117
119
|
}), n;
|
|
118
|
-
},
|
|
120
|
+
}, W = (e) => (e.match(/({%(.*?)%})/g) || []).filter((t) => t.includes("if")).map((t) => (t.match(/{{.*}}/gm) || []).length).reduce((t, n) => t + n, 0) > 0 ? (a({
|
|
119
121
|
type: c.Warning,
|
|
120
122
|
message: r("custom-conditions.no-braces-inside-if-tag")
|
|
121
|
-
}), !1) : !0,
|
|
123
|
+
}), !1) : !0, N = () => f.hasInvalidBlock() ? (a({
|
|
124
|
+
type: c.Alert,
|
|
125
|
+
message: r(X)
|
|
126
|
+
}), !1) : !0, O = () => p.recommendationConfigs && Object.values(p.recommendationConfigs).find((s) => s.filters.find((t) => t.value === "")) !== void 0 ? (a({
|
|
122
127
|
type: c.Alert,
|
|
123
128
|
message: r("newsletter.fill-all-necessary-fields")
|
|
124
|
-
}), !1) : !0,
|
|
129
|
+
}), !1) : !0, D = (e) => {
|
|
125
130
|
const s = /src="[^"]*\.(svg|pst)"/gm;
|
|
126
131
|
return e.match(s) === null ? !0 : (a({
|
|
127
132
|
type: c.Alert,
|
|
128
133
|
message: r("newsletter.invalid-image-type")
|
|
129
134
|
}), !1);
|
|
130
|
-
},
|
|
135
|
+
}, L = (e) => {
|
|
131
136
|
const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
|
|
132
137
|
return Array.from(n).find((o) => {
|
|
133
138
|
var i;
|
|
@@ -136,7 +141,7 @@ const ce = () => {
|
|
|
136
141
|
type: c.Alert,
|
|
137
142
|
message: r("unsubscribe-templates.select-checkbox-groups")
|
|
138
143
|
}), !1) : !0;
|
|
139
|
-
},
|
|
144
|
+
}, _ = (e) => {
|
|
140
145
|
const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
|
|
141
146
|
return Array.from(n).find((o) => {
|
|
142
147
|
var i;
|
|
@@ -148,14 +153,15 @@ const ce = () => {
|
|
|
148
153
|
};
|
|
149
154
|
return { validateHtml: async (e, s, t = !1) => {
|
|
150
155
|
var o, i;
|
|
156
|
+
t && Object.keys(f.blockStates).length > 0 && await f.fetchRecommendationCreateData();
|
|
151
157
|
const n = [
|
|
152
158
|
...s.map((m) => m.value),
|
|
153
|
-
...
|
|
159
|
+
...j,
|
|
154
160
|
...((i = (o = d.value) == null ? void 0 : o.template) == null ? void 0 : i.customFieldAttributes) ?? []
|
|
155
161
|
];
|
|
156
|
-
return await
|
|
162
|
+
return await k(e, n, t) && x(e) && I(e) && F(e) && R(e, n) && T(e) && B(e) && W(e) && N() && O() && D(e) && L(e) && _(e);
|
|
157
163
|
} };
|
|
158
164
|
};
|
|
159
165
|
export {
|
|
160
|
-
|
|
166
|
+
ge as useHtmlValidator
|
|
161
167
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useDebounce as p } from "./useDebounce.js";
|
|
2
|
-
import { ResponsivePreviewRegex as c,
|
|
2
|
+
import { ResponsivePreviewRegex as c, ResponsivePreviewConfig as a, ResponsivePreviewSelectors as v } from "../enums/preview.js";
|
|
3
3
|
let i = null, l = null;
|
|
4
4
|
const { debounce: y } = p(), h = (t) => {
|
|
5
5
|
if (!t)
|
|
@@ -9,14 +9,14 @@ class B {
|
|
|
9
9
|
}
|
|
10
10
|
migrate(e) {
|
|
11
11
|
try {
|
|
12
|
-
const t = this.parser.parseFromString(e, "text/html"),
|
|
13
|
-
if (
|
|
12
|
+
const t = this.parser.parseFromString(e, "text/html"), s = t.querySelectorAll("td.radio-button-block"), i = t.querySelectorAll("td.radio-button-v2");
|
|
13
|
+
if (s.length === 0 && i.length === 0)
|
|
14
14
|
return e;
|
|
15
15
|
let o = !1;
|
|
16
|
-
return
|
|
16
|
+
return s.forEach((r) => {
|
|
17
17
|
if (r.classList.contains("radio-button-v2"))
|
|
18
18
|
return;
|
|
19
|
-
const n = r.getAttribute("id"), a = this.extractTextFromElement(r, "ins-title"), g = this.extractTextFromElement(r, "ins-description"), c = this.extractTextFromElement(r, "ins-subscribe"), u = this.extractTextFromElement(r, "ins-unsubscribe"),
|
|
19
|
+
const n = r.getAttribute("id"), a = this.extractTextFromElement(r, "ins-title"), g = this.extractTextFromElement(r, "ins-description"), c = this.extractTextFromElement(r, "ins-subscribe"), u = this.extractTextFromElement(r, "ins-unsubscribe"), p = this.buildTextBlock(a), d = this.buildTextBlock(g), y = this.buildTextBlock({ ...c, classList: "" }), f = this.buildTextBlock({ ...u, classList: "" }), h = S.replace("{-{-TITLE-}-}", p).replace("{-{-DESCRIPTION-}-}", d).replace("{-{-YES-}-}", y).replace("{-{-NO-}-}", f), m = this.parser.parseFromString(
|
|
20
20
|
`<table id="tempDoc"><tbody><tr>${h}</tr></tbody></table>`,
|
|
21
21
|
"text/html"
|
|
22
22
|
).querySelector(".radio-button-v2");
|
|
@@ -28,25 +28,26 @@ class B {
|
|
|
28
28
|
}
|
|
29
29
|
healRadioButtonV2(e) {
|
|
30
30
|
let t = !1;
|
|
31
|
-
return e.querySelectorAll("td.radio-button-v2").forEach((
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
return e.querySelectorAll("td.radio-button-v2").forEach((s) => {
|
|
32
|
+
var d;
|
|
33
|
+
s.classList.contains("radio-button-block") || (s.classList.add("radio-button-block"), t = !0);
|
|
34
|
+
const i = s.querySelector("input#radioYes"), o = s.querySelector("input#radioNo");
|
|
35
|
+
if (!i || !o)
|
|
35
36
|
return;
|
|
36
|
-
const r = ((
|
|
37
|
-
if (!r && !
|
|
37
|
+
const r = ((d = i.parentElement) == null ? void 0 : d.querySelector(":scope > p")) || null;
|
|
38
|
+
if (!r && !i.hasAttribute("align"))
|
|
38
39
|
return;
|
|
39
|
-
const n =
|
|
40
|
+
const n = i.closest("tr"), a = o.closest("tr");
|
|
40
41
|
if (!n || !a || n === a || !n.parentNode)
|
|
41
42
|
return;
|
|
42
|
-
const g = (r == null ? void 0 : r.innerHTML.trim()) || "Yes", c = a.cloneNode(!0), u = c.querySelector("input#radioNo"),
|
|
43
|
-
u && (u.setAttribute("id", "radioYes"), u.removeAttribute("align")),
|
|
43
|
+
const g = (r == null ? void 0 : r.innerHTML.trim()) || "Yes", c = a.cloneNode(!0), u = c.querySelector("input#radioNo"), p = c.querySelector("p");
|
|
44
|
+
u && (u.setAttribute("id", "radioYes"), u.removeAttribute("align")), p && (p.innerHTML = g), n.parentNode.replaceChild(c, n), t = !0;
|
|
44
45
|
}), t;
|
|
45
46
|
}
|
|
46
47
|
extractTextFromElement(e, t) {
|
|
47
|
-
var
|
|
48
|
-
const
|
|
49
|
-
if (!
|
|
48
|
+
var d, y;
|
|
49
|
+
const s = e.querySelector(`.${t}`);
|
|
50
|
+
if (!s)
|
|
50
51
|
return {
|
|
51
52
|
text: t === "ins-title" ? "Title" : "Description",
|
|
52
53
|
isBold: !1,
|
|
@@ -55,42 +56,42 @@ class B {
|
|
|
55
56
|
styles: "",
|
|
56
57
|
classList: ""
|
|
57
58
|
};
|
|
58
|
-
const
|
|
59
|
-
if (!
|
|
59
|
+
const i = s.querySelector("p");
|
|
60
|
+
if (!i)
|
|
60
61
|
return {
|
|
61
|
-
text: ((
|
|
62
|
+
text: ((d = s.textContent) == null ? void 0 : d.trim()) || (t === "ins-title" ? "Title" : "Description"),
|
|
62
63
|
isBold: !1,
|
|
63
64
|
isItalic: !1,
|
|
64
|
-
align:
|
|
65
|
+
align: s.getAttribute("align") || "left",
|
|
65
66
|
styles: "",
|
|
66
67
|
classList: ""
|
|
67
68
|
};
|
|
68
|
-
const o = ((y =
|
|
69
|
+
const o = ((y = i.textContent) == null ? void 0 : y.trim()) || (t === "ins-title" ? "Title" : "Description"), r = i.getAttribute("style") || "", n = s.getAttribute("align") || i.getAttribute("align") || "left", a = /font-weight\s*:\s*bold/i.test(r) || !!i.querySelector("b, strong"), g = /font-style\s*:\s*italic/i.test(r) || !!i.querySelector("i, em"), c = this.removeStyleProperties(r, ["font-weight", "font-style"]), u = this.convertInlineToBlock(c), p = s.getAttribute("class") || "";
|
|
69
70
|
return {
|
|
70
71
|
text: o,
|
|
71
72
|
isBold: a,
|
|
72
73
|
isItalic: g,
|
|
73
74
|
align: n,
|
|
74
75
|
styles: u,
|
|
75
|
-
classList:
|
|
76
|
+
classList: p
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
79
|
buildTextBlock(e) {
|
|
79
80
|
let t = e.text;
|
|
80
81
|
e.isBold && e.isItalic ? t = `<strong path="1,0"><em path="1,0,0">${t}</em></strong>` : e.isBold ? t = `<strong path="1,0">${t}</strong>` : e.isItalic && (t = `<em path="1,0">${t}</em>`);
|
|
81
|
-
const
|
|
82
|
+
const s = e.align ? ` align="${e.align}"` : "", i = e.styles ? ` style="${e.styles.replaceAll('"', "'")}"` : "";
|
|
82
83
|
return `
|
|
83
|
-
<td class="esd-block-text ${e.classList}" ${
|
|
84
|
-
<p path="1" ${
|
|
84
|
+
<td class="esd-block-text ${e.classList}" ${s}>
|
|
85
|
+
<p path="1" ${i}>
|
|
85
86
|
${t}
|
|
86
87
|
</p>
|
|
87
88
|
</td>
|
|
88
89
|
`;
|
|
89
90
|
}
|
|
90
91
|
removeStyleProperties(e, t) {
|
|
91
|
-
return e ? t.reduce((
|
|
92
|
+
return e ? t.reduce((i, o) => {
|
|
92
93
|
const r = new RegExp(`${o}\\s*:\\s*[^;]*;?`, "gi");
|
|
93
|
-
return
|
|
94
|
+
return i.replace(r, "");
|
|
94
95
|
}, e).replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim() : "";
|
|
95
96
|
}
|
|
96
97
|
convertInlineToBlock(e) {
|
|
@@ -100,9 +101,9 @@ class B {
|
|
|
100
101
|
return /display\s*:/i.test(t) || (t = t ? `${t}; display: block` : "display: block"), t.replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim();
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
|
-
function
|
|
104
|
+
function L(l) {
|
|
104
105
|
return new B().migrate(l);
|
|
105
106
|
}
|
|
106
107
|
export {
|
|
107
|
-
|
|
108
|
+
L as migrateRadioButton
|
|
108
109
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { useTranslations as
|
|
2
|
-
const
|
|
1
|
+
import { useTranslations as r } from "../../composables/useTranslations.js";
|
|
2
|
+
const l = {
|
|
3
3
|
RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com"
|
|
4
|
-
},
|
|
4
|
+
}, c = {
|
|
5
5
|
CLIENT_ID: "clientId"
|
|
6
|
-
},
|
|
7
|
-
const e =
|
|
6
|
+
}, d = () => {
|
|
7
|
+
const e = r();
|
|
8
8
|
return [
|
|
9
9
|
{
|
|
10
10
|
id: 11,
|
|
@@ -67,72 +67,73 @@ const u = {
|
|
|
67
67
|
path: "top-sellers"
|
|
68
68
|
}
|
|
69
69
|
];
|
|
70
|
-
},
|
|
70
|
+
}, m = ["discount", "omnibus_price", "omnibus_discount", "price", "original_price"], p = [
|
|
71
71
|
{ text: "before the amount", value: "0" },
|
|
72
72
|
{ text: "after the amount", value: "1" }
|
|
73
|
-
],
|
|
73
|
+
], v = [
|
|
74
74
|
{ text: "dot(.)", value: "." },
|
|
75
75
|
{ text: "comma(,)", value: "," },
|
|
76
76
|
{ text: "space( )", value: " " }
|
|
77
|
-
],
|
|
77
|
+
], h = [
|
|
78
78
|
{ text: "0", value: "0" },
|
|
79
79
|
{ text: "1", value: "1" },
|
|
80
80
|
{ text: "2", value: "2" },
|
|
81
81
|
{ text: "3", value: "3" },
|
|
82
82
|
{ text: "4", value: "4" },
|
|
83
83
|
{ text: "5", value: "5" }
|
|
84
|
-
], t = [
|
|
84
|
+
], a = "||", t = [
|
|
85
85
|
{ text: "is exactly", value: "=" },
|
|
86
86
|
{ text: "contains", value: "~" },
|
|
87
87
|
{ text: "does not contain", value: "!~" },
|
|
88
|
-
{ text: "any of", value:
|
|
89
|
-
],
|
|
88
|
+
{ text: "any of", value: a }
|
|
89
|
+
], n = [
|
|
90
90
|
{ text: "is exactly", value: "=" },
|
|
91
91
|
{ text: "is not exactly", value: "!==" },
|
|
92
92
|
{ text: "contains", value: "~" },
|
|
93
93
|
{ text: "does not contain", value: "!~" },
|
|
94
|
-
{ text: "any of", value:
|
|
95
|
-
],
|
|
94
|
+
{ text: "any of", value: a }
|
|
95
|
+
], o = [
|
|
96
96
|
{ text: "is equal to", value: "=" },
|
|
97
97
|
{ text: "is greater than", value: ">" },
|
|
98
98
|
{ text: "is less than", value: "<" }
|
|
99
|
-
],
|
|
99
|
+
], s = [
|
|
100
100
|
{ text: "is equal to", value: "=" },
|
|
101
101
|
{ text: "after", value: ">" },
|
|
102
102
|
{ text: "before", value: "<" }
|
|
103
|
-
],
|
|
103
|
+
], i = [
|
|
104
104
|
{ text: "true", value: "==" },
|
|
105
105
|
{ text: "false", value: "!=" }
|
|
106
|
-
],
|
|
106
|
+
], x = (e) => {
|
|
107
107
|
if (!e)
|
|
108
108
|
return t;
|
|
109
109
|
switch (e) {
|
|
110
110
|
case "Boolean":
|
|
111
|
-
return
|
|
111
|
+
return i;
|
|
112
112
|
case "Date":
|
|
113
|
-
return
|
|
113
|
+
return s;
|
|
114
114
|
case "Number":
|
|
115
|
-
return
|
|
115
|
+
return o;
|
|
116
116
|
case "String":
|
|
117
117
|
return t;
|
|
118
118
|
case "Strings":
|
|
119
|
-
return
|
|
119
|
+
return n;
|
|
120
120
|
default:
|
|
121
121
|
return t;
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
export {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
p as
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
125
|
+
a as OP_ANY_OF,
|
|
126
|
+
m as PriceAttributes,
|
|
127
|
+
c as QUERY_PARAMS,
|
|
128
|
+
l as URLS,
|
|
129
|
+
h as currencyDecimalCounts,
|
|
130
|
+
p as currencyLocationMaps,
|
|
131
|
+
v as currencyOperators,
|
|
132
|
+
x as getOperatorOptions,
|
|
133
|
+
d as getRecommendationFeedSourceMaps,
|
|
134
|
+
n as operatorOptionsForArrayOfStrings,
|
|
135
|
+
i as operatorOptionsForBooleans,
|
|
136
|
+
s as operatorOptionsForDates,
|
|
137
|
+
o as operatorOptionsForNumbers,
|
|
137
138
|
t as operatorOptionsForStrings
|
|
138
139
|
};
|
|
@@ -5,7 +5,7 @@ const e = {
|
|
|
5
5
|
YES: "Yes",
|
|
6
6
|
NO: "No"
|
|
7
7
|
}, d = `
|
|
8
|
-
<td align="left" class="radio-button radio-button-v2 esd-block-radio es-p10t es-p10b es-p30r es-p30l">
|
|
8
|
+
<td align="left" class="radio-button-block radio-button-v2 esd-block-radio es-p10t es-p10b es-p30r es-p30l">
|
|
9
9
|
<table cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
|
10
10
|
<tbody>
|
|
11
11
|
<tr>
|
|
@@ -75,13 +75,13 @@ const e = {
|
|
|
75
75
|
</tbody>
|
|
76
76
|
</table>
|
|
77
77
|
</td>
|
|
78
|
-
`,
|
|
78
|
+
`, l = `
|
|
79
79
|
<td
|
|
80
80
|
align="left"
|
|
81
81
|
esd-extension-block-id="radio-button-block"
|
|
82
82
|
esd-handler-name="esd-extension-RadioButtonBlock"
|
|
83
83
|
class="
|
|
84
|
-
radio-button
|
|
84
|
+
radio-button-block
|
|
85
85
|
radio-button-v2
|
|
86
86
|
esd-block-ra
|
|
87
87
|
esd-radio-button-block
|
|
@@ -149,10 +149,10 @@ const e = {
|
|
|
149
149
|
</table>
|
|
150
150
|
</td>
|
|
151
151
|
`;
|
|
152
|
-
function
|
|
152
|
+
function a() {
|
|
153
153
|
return d.replace("{-{-TITLE-}-}", `<p path="1">${e.TITLE}</p>`).replace("{-{-DESCRIPTION-}-}", `<p path="1">${e.DESCRIPTION}</p>`).replace("{-{-YES-}-}", `<p path="1">${e.YES}</p>`).replace("{-{-NO-}-}", `<p path="1">${e.NO}</p>`);
|
|
154
154
|
}
|
|
155
155
|
export {
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
l as default,
|
|
157
|
+
a as getDefaultTemplate
|
|
158
158
|
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { getRecommendationFeedSourceMaps as
|
|
1
|
+
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as y } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
2
|
import { useRecommendationApi as C } from "../../../../services/recommendationApi.js";
|
|
3
3
|
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
4
|
import { defineStore as P } from "pinia";
|
|
5
5
|
import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
|
|
6
6
|
import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
|
|
7
|
-
import { getDefaultProducts as
|
|
7
|
+
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
8
8
|
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
9
9
|
import { isFilterValid as w } from "../validation/filterSchema.js";
|
|
10
|
+
import { isConfigValid as v } from "../validation/requiredFields.js";
|
|
10
11
|
const h = C();
|
|
11
|
-
let
|
|
12
|
+
let m = null, u = null, d = null;
|
|
12
13
|
function k() {
|
|
13
14
|
return {
|
|
14
15
|
cardsInRow: F,
|
|
@@ -48,7 +49,7 @@ function I() {
|
|
|
48
49
|
filterSnapshot: null
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
|
-
const
|
|
52
|
+
const N = () => ({
|
|
52
53
|
recommendationCampaignUrls: {},
|
|
53
54
|
activePredictiveAlgorithms: [],
|
|
54
55
|
languages: {},
|
|
@@ -57,8 +58,8 @@ const v = () => ({
|
|
|
57
58
|
blockStates: {},
|
|
58
59
|
currentRecommendationId: null,
|
|
59
60
|
configVersion: 0
|
|
60
|
-
}),
|
|
61
|
-
state: () =>
|
|
61
|
+
}), M = P("guidoRecommendationExtension", {
|
|
62
|
+
state: () => N(),
|
|
62
63
|
getters: {
|
|
63
64
|
// ====================================================================
|
|
64
65
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -113,7 +114,7 @@ const v = () => ({
|
|
|
113
114
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
114
115
|
},
|
|
115
116
|
getActivePredictiveAlgorithms: (t) => {
|
|
116
|
-
const e =
|
|
117
|
+
const e = g(), r = [];
|
|
117
118
|
return t.activePredictiveAlgorithms.filter((n) => !D.includes(n)).forEach((n) => {
|
|
118
119
|
r.push(...e.filter((c) => c.id === n));
|
|
119
120
|
}), r.map((n) => ({
|
|
@@ -293,11 +294,11 @@ const v = () => ({
|
|
|
293
294
|
// ====================================================================
|
|
294
295
|
async fetchRecommendationCreateData() {
|
|
295
296
|
if (!this.activePredictiveAlgorithms.length) {
|
|
296
|
-
if (
|
|
297
|
-
await
|
|
297
|
+
if (m) {
|
|
298
|
+
await m;
|
|
298
299
|
return;
|
|
299
300
|
}
|
|
300
|
-
|
|
301
|
+
m = (async () => {
|
|
301
302
|
const {
|
|
302
303
|
activePredictiveAlgorithms: t,
|
|
303
304
|
languages: e,
|
|
@@ -310,26 +311,26 @@ const v = () => ({
|
|
|
310
311
|
this.currencyList = r;
|
|
311
312
|
})();
|
|
312
313
|
try {
|
|
313
|
-
await
|
|
314
|
+
await m;
|
|
314
315
|
} finally {
|
|
315
|
-
|
|
316
|
+
m = null;
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
},
|
|
319
320
|
async fetchRecommendationFilters() {
|
|
320
321
|
if (!Object.keys(this.filterList).length) {
|
|
321
|
-
if (
|
|
322
|
-
await
|
|
322
|
+
if (u) {
|
|
323
|
+
await u;
|
|
323
324
|
return;
|
|
324
325
|
}
|
|
325
|
-
|
|
326
|
+
u = (async () => {
|
|
326
327
|
const t = await h.fetchRecommendationFilters();
|
|
327
328
|
this.filterList = t;
|
|
328
329
|
})();
|
|
329
330
|
try {
|
|
330
|
-
await
|
|
331
|
+
await u;
|
|
331
332
|
} finally {
|
|
332
|
-
|
|
333
|
+
u = null;
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
336
|
},
|
|
@@ -398,6 +399,14 @@ const v = () => ({
|
|
|
398
399
|
generateFilterQuery() {
|
|
399
400
|
return b(this.recommendationConfigs.filters);
|
|
400
401
|
},
|
|
402
|
+
/**
|
|
403
|
+
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
404
|
+
* (not a getter) so reading it does not register reactive tracking on
|
|
405
|
+
* every block's recommendationConfigs across user edits.
|
|
406
|
+
*/
|
|
407
|
+
hasInvalidBlock() {
|
|
408
|
+
return Object.values(this.blockStates).some((t) => !v(t.recommendationConfigs, this));
|
|
409
|
+
},
|
|
401
410
|
// ====================================================================
|
|
402
411
|
// Per-Block Product Fetching
|
|
403
412
|
// ====================================================================
|
|
@@ -417,7 +426,7 @@ const v = () => ({
|
|
|
417
426
|
},
|
|
418
427
|
async _doFetchProducts() {
|
|
419
428
|
var p;
|
|
420
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p =
|
|
429
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
|
|
421
430
|
locale: r.language,
|
|
422
431
|
currency: r.currencySettings.value,
|
|
423
432
|
partnerName: o.partnerName,
|
|
@@ -433,15 +442,15 @@ const v = () => ({
|
|
|
433
442
|
f = [];
|
|
434
443
|
}
|
|
435
444
|
if (this.blockStates[t]) {
|
|
436
|
-
const l = f.length > 0 ? f :
|
|
445
|
+
const l = f.length > 0 ? f : S(s);
|
|
437
446
|
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
438
447
|
...l,
|
|
439
|
-
...
|
|
448
|
+
...S(s - l.length)
|
|
440
449
|
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
441
450
|
}
|
|
442
451
|
}
|
|
443
452
|
}
|
|
444
453
|
});
|
|
445
454
|
export {
|
|
446
|
-
|
|
455
|
+
M as useRecommendationExtensionStore
|
|
447
456
|
};
|