@designcrowd/library.brand-page 5.16.3 → 5.16.4-abtest-1

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 (125) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-BVouwZJN.js → CreatedOnBrandCrowd-de-de-DQc3IjpR.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-Dtx-1uWO.js → CreatedOnBrandCrowd-en-us-CIgIJjzf.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CmlnW8oC.js → CreatedOnBrandCrowd-es-es-C4JLISvP.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-C95ioWzr.js → CreatedOnBrandCrowd-fr-ca-DPpWX0aJ.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-C95ioWzr.js → CreatedOnBrandCrowd-fr-fr-DPpWX0aJ.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-C_5SiaiE.js → CreatedOnBrandCrowd-pt-br-DmKD5o2o.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-C_5SiaiE.js → CreatedOnBrandCrowd-pt-pt-DmKD5o2o.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BP4saQXn.js → CreatedOnDcom-de-de-DhALOqwz.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-B8Taru6f.js → CreatedOnDcom-en-us-LmejZqTn.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-Bo3JhWwd.js → CreatedOnDcom-es-es-D3ZH5JD5.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CDk3ZAHU.js → CreatedOnDcom-fr-ca-BUOMh8kU.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-CD04W_hw.js → CreatedOnDcom-fr-fr-CNc-56QW.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-B2DGv1qj.js → CreatedOnDcom-pt-br-BGvy2ON7.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-TYqvgQ08.js → CreatedOnDcom-pt-pt-FaVxQHpN.js} +1 -1
  15. package/lib/src/brand-page/models/brand-page-context.model.d.ts +1 -1
  16. package/lib/src/brand-page/models/brand-page-context.model.js +5 -1
  17. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -0
  18. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +30 -1
  19. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +0 -12
  20. package/lib/src/brand-page-maker/stores/index.d.ts +1 -0
  21. package/lib/src/brand-page-maker/stores/index.js +1 -0
  22. package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.d.ts +14 -0
  23. package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.js +21 -0
  24. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +2 -0
  25. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +117 -0
  26. package/lib/src/bundled-translations-Dw3XtNmX.js +163 -0
  27. package/lib/src/bundled-translations.de-DE-B82Ik9M7.js +163 -0
  28. package/lib/src/bundled-translations.es-ES-cf3pdNuN.js +163 -0
  29. package/lib/src/bundled-translations.fr-CA-DP44EcAZ.js +163 -0
  30. package/lib/src/bundled-translations.fr-FR-V0Zt25kg.js +163 -0
  31. package/lib/src/bundled-translations.pt-BR-Brv6rCss.js +163 -0
  32. package/lib/src/bundled-translations.pt-PT-BTgscCTG.js +163 -0
  33. package/lib/src/bundles/bundled-translations.de-DE.json +15 -1
  34. package/lib/src/bundles/bundled-translations.es-ES.json +15 -1
  35. package/lib/src/bundles/bundled-translations.fr-CA.json +15 -1
  36. package/lib/src/bundles/bundled-translations.fr-FR.json +15 -1
  37. package/lib/src/bundles/bundled-translations.json +15 -1
  38. package/lib/src/bundles/bundled-translations.pt-BR.json +15 -1
  39. package/lib/src/bundles/bundled-translations.pt-PT.json +15 -1
  40. package/lib/src/clients/brand-page-client.d.ts +0 -4
  41. package/lib/src/clients/design-template-client.d.ts +2 -0
  42. package/lib/src/clients/design-template-client.js +33 -0
  43. package/lib/src/composables/useSnapshot.d.ts +5 -0
  44. package/lib/src/composables/useSnapshot.js +74 -0
  45. package/lib/src/composables/useTranslate.d.ts +2 -1
  46. package/lib/src/composables/useTranslate.js +2 -1
  47. package/lib/src/css/library.brand-page-brandCrowd.min.css +149 -8
  48. package/lib/src/css/library.brand-page-brandPage.min.css +136 -8
  49. package/lib/src/css/library.brand-page-designCom.min.css +149 -8
  50. package/lib/src/css/library.brand-page-preview.min.css +133 -8
  51. package/lib/src/index.mjs +1 -1
  52. package/lib/src/{lib-3sE17Ltm.js → lib-CqA2Cr9V.js} +20353 -19606
  53. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -0
  54. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +3 -0
  55. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -0
  56. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +6 -0
  57. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +8 -0
  58. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +44 -1
  59. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +1 -0
  60. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +3 -0
  61. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +21 -3
  62. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +39 -2
  63. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +20 -2
  64. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +41 -2
  65. package/lib/src/shared/content-settings/utils.d.ts +1 -0
  66. package/lib/src/shared/content-settings/utils.js +6 -0
  67. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +0 -1
  68. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -4
  69. package/package.json +2 -2
  70. package/src/brand-page/models/brand-page-context.model.ts +13 -3
  71. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +31 -0
  72. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +2 -1
  73. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +0 -36
  74. package/src/brand-page-maker/stores/index.ts +1 -0
  75. package/src/brand-page-maker/stores/snapshot/snapshot-store.ts +31 -0
  76. package/src/brand-page-maker/utils/rich-text-editor.util.ts +154 -0
  77. package/src/bundles/bundled-translations.de-DE.json +15 -1
  78. package/src/bundles/bundled-translations.es-ES.json +15 -1
  79. package/src/bundles/bundled-translations.fr-CA.json +15 -1
  80. package/src/bundles/bundled-translations.fr-FR.json +15 -1
  81. package/src/bundles/bundled-translations.json +15 -1
  82. package/src/bundles/bundled-translations.pt-BR.json +15 -1
  83. package/src/bundles/bundled-translations.pt-PT.json +15 -1
  84. package/src/clients/brand-page-client.ts +0 -4
  85. package/src/clients/design-template-client.ts +57 -0
  86. package/src/composables/useSnapshot.ts +97 -0
  87. package/src/composables/useTranslate.ts +3 -0
  88. package/src/shared/common/i18n/common.de-DE.json +5 -1
  89. package/src/shared/common/i18n/common.es-ES.json +5 -1
  90. package/src/shared/common/i18n/common.fr-CA.json +5 -1
  91. package/src/shared/common/i18n/common.fr-FR.json +5 -1
  92. package/src/shared/common/i18n/common.json +5 -1
  93. package/src/shared/common/i18n/common.pt-BR.json +5 -1
  94. package/src/shared/common/i18n/common.pt-PT.json +5 -1
  95. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +3 -0
  96. package/src/shared/content-settings/components/content-settings/ContentSettings.vue +2 -0
  97. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +8 -0
  98. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.vue +1 -0
  99. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +54 -0
  100. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +20 -2
  101. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +3 -1
  102. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.vue +1 -0
  103. package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +95 -0
  104. package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +500 -0
  105. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.de-DE.json +12 -0
  106. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.es-ES.json +12 -0
  107. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-CA.json +12 -0
  108. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-FR.json +12 -0
  109. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.json +12 -0
  110. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-BR.json +12 -0
  111. package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-PT.json +12 -0
  112. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +44 -2
  113. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +15 -3
  114. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +52 -2
  115. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +16 -3
  116. package/src/shared/content-settings/utils.ts +9 -0
  117. package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -6
  118. package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.vue +1 -1
  119. package/lib/src/bundled-translations-D9iHE5G9.js +0 -161
  120. package/lib/src/bundled-translations.de-DE-DW3iDx_G.js +0 -161
  121. package/lib/src/bundled-translations.es-ES-C9I8wDyq.js +0 -161
  122. package/lib/src/bundled-translations.fr-CA-C0NN8DsO.js +0 -161
  123. package/lib/src/bundled-translations.fr-FR-oKV5NyE1.js +0 -161
  124. package/lib/src/bundled-translations.pt-BR-CTvCfv1X.js +0 -161
  125. package/lib/src/bundled-translations.pt-PT-CbwxwRY1.js +0 -161
@@ -784,6 +784,7 @@ declare const _default: import("vue").DefineComponent<{}, {
784
784
  visibleContentOptions(): AddContentOption<any>[];
785
785
  contentListItems(): ContentItem<Content>[];
786
786
  }, {
787
+ onCapturePreviewSnapshot(): void;
787
788
  onAddContentOptionClicked(option: AddContentOption<any>): Promise<void>;
788
789
  onLockedContentClicked(type: string): Promise<void>;
789
790
  getCategoryLabel(category: string): string;
@@ -75,6 +75,9 @@ export default defineComponent({
75
75
  },
76
76
  },
77
77
  methods: {
78
+ onCapturePreviewSnapshot() {
79
+ this.$emit('capture-preview-snapshot');
80
+ },
78
81
  async onAddContentOptionClicked(option) {
79
82
  const newItem = await this.contentSettingsStore.addItemByType({
80
83
  type: option.type,
@@ -510,6 +510,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
510
510
  personalisationRole(): PersonalisationRole | undefined;
511
511
  }, {
512
512
  onDelete(): void;
513
+ captureSnapshotBeforeModal(): void;
514
+ onCaptureSnapshot(): void;
513
515
  toggleButtonClick(): void;
514
516
  sendSelectContentEvent(): void;
515
517
  onPersonalisationRoleChange(payload: UpdateItemValuePayload<PersonalisationRole | undefined>): void;
@@ -134,6 +134,12 @@ export default defineComponent({
134
134
  onDelete() {
135
135
  this.$emit('on-delete');
136
136
  },
137
+ captureSnapshotBeforeModal() {
138
+ this.$emit('capture-snapshot-before-modal');
139
+ },
140
+ onCaptureSnapshot() {
141
+ this.$emit('capture-preview-snapshot');
142
+ },
137
143
  toggleButtonClick() {
138
144
  const $sideBarContent = document.querySelector(`#${SIDE_BAR_CONTENT_ID}`);
139
145
  if (!$sideBarContent) {
@@ -27,6 +27,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
27
27
  getValue: import("vue").ComputedRef<(id: string, fieldName: string) => string | Content | undefined>;
28
28
  brandPageData: import("vue").ComputedRef<import("../../../../brand-page").BrandPageModel>;
29
29
  isAdmin: import("vue").ComputedRef<boolean>;
30
+ isDesignCom: import("vue").ComputedRef<boolean>;
30
31
  canUseRichTextEditor: import("vue").ComputedRef<boolean>;
31
32
  brandPageType: import("vue").ComputedRef<"default" | "brandSite" | "brandContact">;
32
33
  isBrandPageOrIsBrandContact: import("vue").ComputedRef<boolean>;
@@ -62,6 +63,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
62
63
  950?: string | undefined;
63
64
  };
64
65
  }>;
66
+ snapshotBase64: import("vue").ComputedRef<string | null>;
65
67
  contentSettingsStore: import("pinia").Store<"uiContentSettings", import("../../store").ContentSettingsState, {
66
68
  contentErrorCount(): number;
67
69
  getContent(state: {
@@ -785,6 +787,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
785
787
  }>;
786
788
  }, {
787
789
  isToggled: boolean;
790
+ richTextEditorKey: number;
788
791
  }, {
789
792
  content(): Content;
790
793
  contentType(): string;
@@ -805,6 +808,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
805
808
  showTextBg(): boolean;
806
809
  showToggle(): boolean | undefined;
807
810
  disableTransparent(): boolean;
811
+ generateText(): string;
812
+ showGenerateText(): boolean;
813
+ plainTextValue(): string;
808
814
  }, {
809
815
  onFieldChanged(payload: UpdateItemValuePayload<unknown>): void;
810
816
  onFieldChangeLogo(): void;
@@ -816,7 +822,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
816
822
  }): void;
817
823
  onToggleInput(isToggled: boolean): void;
818
824
  onToggleStateChange(isToggled: boolean): void;
825
+ onUseGeneratedText(generatedText: string): void;
819
826
  clearFieldValue(): void;
827
+ onCaptureSnapshot(): void;
820
828
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
821
829
  id: {
822
830
  type: StringConstructor;
@@ -3,11 +3,14 @@ import { VIEWPORTS, } from '../../../../brand-page';
3
3
  import { UI_EVENT_SOURCES } from '../../../models';
4
4
  import { useUiContentSettingsStore } from '../../store';
5
5
  import { useUiSideBarStore } from '../../../side-bar/store';
6
- import { useBrandPageMakerStore, useBrandPageMakerUserStore, useUiStore, } from '../../../../brand-page-maker/stores';
6
+ import { useBrandPageContainerStore, useBrandPageMakerStore, useBrandPageMakerUserStore, useUiStore, useSnapshotStore, } from '../../../../brand-page-maker/stores';
7
7
  import { SIDE_BAR_TAB_NAMES } from '../../../../brand-page-maker/constants';
8
8
  import { ITEM_FIELD_TYPES, } from '../../../../brand-page-maker/models';
9
9
  import { useUiPageSettingsStore } from '../../../page-settings/store';
10
10
  import { PAGE_SECTIONS } from '../../../page-settings/models';
11
+ import { commonTr } from '../../../../composables/useTranslate';
12
+ import { getPlainTextFromRTE, replaceTextInRTE, } from '../../../../brand-page-maker/utils';
13
+ import { isDefaultContentText } from '../../utils';
11
14
  import { useUiLogoSettingsStore } from '../../../logo-settings/store';
12
15
  const RTE_ALLOWED_SECTION_TYPES = [
13
16
  'banner-section',
@@ -16,11 +19,18 @@ const RTE_ALLOWED_SECTION_TYPES = [
16
19
  'images-section',
17
20
  'shapes-section',
18
21
  ];
22
+ const AI_ALLOWED_SECTION_TYPES = [
23
+ 'banner-section',
24
+ 'text',
25
+ 'about-section',
26
+ 'testimonials-section',
27
+ ];
19
28
  const RTE_DISALLOWED_STYLE_FIELD_NAMES = [
20
29
  'descriptionStyle',
21
30
  'titleStyle',
22
31
  'textStyle',
23
32
  ];
33
+ const AI_ALLOWED_FIELD_NAMES = ['description', 'title', 'text', 'paragraph'];
24
34
  const RTE_DISALLOWED_FIELD_NAMES = ['buttonText'];
25
35
  export default defineComponent({
26
36
  props: {
@@ -50,6 +60,8 @@ export default defineComponent({
50
60
  const uiStore = useUiStore();
51
61
  const sideBarStore = useUiSideBarStore();
52
62
  const pageSettingsStore = useUiPageSettingsStore();
63
+ const brandPageContainerStore = useBrandPageContainerStore();
64
+ const snapshotStore = useSnapshotStore();
53
65
  const uiLogoSettingsStore = useUiLogoSettingsStore();
54
66
  return {
55
67
  getFieldSettings: computed(() => contentSettingsStore.getFieldSettings),
@@ -57,10 +69,12 @@ export default defineComponent({
57
69
  getValue: computed(() => contentSettingsStore.getValue),
58
70
  brandPageData: computed(() => brandPageMakerStore.brandPageData),
59
71
  isAdmin: computed(() => userStore.isAdmin),
72
+ isDesignCom: computed(() => brandPageContainerStore.isDesignCom),
60
73
  canUseRichTextEditor: computed(() => userStore.features.canUseRichTextEditor),
61
74
  brandPageType: computed(() => brandPageMakerStore.brandPageType),
62
75
  isBrandPageOrIsBrandContact: computed(() => brandPageMakerStore.isBrandPageOrIsBrandContact),
63
76
  logoTheme: computed(() => uiStore.logoTheme),
77
+ snapshotBase64: computed(() => snapshotStore.snapshotBase64),
64
78
  contentSettingsStore,
65
79
  brandPageMakerStore,
66
80
  userStore,
@@ -72,6 +86,7 @@ export default defineComponent({
72
86
  },
73
87
  data: () => ({
74
88
  isToggled: true,
89
+ richTextEditorKey: 0,
75
90
  }),
76
91
  computed: {
77
92
  content() {
@@ -175,6 +190,19 @@ export default defineComponent({
175
190
  disableTransparent() {
176
191
  return this.field.disableTransparent || false;
177
192
  },
193
+ generateText() {
194
+ return commonTr('generateText');
195
+ },
196
+ showGenerateText() {
197
+ return (AI_ALLOWED_SECTION_TYPES.includes(this.type) &&
198
+ AI_ALLOWED_FIELD_NAMES.includes(this.fieldName));
199
+ },
200
+ plainTextValue() {
201
+ const plainText = getPlainTextFromRTE(this.value);
202
+ if (isDefaultContentText(plainText))
203
+ return '';
204
+ return plainText;
205
+ },
178
206
  },
179
207
  watch: {
180
208
  fieldType() {
@@ -242,6 +270,18 @@ export default defineComponent({
242
270
  onToggleStateChange(isToggled) {
243
271
  this.isToggled = isToggled;
244
272
  },
273
+ onUseGeneratedText(generatedText) {
274
+ let formattedText = generatedText;
275
+ if (this.showRichTextEditor && typeof this.value === 'string') {
276
+ formattedText = replaceTextInRTE(this.value, generatedText);
277
+ }
278
+ this.contentSettingsStore.updateItemValue({
279
+ id: this.id,
280
+ name: this.fieldName,
281
+ value: formattedText,
282
+ });
283
+ this.richTextEditorKey = this.richTextEditorKey + 1;
284
+ },
245
285
  clearFieldValue() {
246
286
  const fieldType = this.field.defaultValue;
247
287
  if (typeof fieldType === 'string') {
@@ -252,5 +292,8 @@ export default defineComponent({
252
292
  });
253
293
  }
254
294
  },
295
+ onCaptureSnapshot() {
296
+ this.$emit('capture-preview-snapshot');
297
+ },
255
298
  },
256
299
  });
@@ -469,6 +469,7 @@ declare const _default: import("vue").DefineComponent<{}, {
469
469
  personalisationRole(): PersonalisationRole | undefined;
470
470
  }, {
471
471
  onBackClick(): void;
472
+ onCaptureSnapshotBeforeModal(): void;
472
473
  onToggleGroupCollapseClick(groupId: string): void;
473
474
  onPersonalisationRoleChange(payload: UpdateItemValuePayload<PersonalisationRole | undefined>): void;
474
475
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -164,6 +164,9 @@ export default defineComponent({
164
164
  eventSource: UI_EVENT_SOURCES.contentSettings,
165
165
  });
166
166
  },
167
+ onCaptureSnapshotBeforeModal() {
168
+ this.$emit('capture-preview-snapshot');
169
+ },
167
170
  onToggleGroupCollapseClick(groupId) {
168
171
  if (!this.id) {
169
172
  return;
@@ -28,7 +28,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
28
28
  type: PropType<Content>;
29
29
  required: true;
30
30
  };
31
- }>, {}, {
31
+ isDesignCom: {
32
+ type: BooleanConstructor;
33
+ required: false;
34
+ default: boolean;
35
+ };
36
+ }>, {
37
+ snapshotBase64: import("vue").ComputedRef<string | null>;
38
+ }, {
32
39
  changeDebounce: DebounceHandle | undefined;
33
40
  options: TestimonialItems[];
34
41
  isEmpty: boolean[];
@@ -58,7 +65,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
58
65
  name: string;
59
66
  value: string;
60
67
  }, index: number): void;
61
- }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "on-intent-image-replace")[], "update:modelValue" | "on-intent-image-replace", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
68
+ getPlainTextValue(index: number): string;
69
+ onUseGeneratedText(generatedText: string, index: number): void;
70
+ onCaptureSnapshot(): void;
71
+ }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "capture-preview-snapshot" | "on-intent-image-replace")[], "update:modelValue" | "capture-preview-snapshot" | "on-intent-image-replace", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
62
72
  id: {
63
73
  type: StringConstructor;
64
74
  required: true;
@@ -83,8 +93,16 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
83
93
  type: PropType<Content>;
84
94
  required: true;
85
95
  };
96
+ isDesignCom: {
97
+ type: BooleanConstructor;
98
+ required: false;
99
+ default: boolean;
100
+ };
86
101
  }>> & Readonly<{
87
102
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
88
103
  "onOn-intent-image-replace"?: ((...args: any[]) => any) | undefined;
89
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
104
+ "onCapture-preview-snapshot"?: ((...args: any[]) => any) | undefined;
105
+ }>, {
106
+ isDesignCom: boolean;
107
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
90
108
  export default _default;
@@ -1,7 +1,10 @@
1
- import { defineComponent } from 'vue';
1
+ import { defineComponent, computed } from 'vue';
2
2
  import { EMPTY_TESTIMONIAL, MAX_DESCRIPTION_LENGTH, MAX_LENGTH_ERROR_MESSAGE, MAX_TITLE_LENGTH, } from '../../../../brand-page';
3
3
  import debounce from 'lodash.debounce';
4
4
  import cloneDeep from 'lodash.clonedeep';
5
+ import { useSnapshotStore } from '../../../../brand-page-maker/stores';
6
+ import { getPlainTextFromRTE } from '../../../../brand-page-maker/utils';
7
+ import { isDefaultContentText } from '../../utils';
5
8
  const DEBOUNCE_IN_MS = 250;
6
9
  export default defineComponent({
7
10
  props: {
@@ -29,8 +32,23 @@ export default defineComponent({
29
32
  type: Object,
30
33
  required: true,
31
34
  },
35
+ isDesignCom: {
36
+ type: Boolean,
37
+ required: false,
38
+ default: false,
39
+ },
40
+ },
41
+ setup() {
42
+ const snapshotStore = useSnapshotStore();
43
+ return {
44
+ snapshotBase64: computed(() => snapshotStore.snapshotBase64),
45
+ };
32
46
  },
33
- emits: ['update:modelValue', 'on-intent-image-replace'],
47
+ emits: [
48
+ 'update:modelValue',
49
+ 'on-intent-image-replace',
50
+ 'capture-preview-snapshot',
51
+ ],
34
52
  data: () => ({
35
53
  changeDebounce: undefined,
36
54
  options: [],
@@ -139,5 +157,24 @@ export default defineComponent({
139
157
  this.options[index][payload.name] = payload.value;
140
158
  this.emitChange();
141
159
  },
160
+ getPlainTextValue(index) {
161
+ const text = this.options[index]?.testimonials || '';
162
+ const plainText = getPlainTextFromRTE(text);
163
+ if (isDefaultContentText(plainText)) {
164
+ return '';
165
+ }
166
+ return plainText;
167
+ },
168
+ onUseGeneratedText(generatedText, index) {
169
+ // Update the testimonial text
170
+ this.options[index].testimonials = generatedText;
171
+ this.isModified[index] = true;
172
+ this.isEmpty[index] = false;
173
+ // Emit the change
174
+ this.emitChange();
175
+ },
176
+ onCaptureSnapshot() {
177
+ this.$emit('capture-preview-snapshot');
178
+ },
142
179
  },
143
180
  });
@@ -37,11 +37,19 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
37
37
  required: false;
38
38
  default: undefined;
39
39
  };
40
- }>, {}, {
40
+ isDesignCom: {
41
+ type: BooleanConstructor;
42
+ required: false;
43
+ default: boolean;
44
+ };
45
+ }>, {
46
+ snapshotBase64: import("vue").ComputedRef<string | null>;
47
+ }, {
41
48
  changeDebounce: DebounceHandle | undefined;
42
49
  options: TextItem[];
43
50
  isEmpty: boolean[];
44
51
  isModified: boolean[];
52
+ textAreaKeys: number[];
45
53
  maxTextLength: number;
46
54
  textEmptyErrorMessage: any;
47
55
  textMaxLengthErrorMessage: any;
@@ -70,7 +78,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
70
78
  name: string;
71
79
  value: string;
72
80
  }, index: number): void;
73
- }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:model-value"[], "update:model-value", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
81
+ onUseGeneratedText(generatedText: string, index: number): void;
82
+ getPlainTextValue(index: number): string;
83
+ onCaptureSnapshot(): void;
84
+ }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("capture-preview-snapshot" | "update:model-value")[], "capture-preview-snapshot" | "update:model-value", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
74
85
  id: {
75
86
  type: StringConstructor;
76
87
  required: true;
@@ -105,9 +116,16 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
105
116
  required: false;
106
117
  default: undefined;
107
118
  };
119
+ isDesignCom: {
120
+ type: BooleanConstructor;
121
+ required: false;
122
+ default: boolean;
123
+ };
108
124
  }>> & Readonly<{
109
125
  "onUpdate:model-value"?: ((...args: any[]) => any) | undefined;
126
+ "onCapture-preview-snapshot"?: ((...args: any[]) => any) | undefined;
110
127
  }>, {
128
+ isDesignCom: boolean;
111
129
  contentType: string;
112
130
  showRichTextEditor: boolean;
113
131
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -1,8 +1,11 @@
1
- import { defineComponent } from 'vue';
1
+ import { defineComponent, computed } from 'vue';
2
2
  import { FONT_SIZE_BODY, MAX_LENGTH_ERROR_MESSAGE, MAX_TEXT_LENGTH, TEXT_EMPTY, TEXT_STYLE_TYPES, } from '../../../../brand-page';
3
3
  import debounce from 'lodash.debounce';
4
4
  import cloneDeep from 'lodash.clonedeep';
5
5
  import { escapeContentText } from '../../../../brand-page/utils';
6
+ import { useSnapshotStore } from '../../../../brand-page-maker/stores';
7
+ import { getPlainTextFromRTE, replaceTextInRTE, } from '../../../../brand-page-maker/utils';
8
+ import { isDefaultContentText } from '../../utils';
6
9
  const DEBOUNCE_IN_MS = 250;
7
10
  export default defineComponent({
8
11
  props: {
@@ -40,13 +43,25 @@ export default defineComponent({
40
43
  required: false,
41
44
  default: undefined,
42
45
  },
46
+ isDesignCom: {
47
+ type: Boolean,
48
+ required: false,
49
+ default: false,
50
+ },
51
+ },
52
+ setup() {
53
+ const snapshotStore = useSnapshotStore();
54
+ return {
55
+ snapshotBase64: computed(() => snapshotStore.snapshotBase64),
56
+ };
43
57
  },
44
- emits: ['update:model-value'],
58
+ emits: ['update:model-value', 'capture-preview-snapshot'],
45
59
  data: () => ({
46
60
  changeDebounce: undefined,
47
61
  options: [],
48
62
  isEmpty: [],
49
63
  isModified: [],
64
+ textAreaKeys: [],
50
65
  maxTextLength: MAX_TEXT_LENGTH,
51
66
  textEmptyErrorMessage: TEXT_EMPTY(),
52
67
  textMaxLengthErrorMessage: MAX_LENGTH_ERROR_MESSAGE(),
@@ -54,6 +69,7 @@ export default defineComponent({
54
69
  }),
55
70
  async created() {
56
71
  this.options = cloneDeep(this.value);
72
+ this.textAreaKeys = new Array(this.options.length).fill(0);
57
73
  if (!this.changeDebounce) {
58
74
  this.changeDebounce = debounce(this.emitChange, DEBOUNCE_IN_MS);
59
75
  }
@@ -137,6 +153,29 @@ export default defineComponent({
137
153
  this.options[index][payload.name] = payload.value;
138
154
  this.emitChange();
139
155
  },
156
+ onUseGeneratedText(generatedText, index) {
157
+ // Format text for rich text editor if enabled
158
+ const formattedText = this.showRichTextEditor
159
+ ? replaceTextInRTE(this.options[index].text, generatedText)
160
+ : generatedText;
161
+ // Update data
162
+ this.options[index].text = formattedText;
163
+ this.isModified[index] = true;
164
+ this.textAreaKeys[index] = (this.textAreaKeys[index] || 0) + 1;
165
+ // Notify parent
166
+ this.emitChange();
167
+ },
168
+ getPlainTextValue(index) {
169
+ const text = this.options[index]?.text || '';
170
+ const plainText = getPlainTextFromRTE(text);
171
+ if (isDefaultContentText(plainText)) {
172
+ return '';
173
+ }
174
+ return plainText;
175
+ },
176
+ onCaptureSnapshot() {
177
+ this.$emit('capture-preview-snapshot');
178
+ },
140
179
  },
141
180
  watch: {
142
181
  options: {
@@ -5,3 +5,4 @@ export declare function isUpdateItemValuePayload<T>(payload: UpdateItemValuePayl
5
5
  export declare const getContentSettingsTemplate: (type: ContentType) => ContentSettingsConfig<any> | null;
6
6
  export declare const getContentSettingDisplayName: (template: ContentSettingsConfig<any> | null | undefined) => string;
7
7
  export declare const getContentSettingsFields: (id: string, template: ContentSettingsConfig<any>, getValue: (id: string, fieldName: string) => Content | string | undefined) => Field[];
8
+ export declare const isDefaultContentText: (text: string) => boolean;
@@ -1,5 +1,6 @@
1
1
  import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
2
2
  import { CONTENT_SETTINGS_CONFIGS } from '../../brand-page-maker/constants';
3
+ import { contentSettingsTr } from '../../composables/useTranslate';
3
4
  export function isUpdateItemValuePayload(payload) {
4
5
  return !(!payload || !payload.id || !payload.name || !payload.value);
5
6
  }
@@ -41,3 +42,8 @@ export const getContentSettingsFields = (id, template, getValue) => {
41
42
  .filter((field) => field.shouldRender !== false)
42
43
  .filter((field) => !hiddenFields.find((f) => f == field.name));
43
44
  };
45
+ export const isDefaultContentText = (text) => {
46
+ return (text === contentSettingsTr(`thisIsABannerTitle`) ||
47
+ text === contentSettingsTr(`aboutSectionTitle`) ||
48
+ text === contentSettingsTr(`defaultTextValue`));
49
+ };
@@ -457,7 +457,6 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
457
457
  getBusinessName(): string | undefined;
458
458
  hasPurchasedDomains(): boolean;
459
459
  isActiveDomain(): boolean;
460
- showUpsellRotation(): boolean;
461
460
  }, {
462
461
  closeModal(): void;
463
462
  onCopyUrlClicked(): void;
@@ -133,10 +133,6 @@ export default defineComponent({
133
133
  this.brandPageContainerStore.customDomain.status ===
134
134
  CUSTOM_DOMAIN_STATUSES.active);
135
135
  },
136
- showUpsellRotation() {
137
- return (this.abTests.bp_4092_rotating_upsells_at_publish &&
138
- this.abTests.bp_4092_rotating_upsells_at_publish.isVariation);
139
- },
140
136
  },
141
137
  watch: {
142
138
  customDomain(newCustomDomain) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "5.16.3",
4
+ "version": "5.16.4-abtest-1",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@ckpack/vue-color": "1.4.1",
58
- "@designcrowd/fe-shared-lib": "1.4.3",
58
+ "@designcrowd/fe-shared-lib": "1.5.0",
59
59
  "@pinia/nuxt": "0.11.0",
60
60
  "@storybook/react": "9.0.4",
61
61
  "@tiptap/extension-bubble-menu": "^2.14.0",
@@ -48,14 +48,15 @@ export interface AbTestResult {
48
48
 
49
49
  const AB_TEST_KEYS = {
50
50
  BP_3926_FREEMIUM_WATERMARK: 'bc-bp-3926-freemium-cta-in-website-editor',
51
- BP_4092_ROTATING_UPSELLS_AT_PUBLISH:
52
- 'bc-bp-4092-rotating-upsells-at-website-publish',
51
+ BP_4572_AI_TEXT_GENERATION_POST_PURCHASE:
52
+ 'bc-bp-4572-ai-text-generation-post-purchase',
53
53
  };
54
54
 
55
55
  export interface AbTest {
56
56
  bp_3926_freemium_watermark?: AbTestResult;
57
- bp_4092_rotating_upsells_at_publish?: AbTestResult;
57
+ bp_4572_ai_text_generation_post_purchase?: AbTestResult;
58
58
  }
59
+
59
60
  export const MEDIA_SIZES = {
60
61
  size1x: 'size1x',
61
62
  size2x: 'size2x',
@@ -125,5 +126,14 @@ export const getAbTestResults = (
125
126
  );
126
127
  }
127
128
 
129
+ // AB Test for BP-4572 - AI Text Generation Post Purchase
130
+
131
+ if (abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE]) {
132
+ abTests.bp_4572_ai_text_generation_post_purchase = getValueType(
133
+ AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE,
134
+ abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE],
135
+ );
136
+ }
137
+
128
138
  return abTests;
129
139
  };
@@ -32,6 +32,7 @@ import {
32
32
  useBrandPageMakerUserStore,
33
33
  useLocalisedRouteStore,
34
34
  useUiStore,
35
+ useSnapshotStore,
35
36
  useVideoStore,
36
37
  } from '../../stores';
37
38
  import type { AdminPreviewLogoTemplateModel } from '../../stores/admin-logo-settings';
@@ -47,6 +48,7 @@ import { useProductConfigStore } from '../../../brand-page-maker/stores/product-
47
48
  import type { UpdateItemValuePayload } from '../../../shared/content-settings/models';
48
49
  import { UPGRADE_CTA_LOCATIONS } from '../../composables/useEventTracker';
49
50
  import { commonTr } from '../../../composables/useTranslate';
51
+ import { useSnapshot } from '../../../composables/useSnapshot';
50
52
 
51
53
  export interface BrandPageMakerViewModel {
52
54
  adminPreviewLogoTemplateModels?: AdminPreviewLogoTemplateModel[];
@@ -87,6 +89,8 @@ export default defineComponent({
87
89
  const productSettingStore = useProductConfigStore();
88
90
  const router = useRouter();
89
91
  const localisedRouteStore = useLocalisedRouteStore();
92
+ const snapshotStore = useSnapshotStore();
93
+ const { captureSnapshot } = useSnapshot();
90
94
  const videoStore = useVideoStore();
91
95
 
92
96
  return {
@@ -145,6 +149,8 @@ export default defineComponent({
145
149
  shopSettingStore,
146
150
  productSettingStore,
147
151
  router,
152
+ snapshotStore,
153
+ captureSnapshot,
148
154
  videoStore,
149
155
  };
150
156
  },
@@ -160,6 +166,9 @@ export default defineComponent({
160
166
  previewContainer(): any {
161
167
  return this.$refs.previewContainer;
162
168
  },
169
+ previewContent(): any {
170
+ return this.$refs.previewContent;
171
+ },
163
172
  },
164
173
  async created() {
165
174
  if (
@@ -305,6 +314,28 @@ export default defineComponent({
305
314
  }
306
315
  },
307
316
 
317
+ async handleCaptureSnapshot() {
318
+ if (!this.previewContent) {
319
+ return;
320
+ }
321
+
322
+ this.snapshotStore.setIsCapturing(true);
323
+
324
+ try {
325
+ const snapshot = await this.captureSnapshot(this.previewContent);
326
+
327
+ if (snapshot) {
328
+ this.snapshotStore.setBase64Snapshot(snapshot);
329
+ } else {
330
+ console.warn('⚠️ Snapshot capture returned null');
331
+ }
332
+ } catch (error) {
333
+ console.error('❌ Failed to capture snapshot:', error);
334
+ } finally {
335
+ this.snapshotStore.setIsCapturing(false);
336
+ }
337
+ },
338
+
308
339
  onResizeWithDebounce() {
309
340
  if (this.debounceOnResize) {
310
341
  this.debounceOnResize();
@@ -61,7 +61,7 @@
61
61
  :has-quick-links="isPublished"
62
62
  :container="previewContainer"
63
63
  >
64
- <div class="tw-h-full">
64
+ <div ref="previewContent" class="tw-h-full">
65
65
  <PreviewWithState :device-mode="deviceMode" />
66
66
  </div>
67
67
  </Device>
@@ -101,6 +101,7 @@
101
101
  <component
102
102
  :is="selectedTabName"
103
103
  v-if="selectedTabName !== 'Preview'"
104
+ @capture-preview-snapshot="handleCaptureSnapshot"
104
105
  />
105
106
  </template>
106
107
  </SideBar>