@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.
- package/lib/src/{CreatedOnBrandCrowd-de-de-BVouwZJN.js → CreatedOnBrandCrowd-de-de-DQc3IjpR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-Dtx-1uWO.js → CreatedOnBrandCrowd-en-us-CIgIJjzf.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-CmlnW8oC.js → CreatedOnBrandCrowd-es-es-C4JLISvP.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-C95ioWzr.js → CreatedOnBrandCrowd-fr-ca-DPpWX0aJ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-C95ioWzr.js → CreatedOnBrandCrowd-fr-fr-DPpWX0aJ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-C_5SiaiE.js → CreatedOnBrandCrowd-pt-br-DmKD5o2o.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-C_5SiaiE.js → CreatedOnBrandCrowd-pt-pt-DmKD5o2o.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-BP4saQXn.js → CreatedOnDcom-de-de-DhALOqwz.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-B8Taru6f.js → CreatedOnDcom-en-us-LmejZqTn.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-Bo3JhWwd.js → CreatedOnDcom-es-es-D3ZH5JD5.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-CDk3ZAHU.js → CreatedOnDcom-fr-ca-BUOMh8kU.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-CD04W_hw.js → CreatedOnDcom-fr-fr-CNc-56QW.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-B2DGv1qj.js → CreatedOnDcom-pt-br-BGvy2ON7.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-TYqvgQ08.js → CreatedOnDcom-pt-pt-FaVxQHpN.js} +1 -1
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +1 -1
- package/lib/src/brand-page/models/brand-page-context.model.js +5 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +30 -1
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +0 -12
- package/lib/src/brand-page-maker/stores/index.d.ts +1 -0
- package/lib/src/brand-page-maker/stores/index.js +1 -0
- package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.d.ts +14 -0
- package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.js +21 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +2 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +117 -0
- package/lib/src/bundled-translations-Dw3XtNmX.js +163 -0
- package/lib/src/bundled-translations.de-DE-B82Ik9M7.js +163 -0
- package/lib/src/bundled-translations.es-ES-cf3pdNuN.js +163 -0
- package/lib/src/bundled-translations.fr-CA-DP44EcAZ.js +163 -0
- package/lib/src/bundled-translations.fr-FR-V0Zt25kg.js +163 -0
- package/lib/src/bundled-translations.pt-BR-Brv6rCss.js +163 -0
- package/lib/src/bundled-translations.pt-PT-BTgscCTG.js +163 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +15 -1
- package/lib/src/bundles/bundled-translations.es-ES.json +15 -1
- package/lib/src/bundles/bundled-translations.fr-CA.json +15 -1
- package/lib/src/bundles/bundled-translations.fr-FR.json +15 -1
- package/lib/src/bundles/bundled-translations.json +15 -1
- package/lib/src/bundles/bundled-translations.pt-BR.json +15 -1
- package/lib/src/bundles/bundled-translations.pt-PT.json +15 -1
- package/lib/src/clients/brand-page-client.d.ts +0 -4
- package/lib/src/clients/design-template-client.d.ts +2 -0
- package/lib/src/clients/design-template-client.js +33 -0
- package/lib/src/composables/useSnapshot.d.ts +5 -0
- package/lib/src/composables/useSnapshot.js +74 -0
- package/lib/src/composables/useTranslate.d.ts +2 -1
- package/lib/src/composables/useTranslate.js +2 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +149 -8
- package/lib/src/css/library.brand-page-brandPage.min.css +136 -8
- package/lib/src/css/library.brand-page-designCom.min.css +149 -8
- package/lib/src/css/library.brand-page-preview.min.css +133 -8
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-3sE17Ltm.js → lib-CqA2Cr9V.js} +20353 -19606
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -0
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +3 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +6 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +8 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +44 -1
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +1 -0
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +3 -0
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +21 -3
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +39 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +20 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +41 -2
- package/lib/src/shared/content-settings/utils.d.ts +1 -0
- package/lib/src/shared/content-settings/utils.js +6 -0
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +0 -1
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -4
- package/package.json +2 -2
- package/src/brand-page/models/brand-page-context.model.ts +13 -3
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +31 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +2 -1
- package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +0 -36
- package/src/brand-page-maker/stores/index.ts +1 -0
- package/src/brand-page-maker/stores/snapshot/snapshot-store.ts +31 -0
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +154 -0
- package/src/bundles/bundled-translations.de-DE.json +15 -1
- package/src/bundles/bundled-translations.es-ES.json +15 -1
- package/src/bundles/bundled-translations.fr-CA.json +15 -1
- package/src/bundles/bundled-translations.fr-FR.json +15 -1
- package/src/bundles/bundled-translations.json +15 -1
- package/src/bundles/bundled-translations.pt-BR.json +15 -1
- package/src/bundles/bundled-translations.pt-PT.json +15 -1
- package/src/clients/brand-page-client.ts +0 -4
- package/src/clients/design-template-client.ts +57 -0
- package/src/composables/useSnapshot.ts +97 -0
- package/src/composables/useTranslate.ts +3 -0
- package/src/shared/common/i18n/common.de-DE.json +5 -1
- package/src/shared/common/i18n/common.es-ES.json +5 -1
- package/src/shared/common/i18n/common.fr-CA.json +5 -1
- package/src/shared/common/i18n/common.fr-FR.json +5 -1
- package/src/shared/common/i18n/common.json +5 -1
- package/src/shared/common/i18n/common.pt-BR.json +5 -1
- package/src/shared/common/i18n/common.pt-PT.json +5 -1
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +3 -0
- package/src/shared/content-settings/components/content-settings/ContentSettings.vue +2 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +8 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.vue +1 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +54 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +20 -2
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +3 -1
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.vue +1 -0
- package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +95 -0
- package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +500 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.de-DE.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.es-ES.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-CA.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-FR.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-BR.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-PT.json +12 -0
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +44 -2
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +15 -3
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +52 -2
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +16 -3
- package/src/shared/content-settings/utils.ts +9 -0
- package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -6
- package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.vue +1 -1
- package/lib/src/bundled-translations-D9iHE5G9.js +0 -161
- package/lib/src/bundled-translations.de-DE-DW3iDx_G.js +0 -161
- package/lib/src/bundled-translations.es-ES-C9I8wDyq.js +0 -161
- package/lib/src/bundled-translations.fr-CA-C0NN8DsO.js +0 -161
- package/lib/src/bundled-translations.fr-FR-oKV5NyE1.js +0 -161
- package/lib/src/bundled-translations.pt-BR-CTvCfv1X.js +0 -161
- package/lib/src/bundled-translations.pt-PT-CbwxwRY1.js +0 -161
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
const HTML2CANVAS_CDN_URL =
|
|
4
|
+
'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js';
|
|
5
|
+
|
|
6
|
+
let html2canvasLoadPromise: Promise<void> | null = null;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Dynamically loads html2canvas from CDN if not already loaded
|
|
10
|
+
*/
|
|
11
|
+
function loadHtml2Canvas(): Promise<void> {
|
|
12
|
+
// If already loaded, return immediately
|
|
13
|
+
if (typeof window.html2canvas !== 'undefined') {
|
|
14
|
+
return Promise.resolve();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// If already loading, return the existing promise
|
|
18
|
+
if (html2canvasLoadPromise) {
|
|
19
|
+
return html2canvasLoadPromise;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Create new load promise
|
|
23
|
+
html2canvasLoadPromise = new Promise((resolve, reject) => {
|
|
24
|
+
const script = document.createElement('script');
|
|
25
|
+
|
|
26
|
+
script.src = HTML2CANVAS_CDN_URL;
|
|
27
|
+
script.async = true;
|
|
28
|
+
|
|
29
|
+
script.onload = () => {
|
|
30
|
+
console.log('✅ html2canvas loaded successfully from CDN');
|
|
31
|
+
resolve();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
script.onerror = () => {
|
|
35
|
+
console.error('❌ Failed to load html2canvas from CDN');
|
|
36
|
+
html2canvasLoadPromise = null; // Reset so we can retry
|
|
37
|
+
reject(new Error('Failed to load html2canvas'));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
document.head.appendChild(script);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return html2canvasLoadPromise;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function useSnapshot() {
|
|
47
|
+
const isCapturing = ref(false);
|
|
48
|
+
const lastSnapshot = ref<string | null>(null);
|
|
49
|
+
|
|
50
|
+
const captureSnapshot = async (
|
|
51
|
+
element: HTMLElement | null,
|
|
52
|
+
): Promise<string | null> => {
|
|
53
|
+
if (!element) {
|
|
54
|
+
console.error('No element provided for snapshot');
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
isCapturing.value = true;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
// Dynamically load html2canvas if not already loaded
|
|
63
|
+
await loadHtml2Canvas();
|
|
64
|
+
|
|
65
|
+
// Double-check it's loaded
|
|
66
|
+
if (typeof window.html2canvas === 'undefined') {
|
|
67
|
+
throw new Error('html2canvas failed to load');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const canvas = await window.html2canvas(element, {
|
|
71
|
+
allowTaint: true,
|
|
72
|
+
useCORS: true,
|
|
73
|
+
scale: 0.5, // Reduce quality to decrease file size
|
|
74
|
+
logging: false,
|
|
75
|
+
backgroundColor: '#ffffff',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const base64Image = canvas.toDataURL('image/jpeg', 0.8); // Use JPEG with 80% quality for smaller size
|
|
79
|
+
|
|
80
|
+
lastSnapshot.value = base64Image;
|
|
81
|
+
|
|
82
|
+
return base64Image;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('Error capturing snapshot:', error);
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
} finally {
|
|
88
|
+
isCapturing.value = false;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
captureSnapshot,
|
|
94
|
+
isCapturing,
|
|
95
|
+
lastSnapshot,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -206,6 +206,8 @@ const logoSwitchConfirmationModalTr = (key, valuesToInterpolate = {}) =>
|
|
|
206
206
|
tr(`logoSwitchConfirmationModal.${key}`, valuesToInterpolate);
|
|
207
207
|
const logoTemplateSearchModalTr = (key, valuesToInterpolate = {}) =>
|
|
208
208
|
tr(`logoTemplateSearchModal.${key}`, valuesToInterpolate);
|
|
209
|
+
const generateAiModalTr = (key, valuesToInterpolate = {}) =>
|
|
210
|
+
tr(`aiModal.${key}`, valuesToInterpolate);
|
|
209
211
|
|
|
210
212
|
const currentLocale = (): LocaleTypes => {
|
|
211
213
|
const i18 = getI18NextInstance();
|
|
@@ -303,4 +305,5 @@ export {
|
|
|
303
305
|
videoLibraryTr,
|
|
304
306
|
logoSwitchConfirmationModalTr,
|
|
305
307
|
logoTemplateSearchModalTr,
|
|
308
|
+
generateAiModalTr,
|
|
306
309
|
};
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Ersetzen",
|
|
38
38
|
"save" : "Speichern",
|
|
39
39
|
"remove" : "Entfernen",
|
|
40
|
+
"copy" : "Kopieren",
|
|
41
|
+
"sendButtonText" : "Senden",
|
|
42
|
+
"regenerateText" : "Regenerieren",
|
|
40
43
|
"addShapeLabel" : "Form hinzufügen",
|
|
41
44
|
"addImageLabel" : "Bild hinzufügen",
|
|
42
45
|
"addFaviconLabel" : "Favicon hinzufügen",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Weiter",
|
|
53
56
|
"defaultSaveDescription" : "Vergessen Sie nicht, Ihre Änderungen zu veröffentlichen, sobald Sie mit Ihrem Design zufrieden sind.",
|
|
54
57
|
"saveSuccess" : "Gespeichert!",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Wenn Sie die Vorlagen ändern, gehen Ihre Änderungen verloren. Alle Ihre Inhalte werden gelöscht. Wir empfehlen Ihnen, Ihre Website vorher zu duplizieren, wenn Sie Ihre Änderungen beibehalten möchten."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Wenn Sie die Vorlagen ändern, gehen Ihre Änderungen verloren. Alle Ihre Inhalte werden gelöscht. Wir empfehlen Ihnen, Ihre Website vorher zu duplizieren, wenn Sie Ihre Änderungen beibehalten möchten.",
|
|
59
|
+
"generateText" : "Text generieren"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Sustituir",
|
|
38
38
|
"save" : "Guardar",
|
|
39
39
|
"remove" : "Eliminar",
|
|
40
|
+
"copy" : "Copiar",
|
|
41
|
+
"sendButtonText" : "Enviar",
|
|
42
|
+
"regenerateText" : "Volver a generar",
|
|
40
43
|
"addShapeLabel" : "Añadir forma",
|
|
41
44
|
"addImageLabel" : "Añadir imagen",
|
|
42
45
|
"addFaviconLabel" : "Añadir favicon",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Continuar",
|
|
53
56
|
"defaultSaveDescription" : "No olvides publicar los cambios una vez que tengas un diseño que te guste.",
|
|
54
57
|
"saveSuccess" : "¡Se ha guardado correctamente!",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Cambiar las plantillas hará que pierdas los cambios. Se borrará todo el contenido. Te recomendamos que hagas un duplicado de tu sitio web de antemano si quieres conservar los cambios."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Cambiar las plantillas hará que pierdas los cambios. Se borrará todo el contenido. Te recomendamos que hagas un duplicado de tu sitio web de antemano si quieres conservar los cambios.",
|
|
59
|
+
"generateText" : "Generar texto"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Remplacer",
|
|
38
38
|
"save" : "Enregistrer",
|
|
39
39
|
"remove" : "Supprimer",
|
|
40
|
+
"copy" : "Copier",
|
|
41
|
+
"sendButtonText" : "Envoyer",
|
|
42
|
+
"regenerateText" : "Régénérer",
|
|
40
43
|
"addShapeLabel" : "Ajouter une forme",
|
|
41
44
|
"addImageLabel" : "Ajouter une image",
|
|
42
45
|
"addFaviconLabel" : "Ajouter un favicon",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Continuer",
|
|
53
56
|
"defaultSaveDescription" : "N’oubliez pas de publier vos modifications une fois que votre design vous convient.",
|
|
54
57
|
"saveSuccess" : "Enregistrement réussi!",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Si vous changez de modèle, vous perdrez vos modifications et tout votre contenu sera effacé. Nous vous recommandons de dupliquer votre site au préalable si vous souhaitez conserver vos modifications."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Si vous changez de modèle, vous perdrez vos modifications et tout votre contenu sera effacé. Nous vous recommandons de dupliquer votre site au préalable si vous souhaitez conserver vos modifications.",
|
|
59
|
+
"generateText" : "Générer du texte"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Remplacer",
|
|
38
38
|
"save" : "Enregistrer",
|
|
39
39
|
"remove" : "Supprimer",
|
|
40
|
+
"copy" : "Copier",
|
|
41
|
+
"sendButtonText" : "Envoyer",
|
|
42
|
+
"regenerateText" : "Régénérer",
|
|
40
43
|
"addShapeLabel" : "Ajouter une forme",
|
|
41
44
|
"addImageLabel" : "Ajouter une image",
|
|
42
45
|
"addFaviconLabel" : "Ajouter un favicon",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Continuer",
|
|
53
56
|
"defaultSaveDescription" : "N’oubliez pas de publier vos modifications une fois que votre design vous convient.",
|
|
54
57
|
"saveSuccess" : "Enregistrement réussi !",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Si vous changez de modèle, vous perdrez vos modifications et tout votre contenu sera effacé. Nous vous recommandons de dupliquer votre site au préalable si vous souhaitez conserver vos modifications."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Si vous changez de modèle, vous perdrez vos modifications et tout votre contenu sera effacé. Nous vous recommandons de dupliquer votre site au préalable si vous souhaitez conserver vos modifications.",
|
|
59
|
+
"generateText" : "Générer du texte"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -42,6 +42,9 @@
|
|
|
42
42
|
"replace": "Replace",
|
|
43
43
|
"save": "Save",
|
|
44
44
|
"remove": "Remove",
|
|
45
|
+
"copy": "Copy",
|
|
46
|
+
"sendButtonText": "Send",
|
|
47
|
+
"regenerateText": "Regenerate",
|
|
45
48
|
"addShapeLabel": "Add Shape",
|
|
46
49
|
"addImageLabel": "Add Image",
|
|
47
50
|
"addFaviconLabel": "Add Favicon",
|
|
@@ -62,6 +65,7 @@
|
|
|
62
65
|
"defaultSaveDescription": "Don’t forget to publish your changes once you are happy with your design.",
|
|
63
66
|
"saveSuccess": "Save successful!",
|
|
64
67
|
|
|
65
|
-
"changeTemplateConfirmationMessage": "Changing templates will cause you to lose your changes. All your content will be erased. We recommend you duplicate your site beforehand if you want to retain your changes."
|
|
68
|
+
"changeTemplateConfirmationMessage": "Changing templates will cause you to lose your changes. All your content will be erased. We recommend you duplicate your site beforehand if you want to retain your changes.",
|
|
69
|
+
"generateText": "Generate text"
|
|
66
70
|
}
|
|
67
71
|
}
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Substituir",
|
|
38
38
|
"save" : "Salvar",
|
|
39
39
|
"remove" : "Remover",
|
|
40
|
+
"copy" : "Copiar",
|
|
41
|
+
"sendButtonText" : "Enviar",
|
|
42
|
+
"regenerateText" : "Regenerar",
|
|
40
43
|
"addShapeLabel" : "Adicionar forma",
|
|
41
44
|
"addImageLabel" : "Adicionar imagem",
|
|
42
45
|
"addFaviconLabel" : "Adicionar favicon",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Continuar",
|
|
53
56
|
"defaultSaveDescription" : "Não se esqueça de publicar as suas alterações quando estiver satisfeito com o seu design.",
|
|
54
57
|
"saveSuccess" : "Salvo com sucesso!",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Se alterar os modelos, você perderá suas alterações. Todo o seu conteúdo será apagado. Recomendamos que duplique seu site previamente caso queira manter suas alterações."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Se alterar os modelos, você perderá suas alterações. Todo o seu conteúdo será apagado. Recomendamos que duplique seu site previamente caso queira manter suas alterações.",
|
|
59
|
+
"generateText" : "Gerar texto"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"replace" : "Substituir",
|
|
38
38
|
"save" : "Guardar",
|
|
39
39
|
"remove" : "Remover",
|
|
40
|
+
"copy" : "Copiar",
|
|
41
|
+
"sendButtonText" : "Enviar",
|
|
42
|
+
"regenerateText" : "Regenerar",
|
|
40
43
|
"addShapeLabel" : "Adicionar forma",
|
|
41
44
|
"addImageLabel" : "Adicionar imagem",
|
|
42
45
|
"addFaviconLabel" : "Adicionar Favicon",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"continue" : "Continuar",
|
|
53
56
|
"defaultSaveDescription" : "Não se esqueça de publicar as suas alterações quando estiver satisfeito com o seu design.",
|
|
54
57
|
"saveSuccess" : "Gravação bem-sucedida!",
|
|
55
|
-
"changeTemplateConfirmationMessage" : "Se alterar os modelos vai perder as suas alterações. Todo o seu conteúdo será apagado. Recomendamos que duplique o seu site previamente caso queira manter as suas alterações."
|
|
58
|
+
"changeTemplateConfirmationMessage" : "Se alterar os modelos vai perder as suas alterações. Todo o seu conteúdo será apagado. Recomendamos que duplique o seu site previamente caso queira manter as suas alterações.",
|
|
59
|
+
"generateText" : "Gerar texto"
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -120,6 +120,9 @@ export default defineComponent({
|
|
|
120
120
|
},
|
|
121
121
|
},
|
|
122
122
|
methods: {
|
|
123
|
+
onCapturePreviewSnapshot() {
|
|
124
|
+
this.$emit('capture-preview-snapshot');
|
|
125
|
+
},
|
|
123
126
|
async onAddContentOptionClicked(option: AddContentOption<any>) {
|
|
124
127
|
const newItem = await this.contentSettingsStore.addItemByType({
|
|
125
128
|
type: option.type,
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
:ref="item.id"
|
|
66
66
|
:type="item.type"
|
|
67
67
|
@on-delete="onDeleteItem({ id: item.id }, item.type)"
|
|
68
|
+
@capture-snapshot-before-modal="onCapturePreviewSnapshot"
|
|
68
69
|
/>
|
|
69
70
|
</template>
|
|
70
71
|
</ReorderableList>
|
|
@@ -131,6 +132,7 @@
|
|
|
131
132
|
<!-- Start of Single Content Item Settings -->
|
|
132
133
|
<FocusedContentItemSettings
|
|
133
134
|
v-if="mode === CONTENT_SETTINGS_MODES.focusedContentItem"
|
|
135
|
+
@capture-preview-snapshot="onCapturePreviewSnapshot"
|
|
134
136
|
/>
|
|
135
137
|
<!-- End of Single Content Item Settings -->
|
|
136
138
|
|
package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts
CHANGED
|
@@ -193,6 +193,14 @@ export default defineComponent({
|
|
|
193
193
|
this.$emit('on-delete');
|
|
194
194
|
},
|
|
195
195
|
|
|
196
|
+
captureSnapshotBeforeModal() {
|
|
197
|
+
this.$emit('capture-snapshot-before-modal');
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
onCaptureSnapshot() {
|
|
201
|
+
this.$emit('capture-preview-snapshot');
|
|
202
|
+
},
|
|
203
|
+
|
|
196
204
|
toggleButtonClick(): void {
|
|
197
205
|
const $sideBarContent = document.querySelector(`#${SIDE_BAR_CONTENT_ID}`);
|
|
198
206
|
|
|
@@ -10,9 +10,11 @@ import { UI_EVENT_SOURCES } from '../../../models';
|
|
|
10
10
|
import { useUiContentSettingsStore } from '../../store';
|
|
11
11
|
import { useUiSideBarStore } from '../../../side-bar/store';
|
|
12
12
|
import {
|
|
13
|
+
useBrandPageContainerStore,
|
|
13
14
|
useBrandPageMakerStore,
|
|
14
15
|
useBrandPageMakerUserStore,
|
|
15
16
|
useUiStore,
|
|
17
|
+
useSnapshotStore,
|
|
16
18
|
} from '../../../../brand-page-maker/stores';
|
|
17
19
|
import { SIDE_BAR_TAB_NAMES } from '../../../../brand-page-maker/constants';
|
|
18
20
|
import {
|
|
@@ -21,6 +23,12 @@ import {
|
|
|
21
23
|
} from '../../../../brand-page-maker/models';
|
|
22
24
|
import { useUiPageSettingsStore } from '../../../page-settings/store';
|
|
23
25
|
import { PAGE_SECTIONS } from '../../../page-settings/models';
|
|
26
|
+
import { commonTr } from '../../../../composables/useTranslate';
|
|
27
|
+
import {
|
|
28
|
+
getPlainTextFromRTE,
|
|
29
|
+
replaceTextInRTE,
|
|
30
|
+
} from '../../../../brand-page-maker/utils';
|
|
31
|
+
import { isDefaultContentText } from '../../utils';
|
|
24
32
|
import { useUiLogoSettingsStore } from '../../../logo-settings/store';
|
|
25
33
|
|
|
26
34
|
const RTE_ALLOWED_SECTION_TYPES = [
|
|
@@ -30,11 +38,18 @@ const RTE_ALLOWED_SECTION_TYPES = [
|
|
|
30
38
|
'images-section',
|
|
31
39
|
'shapes-section',
|
|
32
40
|
];
|
|
41
|
+
const AI_ALLOWED_SECTION_TYPES = [
|
|
42
|
+
'banner-section',
|
|
43
|
+
'text',
|
|
44
|
+
'about-section',
|
|
45
|
+
'testimonials-section',
|
|
46
|
+
];
|
|
33
47
|
const RTE_DISALLOWED_STYLE_FIELD_NAMES = [
|
|
34
48
|
'descriptionStyle',
|
|
35
49
|
'titleStyle',
|
|
36
50
|
'textStyle',
|
|
37
51
|
];
|
|
52
|
+
const AI_ALLOWED_FIELD_NAMES = ['description', 'title', 'text', 'paragraph'];
|
|
38
53
|
const RTE_DISALLOWED_FIELD_NAMES = ['buttonText'];
|
|
39
54
|
|
|
40
55
|
export default defineComponent({
|
|
@@ -65,6 +80,8 @@ export default defineComponent({
|
|
|
65
80
|
const uiStore = useUiStore();
|
|
66
81
|
const sideBarStore = useUiSideBarStore();
|
|
67
82
|
const pageSettingsStore = useUiPageSettingsStore();
|
|
83
|
+
const brandPageContainerStore = useBrandPageContainerStore();
|
|
84
|
+
const snapshotStore = useSnapshotStore();
|
|
68
85
|
const uiLogoSettingsStore = useUiLogoSettingsStore();
|
|
69
86
|
|
|
70
87
|
return {
|
|
@@ -73,6 +90,7 @@ export default defineComponent({
|
|
|
73
90
|
getValue: computed(() => contentSettingsStore.getValue),
|
|
74
91
|
brandPageData: computed(() => brandPageMakerStore.brandPageData),
|
|
75
92
|
isAdmin: computed(() => userStore.isAdmin),
|
|
93
|
+
isDesignCom: computed(() => brandPageContainerStore.isDesignCom),
|
|
76
94
|
canUseRichTextEditor: computed(
|
|
77
95
|
() => userStore.features.canUseRichTextEditor,
|
|
78
96
|
),
|
|
@@ -81,6 +99,7 @@ export default defineComponent({
|
|
|
81
99
|
() => brandPageMakerStore.isBrandPageOrIsBrandContact,
|
|
82
100
|
),
|
|
83
101
|
logoTheme: computed(() => uiStore.logoTheme),
|
|
102
|
+
snapshotBase64: computed(() => snapshotStore.snapshotBase64),
|
|
84
103
|
contentSettingsStore,
|
|
85
104
|
brandPageMakerStore,
|
|
86
105
|
userStore,
|
|
@@ -92,6 +111,7 @@ export default defineComponent({
|
|
|
92
111
|
},
|
|
93
112
|
data: () => ({
|
|
94
113
|
isToggled: true,
|
|
114
|
+
richTextEditorKey: 0,
|
|
95
115
|
}),
|
|
96
116
|
computed: {
|
|
97
117
|
content(): Content {
|
|
@@ -216,6 +236,22 @@ export default defineComponent({
|
|
|
216
236
|
disableTransparent(): boolean {
|
|
217
237
|
return this.field.disableTransparent || false;
|
|
218
238
|
},
|
|
239
|
+
generateText(): string {
|
|
240
|
+
return commonTr('generateText');
|
|
241
|
+
},
|
|
242
|
+
showGenerateText(): boolean {
|
|
243
|
+
return (
|
|
244
|
+
AI_ALLOWED_SECTION_TYPES.includes(this.type) &&
|
|
245
|
+
AI_ALLOWED_FIELD_NAMES.includes(this.fieldName)
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
plainTextValue(): string {
|
|
249
|
+
const plainText = getPlainTextFromRTE(this.value);
|
|
250
|
+
|
|
251
|
+
if (isDefaultContentText(plainText)) return '';
|
|
252
|
+
|
|
253
|
+
return plainText;
|
|
254
|
+
},
|
|
219
255
|
},
|
|
220
256
|
watch: {
|
|
221
257
|
fieldType() {
|
|
@@ -298,6 +334,21 @@ export default defineComponent({
|
|
|
298
334
|
onToggleStateChange(isToggled: boolean) {
|
|
299
335
|
this.isToggled = isToggled;
|
|
300
336
|
},
|
|
337
|
+
onUseGeneratedText(generatedText: string) {
|
|
338
|
+
let formattedText = generatedText;
|
|
339
|
+
|
|
340
|
+
if (this.showRichTextEditor && typeof this.value === 'string') {
|
|
341
|
+
formattedText = replaceTextInRTE(this.value, generatedText);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
this.contentSettingsStore.updateItemValue({
|
|
345
|
+
id: this.id,
|
|
346
|
+
name: this.fieldName,
|
|
347
|
+
value: formattedText,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
this.richTextEditorKey = this.richTextEditorKey + 1;
|
|
351
|
+
},
|
|
301
352
|
clearFieldValue() {
|
|
302
353
|
const fieldType = this.field.defaultValue;
|
|
303
354
|
|
|
@@ -309,5 +360,8 @@ export default defineComponent({
|
|
|
309
360
|
});
|
|
310
361
|
}
|
|
311
362
|
},
|
|
363
|
+
onCaptureSnapshot() {
|
|
364
|
+
this.$emit('capture-preview-snapshot');
|
|
365
|
+
},
|
|
312
366
|
},
|
|
313
367
|
});
|
package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue
CHANGED
|
@@ -16,11 +16,22 @@
|
|
|
16
16
|
'tw-flex tw-w-full tw-mb-4': showToggle,
|
|
17
17
|
}"
|
|
18
18
|
>
|
|
19
|
-
<div class="tw-
|
|
19
|
+
<div class="tw-flex tw-flex-row tw-w-full tw-justify-between">
|
|
20
20
|
<FieldSubHeader
|
|
21
|
-
:class="{
|
|
21
|
+
:class="{
|
|
22
|
+
'tw-mb-2': !showGenerateText || (!field.showToggle && !isInline),
|
|
23
|
+
}"
|
|
22
24
|
:title="field.title"
|
|
23
25
|
/>
|
|
26
|
+
<GenerateAiButton
|
|
27
|
+
v-if="showGenerateText"
|
|
28
|
+
:id="`${id}-${field.name}`"
|
|
29
|
+
:existing-text="plainTextValue"
|
|
30
|
+
:is-design-com="isDesignCom"
|
|
31
|
+
:field-type="field.name"
|
|
32
|
+
@capture-snapshot="onCaptureSnapshot"
|
|
33
|
+
@on-use-text="onUseGeneratedText"
|
|
34
|
+
/>
|
|
24
35
|
</div>
|
|
25
36
|
<Toggle
|
|
26
37
|
v-if="showToggle"
|
|
@@ -33,6 +44,9 @@
|
|
|
33
44
|
:is="`${fieldType}-field`"
|
|
34
45
|
v-show="!showToggle || isToggled"
|
|
35
46
|
:id="id"
|
|
47
|
+
:key="
|
|
48
|
+
showRichTextEditor ? `rte-${id}-${richTextEditorKey}` : `field-${id}`
|
|
49
|
+
"
|
|
36
50
|
:attrs="{
|
|
37
51
|
'data-test-tag': `${displayName.toLowerCase()}-${field.name}`,
|
|
38
52
|
}"
|
|
@@ -63,10 +77,12 @@
|
|
|
63
77
|
:show-text-alignment-options="showAlignment"
|
|
64
78
|
:show-text-background-color-options="showTextBg"
|
|
65
79
|
:disable-transparent="disableTransparent"
|
|
80
|
+
:is-design-com="isDesignCom"
|
|
66
81
|
@update:model-value="onFieldChanged"
|
|
67
82
|
@change-logo="onFieldChangeLogo"
|
|
68
83
|
@on-intent-image-replace="onIntentImageReplace"
|
|
69
84
|
@on-toggle-state-change="onToggleStateChange"
|
|
85
|
+
@capture-preview-snapshot="onCaptureSnapshot"
|
|
70
86
|
/>
|
|
71
87
|
</div>
|
|
72
88
|
</div>
|
|
@@ -109,6 +125,7 @@ import SliderField from '../slider-field/SliderField.vue';
|
|
|
109
125
|
import PageDropdownField from '../page-dropdown-field/PageDropdownField.vue';
|
|
110
126
|
import PersonalisationOverrideField from '../personalisation-override-field/PersonalisationOverrideField.vue';
|
|
111
127
|
import BookingUrlField from '../booking-url-field/BookingUrlField.vue';
|
|
128
|
+
import GenerateAiButton from '../generate-ai-button/GenerateAiButton.vue';
|
|
112
129
|
|
|
113
130
|
export default {
|
|
114
131
|
components: {
|
|
@@ -147,6 +164,7 @@ export default {
|
|
|
147
164
|
'product-config-option-field': ProductConfigOptionField,
|
|
148
165
|
FieldSubHeader,
|
|
149
166
|
Toggle,
|
|
167
|
+
GenerateAiButton,
|
|
150
168
|
'page-dropdown-field': PageDropdownField,
|
|
151
169
|
'personalisation-override-field': PersonalisationOverrideField,
|
|
152
170
|
},
|
|
@@ -228,7 +228,9 @@ export default defineComponent({
|
|
|
228
228
|
eventSource: UI_EVENT_SOURCES.contentSettings,
|
|
229
229
|
});
|
|
230
230
|
},
|
|
231
|
-
|
|
231
|
+
onCaptureSnapshotBeforeModal() {
|
|
232
|
+
this.$emit('capture-preview-snapshot');
|
|
233
|
+
},
|
|
232
234
|
onToggleGroupCollapseClick(groupId: string) {
|
|
233
235
|
if (!this.id) {
|
|
234
236
|
return;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="showButton">
|
|
3
|
+
<p
|
|
4
|
+
:title="generateText"
|
|
5
|
+
class="tw-text-sm tw-text-primary-500 tw-font-bold tw-cursor-pointer tw-flex tw-items-center"
|
|
6
|
+
:class="{
|
|
7
|
+
'tw-uppercase': !props.isDesignCom,
|
|
8
|
+
}"
|
|
9
|
+
@click="onShowGenerateModal"
|
|
10
|
+
>
|
|
11
|
+
<Icon name="ai" class="tw-mr-1 tw-flex" />
|
|
12
|
+
{{ generateText }}
|
|
13
|
+
</p>
|
|
14
|
+
<GenerateAiModal
|
|
15
|
+
:is-visible="generateTextModalVisible"
|
|
16
|
+
:existing-text="props.existingText"
|
|
17
|
+
:is-design-com="props.isDesignCom"
|
|
18
|
+
:snapshot-base64="snapshotBase64"
|
|
19
|
+
:field-type="props.fieldType"
|
|
20
|
+
@on-close="onCloseGenerateTextModal"
|
|
21
|
+
@on-use-text="handleUseGeneratedText"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import { ref, computed } from 'vue';
|
|
28
|
+
import { Icon } from '@designcrowd/fe-shared-lib';
|
|
29
|
+
import GenerateAiModal from '../generate-ai-modal/GenerateAiModal.vue';
|
|
30
|
+
import { commonTr } from '../../../../composables/useTranslate';
|
|
31
|
+
import {
|
|
32
|
+
useBrandPageContainerStore,
|
|
33
|
+
useSnapshotStore,
|
|
34
|
+
} from '../../../../brand-page-maker/stores';
|
|
35
|
+
import type { AbTestResult } from '../../../../brand-page/models/brand-page-context.model';
|
|
36
|
+
|
|
37
|
+
interface Props {
|
|
38
|
+
id: string;
|
|
39
|
+
existingText: string;
|
|
40
|
+
isDesignCom?: boolean;
|
|
41
|
+
captureSnapshotDelay?: number;
|
|
42
|
+
fieldType?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
46
|
+
isDesignCom: false,
|
|
47
|
+
fieldType: 'text',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const emit = defineEmits<{
|
|
51
|
+
'on-use-text': [text: string];
|
|
52
|
+
'capture-snapshot': [];
|
|
53
|
+
}>();
|
|
54
|
+
|
|
55
|
+
const snapshotStore = useSnapshotStore();
|
|
56
|
+
const brandPageContainerStore = useBrandPageContainerStore();
|
|
57
|
+
|
|
58
|
+
const snapshotBase64 = computed(() => snapshotStore.snapshotBase64);
|
|
59
|
+
const abTests = computed(() => brandPageContainerStore.abTests);
|
|
60
|
+
|
|
61
|
+
const showButton = computed(() => {
|
|
62
|
+
const abTest = abTests.value
|
|
63
|
+
.bp_4572_ai_text_generation_post_purchase as unknown as
|
|
64
|
+
| AbTestResult
|
|
65
|
+
| undefined;
|
|
66
|
+
return abTest?.isVariation ?? false;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const generateTextModalVisible = ref(false);
|
|
70
|
+
const generateText = commonTr('generateText');
|
|
71
|
+
|
|
72
|
+
const onShowGenerateModal = async () => {
|
|
73
|
+
emit('capture-snapshot');
|
|
74
|
+
|
|
75
|
+
const maxWaitTime = 5000; // 5 seconds max
|
|
76
|
+
const pollInterval = 50; // Check every 50ms
|
|
77
|
+
let elapsedTime = 0;
|
|
78
|
+
|
|
79
|
+
while (!snapshotBase64.value && elapsedTime < maxWaitTime) {
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
81
|
+
elapsedTime += pollInterval;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
generateTextModalVisible.value = true;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const onCloseGenerateTextModal = () => {
|
|
88
|
+
generateTextModalVisible.value = false;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const handleUseGeneratedText = (generatedText: string) => {
|
|
92
|
+
emit('on-use-text', generatedText);
|
|
93
|
+
onCloseGenerateTextModal();
|
|
94
|
+
};
|
|
95
|
+
</script>
|