@useinsider/guido 3.17.0-beta.e6704da → 3.17.0-beta.eae947f
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/README.md +5 -6
- package/dist/@types/config/schemas.js +6 -12
- package/dist/components/Guido.vue.js +6 -6
- package/dist/components/Guido.vue2.js +61 -63
- package/dist/composables/useCustomInterfaceAppearance.js +16 -19
- package/dist/composables/useRecommendation.js +34 -41
- package/dist/config/migrator/recommendationMigrator.js +4 -6
- package/dist/enums/academy.js +1 -2
- package/dist/enums/date.js +3 -4
- package/dist/enums/extensions/recommendationBlock.js +23 -25
- package/dist/extensions/Blocks/Items/block.js +98 -49
- package/dist/extensions/Blocks/Items/constants/currency.js +11 -0
- package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
- package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
- package/dist/extensions/Blocks/Items/template.js +153 -152
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +11 -13
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +95 -96
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +154 -156
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +68 -216
- package/dist/extensions/Blocks/common-control.js +19 -22
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +29 -78
- package/dist/src/@types/config/schemas.d.ts +0 -12
- package/dist/src/composables/useConfig.d.ts +0 -2
- package/dist/src/composables/useRecommendation.d.ts +0 -1
- package/dist/src/enums/academy.d.ts +0 -1
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
- package/dist/src/extensions/Blocks/Items/block.d.ts +21 -0
- package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +19 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -14
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +10 -214
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -6
- package/dist/src/extensions/Blocks/common-control.d.ts +1 -4
- package/dist/src/services/recommendationApi.d.ts +1 -4
- package/dist/src/stores/config.d.ts +0 -18
- package/dist/utils/dateUtil.js +10 -23
- package/dist/utils/pairProductVariables.js +60 -59
- package/dist/utils/templatePreparation.js +34 -37
- package/package.json +2 -3
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +0 -18
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +0 -70
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue.js +0 -20
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue2.js +0 -55
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -141
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +0 -3
- package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBox.vue.d.ts +0 -24
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -29
- package/dist/src/mock/api/recommendation-strategies.d.ts +0 -43
- package/dist/static/styles/components/recommendation-strategy.css.js +0 -171
|
@@ -1,101 +1,52 @@
|
|
|
1
|
-
import { useHttp as
|
|
2
|
-
import {
|
|
3
|
-
const R =
|
|
4
|
-
(
|
|
5
|
-
attributeName:
|
|
6
|
-
attributeJs:
|
|
7
|
-
attributeType:
|
|
8
|
-
type:
|
|
9
|
-
displayName:
|
|
10
|
-
isFilterable:
|
|
11
|
-
},
|
|
1
|
+
import { useHttp as d } from "../composables/useHttp.js";
|
|
2
|
+
import { QUERY_PARAMS as l, URLS as u } from "../enums/extensions/recommendationBlock.js";
|
|
3
|
+
const R = (o) => o.reduce(
|
|
4
|
+
(a, t, s) => (a[s] = {
|
|
5
|
+
attributeName: t.attributeName,
|
|
6
|
+
attributeJs: t.attributeJs,
|
|
7
|
+
attributeType: t.attributeType,
|
|
8
|
+
type: t.type,
|
|
9
|
+
displayName: t.displayName,
|
|
10
|
+
isFilterable: t.isFilterable
|
|
11
|
+
}, a),
|
|
12
12
|
{}
|
|
13
|
-
),
|
|
14
|
-
const { get:
|
|
13
|
+
), f = () => {
|
|
14
|
+
const { get: o } = d(), { get: a } = d({ headers: {} }), t = "6KcLM9TwheVB1mgK";
|
|
15
15
|
return {
|
|
16
16
|
fetchRecommendationCreateData: async () => {
|
|
17
17
|
try {
|
|
18
|
-
return (await
|
|
18
|
+
return (await o("/newsletter/recommendations/create-data")).data;
|
|
19
19
|
} catch (e) {
|
|
20
20
|
throw console.error("fetchUserModalState error:", e), e;
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
fetchRecommendationFilters: async () => {
|
|
24
24
|
try {
|
|
25
|
-
const { data: e } = await
|
|
26
|
-
|
|
27
|
-
),
|
|
28
|
-
return
|
|
25
|
+
const { data: e } = await o(
|
|
26
|
+
u.PRODUCT_ATTRIBUTES_PATH
|
|
27
|
+
), n = Array.isArray(e) ? e : (e == null ? void 0 : e.data) ?? [];
|
|
28
|
+
return R(n);
|
|
29
29
|
} catch (e) {
|
|
30
30
|
throw console.error("fetchRecommendationFilters error:", e), e;
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
|
-
fetchRecommendationProducts: async (e,
|
|
34
|
-
var
|
|
33
|
+
fetchRecommendationProducts: async (e, n) => {
|
|
34
|
+
var i;
|
|
35
35
|
try {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
console.debug("🏁 Recommendation API Query:",
|
|
40
|
-
const
|
|
41
|
-
`${
|
|
36
|
+
const r = new URLSearchParams(Object.entries(n));
|
|
37
|
+
r.set(l.CLIENT_ID, t);
|
|
38
|
+
const m = decodeURIComponent(r.toString());
|
|
39
|
+
console.debug("🏁 Recommendation API Query:", m);
|
|
40
|
+
const c = await a(
|
|
41
|
+
`${u.RECOMMENDATION_API_URL}/v2/${e}?${m}`
|
|
42
42
|
);
|
|
43
|
-
return ((
|
|
44
|
-
} catch (o) {
|
|
45
|
-
throw console.error("fetchRecommendationProducts error:", o), o;
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
fetchRecommendationProductsByUrl: async (e) => {
|
|
49
|
-
var t;
|
|
50
|
-
try {
|
|
51
|
-
const r = new RegExp(`[?&]${h.CLIENT_ID}=`).test(e), o = e.includes("?") ? "&" : "?", c = r ? e : `${e}${o}${h.CLIENT_ID}=${d}`, n = await a(
|
|
52
|
-
c
|
|
53
|
-
);
|
|
54
|
-
return ((t = n == null ? void 0 : n.data) == null ? void 0 : t.data) ?? [];
|
|
43
|
+
return ((i = c == null ? void 0 : c.data) == null ? void 0 : i.data) ?? [];
|
|
55
44
|
} catch (r) {
|
|
56
|
-
throw console.error("
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
fetchRecommendationStrategies: async () => {
|
|
60
|
-
try {
|
|
61
|
-
const e = /* @__PURE__ */ new Map();
|
|
62
|
-
let t = 1;
|
|
63
|
-
for (; ; ) {
|
|
64
|
-
const { data: r } = await s(
|
|
65
|
-
`${m.RECOMMENDATION_STRATEGIES_PATH}?filters=${encodeURIComponent(l)}&per_page=${R}&page=${t}`
|
|
66
|
-
), o = Array.isArray(r) ? r : (r == null ? void 0 : r.data) ?? [], c = e.size;
|
|
67
|
-
if (o.forEach((n) => e.set(n.strategy_id, n)), o.length < R || e.size === c)
|
|
68
|
-
break;
|
|
69
|
-
t += 1;
|
|
70
|
-
}
|
|
71
|
-
return [...e.values()];
|
|
72
|
-
} catch (e) {
|
|
73
|
-
throw console.error("fetchRecommendationStrategies error:", e), e;
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
generateStrategyEndpoint: async (e) => {
|
|
77
|
-
try {
|
|
78
|
-
const { data: t } = await i(
|
|
79
|
-
`${m.RECOMMENDATION_STRATEGIES_PATH}/endpoint-generate`,
|
|
80
|
-
{
|
|
81
|
-
// Email designs have no campaign yet; backend only needs it
|
|
82
|
-
// for previewer flows.
|
|
83
|
-
campaignId: 0,
|
|
84
|
-
pageTypes: [],
|
|
85
|
-
isPreviewer: !1,
|
|
86
|
-
strategy: e,
|
|
87
|
-
userId: ""
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
if (!t || typeof t != "object" || !("full_path" in t || "data" in t))
|
|
91
|
-
throw new Error("Unexpected endpoint-generate response shape");
|
|
92
|
-
return "full_path" in t ? t : t.data;
|
|
93
|
-
} catch (t) {
|
|
94
|
-
throw console.error("generateStrategyEndpoint error:", t), t;
|
|
45
|
+
throw console.error("fetchRecommendationProducts error:", r), r;
|
|
95
46
|
}
|
|
96
47
|
}
|
|
97
48
|
};
|
|
98
49
|
};
|
|
99
50
|
export {
|
|
100
|
-
|
|
51
|
+
f as useRecommendationApi
|
|
101
52
|
};
|
|
@@ -395,12 +395,6 @@ export declare const FeaturesSchema: v.ObjectSchema<{
|
|
|
395
395
|
readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
396
396
|
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
397
397
|
readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
398
|
-
/**
|
|
399
|
-
* Assign a Reusable Recommendation Strategy (RRS) to recommendation blocks instead of
|
|
400
|
-
* per-block algorithm settings. Hides Algorithm, Filters, Shuffle and Number of Products
|
|
401
|
-
* (they live on the strategy) and adds the Assign Strategy flow.
|
|
402
|
-
*/
|
|
403
|
-
readonly reusableRecommendationStrategy: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
404
398
|
}, undefined>;
|
|
405
399
|
/**
|
|
406
400
|
* Default block types available in Stripo
|
|
@@ -800,12 +794,6 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
|
|
|
800
794
|
readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
801
795
|
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
802
796
|
readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
803
|
-
/**
|
|
804
|
-
* Assign a Reusable Recommendation Strategy (RRS) to recommendation blocks instead of
|
|
805
|
-
* per-block algorithm settings. Hides Algorithm, Filters, Shuffle and Number of Products
|
|
806
|
-
* (they live on the strategy) and adds the Assign Strategy flow.
|
|
807
|
-
*/
|
|
808
|
-
readonly reusableRecommendationStrategy: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
809
797
|
}, undefined>, {}>;
|
|
810
798
|
/** Block configuration */
|
|
811
799
|
readonly blocks: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -99,7 +99,6 @@ export declare const useConfig: () => {
|
|
|
99
99
|
autosave: boolean;
|
|
100
100
|
allowlistEnabled: boolean;
|
|
101
101
|
linkTrackingIds: boolean;
|
|
102
|
-
reusableRecommendationStrategy: boolean;
|
|
103
102
|
};
|
|
104
103
|
blocks: {
|
|
105
104
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -234,7 +233,6 @@ export declare const useConfig: () => {
|
|
|
234
233
|
autosave: boolean;
|
|
235
234
|
allowlistEnabled: boolean;
|
|
236
235
|
linkTrackingIds: boolean;
|
|
237
|
-
reusableRecommendationStrategy: boolean;
|
|
238
236
|
} | null>;
|
|
239
237
|
blocks: import("vue").ComputedRef<{
|
|
240
238
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -18,7 +18,6 @@ export declare const useRecommendation: () => {
|
|
|
18
18
|
getRecommendationCampaignData: (id: string) => CampaignData;
|
|
19
19
|
buildCampaignUrl: (campaignId: string, overrides?: {
|
|
20
20
|
strategy: string;
|
|
21
|
-
strategyId: string;
|
|
22
21
|
language: string;
|
|
23
22
|
currencyCode: string;
|
|
24
23
|
size: string;
|
|
@@ -8,6 +8,5 @@ export declare const ACADEMY_LINKS: {
|
|
|
8
8
|
readonly EMAIL_EDITOR: "https://academy.insiderone.com/docs/email-drag-and-drop-editor";
|
|
9
9
|
readonly GLOBAL_UNSUBSCRIBE: "https://academy.insiderone.com/docs/global-unsubscribe-preference-center";
|
|
10
10
|
readonly AMP_FOR_EMAILS: "https://academy.insiderone.com/docs/amp-for-emails";
|
|
11
|
-
readonly EMAIL_RECOMMENDATION_BLOCK: "https://academy.insiderone.com/docs/new-editor-email-recommendation-block";
|
|
12
11
|
};
|
|
13
12
|
export type AcademyLinkKey = keyof typeof ACADEMY_LINKS;
|
|
@@ -3,9 +3,7 @@ import type { RecommendationFeedItem } from '@@/Types/recommendation';
|
|
|
3
3
|
export declare const URLS: {
|
|
4
4
|
RECOMMENDATION_API_URL: string;
|
|
5
5
|
PRODUCT_ATTRIBUTES_PATH: string;
|
|
6
|
-
RECOMMENDATION_STRATEGIES_PATH: string;
|
|
7
6
|
};
|
|
8
|
-
export declare const RRS_ACTIVE_EMAIL_FILTER = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]";
|
|
9
7
|
export declare const QUERY_PARAMS: {
|
|
10
8
|
CLIENT_ID: string;
|
|
11
9
|
};
|
|
@@ -16,6 +16,8 @@ export declare const BLOCK_ID: BlockId;
|
|
|
16
16
|
* - Onboarding support
|
|
17
17
|
*/
|
|
18
18
|
export declare class ItemsBlock extends Block {
|
|
19
|
+
/** Block instances whose currency attrs were already self-healed this session (SD-147588 — undo-safe). */
|
|
20
|
+
private _currencyHealed;
|
|
19
21
|
getId(): string;
|
|
20
22
|
getIcon(): string;
|
|
21
23
|
getBlockCompositionType(): BlockCompositionType;
|
|
@@ -42,4 +44,23 @@ export declare class ItemsBlock extends Block {
|
|
|
42
44
|
* relies on this td-level fallback in pairProductVariables.
|
|
43
45
|
*/
|
|
44
46
|
private _stampProductTdDomAttributes;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the currency self-heal should run for this block. Two guards (SD-147588):
|
|
49
|
+
* 1. Config is only authoritative when the symbol was actually customized — a symbol still at
|
|
50
|
+
* the 'USD' sentinel may be a migrator default, so we trust the DOM's real value over a
|
|
51
|
+
* defaulted config and never overwrite it.
|
|
52
|
+
* 2. Heal each instance at most once per session, so the auto-fix can't fight undo (undo
|
|
53
|
+
* re-drifts the attr, which would otherwise re-trigger the heal forever).
|
|
54
|
+
*/
|
|
55
|
+
private _shouldReconcileCurrency;
|
|
56
|
+
/** Marks a block instance's currency as reconciled so it is not healed again (undo-safe). */
|
|
57
|
+
private _markCurrencyHealed;
|
|
58
|
+
/**
|
|
59
|
+
* Stamps the export-read currency attrs onto every price `<p>` from config, so a template whose
|
|
60
|
+
* attrs drifted (e.g. a location toggle before the sync fix) self-heals to match the editor.
|
|
61
|
+
* Config is the source of truth — never derive from visible text. Callers gate this with
|
|
62
|
+
* `_shouldReconcileCurrency`. Returns true only when an attr actually changed, so the caller can
|
|
63
|
+
* skip an empty apply that would otherwise re-trigger onDocumentChanged and loop (SD-147588).
|
|
64
|
+
*/
|
|
65
|
+
private _reconcileCurrencyDomAttributes;
|
|
45
66
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single owner for the Items price currency export contract (SD-147588).
|
|
3
|
+
*
|
|
4
|
+
* `data-curency` is deliberately misspelled (one `r`) — it is the attribute the
|
|
5
|
+
* server-side export transform (pairProductVariables) actually reads, so every
|
|
6
|
+
* layer that writes it and the live reader (template, controls, block self-heal,
|
|
7
|
+
* pairProductVariables) MUST go through these constants. A typo fix or mapping change
|
|
8
|
+
* in one of them would otherwise silently break sync with the others and ship the wrong
|
|
9
|
+
* currency position/token to the inbox. Mirrors the Recommendation block's `CURRENCY_ATTR`.
|
|
10
|
+
*
|
|
11
|
+
* Exception: the legacy migrator reads the raw misspelled string on purpose — it parses
|
|
12
|
+
* old templates frozen with that exact attr name, so it must NOT follow a future rename here.
|
|
13
|
+
*/
|
|
14
|
+
export declare const ITEMS_CURRENCY_ATTR: {
|
|
15
|
+
readonly POSITION: "data-curency";
|
|
16
|
+
readonly SYMBOL: "data-currency_symbol";
|
|
17
|
+
};
|
|
18
|
+
/** Currency location select value `'1'` = after (price then symbol), anything else = before. */
|
|
19
|
+
export declare function currencyPositionFromLocation(location: string | undefined): 'after' | 'before';
|
|
@@ -9,9 +9,8 @@ import { PricePlacementControl, PRICE_PLACEMENT_CONTROL_ID } from './pricePlacem
|
|
|
9
9
|
import { ProductCountControl, PRODUCT_COUNT_CONTROL_ID } from './productCount';
|
|
10
10
|
import { ProductLayoutControl, PRODUCT_LAYOUT_CONTROL_ID } from './productLayout';
|
|
11
11
|
import { ShuffleControl, SHUFFLE_CONTROL_ID } from './shuffle';
|
|
12
|
-
import { StrategyControl, STRATEGY_CONTROL_ID } from './strategy';
|
|
13
12
|
export declare const CONTROL_BLOCK_ID = "ui-elements-recommendation-block";
|
|
14
|
-
export { AlgorithmControl, ALGORITHM_CONTROL_ID, LocaleControl, LOCALE_CONTROL_ID, CurrencyControl, CURRENCY_CONTROL_ID, ProductCountControl, PRODUCT_COUNT_CONTROL_ID, ProductLayoutControl, PRODUCT_LAYOUT_CONTROL_ID, FiltersControl, FILTERS_CONTROL_ID, ShuffleControl, SHUFFLE_CONTROL_ID, LayoutOrientationControl, LAYOUT_ORIENTATION_CONTROL_ID, PricePlacementControl, PRICE_PLACEMENT_CONTROL_ID,
|
|
13
|
+
export { AlgorithmControl, ALGORITHM_CONTROL_ID, LocaleControl, LOCALE_CONTROL_ID, CurrencyControl, CURRENCY_CONTROL_ID, ProductCountControl, PRODUCT_COUNT_CONTROL_ID, ProductLayoutControl, PRODUCT_LAYOUT_CONTROL_ID, FiltersControl, FILTERS_CONTROL_ID, ShuffleControl, SHUFFLE_CONTROL_ID, LayoutOrientationControl, LAYOUT_ORIENTATION_CONTROL_ID, PricePlacementControl, PRICE_PLACEMENT_CONTROL_ID, };
|
|
15
14
|
export * from './utils';
|
|
16
15
|
/**
|
|
17
16
|
* Main recommendation block control that composes all sub-controls
|
|
@@ -30,10 +29,7 @@ export declare class RecommendationBlockControl extends CommonControl {
|
|
|
30
29
|
private shuffleControl;
|
|
31
30
|
private pricePlacementControl;
|
|
32
31
|
private layoutOrientationControl;
|
|
33
|
-
private strategyControl;
|
|
34
32
|
getId(): string;
|
|
35
|
-
/** Every sub-control the coordinator owns, in panel order. */
|
|
36
|
-
private get _subControls();
|
|
37
33
|
getTemplate(): string;
|
|
38
34
|
onRender(): Promise<void>;
|
|
39
35
|
onTemplateNodeUpdated(node: ImmutableHtmlNode): void;
|
|
@@ -111,15 +107,8 @@ export declare class RecommendationBlockControl extends CommonControl {
|
|
|
111
107
|
*/
|
|
112
108
|
private _listenStateUpdates;
|
|
113
109
|
/**
|
|
114
|
-
* Persists the current filter
|
|
115
|
-
*
|
|
116
|
-
* (strategyId must be in esd-ext-config before any save — SD-149105).
|
|
117
|
-
*
|
|
118
|
-
* `size` rides along because assigning a strategy overwrites it in the
|
|
119
|
-
* store only. Without this write, `_syncNodeConfigToStore` re-seeds the
|
|
120
|
-
* store from the stale node config on the next panel open, and a block
|
|
121
|
-
* whose saved HTML has the strategy's slot count gets rebuilt against the
|
|
122
|
-
* old one — resetting migrator-applied per-element styles.
|
|
110
|
+
* Persists the current filter state from Pinia store to the Stripo node config.
|
|
111
|
+
* This ensures filters survive template save/reload cycles.
|
|
123
112
|
*/
|
|
124
113
|
private _persistFiltersToNodeConfig;
|
|
125
114
|
}
|