@useinsider/guido 3.12.0-beta.d2745e7 → 3.12.0-beta.d77b0d2

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.
Files changed (73) hide show
  1. package/dist/@types/config/schemas.js +9 -4
  2. package/dist/components/Guido.vue.js +6 -6
  3. package/dist/components/Guido.vue2.js +50 -49
  4. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +38 -0
  5. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +271 -0
  6. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +18 -0
  7. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +42 -0
  8. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +20 -0
  9. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +18 -0
  10. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +20 -0
  11. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +60 -0
  12. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +19 -0
  13. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +19 -0
  14. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +22 -0
  15. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +29 -0
  16. package/dist/composables/useHtmlValidator.js +68 -60
  17. package/dist/composables/useHttp.js +61 -52
  18. package/dist/composables/useRecommendation.js +56 -40
  19. package/dist/composables/useSave.js +22 -22
  20. package/dist/composables/useStrategyFilters.js +16 -0
  21. package/dist/config/migrator/recommendationMigrator.js +7 -4
  22. package/dist/enums/date.js +4 -3
  23. package/dist/enums/extensions/filteringV2.js +1024 -0
  24. package/dist/enums/extensions/recommendationBlock.js +45 -24
  25. package/dist/enums/extensions/strategyDetail.js +149 -0
  26. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
  27. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +141 -123
  28. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +297 -0
  29. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +16 -2
  30. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +137 -0
  31. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +549 -165
  32. package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
  33. package/dist/extensions/Blocks/Recommendation/utils/strategyNavigation.js +8 -0
  34. package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +95 -0
  35. package/dist/extensions/Blocks/Recommendation/utils/strategyUrl.js +43 -0
  36. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -10
  37. package/dist/extensions/Blocks/common-control.js +37 -35
  38. package/dist/guido.css +1 -1
  39. package/dist/services/recommendationApi.js +127 -33
  40. package/dist/services/stripoApi.js +18 -18
  41. package/dist/src/@types/config/schemas.d.ts +10 -0
  42. package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +2 -0
  43. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +43 -0
  44. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +29 -0
  45. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +40 -0
  46. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +38 -0
  47. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +51 -0
  48. package/dist/src/composables/useConfig.d.ts +2 -0
  49. package/dist/src/composables/useHtmlValidator.d.ts +2 -0
  50. package/dist/src/composables/useRecommendation.d.ts +2 -0
  51. package/dist/src/composables/useStrategyFilters.d.ts +24 -0
  52. package/dist/src/enums/extensions/filteringV2.d.ts +72 -0
  53. package/dist/src/enums/extensions/recommendationBlock.d.ts +33 -0
  54. package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
  55. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +10 -4
  56. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +118 -0
  57. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +958 -1
  58. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  59. package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +50 -0
  60. package/dist/src/extensions/Blocks/Recommendation/utils/strategyNavigation.d.ts +10 -0
  61. package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
  62. package/dist/src/extensions/Blocks/Recommendation/utils/strategyUrl.d.ts +51 -0
  63. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +8 -1
  64. package/dist/src/extensions/Blocks/common-control.d.ts +5 -2
  65. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  66. package/dist/src/services/recommendationApi.d.ts +9 -1
  67. package/dist/src/stores/config.d.ts +18 -0
  68. package/dist/src/utils/genericUtil.d.ts +9 -0
  69. package/dist/static/styles/components/base-input.css.js +6 -7
  70. package/dist/utils/dateUtil.js +23 -10
  71. package/dist/utils/genericUtil.js +10 -1
  72. package/dist/utils/templatePreparation.js +70 -57
  73. package/package.json +1 -1
@@ -1,52 +1,146 @@
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
1
+ import { useHttp as g } from "../composables/useHttp.js";
2
+ import { URLS as i, RRS_STRATEGIES_MAX_PAGES as f, QUERY_PARAMS as m, RRS_STRATEGIES_PER_PAGE as A, RRS_EMAIL_ACTIVE_FILTER as y } from "../enums/extensions/recommendationBlock.js";
3
+ const l = (n) => {
4
+ if (Array.isArray(n))
5
+ return n;
6
+ const a = !!n && typeof n == "object" && "data" in n, o = n == null ? void 0 : n.data;
7
+ return Array.isArray(o) ? o : (n && (!a || o != null) && console.error("[Guido] Unexpected RRS payload shape, falling back to empty:", Object.keys(n)), []);
8
+ }, E = (n) => !n || typeof n != "object" ? null : "data" in n ? n.data ?? null : Object.keys(n).length ? n : null, T = (n) => n.reduce(
9
+ (a, o, d) => (a[d] = {
10
+ attributeName: o.attributeName,
11
+ attributeJs: o.attributeJs,
12
+ attributeType: o.attributeType,
13
+ type: o.type,
14
+ displayName: o.displayName,
15
+ isFilterable: o.isFilterable
11
16
  }, a),
12
17
  {}
13
- ), f = () => {
14
- const { get: o } = d(), { get: a } = d({ headers: {} }), t = "6KcLM9TwheVB1mgK";
18
+ ), G = () => {
19
+ const { get: n, post: a } = g(), { get: o } = g({ headers: {} }), d = "6KcLM9TwheVB1mgK";
15
20
  return {
21
+ duplicateStrategy: async (r) => {
22
+ try {
23
+ const { data: t } = await a(
24
+ i.STRATEGY_DUPLICATE_PATH.replace("{{id}}", r)
25
+ ), e = E(t) ?? t;
26
+ return !(e != null && e.strategyId) || e.status === !1 ? null : String(e.strategyId);
27
+ } catch (t) {
28
+ return console.error("duplicateStrategy error:", t), null;
29
+ }
30
+ },
16
31
  fetchRecommendationCreateData: async () => {
17
32
  try {
18
- return (await o("/newsletter/recommendations/create-data")).data;
19
- } catch (e) {
20
- throw console.error("fetchUserModalState error:", e), e;
33
+ const t = (await n("/newsletter/recommendations/create-data")).data;
34
+ return {
35
+ ...t,
36
+ currencies: Array.isArray(t == null ? void 0 : t.currencies) ? t.currencies : [],
37
+ activePredictiveAlgorithms: Array.isArray(t == null ? void 0 : t.activePredictiveAlgorithms) ? t.activePredictiveAlgorithms : [],
38
+ languages: (t == null ? void 0 : t.languages) ?? {}
39
+ };
40
+ } catch (r) {
41
+ throw console.error("fetchRecommendationCreateData error:", r), r;
21
42
  }
22
43
  },
23
44
  fetchRecommendationFilters: async () => {
24
45
  try {
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
- } catch (e) {
30
- throw console.error("fetchRecommendationFilters error:", e), e;
46
+ const { data: r } = await n(
47
+ i.PRODUCT_ATTRIBUTES_PATH
48
+ ), t = Array.isArray(r) ? r : (r == null ? void 0 : r.data) ?? [];
49
+ return T(t);
50
+ } catch (r) {
51
+ throw console.error("fetchRecommendationFilters error:", r), r;
31
52
  }
32
53
  },
33
- fetchRecommendationProducts: async (e, n) => {
34
- var i;
35
- try {
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}`
54
+ fetchRecommendationProducts: async (r, t) => {
55
+ var e;
56
+ try {
57
+ const c = new URLSearchParams(Object.entries(t));
58
+ c.set(m.CLIENT_ID, d);
59
+ const u = decodeURIComponent(c.toString());
60
+ console.debug("🏁 Recommendation API Query:", u);
61
+ const s = await o(
62
+ `${i.RECOMMENDATION_API_URL}/v2/${r}?${u}`
42
63
  );
43
- return ((i = c == null ? void 0 : c.data) == null ? void 0 : i.data) ?? [];
64
+ return ((e = s == null ? void 0 : s.data) == null ? void 0 : e.data) ?? [];
65
+ } catch (c) {
66
+ throw console.error("fetchRecommendationProducts error:", c), c;
67
+ }
68
+ },
69
+ fetchRecommendationProductsByUrl: async (r) => {
70
+ var t;
71
+ try {
72
+ const e = await o(r);
73
+ return ((t = e == null ? void 0 : e.data) == null ? void 0 : t.data) ?? [];
74
+ } catch (e) {
75
+ throw console.error("fetchRecommendationProductsByUrl error:", e), e;
76
+ }
77
+ },
78
+ fetchRecommendationStrategies: async () => {
79
+ try {
80
+ const r = [], t = /* @__PURE__ */ new Set();
81
+ for (let e = 1; e <= f; e++) {
82
+ const c = new URLSearchParams({
83
+ [m.FILTERS]: y,
84
+ [m.PER_PAGE]: String(A),
85
+ [m.PAGE]: String(e)
86
+ }), { data: u } = await n(
87
+ `${i.RECOMMENDATION_STRATEGIES_PATH}?${c.toString()}`
88
+ ), s = l(u), S = t.size;
89
+ if (s.forEach((R) => {
90
+ const h = String(R.strategy_id);
91
+ t.has(h) || (t.add(h), r.push(R));
92
+ }), s.length < A || t.size === S)
93
+ break;
94
+ }
95
+ return r;
44
96
  } catch (r) {
45
- throw console.error("fetchRecommendationProducts error:", r), r;
97
+ throw console.error("fetchRecommendationStrategies error:", r), r;
98
+ }
99
+ },
100
+ fetchStrategyCampaigns: async (r, t) => {
101
+ try {
102
+ const { data: e } = await n(
103
+ `${i.RECOMMENDATION_STRATEGIES_PATH}/${r}/campaigns`
104
+ );
105
+ return l(e).map((c) => ({
106
+ id: c.id,
107
+ name: c.name,
108
+ status: c.status,
109
+ variants: c.variants ?? [],
110
+ channel: t(`products.${c.productAlias}`),
111
+ productAlias: c.productAlias,
112
+ isPreventing: c.isPreventing
113
+ }));
114
+ } catch (e) {
115
+ return console.error("fetchStrategyCampaigns error:", e), [];
116
+ }
117
+ },
118
+ generateStrategyEndpoint: async (r, t) => {
119
+ try {
120
+ const e = {
121
+ campaignId: t,
122
+ // Email has no page types (RecommendationStrategyEnums::NON_PAGE_TYPE_CHANNELS),
123
+ // so this stays empty rather than splitting an empty string into [''].
124
+ pageTypes: [],
125
+ isPreviewer: !1,
126
+ strategy: r,
127
+ // Resolved per recipient at send time, never here.
128
+ userId: ""
129
+ }, { data: c } = await a(
130
+ i.STRATEGY_ENDPOINT_GENERATE_PATH,
131
+ e
132
+ );
133
+ return E(c);
134
+ } catch (e) {
135
+ console.error("generateStrategyEndpoint error:", e);
136
+ const c = e == null ? void 0 : e.status;
137
+ if (typeof c == "number" && c >= 400 && c < 500)
138
+ return null;
139
+ throw e;
46
140
  }
47
141
  }
48
142
  };
49
143
  };
50
144
  export {
51
- f as useRecommendationApi
145
+ G as useRecommendationApi
52
146
  };
@@ -1,9 +1,13 @@
1
- import { useHttp as d } from "../composables/useHttp.js";
2
- import { useToaster as m } from "../composables/useToaster.js";
3
- import { MAX_DEFAULT_TEMPLATE_ID as y } from "../enums/defaults.js";
4
- import { useBlankTemplate as f } from "./blankTemplate.js";
5
- const D = () => {
6
- const { get: s, post: u } = d(), { handleError: r } = m(), { getBlankTemplate: o } = f();
1
+ import { useHttp as m } from "../composables/useHttp.js";
2
+ import { useToaster as y } from "../composables/useToaster.js";
3
+ import { MAX_DEFAULT_TEMPLATE_ID as f } from "../enums/defaults.js";
4
+ import { useBlankTemplate as g } from "./blankTemplate.js";
5
+ const l = () => ({
6
+ id: 0,
7
+ stripoId: 0,
8
+ unsubscriptionPreferencePages: []
9
+ }), D = () => {
10
+ const { get: s, post: u } = m(), { handleError: r } = y(), { getBlankTemplate: n } = g();
7
11
  return {
8
12
  getToken: async () => {
9
13
  try {
@@ -26,13 +30,13 @@ const D = () => {
26
30
  },
27
31
  getDefaultTemplate: async () => {
28
32
  try {
29
- const t = new URLSearchParams(window.location.search), e = t.get("default-template"), l = t.get("master"), n = e ? parseInt(e) : 0, i = n >= 1 && n <= y ? n : 0;
30
- if (!i && !l)
31
- return await o();
32
- const p = `/stripo/default-template/${i}`, { data: c } = await s(p), a = typeof c == "string" ? JSON.parse(c) : c;
33
- return !a || typeof a != "object" || !("html" in a) || !("css" in a) ? await o() : a;
33
+ const t = new URLSearchParams(window.location.search), e = t.get("default-template"), p = t.get("master"), o = e ? parseInt(e) : 0, i = o >= 1 && o <= f ? o : 0;
34
+ if (!i && !p)
35
+ return await n();
36
+ const d = `/stripo/default-template/${i}`, { data: c } = await s(d), a = typeof c == "string" ? JSON.parse(c) : c;
37
+ return !a || typeof a != "object" || !("html" in a) || !("css" in a) ? await n() : a;
34
38
  } catch (t) {
35
- return r(t, "Failed to fetch default template"), o();
39
+ return r(t, "Failed to fetch default template"), n();
36
40
  }
37
41
  },
38
42
  getSyncModulesStatus: async () => {
@@ -53,13 +57,9 @@ const D = () => {
53
57
  getSyncModule: async (t) => {
54
58
  try {
55
59
  const { data: e } = await s(`/stripo/stripo-modules/${t}/get`);
56
- return e;
60
+ return Array.isArray(e == null ? void 0 : e.unsubscriptionPreferencePages) ? e : l();
57
61
  } catch (e) {
58
- return r(e, "Failed to get sync module"), {
59
- id: 0,
60
- stripoId: 0,
61
- unsubscriptionPreferencePages: []
62
- };
62
+ return r(e, "Failed to get sync module"), l();
63
63
  }
64
64
  },
65
65
  setSyncModuleUnsubscriptionPages: async (t) => {
@@ -377,6 +377,11 @@ export declare const FeaturesSchema: v.ObjectSchema<{
377
377
  readonly liquidSyntax: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
378
378
  /** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
379
379
  readonly autosave: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
380
+ /**
381
+ * Select a Reusable Recommendation Strategy (RRS) instead of a per-block algorithm.
382
+ * Replaces the algorithm dropdown with a strategy dropdown fed from Smart Recommender.
383
+ */
384
+ readonly reusableRecommendationStrategy: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
380
385
  }, undefined>;
381
386
  /**
382
387
  * Default block types available in Stripo
@@ -764,6 +769,11 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
764
769
  readonly liquidSyntax: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
765
770
  /** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
766
771
  readonly autosave: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
772
+ /**
773
+ * Select a Reusable Recommendation Strategy (RRS) instead of a per-block algorithm.
774
+ * Replaces the algorithm dropdown with a strategy dropdown fed from Smart Recommender.
775
+ */
776
+ readonly reusableRecommendationStrategy: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
767
777
  }, undefined>, {}>;
768
778
  /** Block configuration */
769
779
  readonly blocks: v.OptionalSchema<v.ObjectSchema<{
@@ -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;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Campaigns a strategy is used in — the drawer's second tab.
3
+ *
4
+ * Ported from design-system-organisms
5
+ * `src/organisms/OrgStrategyDetailModal/components/CampaignTable.vue`.
6
+ *
7
+ * DS 1.3.0 note: the source passed `is-wrapper-box` and `skeleton-status` to
8
+ * `InDataTableV2`. Neither prop exists at this version, so both are dropped —
9
+ * loading state is expressed through `loading-status` alone.
10
+ */
11
+ import type { RrsCampaign } from '@@/Types/recommendation';
12
+ type __VLS_Props = {
13
+ campaigns?: RrsCampaign[];
14
+ loading?: boolean;
15
+ };
16
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
17
+ campaigns: () => never[];
18
+ loading: boolean;
19
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
20
+ campaigns: () => never[];
21
+ loading: boolean;
22
+ }>>>, {
23
+ campaigns: RrsCampaign[];
24
+ loading: boolean;
25
+ }>;
26
+ export default _default;
27
+ type __VLS_WithDefaults<P, D> = {
28
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
29
+ default: D[K];
30
+ }> : P[K];
31
+ };
32
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
33
+ type __VLS_TypePropsToOption<T> = {
34
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
35
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
36
+ } : {
37
+ type: import('vue').PropType<T[K]>;
38
+ required: true;
39
+ };
40
+ };
41
+ type __VLS_PrettifyLocal<T> = {
42
+ [K in keyof T]: T[K];
43
+ } & {};
@@ -0,0 +1,29 @@
1
+ type __VLS_Props = {
2
+ /** Raw `filters` JSON exactly as the strategy stores it. */
3
+ filters?: string;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
6
+ filters: string;
7
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
8
+ filters: string;
9
+ }>>>, {
10
+ filters: string;
11
+ }>;
12
+ export default _default;
13
+ type __VLS_WithDefaults<P, D> = {
14
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
15
+ default: D[K];
16
+ }> : P[K];
17
+ };
18
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
19
+ type __VLS_TypePropsToOption<T> = {
20
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
21
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
22
+ } : {
23
+ type: import('vue').PropType<T[K]>;
24
+ required: true;
25
+ };
26
+ };
27
+ type __VLS_PrettifyLocal<T> = {
28
+ [K in keyof T]: T[K];
29
+ } & {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * One humanized filter condition, e.g. "Product type · does not contain [Shirt]".
3
+ *
4
+ * Ported from design-system-organisms
5
+ * `src/organisms/OrgStrategyDetailModal/components/HumanizerCondition.vue`.
6
+ *
7
+ * DS 1.3.0 note: `InStatusText` has no `color` prop and requires `status`. The source
8
+ * passed `color="grey"`; `status="draft"` is the grey pair at this version.
9
+ */
10
+ import type { RrsDetailCondition } from '@@/Types/recommendation';
11
+ type __VLS_Props = {
12
+ condition: RrsDetailCondition;
13
+ index: number;
14
+ isLast?: boolean;
15
+ };
16
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
17
+ isLast: boolean;
18
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
19
+ isLast: boolean;
20
+ }>>>, {
21
+ isLast: boolean;
22
+ }>;
23
+ export default _default;
24
+ type __VLS_WithDefaults<P, D> = {
25
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
26
+ default: D[K];
27
+ }> : P[K];
28
+ };
29
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
30
+ type __VLS_TypePropsToOption<T> = {
31
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
32
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
33
+ } : {
34
+ type: import('vue').PropType<T[K]>;
35
+ required: true;
36
+ };
37
+ };
38
+ type __VLS_PrettifyLocal<T> = {
39
+ [K in keyof T]: T[K];
40
+ } & {};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * One filter group: its conditions, plus the AND/OR chip joining it to the next group.
3
+ *
4
+ * Ported from design-system-organisms
5
+ * `src/organisms/OrgStrategyDetailModal/components/HumanizerGroup.vue`.
6
+ */
7
+ import type { RrsDetailCondition, RrsDetailFilterGroup } from '@@/Types/recommendation';
8
+ type __VLS_Props = {
9
+ filters: Record<string, RrsDetailFilterGroup>;
10
+ conditionList: RrsDetailCondition[];
11
+ groupIndex: string;
12
+ groupLogic?: string;
13
+ };
14
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
15
+ groupLogic: string;
16
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
17
+ groupLogic: string;
18
+ }>>>, {
19
+ groupLogic: string;
20
+ }>;
21
+ export default _default;
22
+ type __VLS_WithDefaults<P, D> = {
23
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
24
+ default: D[K];
25
+ }> : P[K];
26
+ };
27
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
28
+ type __VLS_TypePropsToOption<T> = {
29
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
30
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
31
+ } : {
32
+ type: import('vue').PropType<T[K]>;
33
+ required: true;
34
+ };
35
+ };
36
+ type __VLS_PrettifyLocal<T> = {
37
+ [K in keyof T]: T[K];
38
+ } & {};
@@ -0,0 +1,51 @@
1
+ type __VLS_Props = {
2
+ index: number;
3
+ title: string;
4
+ value: string;
5
+ /** When true, each comma-part of `value` is a translation key rather than a literal. */
6
+ translateValue?: boolean;
7
+ icon?: string;
8
+ iconTooltip?: string;
9
+ /** Shown briefly after the icon is clicked, e.g. "Copied". */
10
+ iconTooltipAfterClicked?: string;
11
+ disabled?: boolean;
12
+ };
13
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
14
+ translateValue: boolean;
15
+ icon: string;
16
+ iconTooltip: string;
17
+ iconTooltipAfterClicked: string;
18
+ disabled: boolean;
19
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {
20
+ iconClick: () => void;
21
+ }, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
22
+ translateValue: boolean;
23
+ icon: string;
24
+ iconTooltip: string;
25
+ iconTooltipAfterClicked: string;
26
+ disabled: boolean;
27
+ }>>>, {
28
+ icon: string;
29
+ disabled: boolean;
30
+ translateValue: boolean;
31
+ iconTooltip: string;
32
+ iconTooltipAfterClicked: string;
33
+ }>;
34
+ export default _default;
35
+ type __VLS_WithDefaults<P, D> = {
36
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
37
+ default: D[K];
38
+ }> : P[K];
39
+ };
40
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
41
+ type __VLS_TypePropsToOption<T> = {
42
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
43
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
44
+ } : {
45
+ type: import('vue').PropType<T[K]>;
46
+ required: true;
47
+ };
48
+ };
49
+ type __VLS_PrettifyLocal<T> = {
50
+ [K in keyof T]: T[K];
51
+ } & {};
@@ -96,6 +96,7 @@ export declare const useConfig: () => {
96
96
  modulesDisabled: boolean;
97
97
  liquidSyntax: boolean;
98
98
  autosave: boolean;
99
+ reusableRecommendationStrategy: boolean;
99
100
  };
100
101
  blocks: {
101
102
  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")[];
@@ -227,6 +228,7 @@ export declare const useConfig: () => {
227
228
  modulesDisabled: boolean;
228
229
  liquidSyntax: boolean;
229
230
  autosave: boolean;
231
+ reusableRecommendationStrategy: boolean;
230
232
  } | null>;
231
233
  blocks: import("vue").ComputedRef<{
232
234
  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")[];
@@ -28,4 +28,6 @@ export declare function buildPartnerAttributeNameSet(filterList: FiltersResponse
28
28
  export declare function findInvalidCustomFields(html: string, validCustomFields: string[], recommendationBlockIds: string[], ignoredIds: Set<string>, ignoredAttributeNames: Set<string> | null): string[];
29
29
  export declare const useHtmlValidator: () => {
30
30
  validateHtml: (html: string, customFields: DynamicContent[], isOnSaveValidation?: boolean) => Promise<boolean>;
31
+ validateRecommendationBlocks: () => boolean;
32
+ validateRecommendationFilters: () => boolean;
31
33
  };
@@ -18,6 +18,8 @@ export declare const useRecommendation: () => {
18
18
  getRecommendationCampaignData: (id: string) => CampaignData;
19
19
  buildCampaignUrl: (campaignId: string, overrides?: {
20
20
  strategy: string;
21
+ /** RRS strategy id; empty string when the block still uses an algorithm. */
22
+ strategyId: string;
21
23
  language: string;
22
24
  currencyCode: string;
23
25
  size: string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Parses a strategy's `filters` JSON into groups and caps how many are shown.
3
+ *
4
+ * Ported from design-system-organisms
5
+ * `src/organisms/OrgStrategyDetailModal/composables/useFilters.ts` (branch `develop`).
6
+ *
7
+ * The drawer lists two filter groups by default and reveals the rest behind a
8
+ * "Show more" toggle, so a strategy with a dozen groups cannot push the campaign
9
+ * tab off the screen.
10
+ */
11
+ import type { RrsDetailFilterGroup } from '@@/Types/recommendation';
12
+ import { type ComputedRef, type Ref } from 'vue';
13
+ export interface UseStrategyFilters {
14
+ filterQuery: ComputedRef<Record<string, RrsDetailFilterGroup>>;
15
+ hasAnyFilter: ComputedRef<boolean>;
16
+ canToggle: ComputedRef<boolean>;
17
+ isCollapsed: Ref<boolean>;
18
+ toggleMore: () => void;
19
+ }
20
+ /**
21
+ * @param filters - Getter for the raw `filters` JSON string, so the caller can pass a
22
+ * reactive prop without this composable needing to know about props.
23
+ */
24
+ export declare function useStrategyFilters(filters: () => string | undefined): UseStrategyFilters;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Filtering enums for Reusable Recommendation Strategies (RRS).
3
+ *
4
+ * Ported verbatim from discovery-strategies-fe `src/enums/FilteringEnumsV2.js`
5
+ * (branch `develop`). Only the subset the strategy info-box / humanizer needs is
6
+ * carried over: `Operators`, `OperatorAbbreviations`, `DataTypes`,
7
+ * `MultiSelectDataTypes`, `OperatorNames`, `TimeAbbreviations`.
8
+ *
9
+ * Guido has no equivalent — `utils/filterUtil.ts` and `validation/filterSchema.ts`
10
+ * serve the recommendation block's filters, which are a different shape from a
11
+ * strategy's filters. Do not merge the two.
12
+ *
13
+ * The `text` values are translation keys, not literals; resolve them through
14
+ * `useTranslations().trans()`.
15
+ *
16
+ * ponytail: kept as a literal copy rather than a re-derivation so it stays easy
17
+ * to diff against the source when Smart Recommender adds an operator.
18
+ */
19
+ /** A single operator option, keyed under its attribute data type. */
20
+ export interface OperatorDefinition {
21
+ value: string;
22
+ text: string;
23
+ operator: string;
24
+ /** Alternative label used when the strategy targets the cart page. */
25
+ cartPageText?: string;
26
+ /** Absent on the `Object` data type in the source. */
27
+ filterType?: string;
28
+ }
29
+ export declare const Operators: Record<string, OperatorDefinition[]>;
30
+ export declare const TimeAbbreviations: {
31
+ readonly WEEK: "w";
32
+ readonly DAY: "d";
33
+ readonly HOUR: "h";
34
+ };
35
+ export declare const OperatorAbbreviations: {
36
+ readonly OPERATOR: {
37
+ readonly IN_LAST: "in-last";
38
+ readonly IS_EMPTY: "is-empty";
39
+ readonly IS_NOT_EMPTY: "is-not-empty";
40
+ readonly IN_BETWEEN: "is-between";
41
+ readonly IS_TRUE: "true";
42
+ readonly IS_FALSE: "false";
43
+ };
44
+ readonly OPERATOR_EXPRESSION: {
45
+ readonly IS_EMPTY: "?";
46
+ readonly IS_NOT_EMPTY: "!?";
47
+ };
48
+ readonly DATE_PICKER_OPERATORS: readonly ["after", "before", "is", "is-not"];
49
+ readonly NON_INPUT_OPERATORS: readonly ["in", "not-in", "after", "before", "is", "is-not", "is-empty", "is-not-empty"];
50
+ readonly CHIPS_WIDGET_OPERATORS: readonly ["in", "not-in"];
51
+ };
52
+ export declare const DataTypes: {
53
+ readonly STRING: "String";
54
+ readonly BOOLEAN: "Boolean";
55
+ readonly DATE: "Date";
56
+ readonly NUMBER: "Number";
57
+ readonly TEXT: "Text";
58
+ readonly URL: "Image";
59
+ readonly NUMBERS: "Numbers";
60
+ readonly DATES: "Dates";
61
+ readonly BOOLEANS: "Booleans";
62
+ readonly STRINGS: "Strings";
63
+ };
64
+ export declare const MultiSelectDataTypes: readonly ["Strings", "String", "Array"];
65
+ export declare const OperatorNames: {
66
+ readonly IS_EXACTLY: "is-exactly";
67
+ readonly IS_NOT_EXACTLY: "is-not-exactly";
68
+ readonly CONTAINS: "contains";
69
+ readonly NOT_CONTAINS: "does-not-contain";
70
+ readonly IN: "in";
71
+ readonly NOT_IN: "not-in";
72
+ };
@@ -3,10 +3,43 @@ 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
+ STRATEGY_ENDPOINT_GENERATE_PATH: string;
8
+ STRATEGY_DUPLICATE_PATH: string;
9
+ };
10
+ /**
11
+ * Smart Recommender panel routes, relative to the embedding inone origin.
12
+ * Guido navigates in the same tab; the flow continues on those pages and does
13
+ * not come back (`{{id}}` is substituted by `buildStrategyEditPath`).
14
+ */
15
+ export declare const STRATEGY_PAGES: {
16
+ LISTING: string;
17
+ CREATE: string;
18
+ EDIT: string;
6
19
  };
7
20
  export declare const QUERY_PARAMS: {
8
21
  CLIENT_ID: string;
22
+ FILTERS: string;
23
+ PAGE: string;
24
+ PER_PAGE: string;
9
25
  };
26
+ /**
27
+ * Page size for the strategy listing.
28
+ *
29
+ * Sent explicitly because Smart Recommender's default page size is not documented
30
+ * anywhere we can read: an unpaginated call would silently return only the first
31
+ * page and the marketer would see a short list with no error. The caller pages
32
+ * until a short page comes back.
33
+ */
34
+ export declare const RRS_STRATEGIES_PER_PAGE = 100;
35
+ /** Safety stop for the listing pager, mirroring discovery-strategies-fe's helper. */
36
+ export declare const RRS_STRATEGIES_MAX_PAGES = 50;
37
+ /**
38
+ * Smart Recommender's filter grammar: `[table.field][operator][value]`, ANDed with `*`.
39
+ * `~` means "contains" — required because `suitable_channels` is a comma-separated
40
+ * column, so `=` would only ever match single-channel strategies.
41
+ */
42
+ export declare const RRS_EMAIL_ACTIVE_FILTER = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]";
10
43
  /**
11
44
  * Get recommendation feed source maps lazily so translated names resolve at access time.
12
45
  * Must be called within a Vue component context or after Pinia is initialized.