@useinsider/guido 2.1.0-beta.a873eb7 → 2.1.0-beta.ab9a598
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/organisms/extensions/recommendation/FilterItem.vue.js +13 -11
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +23 -54
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +3 -3
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +21 -34
- package/dist/components/organisms/extensions/recommendation/Filters.vue.js +11 -11
- package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +34 -44
- package/dist/components/organisms/header/EditorActions.vue.js +10 -8
- package/dist/components/organisms/header/EditorActions.vue2.js +40 -30
- package/dist/components/organisms/header/MigrationConfirmModal.vue.js +17 -0
- package/dist/components/organisms/header/MigrationConfirmModal.vue2.js +39 -0
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
- package/dist/composables/useStripo.js +25 -23
- package/dist/composables/useVersionHistoryApi.js +1 -1
- package/dist/config/i18n/en/index.js +11 -0
- package/dist/config/i18n/en/labels.json.js +12 -0
- package/dist/config/i18n/en/toasters.json.js +56 -0
- package/dist/config/i18n/en/tooltips.json.js +82 -0
- package/dist/config/i18n/index.js +7 -0
- package/dist/config/migrator/itemsBlockMigrator.js +136 -131
- package/dist/config/migrator/recommendationMigrator.js +58 -54
- package/dist/enums/block.js +4 -0
- package/dist/extensions/Blocks/Items/block.js +30 -21
- package/dist/extensions/Blocks/Items/iconsRegistry.js +7 -6
- package/dist/extensions/Blocks/Items/items.css.js +48 -0
- package/dist/extensions/Blocks/Recommendation/block.js +22 -13
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +39 -58
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +5 -4
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +48 -0
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +57 -93
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
- package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
- package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
- package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
- package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
- package/dist/extensions/Blocks/common-control.js +12 -4
- package/dist/guido.css +1 -1
- package/dist/src/@types/extensions/block.d.ts +2 -0
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +0 -1
- package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +1 -15
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/MigrationConfirmModal.vue.d.ts +6 -0
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
- package/dist/src/components/wrappers/WpModal.vue.d.ts +2 -2
- package/dist/src/config/i18n/en/index.d.ts +1 -0
- package/dist/src/config/i18n/index.d.ts +16 -0
- package/dist/src/enums/block.d.ts +4 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -5
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -18
- package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +5 -0
- package/dist/src/stores/template.d.ts +29 -0
- package/dist/src/utils/migrationBannerHtml.d.ts +2 -0
- package/dist/static/assets/info.svg.js +5 -0
- package/dist/static/styles/components/notification.css.js +18 -0
- package/dist/static/styles/components/tools.css.js +6 -2
- package/dist/static/styles/variables.css.js +2 -0
- package/dist/stores/template.js +15 -0
- package/dist/stores/unsubscribe.js +37 -34
- package/dist/utils/migrationBannerHtml.js +21 -0
- package/package.json +1 -1
- package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +0 -29
- package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +0 -15
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { BlockId as g } from "../../../enums/block.js";
|
|
2
|
+
import { useOnboardingStore as p } from "../../../stores/onboarding.js";
|
|
3
|
+
import { getMigrationBannerHtml as f } from "../../../utils/migrationBannerHtml.js";
|
|
4
|
+
import { Block as u, BlockCompositionType as I, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { SETTINGS_ENUMS as a, DefaultConfigValues as i } from "./enums/settingsEnums.js";
|
|
6
|
+
import { getDefaultTemplate as C } from "./template.js";
|
|
7
|
+
import { getItemsBlockContainer as y, getItemsBlockConfig as b, getDefaultItemsBlockConfig as h } from "./utils/nodeConfigUtils.js";
|
|
8
|
+
const c = g.Items;
|
|
9
|
+
class E extends u {
|
|
8
10
|
getId() {
|
|
9
|
-
return
|
|
11
|
+
return c;
|
|
10
12
|
}
|
|
11
13
|
getIcon() {
|
|
12
14
|
return "items-icon";
|
|
13
15
|
}
|
|
14
16
|
getBlockCompositionType() {
|
|
15
|
-
return
|
|
17
|
+
return I.CONTAINER;
|
|
16
18
|
}
|
|
17
19
|
getName() {
|
|
18
20
|
return this.api.translate("Items");
|
|
@@ -20,10 +22,17 @@ class B extends g {
|
|
|
20
22
|
getDescription() {
|
|
21
23
|
return this.api.translate("Items lets you display personalized products based on user behavior.");
|
|
22
24
|
}
|
|
25
|
+
getSettingsPanelTitleHtml() {
|
|
26
|
+
return f(
|
|
27
|
+
c,
|
|
28
|
+
this.api.translate("Items"),
|
|
29
|
+
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
|
|
30
|
+
);
|
|
31
|
+
}
|
|
23
32
|
getTemplate() {
|
|
24
|
-
return
|
|
25
|
-
orientation:
|
|
26
|
-
itemsType:
|
|
33
|
+
return C({
|
|
34
|
+
orientation: a.ORIENTATION.VERTICAL,
|
|
35
|
+
itemsType: a.ITEMS_TYPE.CART_ITEMS,
|
|
27
36
|
itemId: "{{Abandoned Cart Item (1) Url}}",
|
|
28
37
|
currencySymbol: i.productPriceCurrencySymbolControlValue,
|
|
29
38
|
currencyLocation: i.productPriceCurrencyLocationControlValue,
|
|
@@ -34,21 +43,21 @@ class B extends g {
|
|
|
34
43
|
return !1;
|
|
35
44
|
}
|
|
36
45
|
onCreated(n) {
|
|
37
|
-
const
|
|
38
|
-
r.querySelector('[product-attr="imageSrc"] img') ||
|
|
39
|
-
const e =
|
|
46
|
+
const l = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
|
|
47
|
+
r.querySelector('[product-attr="imageSrc"] img') || l.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
48
|
+
const e = y(n);
|
|
40
49
|
if (!e)
|
|
41
50
|
return;
|
|
42
|
-
const
|
|
51
|
+
const s = e.getNodeConfig(), m = s && Object.keys(s).length > 0, t = b(n);
|
|
43
52
|
if (t != null && t.initialized)
|
|
44
|
-
|
|
53
|
+
m ? t.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...t, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(t).apply(new o("Migrate legacy config to nodeConfig"));
|
|
45
54
|
else {
|
|
46
|
-
const
|
|
47
|
-
this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(
|
|
55
|
+
const d = h();
|
|
56
|
+
this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(d).apply(new o("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
export {
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
c as BLOCK_ID,
|
|
62
|
+
E as ItemsBlock
|
|
54
63
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import o from "../../../static/assets/info.svg.js";
|
|
2
|
+
import { IconsRegistry as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
3
|
+
class s extends r {
|
|
3
4
|
registerIconsSvg(t) {
|
|
4
5
|
t["items-icon"] = `
|
|
5
6
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -19,14 +20,14 @@ class i extends o {
|
|
|
19
20
|
</svg>
|
|
20
21
|
`, t["horizontal-orientation"] = `
|
|
21
22
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
|
|
22
|
-
<path d="M10 19H4C3.44772 19 3 18.5523 3 18V2C3 1.44772 3.44772 1 4 1H10V19Z" stroke="currentColor"
|
|
23
|
+
<path d="M10 19H4C3.44772 19 3 18.5523 3 18V2C3 1.44772 3.44772 1 4 1H10V19Z" stroke="currentColor"
|
|
23
24
|
stroke-width="2" fill="none"/>
|
|
24
|
-
<path d="M17 2V18C17 18.5523 16.5523 19 16 19H10V1H16C16.5523 1 17 1.44772 17 2Z" stroke="currentColor"
|
|
25
|
+
<path d="M17 2V18C17 18.5523 16.5523 19 16 19H10V1H16C16.5523 1 17 1.44772 17 2Z" stroke="currentColor"
|
|
25
26
|
stroke-width="2" fill="none"/>
|
|
26
27
|
</svg>
|
|
27
|
-
|
|
28
|
+
`, t["migration-info-icon"] = o;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
export {
|
|
31
|
-
|
|
32
|
+
s as ItemsIconsRegistry
|
|
32
33
|
};
|
|
@@ -17,6 +17,54 @@ const n = `/* Utils */
|
|
|
17
17
|
.container:has(.items-controls-container) {
|
|
18
18
|
padding: 0
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/* ─── Migration Info Box ─────────────────────────────────────────────── */
|
|
22
|
+
/* Shown in the settings panel title when a block was migrated from legacy */
|
|
23
|
+
|
|
24
|
+
/* Layout variables for positioning the absolutely-placed info box */
|
|
25
|
+
:host {
|
|
26
|
+
--items-migration-padding: 16px;
|
|
27
|
+
--items-migration-title-height: 61px;
|
|
28
|
+
--items-migration-box-height: 98px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Push tabs down when info box is present inside the control panel header */
|
|
32
|
+
.control-panel-header:has(.items-block-migration-info) {
|
|
33
|
+
position: relative;
|
|
34
|
+
margin-bottom: calc(2 * var(--items-migration-padding) + var(--items-migration-box-height));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Info box container */
|
|
38
|
+
.items-block-migration-info {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: flex-start;
|
|
41
|
+
gap: 8px;
|
|
42
|
+
padding: 12px;
|
|
43
|
+
background: var(--guido-color-background-onpage-message-info);
|
|
44
|
+
border: 1px solid var(--guido-color-border-onpage-message-info);
|
|
45
|
+
border-radius: 4px;
|
|
46
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
|
|
47
|
+
position: absolute;
|
|
48
|
+
left: var(--items-migration-padding);
|
|
49
|
+
right: var(--items-migration-padding);
|
|
50
|
+
top: calc(var(--items-migration-padding) + var(--items-migration-title-height));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
|
|
54
|
+
.items-block-migration-info__icon {
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
width: 24px;
|
|
57
|
+
height: 24px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Text content */
|
|
61
|
+
.items-block-migration-info__text {
|
|
62
|
+
margin: 4px 0;
|
|
63
|
+
white-space: normal;
|
|
64
|
+
font-size: 13px;
|
|
65
|
+
font-weight: 400;
|
|
66
|
+
line-height: 16px;
|
|
67
|
+
}
|
|
20
68
|
`;
|
|
21
69
|
export {
|
|
22
70
|
n as default
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var g = (r, o, t) =>
|
|
4
|
-
import {
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var h = (r, o, t) => o in r ? f(r, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[o] = t;
|
|
3
|
+
var g = (r, o, t) => h(r, typeof o != "symbol" ? o + "" : o, t);
|
|
4
|
+
import { BlockId as I } from "../../../enums/block.js";
|
|
5
|
+
import { getMigrationBannerHtml as k } from "../../../utils/migrationBannerHtml.js";
|
|
6
|
+
import { Block as B, BlockCompositionType as _, ModificationDescription as R } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
7
|
import { ensureMobileCssRulesExist as d } from "./controls/mobileLayout/cssRules.js";
|
|
6
8
|
import { RecommendationConfigService as s } from "./services/configService.js";
|
|
7
9
|
import { useRecommendationExtensionStore as u } from "./store/recommendation.js";
|
|
8
|
-
import { getDefaultTemplate as
|
|
9
|
-
const
|
|
10
|
-
class
|
|
10
|
+
import { getDefaultTemplate as A } from "./templates/grid/template.js";
|
|
11
|
+
const p = I.Recommendation, c = "ins-recommendation-v3-block-v2", a = "recommendation-id";
|
|
12
|
+
class T extends B {
|
|
11
13
|
constructor() {
|
|
12
14
|
super();
|
|
13
15
|
/**
|
|
@@ -17,13 +19,13 @@ class y extends h {
|
|
|
17
19
|
g(this, "_pendingBlockId", null);
|
|
18
20
|
}
|
|
19
21
|
getId() {
|
|
20
|
-
return
|
|
22
|
+
return p;
|
|
21
23
|
}
|
|
22
24
|
getIcon() {
|
|
23
25
|
return "recommendation-icon";
|
|
24
26
|
}
|
|
25
27
|
getBlockCompositionType() {
|
|
26
|
-
return
|
|
28
|
+
return _.CONTAINER;
|
|
27
29
|
}
|
|
28
30
|
getName() {
|
|
29
31
|
return this.api.translate("Recommendation Block");
|
|
@@ -31,6 +33,13 @@ class y extends h {
|
|
|
31
33
|
getDescription() {
|
|
32
34
|
return this.api.translate("Recommendation Block Title Description");
|
|
33
35
|
}
|
|
36
|
+
getSettingsPanelTitleHtml() {
|
|
37
|
+
return k(
|
|
38
|
+
p,
|
|
39
|
+
this.api.translate("Recommendation Block"),
|
|
40
|
+
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.")
|
|
41
|
+
);
|
|
42
|
+
}
|
|
34
43
|
/**
|
|
35
44
|
* Returns the template HTML for a new recommendation block.
|
|
36
45
|
* Generates a unique recommendation ID and embeds the instance class
|
|
@@ -40,7 +49,7 @@ class y extends h {
|
|
|
40
49
|
*/
|
|
41
50
|
getTemplate() {
|
|
42
51
|
const t = this._generateNextId();
|
|
43
|
-
return this._pendingBlockId = t,
|
|
52
|
+
return this._pendingBlockId = t, A(t);
|
|
44
53
|
}
|
|
45
54
|
/**
|
|
46
55
|
* Called when a new block is dropped into the template
|
|
@@ -115,7 +124,7 @@ class y extends h {
|
|
|
115
124
|
if (!n)
|
|
116
125
|
return;
|
|
117
126
|
const i = this.api.getDocumentModifier();
|
|
118
|
-
i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new
|
|
127
|
+
i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new R(`Assign recommendation ID ${e}`));
|
|
119
128
|
}
|
|
120
129
|
/**
|
|
121
130
|
* Gets the recommendation-id from a block node
|
|
@@ -149,6 +158,6 @@ class y extends h {
|
|
|
149
158
|
}
|
|
150
159
|
}
|
|
151
160
|
export {
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
p as BLOCK_ID,
|
|
162
|
+
T as RecommendationBlock
|
|
154
163
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var n = (c, s, t) =>
|
|
4
|
-
import { CommonControl as
|
|
5
|
-
import { RecommendationConfigService as
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var m = (c, s, t) => s in c ? d(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
|
|
3
|
+
var n = (c, s, t) => m(c, typeof s != "symbol" ? s + "" : s, t);
|
|
4
|
+
import { CommonControl as h } from "../../../common-control.js";
|
|
5
|
+
import { RecommendationConfigService as f } from "../../services/configService.js";
|
|
6
6
|
import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
|
|
7
7
|
import { AlgorithmControl as p } from "./algorithm.js";
|
|
8
8
|
import { ALGORITHM_CONTROL_ID as W } from "./algorithm.js";
|
|
@@ -10,17 +10,17 @@ import { CurrencyControl as g } from "./currency.js";
|
|
|
10
10
|
import { CURRENCY_CONTROL_ID as H } from "./currency.js";
|
|
11
11
|
import { FiltersControl as R } from "./filters.js";
|
|
12
12
|
import { FILTERS_CONTROL_ID as j } from "./filters.js";
|
|
13
|
-
import { LocaleControl as
|
|
13
|
+
import { LocaleControl as y } from "./locale.js";
|
|
14
14
|
import { LOCALE_CONTROL_ID as K } from "./locale.js";
|
|
15
|
-
import { ProductLayoutControl as
|
|
15
|
+
import { ProductLayoutControl as _ } from "./productLayout.js";
|
|
16
16
|
import { PRODUCT_LAYOUT_CONTROL_ID as J } from "./productLayout.js";
|
|
17
|
-
import { ShuffleControl as
|
|
17
|
+
import { ShuffleControl as N } from "./shuffle.js";
|
|
18
18
|
import { SHUFFLE_CONTROL_ID as X } from "./shuffle.js";
|
|
19
|
-
import { regenerateProductRowsWithStyles as b, getBlockElement as
|
|
20
|
-
import { formatProductPrice as tt, getCardComposition as et, getCurrentLayout as ot, reapplySpacing as rt, regenerateMobileProductRows as
|
|
21
|
-
import { useDebounceFn as
|
|
19
|
+
import { regenerateProductRowsWithStyles as b, getBlockElement as P, updateProductContentInPlace as I } from "./utils.js";
|
|
20
|
+
import { formatProductPrice as tt, getCardComposition as et, getCurrentLayout as ot, reapplySpacing as rt, regenerateMobileProductRows as nt, regenerateProductRows as it, setCurrencyAttributes as st, updatePricesInPlace as ct, updateSingleProductContent as at } from "./utils.js";
|
|
21
|
+
import { useDebounceFn as l } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
22
22
|
const T = "recommendation-id", S = "ui-elements-recommendation-block";
|
|
23
|
-
class
|
|
23
|
+
class $ extends h {
|
|
24
24
|
constructor() {
|
|
25
25
|
super(...arguments);
|
|
26
26
|
n(this, "store", C());
|
|
@@ -36,19 +36,19 @@ class z extends f {
|
|
|
36
36
|
/**
|
|
37
37
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
38
38
|
*/
|
|
39
|
-
n(this, "_debouncedFetchProducts",
|
|
39
|
+
n(this, "_debouncedFetchProducts", l(() => {
|
|
40
40
|
this.store.fetchRecommendationProducts();
|
|
41
41
|
}, 500));
|
|
42
42
|
/**
|
|
43
43
|
* Debounced regeneration when products arrive from API
|
|
44
44
|
* Tries in-place update first to preserve styles, falls back to full regeneration
|
|
45
45
|
*/
|
|
46
|
-
n(this, "_debouncedRegenerateWithProducts",
|
|
46
|
+
n(this, "_debouncedRegenerateWithProducts", l(() => {
|
|
47
47
|
const t = this.store.recommendationProducts;
|
|
48
48
|
if (!this.currentNode || !this.api)
|
|
49
49
|
return;
|
|
50
50
|
const e = this.api.getDocumentModifier();
|
|
51
|
-
|
|
51
|
+
I({
|
|
52
52
|
currentNode: this.currentNode,
|
|
53
53
|
documentModifier: e,
|
|
54
54
|
products: t
|
|
@@ -59,7 +59,7 @@ class z extends f {
|
|
|
59
59
|
return S;
|
|
60
60
|
}
|
|
61
61
|
getTemplate() {
|
|
62
|
-
return this.algorithmControl = new p(), this.localeControl = new
|
|
62
|
+
return this.algorithmControl = new p(), this.localeControl = new y(), this.currencyControl = new g(), this.productLayoutControl = new _(), this.filtersControl = new R(), this.shuffleControl = new N(), `
|
|
63
63
|
<div class="recommendation-controls-container">
|
|
64
64
|
${this.algorithmControl.getTemplate()}
|
|
65
65
|
${this.localeControl.getTemplate()}
|
|
@@ -95,19 +95,19 @@ class z extends f {
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
onTemplateNodeUpdated(t) {
|
|
98
|
-
var
|
|
98
|
+
var i;
|
|
99
99
|
super.onTemplateNodeUpdated(t);
|
|
100
100
|
const e = this._getRecommendationIdFromNode(t);
|
|
101
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((
|
|
101
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((i = this.store.blockStates[e]) != null && i.isInitialized) && this._fetchBlockData(e), [
|
|
102
102
|
this.algorithmControl,
|
|
103
103
|
this.localeControl,
|
|
104
104
|
this.currencyControl,
|
|
105
105
|
this.productLayoutControl,
|
|
106
106
|
this.filtersControl,
|
|
107
107
|
this.shuffleControl
|
|
108
|
-
].forEach((
|
|
108
|
+
].forEach((r) => {
|
|
109
109
|
var a;
|
|
110
|
-
|
|
110
|
+
r != null && r.api && (r.currentNode = t, (a = r.onTemplateNodeUpdated) == null || a.call(r, t));
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
onDestroy() {
|
|
@@ -152,17 +152,13 @@ class z extends f {
|
|
|
152
152
|
* values are being prepared for the upcoming initial fetch.
|
|
153
153
|
*/
|
|
154
154
|
_syncNodeConfigToStore() {
|
|
155
|
-
|
|
156
|
-
const t = l.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
|
|
155
|
+
const t = f.getConfig(this.currentNode);
|
|
157
156
|
this.store.patchCurrentBlockConfig({
|
|
158
157
|
strategy: t.strategy,
|
|
159
158
|
language: t.language,
|
|
160
159
|
size: t.size,
|
|
161
160
|
productIds: t.productIds,
|
|
162
|
-
|
|
163
|
-
// After initialization, the Pinia store is the source of truth
|
|
164
|
-
// for filters (edited via the filter drawer).
|
|
165
|
-
...o ? {} : { filters: t.filters },
|
|
161
|
+
filters: t.filters,
|
|
166
162
|
shuffleProducts: t.shuffleProducts,
|
|
167
163
|
currencySettings: {
|
|
168
164
|
name: t.currency.code,
|
|
@@ -185,26 +181,26 @@ class z extends f {
|
|
|
185
181
|
this.store.fetchRecommendationFilters(),
|
|
186
182
|
this.store.fetchRecommendationCreateData(),
|
|
187
183
|
this.store.fetchRecommendationProducts()
|
|
188
|
-
])).forEach((o,
|
|
184
|
+
])).forEach((o, i) => {
|
|
189
185
|
o.status === "rejected" && console.warn(`Recommendation block: ${[
|
|
190
186
|
"fetchRecommendationFilters",
|
|
191
187
|
"fetchRecommendationCreateData",
|
|
192
188
|
"fetchRecommendationProducts"
|
|
193
|
-
][
|
|
189
|
+
][i]} failed`, o.reason);
|
|
194
190
|
});
|
|
195
191
|
}
|
|
196
192
|
/**
|
|
197
193
|
* Reads the recommendation-id attribute from the block element within the node
|
|
198
194
|
*/
|
|
199
195
|
_getRecommendationIdFromNode(t) {
|
|
200
|
-
const e =
|
|
196
|
+
const e = P(t);
|
|
201
197
|
if (!e || !("getAttribute" in e))
|
|
202
198
|
return null;
|
|
203
199
|
const o = e.getAttribute(T);
|
|
204
200
|
if (!o)
|
|
205
201
|
return null;
|
|
206
|
-
const
|
|
207
|
-
return Number.isNaN(
|
|
202
|
+
const i = parseInt(o);
|
|
203
|
+
return Number.isNaN(i) ? null : i;
|
|
208
204
|
}
|
|
209
205
|
/**
|
|
210
206
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -217,27 +213,12 @@ class z extends f {
|
|
|
217
213
|
const { store: t } = this;
|
|
218
214
|
let e = t.recommendationProducts, o = t.$state.configVersion;
|
|
219
215
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
a &&
|
|
216
|
+
const i = t.$state.configVersion;
|
|
217
|
+
i !== o && (o = i, this._debouncedFetchProducts());
|
|
218
|
+
const r = t.recommendationProducts, a = r !== e, u = Array.isArray(r) && r.length > 0;
|
|
219
|
+
a && u && (e = r, this._debouncedRegenerateWithProducts());
|
|
224
220
|
});
|
|
225
221
|
}
|
|
226
|
-
/**
|
|
227
|
-
* Persists the current filter state from Pinia store to the Stripo node config.
|
|
228
|
-
* This ensures filters survive template save/reload cycles.
|
|
229
|
-
*/
|
|
230
|
-
_persistFiltersToNodeConfig() {
|
|
231
|
-
if (!this.currentNode || !this.api)
|
|
232
|
-
return;
|
|
233
|
-
const { filters: t } = this.store.recommendationConfigs;
|
|
234
|
-
l.updateConfig(
|
|
235
|
-
this.api,
|
|
236
|
-
this.currentNode,
|
|
237
|
-
{ filters: t },
|
|
238
|
-
"Update recommendation filters"
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
222
|
}
|
|
242
223
|
export {
|
|
243
224
|
W as ALGORITHM_CONTROL_ID,
|
|
@@ -248,22 +229,22 @@ export {
|
|
|
248
229
|
j as FILTERS_CONTROL_ID,
|
|
249
230
|
R as FiltersControl,
|
|
250
231
|
K as LOCALE_CONTROL_ID,
|
|
251
|
-
|
|
232
|
+
y as LocaleControl,
|
|
252
233
|
J as PRODUCT_LAYOUT_CONTROL_ID,
|
|
253
|
-
|
|
254
|
-
|
|
234
|
+
_ as ProductLayoutControl,
|
|
235
|
+
$ as RecommendationBlockControl,
|
|
255
236
|
X as SHUFFLE_CONTROL_ID,
|
|
256
|
-
|
|
237
|
+
N as ShuffleControl,
|
|
257
238
|
tt as formatProductPrice,
|
|
258
|
-
|
|
239
|
+
P as getBlockElement,
|
|
259
240
|
et as getCardComposition,
|
|
260
241
|
ot as getCurrentLayout,
|
|
261
242
|
rt as reapplySpacing,
|
|
262
|
-
|
|
263
|
-
|
|
243
|
+
nt as regenerateMobileProductRows,
|
|
244
|
+
it as regenerateProductRows,
|
|
264
245
|
b as regenerateProductRowsWithStyles,
|
|
265
246
|
st as setCurrencyAttributes,
|
|
266
247
|
ct as updatePricesInPlace,
|
|
267
|
-
|
|
248
|
+
I as updateProductContentInPlace,
|
|
268
249
|
at as updateSingleProductContent
|
|
269
250
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import r from "../../../static/assets/info.svg.js";
|
|
2
|
+
import { IconsRegistry as t } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
3
|
+
class h extends t {
|
|
3
4
|
registerIconsSvg(C) {
|
|
4
5
|
C["recommendation-icon"] = `
|
|
5
6
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
@@ -59,9 +60,9 @@ class o extends r {
|
|
|
59
60
|
<circle cx="3" cy="16" r="1" stroke="currentColor" stroke-width="1"/>
|
|
60
61
|
<rect x="7" y="15" width="11" height="2" rx="1"/>
|
|
61
62
|
</svg>
|
|
62
|
-
|
|
63
|
+
`, C["migration-info-icon"] = r;
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
export {
|
|
66
|
-
|
|
67
|
+
h as RecommendationIconsRegistry
|
|
67
68
|
};
|
|
@@ -22,6 +22,54 @@ const n = `/* Utils */
|
|
|
22
22
|
ue-orderable.orderable-disabled .droppable-icon {
|
|
23
23
|
display: none;
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
/* ─── Migration Info Box ─────────────────────────────────────────────── */
|
|
27
|
+
/* Shown in the settings panel title when a block was migrated from legacy */
|
|
28
|
+
|
|
29
|
+
/* Layout variables for positioning the absolutely-placed info box */
|
|
30
|
+
:host {
|
|
31
|
+
--rec-migration-padding: 16px;
|
|
32
|
+
--rec-migration-title-height: 61px;
|
|
33
|
+
--rec-migration-box-height: 98px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Push tabs down when info box is present inside the control panel header */
|
|
37
|
+
.control-panel-header:has(.recommendation-block-migration-info) {
|
|
38
|
+
position: relative;
|
|
39
|
+
margin-bottom: calc(2 * var(--rec-migration-padding) + var(--rec-migration-box-height));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Info box container */
|
|
43
|
+
.recommendation-block-migration-info {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: flex-start;
|
|
46
|
+
gap: 8px;
|
|
47
|
+
padding: 12px;
|
|
48
|
+
background: var(--guido-color-background-onpage-message-info);
|
|
49
|
+
border: 1px solid var(--guido-color-border-onpage-message-info);
|
|
50
|
+
border-radius: 4px;
|
|
51
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: var(--rec-migration-padding);
|
|
54
|
+
right: var(--rec-migration-padding);
|
|
55
|
+
top: calc(var(--rec-migration-padding) + var(--rec-migration-title-height));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
|
|
59
|
+
.recommendation-block-migration-info__icon {
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
width: 24px;
|
|
62
|
+
height: 24px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Text content */
|
|
66
|
+
.recommendation-block-migration-info__text {
|
|
67
|
+
margin: 4px 0;
|
|
68
|
+
white-space: normal;
|
|
69
|
+
font-size: 13px;
|
|
70
|
+
font-weight: 400;
|
|
71
|
+
line-height: 16px;
|
|
72
|
+
}
|
|
25
73
|
`;
|
|
26
74
|
export {
|
|
27
75
|
n as default
|