@useinsider/guido 3.18.1-beta.e9a6c91 → 3.18.1-beta.fefef3c
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 +21 -3
- package/dist/@types/config/schemas.js +59 -51
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +72 -70
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +7 -9
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +83 -72
- package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
- package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +24 -22
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +28 -26
- package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.js +21 -0
- package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue2.js +46 -0
- package/dist/composables/useCustomInterfaceAppearance.js +46 -42
- package/dist/composables/useHtmlValidator.js +79 -84
- package/dist/composables/useLegacyStrategyConversion.js +61 -0
- package/dist/composables/useRecommendation.js +18 -21
- package/dist/enums/extensions/recommendationBlock.js +25 -29
- package/dist/extensions/Blocks/Recommendation/block.js +39 -43
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +72 -71
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +70 -40
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +45 -44
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +108 -138
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +72 -0
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +7 -7
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +93 -84
- package/dist/src/@types/config/schemas.d.ts +16 -0
- package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
- package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts +2 -0
- package/dist/src/composables/useConfig.d.ts +4 -0
- package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -2
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +4 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +54 -50
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +44 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
- package/dist/src/services/recommendationApi.d.ts +2 -1
- package/dist/src/stores/config.d.ts +322 -0
- package/dist/src/stores/onboarding.d.ts +421 -0
- package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
- package/dist/static/assets/icons/line-info.svg.js +5 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +74 -43
- package/dist/stores/config.js +74 -60
- package/dist/stores/onboarding.js +6 -1
- package/dist/utils/templatePreparation.js +50 -50
- package/package.json +1 -1
|
@@ -1,91 +1,100 @@
|
|
|
1
|
-
import { useHttp as
|
|
2
|
-
import { URLS as
|
|
3
|
-
const
|
|
4
|
-
(
|
|
5
|
-
attributeName:
|
|
6
|
-
attributeJs:
|
|
7
|
-
attributeType:
|
|
8
|
-
type:
|
|
9
|
-
displayName:
|
|
10
|
-
isFilterable:
|
|
11
|
-
},
|
|
1
|
+
import { useHttp as T } from "../composables/useHttp.js";
|
|
2
|
+
import { URLS as c, QUERY_PARAMS as m, TEMPLATE_MIGRATION_SCOPE_SEGMENT as _, MIGRATE_STRATEGIES_SEGMENT as u } from "../enums/extensions/recommendationBlock.js";
|
|
3
|
+
const h = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]", S = (i) => i.reduce(
|
|
4
|
+
(d, o, E) => (d[E] = {
|
|
5
|
+
attributeName: o.attributeName,
|
|
6
|
+
attributeJs: o.attributeJs,
|
|
7
|
+
attributeType: o.attributeType,
|
|
8
|
+
type: o.type,
|
|
9
|
+
displayName: o.displayName,
|
|
10
|
+
isFilterable: o.isFilterable
|
|
11
|
+
}, d),
|
|
12
12
|
{}
|
|
13
|
-
),
|
|
14
|
-
const { get:
|
|
13
|
+
), f = () => {
|
|
14
|
+
const { get: i, post: d } = T(), { get: o } = T({ headers: {} }), E = "6KcLM9TwheVB1mgK", y = async () => {
|
|
15
|
+
try {
|
|
16
|
+
return (await i(`${c.NEWSLETTER_RECOMMENDATIONS_PATH}/create-data`)).data;
|
|
17
|
+
} catch (t) {
|
|
18
|
+
throw console.error("fetchUserModalState error:", t), t;
|
|
19
|
+
}
|
|
20
|
+
}, R = async () => {
|
|
21
|
+
try {
|
|
22
|
+
const { data: t } = await i(
|
|
23
|
+
c.PRODUCT_ATTRIBUTES_PATH
|
|
24
|
+
), a = Array.isArray(t) ? t : (t == null ? void 0 : t.data) ?? [];
|
|
25
|
+
return S(a);
|
|
26
|
+
} catch (t) {
|
|
27
|
+
throw console.error("fetchRecommendationFilters error:", t), t;
|
|
28
|
+
}
|
|
29
|
+
}, l = async (t, a) => {
|
|
30
|
+
var e;
|
|
31
|
+
try {
|
|
32
|
+
const r = new URLSearchParams(Object.entries(a));
|
|
33
|
+
r.set(m.CLIENT_ID, E);
|
|
34
|
+
const n = decodeURIComponent(r.toString());
|
|
35
|
+
console.debug("🏁 Recommendation API Query:", n);
|
|
36
|
+
const s = await o(
|
|
37
|
+
`${c.RECOMMENDATION_API_URL}/v2/${t}?${n}`
|
|
38
|
+
);
|
|
39
|
+
return ((e = s == null ? void 0 : s.data) == null ? void 0 : e.data) ?? [];
|
|
40
|
+
} catch (r) {
|
|
41
|
+
throw console.error("fetchRecommendationProducts error:", r), r;
|
|
42
|
+
}
|
|
43
|
+
}, g = async (t) => {
|
|
44
|
+
var a;
|
|
45
|
+
try {
|
|
46
|
+
const e = new RegExp(`[?&]${m.CLIENT_ID}=`).test(t), r = t.includes("?") ? "&" : "?", n = e ? t : `${t}${r}${m.CLIENT_ID}=${E}`, s = await o(
|
|
47
|
+
n
|
|
48
|
+
);
|
|
49
|
+
return ((a = s == null ? void 0 : s.data) == null ? void 0 : a.data) ?? [];
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return console.error("fetchRecommendationProductsByUrl error:", e), [];
|
|
52
|
+
}
|
|
53
|
+
}, p = async () => {
|
|
54
|
+
try {
|
|
55
|
+
const { data: t } = await i(
|
|
56
|
+
`${c.RECOMMENDATION_STRATEGIES_PATH}?filters=${encodeURIComponent(h)}`
|
|
57
|
+
);
|
|
58
|
+
return Array.isArray(t) ? t : (t == null ? void 0 : t.data) ?? [];
|
|
59
|
+
} catch (t) {
|
|
60
|
+
throw console.error("fetchRecommendationStrategies error:", t), t;
|
|
61
|
+
}
|
|
62
|
+
}, I = async (t, a) => {
|
|
63
|
+
try {
|
|
64
|
+
const { data: e } = await d(
|
|
65
|
+
`${c.RECOMMENDATION_STRATEGIES_PATH}/endpoint-generate`,
|
|
66
|
+
{
|
|
67
|
+
campaignId: 0,
|
|
68
|
+
pageTypes: [],
|
|
69
|
+
isPreviewer: !1,
|
|
70
|
+
strategy: t,
|
|
71
|
+
userId: "",
|
|
72
|
+
currency: a
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
return !e || typeof e != "object" || !("full_path" in e || "data" in e) ? (console.error("generateStrategyEndpoint unexpected response shape:", e), null) : "full_path" in e ? e : e.data;
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return console.error("generateStrategyEndpoint error:", e), null;
|
|
78
|
+
}
|
|
79
|
+
}, A = (t) => t.scope === "template" ? `${c.NEWSLETTER_RECOMMENDATIONS_PATH}/${_}/${u}` : `${c.NEWSLETTER_RECOMMENDATIONS_PATH}/${u}`;
|
|
15
80
|
return {
|
|
16
|
-
fetchRecommendationCreateData:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
throw console.error("fetchRecommendationFilters error:", e), e;
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
fetchRecommendationProducts: async (e, o) => {
|
|
34
|
-
var t;
|
|
35
|
-
try {
|
|
36
|
-
const n = new URLSearchParams(Object.entries(o));
|
|
37
|
-
n.set(u.CLIENT_ID, i);
|
|
38
|
-
const d = decodeURIComponent(n.toString());
|
|
39
|
-
console.debug("🏁 Recommendation API Query:", d);
|
|
40
|
-
const a = await r(
|
|
41
|
-
`${m.RECOMMENDATION_API_URL}/v2/${e}?${d}`
|
|
42
|
-
);
|
|
43
|
-
return ((t = a == null ? void 0 : a.data) == null ? void 0 : t.data) ?? [];
|
|
44
|
-
} catch (n) {
|
|
45
|
-
throw console.error("fetchRecommendationProducts error:", n), n;
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
fetchRecommendationProductsByUrl: async (e) => {
|
|
49
|
-
var o;
|
|
50
|
-
try {
|
|
51
|
-
const t = new RegExp(`[?&]${u.CLIENT_ID}=`).test(e), n = e.includes("?") ? "&" : "?", d = t ? e : `${e}${n}${u.CLIENT_ID}=${i}`, a = await r(
|
|
52
|
-
d
|
|
53
|
-
);
|
|
54
|
-
return ((o = a == null ? void 0 : a.data) == null ? void 0 : o.data) ?? [];
|
|
55
|
-
} catch (t) {
|
|
56
|
-
return console.error("fetchRecommendationProductsByUrl error:", t), [];
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
fetchRecommendationStrategies: async () => {
|
|
60
|
-
try {
|
|
61
|
-
const { data: e } = await c(
|
|
62
|
-
`${m.RECOMMENDATION_STRATEGIES_PATH}?filters=${encodeURIComponent(y)}`
|
|
63
|
-
);
|
|
64
|
-
return Array.isArray(e) ? e : (e == null ? void 0 : e.data) ?? [];
|
|
65
|
-
} catch (e) {
|
|
66
|
-
throw console.error("fetchRecommendationStrategies error:", e), e;
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
generateStrategyEndpoint: async (e, o) => {
|
|
70
|
-
try {
|
|
71
|
-
const { data: t } = await s(
|
|
72
|
-
`${m.RECOMMENDATION_STRATEGIES_PATH}/endpoint-generate`,
|
|
73
|
-
{
|
|
74
|
-
campaignId: 0,
|
|
75
|
-
pageTypes: [],
|
|
76
|
-
isPreviewer: !1,
|
|
77
|
-
strategy: e,
|
|
78
|
-
userId: "",
|
|
79
|
-
currency: o
|
|
80
|
-
}
|
|
81
|
-
);
|
|
82
|
-
return !t || typeof t != "object" || !("full_path" in t || "data" in t) ? (console.error("generateStrategyEndpoint unexpected response shape:", t), null) : "full_path" in t ? t : t.data;
|
|
83
|
-
} catch (t) {
|
|
84
|
-
return console.error("generateStrategyEndpoint error:", t), null;
|
|
85
|
-
}
|
|
81
|
+
fetchRecommendationCreateData: y,
|
|
82
|
+
fetchRecommendationFilters: R,
|
|
83
|
+
fetchRecommendationProducts: l,
|
|
84
|
+
fetchRecommendationProductsByUrl: g,
|
|
85
|
+
fetchRecommendationStrategies: p,
|
|
86
|
+
generateStrategyEndpoint: I,
|
|
87
|
+
migrateLegacyStrategy: async (t, a = { scope: "campaign" }) => {
|
|
88
|
+
const { data: e } = await d(
|
|
89
|
+
A(a),
|
|
90
|
+
t
|
|
91
|
+
), r = e && typeof e == "object" && "data" in e ? e.data : e, n = r == null ? void 0 : r.strategyId;
|
|
92
|
+
if (n == null || n === "")
|
|
93
|
+
throw new Error("[Guido] migrate-strategies returned no strategyId");
|
|
94
|
+
return String(n);
|
|
86
95
|
}
|
|
87
96
|
};
|
|
88
97
|
};
|
|
89
98
|
export {
|
|
90
|
-
|
|
99
|
+
f as useRecommendationApi
|
|
91
100
|
};
|
|
@@ -50,6 +50,14 @@ export declare const IdentitySchema: v.ObjectSchema<{
|
|
|
50
50
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "userId is required">]>;
|
|
51
51
|
/** Optional variation ID for A/B testing */
|
|
52
52
|
readonly variationId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
53
|
+
/** Optional numeric campaign ID of the host campaign; absent for templates and modules */
|
|
54
|
+
readonly campaignId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
55
|
+
/**
|
|
56
|
+
* Optional numeric template-library id of the host template; absent for campaigns and
|
|
57
|
+
* modules. Distinct from `templateId`, which is the editor's document identity (a uuid /
|
|
58
|
+
* Stripo doc id) and is never an endpoint id.
|
|
59
|
+
*/
|
|
60
|
+
readonly templateLibraryId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
53
61
|
}, undefined>;
|
|
54
62
|
/**
|
|
55
63
|
* Partner configuration - organization and product context
|
|
@@ -625,6 +633,14 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
|
|
|
625
633
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "userId is required">]>;
|
|
626
634
|
/** Optional variation ID for A/B testing */
|
|
627
635
|
readonly variationId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
636
|
+
/** Optional numeric campaign ID of the host campaign; absent for templates and modules */
|
|
637
|
+
readonly campaignId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
638
|
+
/**
|
|
639
|
+
* Optional numeric template-library id of the host template; absent for campaigns and
|
|
640
|
+
* modules. Distinct from `templateId`, which is the editor's document identity (a uuid /
|
|
641
|
+
* Stripo doc id) and is never an endpoint id.
|
|
642
|
+
*/
|
|
643
|
+
readonly templateLibraryId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
628
644
|
}, undefined>;
|
|
629
645
|
/** Partner configuration (required) */
|
|
630
646
|
readonly partner: v.ObjectSchema<{
|
package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
2
|
+
export default _default;
|
package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
2
|
+
export default _default;
|
|
@@ -11,6 +11,8 @@ export declare const useConfig: () => {
|
|
|
11
11
|
templateId: string;
|
|
12
12
|
userId: string;
|
|
13
13
|
variationId?: string | undefined;
|
|
14
|
+
campaignId?: string | undefined;
|
|
15
|
+
templateLibraryId?: string | undefined;
|
|
14
16
|
};
|
|
15
17
|
partner: {
|
|
16
18
|
name: string;
|
|
@@ -146,6 +148,8 @@ export declare const useConfig: () => {
|
|
|
146
148
|
templateId: string;
|
|
147
149
|
userId: string;
|
|
148
150
|
variationId?: string | undefined;
|
|
151
|
+
campaignId?: string | undefined;
|
|
152
|
+
templateLibraryId?: string | undefined;
|
|
149
153
|
} | null>;
|
|
150
154
|
partner: import("vue").ComputedRef<{
|
|
151
155
|
name: string;
|
|
@@ -5,9 +5,10 @@ export declare const URLS: {
|
|
|
5
5
|
PRODUCT_ATTRIBUTES_PATH: string;
|
|
6
6
|
RECOMMENDATION_STRATEGIES_PATH: string;
|
|
7
7
|
RECOMMENDATION_STRATEGIES_PANEL_PATH: string;
|
|
8
|
-
|
|
8
|
+
NEWSLETTER_RECOMMENDATIONS_PATH: string;
|
|
9
9
|
};
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const MIGRATE_STRATEGIES_SEGMENT = "migrate-strategies";
|
|
11
|
+
export declare const TEMPLATE_MIGRATION_SCOPE_SEGMENT = "template";
|
|
11
12
|
export declare const QUERY_PARAMS: {
|
|
12
13
|
CLIENT_ID: string;
|
|
13
14
|
};
|
|
@@ -3,6 +3,7 @@ export declare const STRATEGY_CONTROL_ID = "recommendation-strategy-control";
|
|
|
3
3
|
export declare class StrategyControl extends CommonControl {
|
|
4
4
|
private store;
|
|
5
5
|
private onboardingStore;
|
|
6
|
+
private legacyConversion;
|
|
6
7
|
private storeUnsubscription;
|
|
7
8
|
private listeners;
|
|
8
9
|
private lastPaintedState;
|
|
@@ -88,6 +88,8 @@ export interface RegenerateWithStylesOptions extends Omit<RegenerateProductRowsO
|
|
|
88
88
|
products?: RecommendationProduct[];
|
|
89
89
|
/** Optional: pass layout directly to avoid stale DOM reads after setAttribute */
|
|
90
90
|
layout?: Orientation;
|
|
91
|
+
/** Applies the batch even when the rows are unchanged, for callers that staged their own edits. */
|
|
92
|
+
forceApply?: boolean;
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
95
|
* Regenerates product rows while preserving user-applied styles, in a SINGLE commit.
|
|
@@ -151,6 +153,8 @@ export interface UpdateProductContentInPlaceOptions {
|
|
|
151
153
|
currentNode: ImmutableHtmlNode | null | undefined;
|
|
152
154
|
documentModifier: DocumentModifier;
|
|
153
155
|
products: RecommendationProduct[];
|
|
156
|
+
/** Applies the batch even when the cards are unchanged, for callers that staged their own edits. */
|
|
157
|
+
forceApply?: boolean;
|
|
154
158
|
}
|
|
155
159
|
/**
|
|
156
160
|
* Updates product content in-place without regenerating HTML structure.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsStrategy } from '@@/Types/recommendation';
|
|
1
|
+
import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsMigrationPayload, RrsMigrationTarget, RrsStrategy } from '@@/Types/recommendation';
|
|
2
2
|
export interface PerBlockConfigs {
|
|
3
3
|
cardsInRow: number;
|
|
4
4
|
currencySettings: {
|
|
@@ -22,6 +22,7 @@ export interface PerBlockConfigs {
|
|
|
22
22
|
shuffleProducts: boolean;
|
|
23
23
|
strategy: string;
|
|
24
24
|
strategyId: string;
|
|
25
|
+
nodeConfigVersion: number;
|
|
25
26
|
textTrimming: boolean;
|
|
26
27
|
unresponsive: boolean;
|
|
27
28
|
size: string;
|
|
@@ -36,11 +37,13 @@ interface PerBlockState {
|
|
|
36
37
|
filterSelectionDrawerStatus: boolean;
|
|
37
38
|
assignStrategyDrawerStatus: boolean;
|
|
38
39
|
removeStrategyModalStatus: boolean;
|
|
40
|
+
legacyStrategyUpdatedModalStatus: boolean;
|
|
39
41
|
filterGroup: number;
|
|
40
42
|
/** Whether initial API data (filters, algorithms, products) has been fetched for this block */
|
|
41
43
|
isInitialized: boolean;
|
|
42
44
|
/** Snapshot of filters taken when the drawer opens, used to revert on cancel */
|
|
43
45
|
filterSnapshot: Filter[] | null;
|
|
46
|
+
legacyConversionLoading: boolean;
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
46
49
|
* Persisted-config subset used by `seedBlockUrlConfig` to reconstruct
|
|
@@ -71,7 +74,6 @@ interface StoreState {
|
|
|
71
74
|
strategies: RrsStrategy[];
|
|
72
75
|
strategiesLoading: boolean;
|
|
73
76
|
strategyUrlTemplates: Record<string, string>;
|
|
74
|
-
strategiesFetched: boolean;
|
|
75
77
|
blockStates: Record<number, PerBlockState>;
|
|
76
78
|
currentRecommendationId: number | null;
|
|
77
79
|
configVersion: number;
|
|
@@ -100,7 +102,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
100
102
|
}[];
|
|
101
103
|
strategiesLoading: boolean;
|
|
102
104
|
strategyUrlTemplates: Record<string, string>;
|
|
103
|
-
strategiesFetched: boolean;
|
|
104
105
|
blockStates: Record<number, PerBlockState>;
|
|
105
106
|
currentRecommendationId: number | null;
|
|
106
107
|
configVersion: number;
|
|
@@ -127,7 +128,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
127
128
|
}[];
|
|
128
129
|
strategiesLoading: boolean;
|
|
129
130
|
strategyUrlTemplates: Record<string, string>;
|
|
130
|
-
strategiesFetched: boolean;
|
|
131
131
|
blockStates: Record<number, PerBlockState>;
|
|
132
132
|
currentRecommendationId: number | null;
|
|
133
133
|
configVersion: number;
|
|
@@ -154,7 +154,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
154
154
|
}[];
|
|
155
155
|
strategiesLoading: boolean;
|
|
156
156
|
strategyUrlTemplates: Record<string, string>;
|
|
157
|
-
strategiesFetched: boolean;
|
|
158
157
|
blockStates: Record<number, PerBlockState>;
|
|
159
158
|
currentRecommendationId: number | null;
|
|
160
159
|
configVersion: number;
|
|
@@ -178,7 +177,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
178
177
|
}[];
|
|
179
178
|
strategiesLoading: boolean;
|
|
180
179
|
strategyUrlTemplates: Record<string, string>;
|
|
181
|
-
strategiesFetched: boolean;
|
|
182
180
|
blockStates: Record<number, PerBlockState>;
|
|
183
181
|
currentRecommendationId: number | null;
|
|
184
182
|
configVersion: number;
|
|
@@ -202,7 +200,53 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
202
200
|
}[];
|
|
203
201
|
strategiesLoading: boolean;
|
|
204
202
|
strategyUrlTemplates: Record<string, string>;
|
|
205
|
-
|
|
203
|
+
blockStates: Record<number, PerBlockState>;
|
|
204
|
+
currentRecommendationId: number | null;
|
|
205
|
+
configVersion: number;
|
|
206
|
+
} & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
|
|
207
|
+
isLegacyStrategyBlock(): boolean;
|
|
208
|
+
legacyConversionLoading(state: {
|
|
209
|
+
recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
|
|
210
|
+
activePredictiveAlgorithms: number[];
|
|
211
|
+
languages: Languages;
|
|
212
|
+
currencyList: {
|
|
213
|
+
text: string;
|
|
214
|
+
value: string;
|
|
215
|
+
}[];
|
|
216
|
+
filterList: FiltersResponse;
|
|
217
|
+
strategies: {
|
|
218
|
+
[x: string]: unknown;
|
|
219
|
+
strategy_id: number;
|
|
220
|
+
name: string;
|
|
221
|
+
status: string;
|
|
222
|
+
suitable_channels: string;
|
|
223
|
+
size?: (number | string) | undefined;
|
|
224
|
+
}[];
|
|
225
|
+
strategiesLoading: boolean;
|
|
226
|
+
strategyUrlTemplates: Record<string, string>;
|
|
227
|
+
blockStates: Record<number, PerBlockState>;
|
|
228
|
+
currentRecommendationId: number | null;
|
|
229
|
+
configVersion: number;
|
|
230
|
+
} & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
|
|
231
|
+
legacyStrategyUpdatedModalStatus(state: {
|
|
232
|
+
recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
|
|
233
|
+
activePredictiveAlgorithms: number[];
|
|
234
|
+
languages: Languages;
|
|
235
|
+
currencyList: {
|
|
236
|
+
text: string;
|
|
237
|
+
value: string;
|
|
238
|
+
}[];
|
|
239
|
+
filterList: FiltersResponse;
|
|
240
|
+
strategies: {
|
|
241
|
+
[x: string]: unknown;
|
|
242
|
+
strategy_id: number;
|
|
243
|
+
name: string;
|
|
244
|
+
status: string;
|
|
245
|
+
suitable_channels: string;
|
|
246
|
+
size?: (number | string) | undefined;
|
|
247
|
+
}[];
|
|
248
|
+
strategiesLoading: boolean;
|
|
249
|
+
strategyUrlTemplates: Record<string, string>;
|
|
206
250
|
blockStates: Record<number, PerBlockState>;
|
|
207
251
|
currentRecommendationId: number | null;
|
|
208
252
|
configVersion: number;
|
|
@@ -226,7 +270,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
226
270
|
}[];
|
|
227
271
|
strategiesLoading: boolean;
|
|
228
272
|
strategyUrlTemplates: Record<string, string>;
|
|
229
|
-
strategiesFetched: boolean;
|
|
230
273
|
blockStates: Record<number, PerBlockState>;
|
|
231
274
|
currentRecommendationId: number | null;
|
|
232
275
|
configVersion: number;
|
|
@@ -253,7 +296,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
253
296
|
}[];
|
|
254
297
|
strategiesLoading: boolean;
|
|
255
298
|
strategyUrlTemplates: Record<string, string>;
|
|
256
|
-
strategiesFetched: boolean;
|
|
257
299
|
blockStates: Record<number, PerBlockState>;
|
|
258
300
|
currentRecommendationId: number | null;
|
|
259
301
|
configVersion: number;
|
|
@@ -280,7 +322,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
280
322
|
}[];
|
|
281
323
|
strategiesLoading: boolean;
|
|
282
324
|
strategyUrlTemplates: Record<string, string>;
|
|
283
|
-
strategiesFetched: boolean;
|
|
284
325
|
blockStates: Record<number, PerBlockState>;
|
|
285
326
|
currentRecommendationId: number | null;
|
|
286
327
|
configVersion: number;
|
|
@@ -308,7 +349,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
308
349
|
}[];
|
|
309
350
|
strategiesLoading: boolean;
|
|
310
351
|
strategyUrlTemplates: Record<string, string>;
|
|
311
|
-
strategiesFetched: boolean;
|
|
312
352
|
blockStates: Record<number, PerBlockState>;
|
|
313
353
|
currentRecommendationId: number | null;
|
|
314
354
|
configVersion: number;
|
|
@@ -335,7 +375,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
335
375
|
}[];
|
|
336
376
|
strategiesLoading: boolean;
|
|
337
377
|
strategyUrlTemplates: Record<string, string>;
|
|
338
|
-
strategiesFetched: boolean;
|
|
339
378
|
blockStates: Record<number, PerBlockState>;
|
|
340
379
|
currentRecommendationId: number | null;
|
|
341
380
|
configVersion: number;
|
|
@@ -362,7 +401,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
362
401
|
}[];
|
|
363
402
|
strategiesLoading: boolean;
|
|
364
403
|
strategyUrlTemplates: Record<string, string>;
|
|
365
|
-
strategiesFetched: boolean;
|
|
366
404
|
blockStates: Record<number, PerBlockState>;
|
|
367
405
|
currentRecommendationId: number | null;
|
|
368
406
|
configVersion: number;
|
|
@@ -442,43 +480,14 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
442
480
|
cancelFilterDrawer(): void;
|
|
443
481
|
openAssignStrategyDrawer(): void;
|
|
444
482
|
closeAssignStrategyDrawer(): void;
|
|
483
|
+
openLegacyStrategyUpdatedModal(): void;
|
|
484
|
+
closeLegacyStrategyUpdatedModal(): void;
|
|
445
485
|
openRemoveStrategyModal(): void;
|
|
446
486
|
closeRemoveStrategyModal(): void;
|
|
447
487
|
fetchStrategies(): Promise<void>;
|
|
448
|
-
invalidateStrategies(): void;
|
|
449
|
-
/**
|
|
450
|
-
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
451
|
-
* the user comes back. `visibilitychange` covers the tab case; `focus` covers the page
|
|
452
|
-
* landing in a separate window, where this document never goes hidden.
|
|
453
|
-
*
|
|
454
|
-
* Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
|
|
455
|
-
* strategy in it and come back again — a listener that disarmed on the first return would
|
|
456
|
-
* leave that one missing from the list. Armed only once the user actually opens a strategy
|
|
457
|
-
* page, so anyone who never does pays nothing.
|
|
458
|
-
*/
|
|
459
|
-
_armStrategyPageReturn(url: string): void;
|
|
460
|
-
/**
|
|
461
|
-
* Reloads the products of the block the user is on, so an edit made in the strategy tab
|
|
462
|
-
* lands on the canvas instead of waiting for the assign drawer to be reopened.
|
|
463
|
-
*
|
|
464
|
-
* Only the selected block: the canvas regeneration is driven off the active block's
|
|
465
|
-
* product array, so refreshing an unselected block would fetch without redrawing it.
|
|
466
|
-
*/
|
|
467
|
-
_refreshAssignedStrategyProducts(): Promise<void>;
|
|
468
|
-
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
469
|
-
disposeStrategyPageReturn(): void;
|
|
470
|
-
/**
|
|
471
|
-
* Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
|
|
472
|
-
* new strategy is offered; the user picks it themselves.
|
|
473
|
-
*/
|
|
474
|
-
openStrategyCreation(): void;
|
|
475
|
-
/**
|
|
476
|
-
* Opens the strategy's edit page. Every return refreshes the list so the block reflects the
|
|
477
|
-
* edited configuration.
|
|
478
|
-
*/
|
|
479
|
-
openStrategyEdit(strategyId: string | number): void;
|
|
480
488
|
resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
|
|
481
489
|
assignStrategy(strategy: RrsStrategy): void;
|
|
490
|
+
convertLegacyStrategy(payload: RrsMigrationPayload, target?: RrsMigrationTarget): Promise<string>;
|
|
482
491
|
removeStrategy(): void;
|
|
483
492
|
fetchRecommendationCreateData(): Promise<void>;
|
|
484
493
|
fetchRecommendationFilters(): Promise<void>;
|
|
@@ -494,11 +503,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
494
503
|
* every block's recommendationConfigs across user edits.
|
|
495
504
|
*/
|
|
496
505
|
hasInvalidBlock(): boolean;
|
|
497
|
-
/**
|
|
498
|
-
* Which required fields are missing across the design's blocks, so the save
|
|
499
|
-
* toaster can name the cause instead of always showing the generic message.
|
|
500
|
-
*/
|
|
501
|
-
invalidBlockFields(): string[];
|
|
502
506
|
fetchRecommendationProducts(): Promise<void>;
|
|
503
507
|
_doFetchProducts(): Promise<void>;
|
|
504
508
|
_doFetchStrategyProducts(blockId: number): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Filter, RrsMigrationFilterGroup, RrsMigrationPayload, RrsMigrationTarget } from '@@/Types/recommendation';
|
|
2
|
+
type FilterAttribute = {
|
|
3
|
+
value: string;
|
|
4
|
+
type: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* A block authored before reusable strategies: it still carries a plain feed
|
|
8
|
+
* configuration (compiled into a feed URL string) instead of a strategy id.
|
|
9
|
+
* Blocks created under RRS stamp `CURRENT_CONFIG_VERSION`, so the version is
|
|
10
|
+
* what separates "never converted" from "not assigned yet".
|
|
11
|
+
*/
|
|
12
|
+
export declare function isLegacyStrategyConfig({ strategyId, nodeConfigVersion }: {
|
|
13
|
+
strategyId: string;
|
|
14
|
+
nodeConfigVersion: number;
|
|
15
|
+
}): boolean;
|
|
16
|
+
export declare function resolveMigrationTarget({ campaignId, templateLibraryId }: {
|
|
17
|
+
campaignId?: string;
|
|
18
|
+
templateLibraryId?: string;
|
|
19
|
+
}): RrsMigrationTarget;
|
|
20
|
+
/**
|
|
21
|
+
* Groups the block's valid filters the way the feed URL groups them, in the
|
|
22
|
+
* shape the migration endpoint validates. The URL's filter DSL states no
|
|
23
|
+
* attribute type and cannot express a mixed-operator group, which is exactly
|
|
24
|
+
* what this override exists to supply.
|
|
25
|
+
*/
|
|
26
|
+
export declare function toMigrationFilterGroups(filters: Filter[], attributes: FilterAttribute[]): RrsMigrationFilterGroup[];
|
|
27
|
+
interface MigrationInputs {
|
|
28
|
+
blockId: number;
|
|
29
|
+
url: string;
|
|
30
|
+
campaignId: string;
|
|
31
|
+
variationId: string;
|
|
32
|
+
strategy: string;
|
|
33
|
+
productIds: string[];
|
|
34
|
+
filters: Filter[];
|
|
35
|
+
attributes: FilterAttribute[];
|
|
36
|
+
target: RrsMigrationTarget;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The server names and de-duplicates the strategy, so nothing here derives a name. The two
|
|
40
|
+
* routes take different identity fields — the campaign one names from `campaignId`/`variationId`
|
|
41
|
+
* (0 for modules, which carry no numeric campaign), the template one from `templateId`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildLegacyMigrationPayload({ blockId, url, campaignId, variationId, strategy, productIds, filters, attributes, target, }: MigrationInputs): RrsMigrationPayload;
|
|
44
|
+
export {};
|
|
@@ -15,11 +15,7 @@ export interface RequiredField {
|
|
|
15
15
|
getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
|
|
16
16
|
condition?: (config: PerBlockConfigs) => boolean;
|
|
17
17
|
}
|
|
18
|
-
/** Field key of the strategy/algorithm descriptor, used to pick the toaster message. */
|
|
19
|
-
export declare const STRATEGY_FIELD_KEY = "strategy";
|
|
20
18
|
export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
|
|
21
19
|
export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
|
|
22
|
-
/** Shown instead of the generic message when the only thing missing is the strategy. */
|
|
23
|
-
export declare const RecommendationAssignStrategyKey = "newsletter.recommendation-assign-strategy";
|
|
24
20
|
export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
|
|
25
21
|
export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsStrategy } from '@@/Types/recommendation';
|
|
1
|
+
import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsMigrationPayload, RrsMigrationTarget, RrsStrategy } from '@@/Types/recommendation';
|
|
2
2
|
export declare const useRecommendationApi: () => {
|
|
3
3
|
fetchRecommendationCreateData: () => Promise<InitialResponse>;
|
|
4
4
|
fetchRecommendationFilters: () => Promise<FiltersResponse>;
|
|
@@ -6,4 +6,5 @@ export declare const useRecommendationApi: () => {
|
|
|
6
6
|
fetchRecommendationProductsByUrl: (url: string) => Promise<RecommendationProduct[]>;
|
|
7
7
|
fetchRecommendationStrategies: () => Promise<RrsStrategy[]>;
|
|
8
8
|
generateStrategyEndpoint: (strategy: RrsStrategy, currency: string) => Promise<RrsEndpointGenerateResponse | null>;
|
|
9
|
+
migrateLegacyStrategy: (payload: RrsMigrationPayload, target?: RrsMigrationTarget) => Promise<string>;
|
|
9
10
|
};
|