@designcrowd/library.brand-page 5.17.28 → 5.18.0

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 (380) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-CJZpKPNH.js → CreatedOnBrandCrowd-de-de-xmkupPus.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DkIa7iEb.js → CreatedOnBrandCrowd-en-us-Ck7EdTtb.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CE2p6XHz.js → CreatedOnBrandCrowd-es-es-BC8sJuDH.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BBjOZS3M.js → CreatedOnBrandCrowd-fr-ca-CN-UBe1q.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BBjOZS3M.js → CreatedOnBrandCrowd-fr-fr-CN-UBe1q.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-br-CajQyNkx.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-pt-CajQyNkx.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CFzDqfCb.js → CreatedOnDcom-de-de-BRCNMmDq.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-C2jIPBDY.js → CreatedOnDcom-en-us-BzQDtZhc.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-qejpzqho.js → CreatedOnDcom-es-es-D-qAM4Cd.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DMO9Ld7K.js → CreatedOnDcom-fr-ca-CZ1irFOc.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-BFWN9qTP.js → CreatedOnDcom-fr-fr-Gb5BCF0N.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CneD3ghF.js → CreatedOnDcom-pt-br-CAQV0q6o.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Cg1B7s0o.js → CreatedOnDcom-pt-pt-D6tQdQFh.js} +1 -1
  15. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
  16. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
  17. package/lib/src/brand-page/models/brand-page-context.model.js +1 -11
  18. package/lib/src/brand-page/models/index.d.ts +1 -0
  19. package/lib/src/brand-page/models/index.js +1 -0
  20. package/lib/src/brand-page/utils/color.util.js +23 -3
  21. package/lib/src/brand-page/utils/raygun.util.d.ts +5 -1
  22. package/lib/src/brand-page/utils/raygun.util.js +7 -2
  23. package/lib/src/brand-page/utils/svg-color.util.js +1 -2
  24. package/lib/src/brand-page/utils/view-model.util.js +1 -1
  25. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -31
  26. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -2
  27. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -31
  28. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
  29. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -28
  30. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -28
  31. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -28
  32. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -28
  33. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -28
  34. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -28
  35. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +35 -0
  36. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +108 -0
  37. package/lib/src/brand-page-maker/composables/ai-chat/{useAiChat.d.ts → types.d.ts} +5 -13
  38. package/lib/src/brand-page-maker/composables/ai-chat/types.js +1 -0
  39. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +19 -0
  40. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  41. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +1 -1
  42. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +488 -82
  43. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +5 -5
  44. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +6 -16
  45. package/lib/src/brand-page-maker/composables/useEventTracker.js +19 -21
  46. package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +0 -1
  47. package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -15
  48. package/lib/src/brand-page-maker/convertors/image-aspect-ratio.convertor.js +2 -2
  49. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  50. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +30660 -0
  51. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.js +34 -0
  52. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +1 -1
  53. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -28
  54. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
  55. package/lib/src/brand-page-maker/stores/index.d.ts +1 -1
  56. package/lib/src/brand-page-maker/stores/index.js +1 -1
  57. package/lib/src/brand-page-maker/stores/user/user-store.js +0 -1
  58. package/lib/src/bundled-translations-CnareLWC.js +175 -0
  59. package/lib/src/bundled-translations.de-DE-2Ys7epLO.js +175 -0
  60. package/lib/src/bundled-translations.es-ES-Cjp-G8rT.js +175 -0
  61. package/lib/src/bundled-translations.fr-CA-CsaW4Oae.js +175 -0
  62. package/lib/src/bundled-translations.fr-FR-DIT2dd8J.js +175 -0
  63. package/lib/src/bundled-translations.pt-BR-BamoBpDW.js +175 -0
  64. package/lib/src/bundled-translations.pt-PT-C9A4hY_e.js +175 -0
  65. package/lib/src/bundles/bundled-translations.de-DE.json +1 -20
  66. package/lib/src/bundles/bundled-translations.es-ES.json +1 -20
  67. package/lib/src/bundles/bundled-translations.fr-CA.json +1 -20
  68. package/lib/src/bundles/bundled-translations.fr-FR.json +1 -20
  69. package/lib/src/bundles/bundled-translations.json +1 -20
  70. package/lib/src/bundles/bundled-translations.pt-BR.json +1 -20
  71. package/lib/src/bundles/bundled-translations.pt-PT.json +1 -20
  72. package/lib/src/clients/ai-assistant-client.d.ts +30 -29
  73. package/lib/src/clients/ai-assistant-client.js +16 -16
  74. package/lib/src/clients/design-template-client.d.ts +0 -2
  75. package/lib/src/clients/design-template-client.js +0 -38
  76. package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
  77. package/lib/src/composables/useTranslate.d.ts +2 -1
  78. package/lib/src/composables/useTranslate.js +2 -1
  79. package/lib/src/constants/ui.d.ts +0 -1
  80. package/lib/src/css/library.brand-page-brandCrowd.min.css +225 -134
  81. package/lib/src/css/library.brand-page-brandPage.min.css +227 -121
  82. package/lib/src/css/library.brand-page-designCom.min.css +225 -134
  83. package/lib/src/css/library.brand-page-preview.min.css +225 -118
  84. package/lib/src/index.d.ts +1 -1
  85. package/lib/src/index.mjs +1 -1
  86. package/lib/src/{lib-33w_DBny.js → lib-CSRUPpSo.js} +30887 -29395
  87. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +21 -0
  88. package/lib/src/metadata-builder/ai-metadata-executor.js +56 -3
  89. package/lib/src/metadata-builder/builders/add-page-builder.d.ts +2 -4
  90. package/lib/src/metadata-builder/builders/add-page-builder.js +5 -8
  91. package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
  92. package/lib/src/metadata-builder/builders/footer-builder.js +151 -0
  93. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
  94. package/lib/src/metadata-builder/builders/global-styles-builder.js +129 -0
  95. package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
  96. package/lib/src/metadata-builder/builders/header-builder.js +167 -0
  97. package/lib/src/metadata-builder/builders/rename-page-builder.d.ts +12 -0
  98. package/lib/src/metadata-builder/builders/rename-page-builder.js +49 -0
  99. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +2 -0
  100. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +44 -4
  101. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +2 -0
  102. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +70 -6
  103. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +36 -4
  104. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +102 -12
  105. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +8 -0
  106. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
  107. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +2 -0
  108. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +5 -1
  109. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +2 -0
  110. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +47 -3
  111. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +2 -1
  112. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +5 -2
  113. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +2 -0
  114. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +11 -1
  115. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +2 -0
  116. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +52 -13
  117. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +2 -0
  118. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +47 -17
  119. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
  120. package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
  121. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +2 -0
  122. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +20 -2
  123. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +2 -0
  124. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +20 -2
  125. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +2 -0
  126. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +36 -2
  127. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +2 -0
  128. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +70 -27
  129. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +2 -0
  130. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +7 -2
  131. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +2 -0
  132. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +91 -26
  133. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +2 -0
  134. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +69 -31
  135. package/lib/src/metadata-builder/builders/section-content-factory.d.ts +2 -2
  136. package/lib/src/metadata-builder/builders/section-content-factory.js +8 -2
  137. package/lib/src/metadata-builder/builders/section-field-maps.js +30 -2
  138. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +46 -7
  139. package/lib/src/metadata-builder/builders/section-field-utils.js +86 -62
  140. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.d.ts +2 -0
  141. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.js +20 -0
  142. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.d.ts +7 -0
  143. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.js +8 -0
  144. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.d.ts +2 -0
  145. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +27 -0
  146. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.d.ts +2 -0
  147. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.js +16 -0
  148. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.d.ts +2 -0
  149. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.js +13 -0
  150. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.d.ts +2 -0
  151. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.js +16 -0
  152. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.d.ts +2 -0
  153. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.js +7 -0
  154. package/lib/src/metadata-builder/builders/section-rules/footer.rules.d.ts +4 -0
  155. package/lib/src/metadata-builder/builders/section-rules/footer.rules.js +5 -0
  156. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +6 -0
  157. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +26 -0
  158. package/lib/src/metadata-builder/builders/section-rules/header.rules.d.ts +4 -0
  159. package/lib/src/metadata-builder/builders/section-rules/header.rules.js +41 -0
  160. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.d.ts +2 -0
  161. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.js +10 -0
  162. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.d.ts +2 -0
  163. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.js +31 -0
  164. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.d.ts +2 -0
  165. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.js +11 -0
  166. package/lib/src/metadata-builder/builders/section-rules/profile.rules.d.ts +2 -0
  167. package/lib/src/metadata-builder/builders/section-rules/profile.rules.js +14 -0
  168. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.d.ts +7 -0
  169. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.js +8 -0
  170. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.d.ts +2 -0
  171. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.js +27 -0
  172. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.d.ts +2 -0
  173. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +9 -0
  174. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.d.ts +7 -0
  175. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.js +26 -0
  176. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.d.ts +2 -0
  177. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.js +14 -0
  178. package/lib/src/metadata-builder/builders/shape-color-utils.d.ts +26 -0
  179. package/lib/src/metadata-builder/builders/shape-color-utils.js +52 -0
  180. package/lib/src/metadata-builder/builders/undo-builder.d.ts +48 -0
  181. package/lib/src/metadata-builder/builders/undo-builder.js +58 -0
  182. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +15 -4
  184. package/lib/src/metadata-builder/helpers/rte.helpers.js +24 -10
  185. package/lib/src/metadata-builder/metadata-executor.d.ts +2 -1
  186. package/lib/src/metadata-builder/metadata-executor.js +32 -5
  187. package/lib/src/metadata-builder/models.d.ts +26 -1
  188. package/lib/src/metadata-builder/models.js +14 -1
  189. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +144 -0
  190. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +17 -0
  191. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +113 -24
  192. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
  193. package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +22 -0
  194. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +84 -0
  195. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +47 -0
  196. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +60 -0
  197. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +41 -0
  198. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +274 -0
  199. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -1
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -16
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.stories.js +0 -1
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -1
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -3
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -4
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +6 -8
  206. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -28
  207. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -1
  208. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -28
  209. package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
  210. package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
  211. package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
  212. package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
  213. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -30
  214. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -28
  215. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -43
  216. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -30
  217. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +2 -3
  218. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +0 -12
  219. package/lib/src/shared/side-bar/store/side-bar-store.js +0 -7
  220. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -29
  221. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +2 -1
  222. package/lib/src/utils/build-asset-manifest.d.ts +26 -0
  223. package/lib/src/utils/build-asset-manifest.js +114 -0
  224. package/lib/src/utils/minify-brand-page-metadata.d.ts +49 -1
  225. package/lib/src/utils/minify-brand-page-metadata.js +216 -129
  226. package/package.json +1 -1
  227. package/src/brand-page/components/banner-section/BannerSection.vue +1 -1
  228. package/src/brand-page/components/contact-form/ContactForm.vue +29 -26
  229. package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
  230. package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -5
  231. package/src/brand-page/models/brand-page-context.model.ts +1 -25
  232. package/src/brand-page/models/index.ts +1 -0
  233. package/src/brand-page/utils/color.util.test.ts +48 -0
  234. package/src/brand-page/utils/color.util.ts +29 -4
  235. package/src/brand-page/utils/raygun.util.ts +11 -2
  236. package/src/brand-page/utils/svg-color.util.ts +1 -3
  237. package/src/brand-page/utils/view-model.util.ts +1 -4
  238. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
  239. package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
  240. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +57 -5
  241. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.de-DE.json +0 -20
  242. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.es-ES.json +0 -20
  243. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-CA.json +0 -20
  244. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-FR.json +0 -20
  245. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.json +0 -20
  246. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-BR.json +0 -20
  247. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-PT.json +0 -20
  248. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
  249. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.de-DE.json +3 -0
  250. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.es-ES.json +3 -0
  251. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-CA.json +3 -0
  252. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-FR.json +3 -0
  253. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.json +3 -0
  254. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-BR.json +3 -0
  255. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-PT.json +3 -0
  256. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +3 -28
  257. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -2
  258. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.test.ts +229 -0
  259. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +164 -0
  260. package/src/brand-page-maker/composables/ai-chat/types.ts +49 -0
  261. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +20 -0
  262. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +651 -94
  263. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +9 -9
  264. package/src/brand-page-maker/composables/useEventTracker.ts +31 -25
  265. package/src/brand-page-maker/constants/sidebar-constant.ts +7 -15
  266. package/src/brand-page-maker/convertors/image-aspect-ratio.convertor.ts +2 -2
  267. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +3 -3
  268. package/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.ts +54 -0
  269. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
  270. package/src/brand-page-maker/stores/index.ts +1 -1
  271. package/src/brand-page-maker/stores/user/user-store.ts +0 -1
  272. package/src/bundles/bundled-translations.de-DE.json +1 -20
  273. package/src/bundles/bundled-translations.es-ES.json +1 -20
  274. package/src/bundles/bundled-translations.fr-CA.json +1 -20
  275. package/src/bundles/bundled-translations.fr-FR.json +1 -20
  276. package/src/bundles/bundled-translations.json +1 -20
  277. package/src/bundles/bundled-translations.pt-BR.json +1 -20
  278. package/src/bundles/bundled-translations.pt-PT.json +1 -20
  279. package/src/clients/ai-assistant-client.ts +59 -46
  280. package/src/clients/design-template-client.ts +0 -66
  281. package/src/clients/websocket-gateway-client.ts +17 -1
  282. package/src/composables/useTranslate.ts +3 -0
  283. package/src/constants/ui.ts +0 -1
  284. package/src/lib.ts +1 -0
  285. package/src/metadata-builder/ai-metadata-executor.ts +94 -1
  286. package/src/metadata-builder/builders/add-page-builder.ts +9 -13
  287. package/src/metadata-builder/builders/footer-builder.test.ts +76 -0
  288. package/src/metadata-builder/builders/footer-builder.ts +226 -0
  289. package/src/metadata-builder/builders/global-styles-builder.ts +187 -0
  290. package/src/metadata-builder/builders/header-builder.test.ts +106 -0
  291. package/src/metadata-builder/builders/header-builder.ts +254 -0
  292. package/src/metadata-builder/builders/rename-page-builder.ts +79 -0
  293. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +73 -5
  294. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +112 -7
  295. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +149 -11
  296. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +87 -0
  297. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +6 -1
  298. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +74 -4
  299. package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +15 -1
  300. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +13 -1
  301. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +91 -31
  302. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +102 -48
  303. package/src/metadata-builder/builders/section-builders/index.ts +1 -0
  304. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +38 -2
  305. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +38 -2
  306. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +55 -3
  307. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +170 -77
  308. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +119 -0
  309. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +13 -2
  310. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +178 -57
  311. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +130 -30
  312. package/src/metadata-builder/builders/section-content-factory.ts +15 -2
  313. package/src/metadata-builder/builders/section-field-maps.ts +34 -1
  314. package/src/metadata-builder/builders/section-field-utils.ts +131 -72
  315. package/src/metadata-builder/builders/section-rules/about-section.rules.ts +38 -0
  316. package/src/metadata-builder/builders/section-rules/add-page.rules.ts +17 -0
  317. package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +49 -0
  318. package/src/metadata-builder/builders/section-rules/booking-section.rules.ts +34 -0
  319. package/src/metadata-builder/builders/section-rules/button-section.rules.ts +22 -0
  320. package/src/metadata-builder/builders/section-rules/contact-form.rules.ts +30 -0
  321. package/src/metadata-builder/builders/section-rules/divider-section.rules.ts +17 -0
  322. package/src/metadata-builder/builders/section-rules/footer.rules.ts +21 -0
  323. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +44 -0
  324. package/src/metadata-builder/builders/section-rules/header.rules.ts +75 -0
  325. package/src/metadata-builder/builders/section-rules/image-gallery.rules.ts +22 -0
  326. package/src/metadata-builder/builders/section-rules/images-section.rules.ts +55 -0
  327. package/src/metadata-builder/builders/section-rules/mailing-list.rules.ts +21 -0
  328. package/src/metadata-builder/builders/section-rules/profile.rules.ts +27 -0
  329. package/src/metadata-builder/builders/section-rules/rename-page.rules.ts +17 -0
  330. package/src/metadata-builder/builders/section-rules/shapes-section.rules.ts +51 -0
  331. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +27 -0
  332. package/src/metadata-builder/builders/section-rules/testimonial-section.rules.ts +48 -0
  333. package/src/metadata-builder/builders/section-rules/text-section.rules.ts +28 -0
  334. package/src/metadata-builder/builders/shape-color-utils.test.ts +115 -0
  335. package/src/metadata-builder/builders/shape-color-utils.ts +75 -0
  336. package/src/metadata-builder/builders/undo-builder.ts +105 -0
  337. package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -1
  338. package/src/metadata-builder/helpers/rte.helpers.ts +27 -13
  339. package/src/metadata-builder/metadata-executor.ts +42 -2
  340. package/src/metadata-builder/models.ts +39 -1
  341. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +152 -0
  342. package/src/metadata-builder/parsers/section-tool-arguments.ts +138 -24
  343. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +659 -0
  344. package/src/metadata-builder/sanitizers/rte-schema-check.ts +99 -0
  345. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +97 -0
  346. package/src/metadata-builder/sanitizers/section-args-validator.ts +445 -0
  347. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +10 -16
  348. package/src/shared/content-settings/components/content-settings/ContentSettings.stories.ts +0 -1
  349. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -10
  350. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -23
  351. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +0 -15
  352. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +0 -15
  353. package/src/shared/navigation-style-settings/store/index.ts +5 -0
  354. package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
  355. package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
  356. package/src/shared/side-bar/components/SideBar.vue +14 -1
  357. package/src/shared/side-bar/store/side-bar-store.ts +0 -20
  358. package/src/utils/build-asset-manifest.ts +153 -0
  359. package/src/utils/minify-brand-page-metadata.ts +362 -130
  360. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +0 -368
  361. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.d.ts +0 -18
  362. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.js +0 -144
  363. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +0 -155
  364. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.js +0 -25
  365. package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +0 -1
  366. package/lib/src/brand-page-maker/utils/mixpanel.util.js +0 -29
  367. package/lib/src/bundled-translations-CNK7l6_v.js +0 -173
  368. package/lib/src/bundled-translations.de-DE-BLE4_y0H.js +0 -173
  369. package/lib/src/bundled-translations.es-ES-thO9osbg.js +0 -173
  370. package/lib/src/bundled-translations.fr-CA-BZkhiNgU.js +0 -173
  371. package/lib/src/bundled-translations.fr-FR-bhDLPKgZ.js +0 -173
  372. package/lib/src/bundled-translations.pt-BR-CI9a5Bq1.js +0 -173
  373. package/lib/src/bundled-translations.pt-PT-DBoErBaq.js +0 -173
  374. package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +0 -154
  375. package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +0 -562
  376. package/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.ts +0 -196
  377. package/src/brand-page-maker/stores/ai-thread/ai-thread-store.ts +0 -31
  378. package/src/brand-page-maker/utils/mixpanel.util.ts +0 -42
  379. package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +0 -114
  380. package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +0 -761
@@ -1,85 +1,167 @@
1
1
  import type {
2
+ ColorReplacement,
2
3
  TestimonialSectionContent,
3
4
  BrandPageModel,
5
+ TextStyleDeclaration,
4
6
  } from '../../../brand-page/models';
5
- import type {
6
- TestimonialItem,
7
- TestimonialSectionArguments,
7
+ import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
8
+ import {
9
+ isTiptapDocument,
10
+ type TestimonialItem,
11
+ type TestimonialSectionArguments,
8
12
  } from '../../parsers/section-tool-arguments';
9
13
  import type { BuilderResult } from '../../models';
10
- import { applyScalarFields, applyStyleFields } from '../section-field-utils';
14
+ import {
15
+ applyScalarFields,
16
+ applyStyleFields,
17
+ resolveGlobalPresetIntoStyle,
18
+ } from '../section-field-utils';
19
+ import {
20
+ applyColorThemeToReplacements,
21
+ resolveShapeColorReplacementsAsync,
22
+ } from '../shape-color-utils';
11
23
  import { BaseSectionBuilder } from './base-section-builder';
24
+ import {
25
+ validateTestimonialSection,
26
+ TESTIMONIAL_ITEM_CAP,
27
+ } from '../section-rules/testimonial-section.rules';
28
+
29
+ const resolveItemColorsAsync = async (
30
+ item: TestimonialItem,
31
+ existing: ColorReplacement[] | undefined,
32
+ prevImageUrl: string | undefined,
33
+ ): Promise<ColorReplacement[]> => {
34
+ let colors = existing ?? [];
35
+
36
+ if (item.avatar_shape_url && item.avatar_shape_url !== prevImageUrl) {
37
+ colors = await resolveShapeColorReplacementsAsync(item.avatar_shape_url);
38
+ }
39
+
40
+ if (item.color_theme) {
41
+ colors = applyColorThemeToReplacements(colors, item.color_theme);
42
+ }
43
+
44
+ return colors;
45
+ };
12
46
 
13
- const applyTestimonialItems = (
47
+ const applyTestimonialItemsAsync = async (
14
48
  content: TestimonialSectionContent,
15
49
  items: TestimonialItem[],
16
- ): void => {
17
- content.items = items.map((item) => ({
18
- imageUrl: item.avatar_image_url || '',
19
- name: item.name || '',
20
- position: item.position || '',
21
- testimonials: item.testimonial || '',
22
- colorReplacements: [],
23
- mediaType: 'image',
24
- }));
50
+ ): Promise<void> => {
51
+ content.items = await Promise.all(
52
+ items.map(async (item) => ({
53
+ imageUrl: item.avatar_shape_url || item.avatar_image_url || '',
54
+ name: item.name || '',
55
+ position: item.position || '',
56
+ testimonials: item.testimonial || '',
57
+ colorReplacements: await resolveItemColorsAsync(item, [], undefined),
58
+ mediaType: item.avatar_shape_url ? 'shape' : 'image',
59
+ })),
60
+ );
25
61
  };
26
62
 
27
- const mergeTestimonialItems = (
63
+ const mergeTestimonialItemsAsync = async (
28
64
  content: TestimonialSectionContent,
29
65
  items: TestimonialItem[],
30
66
  replaceAll: boolean,
31
- ): void => {
67
+ ): Promise<void> => {
32
68
  const hasIndexedItems = items.some((item) => item.item_index !== undefined);
33
69
 
34
70
  if (hasIndexedItems) {
35
- for (const item of items) {
36
- const targetIndex = item.item_index;
37
-
38
- if (
39
- targetIndex === undefined ||
40
- targetIndex < 0 ||
41
- !content.items?.[targetIndex]
42
- )
43
- continue;
44
-
45
- const existing = content.items[targetIndex];
71
+ await Promise.all(
72
+ items.map(async (item) => {
73
+ const targetIndex = item.item_index;
74
+
75
+ if (
76
+ targetIndex === undefined ||
77
+ targetIndex < 0 ||
78
+ !content.items?.[targetIndex]
79
+ )
80
+ return;
81
+
82
+ const existing = content.items[targetIndex];
83
+ const prevImageUrl = existing.imageUrl;
84
+
85
+ if (item.avatar_shape_url !== undefined) {
86
+ existing.imageUrl = item.avatar_shape_url;
87
+ existing.mediaType = 'shape';
88
+ } else if (item.avatar_image_url !== undefined) {
89
+ existing.imageUrl = item.avatar_image_url;
90
+ existing.mediaType = 'image';
91
+ }
46
92
 
47
- if (item.avatar_image_url !== undefined)
48
- existing.imageUrl = item.avatar_image_url;
93
+ if (item.name !== undefined) existing.name = item.name;
49
94
 
50
- if (item.name !== undefined) existing.name = item.name;
95
+ if (item.position !== undefined) existing.position = item.position;
51
96
 
52
- if (item.position !== undefined) existing.position = item.position;
97
+ if (item.testimonial !== undefined)
98
+ existing.testimonials = item.testimonial;
53
99
 
54
- if (item.testimonial !== undefined)
55
- existing.testimonials = item.testimonial;
56
- }
100
+ if (
101
+ item.avatar_shape_url !== undefined ||
102
+ item.color_theme !== undefined
103
+ ) {
104
+ existing.colorReplacements = await resolveItemColorsAsync(
105
+ item,
106
+ existing.colorReplacements,
107
+ prevImageUrl,
108
+ );
109
+ }
110
+ }),
111
+ );
57
112
 
58
113
  return;
59
114
  }
60
115
 
61
- const updatedItems = items.map((item, index) => {
62
- const existing = content.items?.[index];
63
-
64
- return {
65
- ...(existing || {}),
66
- imageUrl: item.avatar_image_url ?? existing?.imageUrl ?? '',
67
- name: item.name ?? existing?.name ?? '',
68
- position: item.position ?? existing?.position ?? '',
69
- testimonials: item.testimonial ?? existing?.testimonials ?? '',
70
- colorReplacements: existing?.colorReplacements ?? [],
71
- mediaType: existing?.mediaType ?? 'image',
72
- };
73
- });
74
-
75
- if (!replaceAll && content.items && content.items.length > items.length) {
76
- updatedItems.push(...content.items.slice(items.length));
116
+ const itemsToMerge = items.filter((item) => item.insert_at === undefined);
117
+
118
+ const updatedItems = await Promise.all(
119
+ itemsToMerge.map(async (item, index) => {
120
+ const existing = content.items?.[index];
121
+
122
+ const imageUrl =
123
+ item.avatar_shape_url ??
124
+ item.avatar_image_url ??
125
+ existing?.imageUrl ??
126
+ '';
127
+ const mediaType = item.avatar_shape_url
128
+ ? 'shape'
129
+ : item.avatar_image_url
130
+ ? 'image'
131
+ : existing?.mediaType ?? 'image';
132
+
133
+ return {
134
+ ...(existing || {}),
135
+ imageUrl,
136
+ name: item.name ?? existing?.name ?? '',
137
+ position: item.position ?? existing?.position ?? '',
138
+ testimonials: item.testimonial ?? existing?.testimonials ?? '',
139
+ colorReplacements: await resolveItemColorsAsync(
140
+ item,
141
+ existing?.colorReplacements,
142
+ existing?.imageUrl,
143
+ ),
144
+ mediaType,
145
+ };
146
+ }),
147
+ );
148
+
149
+ if (
150
+ !replaceAll &&
151
+ content.items &&
152
+ content.items.length > itemsToMerge.length
153
+ ) {
154
+ updatedItems.push(...content.items.slice(itemsToMerge.length));
77
155
  }
78
156
 
79
157
  content.items = updatedItems;
80
158
  };
81
159
 
82
160
  export class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSectionContent> {
161
+ protected get sectionValidate() {
162
+ return validateTestimonialSection;
163
+ }
164
+
83
165
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
84
166
  this.log('Build called');
85
167
 
@@ -89,16 +171,34 @@ export class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSec
89
171
  return { request: this.request, model, errors: validation.errors };
90
172
  }
91
173
 
92
- const resolved = this.resolveContent(model);
174
+ const resolved = this.resolveAndRepositionContent(model);
93
175
 
94
176
  if ('error' in resolved) return resolved.error;
95
177
 
96
178
  const content = resolved.content;
97
179
 
98
180
  applyScalarFields(content, this.args, this.sectionType);
99
- applyStyleFields(content, this.args, this.sectionType);
181
+ applyStyleFields(
182
+ content,
183
+ this.args,
184
+ this.sectionType,
185
+ this.getGlobalTextStyles(model),
186
+ );
100
187
 
101
188
  const args = this.args as TestimonialSectionArguments;
189
+ const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
190
+
191
+ if (args.title !== undefined) {
192
+ if (isTiptapDocument(args.title)) {
193
+ content.title = tiptapJsonToHtml(args.title);
194
+ content.titleStyle = resolveGlobalPresetIntoStyle(
195
+ content.titleStyle,
196
+ textStyleOptions,
197
+ ) as TextStyleDeclaration;
198
+ } else {
199
+ content.title = args.title;
200
+ }
201
+ }
102
202
 
103
203
  if (args.background_style && typeof args.background_style === 'object') {
104
204
  const existing = content.backgroundStyle || {};
@@ -130,9 +230,13 @@ export class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSec
130
230
 
131
231
  if (args.items && Array.isArray(args.items)) {
132
232
  if (this.mode === 'create') {
133
- applyTestimonialItems(content, args.items);
233
+ await applyTestimonialItemsAsync(content, args.items);
134
234
  } else {
135
- mergeTestimonialItems(content, args.items, !!args._replace_items);
235
+ await mergeTestimonialItemsAsync(
236
+ content,
237
+ args.items,
238
+ !!args._replace_items,
239
+ );
136
240
  }
137
241
  }
138
242
 
@@ -161,12 +265,12 @@ export class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSec
161
265
  Math.min(item.insert_at ?? 0, content.items?.length ?? 0),
162
266
  );
163
267
  const newItem = {
164
- imageUrl: item.avatar_image_url ?? '',
268
+ imageUrl: item.avatar_shape_url ?? item.avatar_image_url ?? '',
165
269
  name: item.name ?? '',
166
270
  position: item.position ?? '',
167
271
  testimonials: item.testimonial ?? '',
168
- colorReplacements: [],
169
- mediaType: 'image',
272
+ colorReplacements: await resolveItemColorsAsync(item, [], undefined),
273
+ mediaType: item.avatar_shape_url ? 'shape' : 'image',
170
274
  };
171
275
 
172
276
  content.items = content.items ?? [];
@@ -189,6 +293,23 @@ export class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSec
189
293
  }
190
294
  }
191
295
 
296
+ // Post-merge cap check. itemCapCheck only fires for create / update with
297
+ // _replace_items, so insert_at on an already-full section silently bloats
298
+ // the array. Surface as an error so the AI retry loop gets a signal and
299
+ // can reissue with _remove_item_indices or fewer inserts.
300
+ // brandSite key mirrors base-section-builder's hardcoded brandPageType.
301
+ const cap = TESTIMONIAL_ITEM_CAP.brandSite;
302
+
303
+ if (content.items && content.items.length > cap) {
304
+ return {
305
+ request: this.request,
306
+ model,
307
+ errors: [
308
+ `"${TESTIMONIAL_ITEM_CAP.arrayField}" has ${content.items.length} items but "testimonial-section" supports a maximum of ${cap}`,
309
+ ],
310
+ };
311
+ }
312
+
192
313
  return { request: this.request, model };
193
314
  }
194
315
  }
@@ -5,34 +5,69 @@ import type {
5
5
  TextStyleDeclaration,
6
6
  BrandPageModel,
7
7
  } from '../../../brand-page/models';
8
- import { updateRTEText } from '../../helpers/rte.helpers';
9
- import type {
10
- TextSectionArguments,
11
- TextSectionItem,
8
+ import type { TextStyleOptions } from '../../../brand-page/models/styles.model';
9
+ import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
10
+ import {
11
+ isTiptapDocument,
12
+ type TextSectionArguments,
13
+ type TextSectionItem,
12
14
  } from '../../parsers/section-tool-arguments';
13
- import { applyScalarFields, applyStyleFields } from '../section-field-utils';
15
+ import {
16
+ applyScalarFields,
17
+ applyStyleFields,
18
+ resolveGlobalPresetIntoStyle,
19
+ } from '../section-field-utils';
14
20
  import { BaseSectionBuilder } from './base-section-builder';
21
+ import { validateTextSection } from '../section-rules/text-section.rules';
22
+
23
+ /** Resolve a RichTextField (string or TiptapDocument) to a plain HTML string. */
24
+ const resolveText = (value: unknown): { html: string; wasTiptap: boolean } => {
25
+ if (isTiptapDocument(value))
26
+ return { html: tiptapJsonToHtml(value), wasTiptap: true };
27
+
28
+ return { html: typeof value === 'string' ? value : '', wasTiptap: false };
29
+ };
30
+
31
+ const clearTextStyleTypeIfTiptap = (
32
+ style: TextStyleDeclaration,
33
+ wasTiptap: boolean,
34
+ textStyleOptions: TextStyleOptions | undefined,
35
+ ): TextStyleDeclaration =>
36
+ wasTiptap
37
+ ? (resolveGlobalPresetIntoStyle(
38
+ style,
39
+ textStyleOptions,
40
+ ) as TextStyleDeclaration)
41
+ : style;
15
42
 
16
43
  const createTextItem = (
17
44
  item: TextSectionItem,
18
45
  baseStyle: TextStyleDeclaration,
46
+ textStyleOptions: TextStyleOptions | undefined,
19
47
  ): TextItem => {
20
48
  const textStyle = (
21
49
  item.text_style ? { ...baseStyle, ...item.text_style } : { ...baseStyle }
22
50
  ) as TextStyleDeclaration;
23
51
 
52
+ const { html, wasTiptap } = resolveText(item.text);
53
+
24
54
  return {
25
- text: item.text || '',
26
- textStyle,
55
+ text: html,
56
+ textStyle: clearTextStyleTypeIfTiptap(
57
+ textStyle,
58
+ wasTiptap,
59
+ textStyleOptions,
60
+ ),
27
61
  };
28
62
  };
29
63
 
30
64
  const applyTextItems = (
31
65
  content: TextContent,
32
66
  items: TextSectionItem[],
67
+ textStyleOptions: TextStyleOptions | undefined,
33
68
  ): void => {
34
69
  content.textItems = items.map((item) =>
35
- createTextItem(item, content.textStyle || {}),
70
+ createTextItem(item, content.textStyle || {}, textStyleOptions),
36
71
  );
37
72
  };
38
73
 
@@ -40,6 +75,7 @@ const mergeTextItems = (
40
75
  content: TextContent,
41
76
  items: TextSectionItem[],
42
77
  replaceAll: boolean,
78
+ textStyleOptions: TextStyleOptions | undefined,
43
79
  ): void => {
44
80
  const hasIndexedItems = items.some((item) => item.item_index !== undefined);
45
81
 
@@ -56,7 +92,16 @@ const mergeTextItems = (
56
92
 
57
93
  const existing = content.textItems[targetIndex];
58
94
 
59
- if (item.text !== undefined) existing.text = item.text;
95
+ if (item.text !== undefined) {
96
+ const { html, wasTiptap } = resolveText(item.text);
97
+
98
+ existing.text = html;
99
+ existing.textStyle = clearTextStyleTypeIfTiptap(
100
+ existing.textStyle || {},
101
+ wasTiptap,
102
+ textStyleOptions,
103
+ );
104
+ }
60
105
 
61
106
  if (item.text_style && typeof item.text_style === 'object') {
62
107
  const mergedStyle = (
@@ -66,14 +111,15 @@ const mergeTextItems = (
66
111
  ) as TextStyleDeclaration;
67
112
 
68
113
  existing.textStyle = mergedStyle;
69
- existing.text = updateRTEText(existing.text, mergedStyle);
70
114
  }
71
115
  }
72
116
 
73
117
  return;
74
118
  }
75
119
 
76
- const updatedItems = items.map((item, index) => {
120
+ const itemsToMerge = items.filter((item) => item.insert_at === undefined);
121
+
122
+ const updatedItems = itemsToMerge.map((item, index) => {
77
123
  const existing = content.textItems?.[index];
78
124
  const baseStyle = existing?.textStyle || content.textStyle || {};
79
125
 
@@ -81,20 +127,25 @@ const mergeTextItems = (
81
127
  item.text_style ? { ...baseStyle, ...item.text_style } : baseStyle
82
128
  ) as TextStyleDeclaration;
83
129
 
84
- const text = item.text ?? existing?.text ?? '';
130
+ const resolved = item.text !== undefined ? resolveText(item.text) : null;
131
+ const text = resolved ? resolved.html : existing?.text ?? '';
85
132
 
86
133
  return {
87
- text: item.text_style ? updateRTEText(text, mergedStyle) : text,
88
- textStyle: mergedStyle,
134
+ text,
135
+ textStyle: clearTextStyleTypeIfTiptap(
136
+ mergedStyle,
137
+ resolved?.wasTiptap ?? false,
138
+ textStyleOptions,
139
+ ),
89
140
  };
90
141
  });
91
142
 
92
143
  if (
93
144
  !replaceAll &&
94
145
  content.textItems &&
95
- content.textItems.length > items.length
146
+ content.textItems.length > itemsToMerge.length
96
147
  ) {
97
- updatedItems.push(...content.textItems.slice(items.length));
148
+ updatedItems.push(...content.textItems.slice(itemsToMerge.length));
98
149
  }
99
150
 
100
151
  content.textItems = updatedItems;
@@ -107,18 +158,30 @@ const mergeTextItems = (
107
158
  const applySingleTextField = (
108
159
  content: TextContent,
109
160
  args: TextSectionArguments,
161
+ textStyleOptions: TextStyleOptions | undefined,
110
162
  ): void => {
111
- if (typeof args.text === 'string') {
163
+ if (args.text !== undefined) {
164
+ const { html, wasTiptap } = resolveText(args.text);
165
+
112
166
  if (Array.isArray(content.textItems) && content.textItems.length > 0) {
113
167
  content.textItems[0] = {
114
168
  ...content.textItems[0],
115
- text: args.text,
169
+ text: html,
170
+ textStyle: clearTextStyleTypeIfTiptap(
171
+ content.textItems[0].textStyle || {},
172
+ wasTiptap,
173
+ textStyleOptions,
174
+ ),
116
175
  };
117
176
  } else {
118
177
  content.textItems = [
119
178
  {
120
- text: args.text,
121
- textStyle: { ...(content.textStyle || {}) },
179
+ text: html,
180
+ textStyle: clearTextStyleTypeIfTiptap(
181
+ { ...(content.textStyle || {}) },
182
+ wasTiptap,
183
+ textStyleOptions,
184
+ ),
122
185
  },
123
186
  ];
124
187
  }
@@ -132,18 +195,21 @@ const applySingleTextField = (
132
195
  ) {
133
196
  const mergedStyle = {
134
197
  ...(content.textItems[0].textStyle || {}),
135
- ...(content.textStyle || {}),
136
- };
198
+ ...args.text_style,
199
+ } as TextStyleDeclaration;
137
200
 
138
201
  content.textItems[0] = {
139
202
  ...content.textItems[0],
140
203
  textStyle: mergedStyle,
141
- text: updateRTEText(content.textItems[0].text, mergedStyle),
142
204
  };
143
205
  }
144
206
  };
145
207
 
146
208
  export class TextSectionBuilder extends BaseSectionBuilder<TextContent> {
209
+ protected get sectionValidate() {
210
+ return validateTextSection;
211
+ }
212
+
147
213
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
148
214
  this.log('Build called');
149
215
 
@@ -153,25 +219,36 @@ export class TextSectionBuilder extends BaseSectionBuilder<TextContent> {
153
219
  return { request: this.request, model, errors: validation.errors };
154
220
  }
155
221
 
156
- const resolved = this.resolveContent(model);
222
+ const resolved = this.resolveAndRepositionContent(model);
157
223
 
158
224
  if ('error' in resolved) return resolved.error;
159
225
 
160
226
  const content = resolved.content;
227
+ const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
161
228
 
162
229
  applyScalarFields(content, this.args, this.sectionType);
163
- applyStyleFields(content, this.args, this.sectionType);
230
+ applyStyleFields(
231
+ content,
232
+ this.args,
233
+ this.sectionType,
234
+ this.getGlobalTextStyles(model),
235
+ );
164
236
 
165
237
  const args = this.args as TextSectionArguments;
166
238
 
167
239
  if (args.items && Array.isArray(args.items)) {
168
240
  if (this.mode === 'create') {
169
- applyTextItems(content, args.items);
241
+ applyTextItems(content, args.items, textStyleOptions);
170
242
  } else {
171
- mergeTextItems(content, args.items, !!args._replace_items);
243
+ mergeTextItems(
244
+ content,
245
+ args.items,
246
+ !!args._replace_items,
247
+ textStyleOptions,
248
+ );
172
249
  }
173
250
  } else {
174
- applySingleTextField(content, args);
251
+ applySingleTextField(content, args, textStyleOptions);
175
252
  }
176
253
 
177
254
  // Phase 2: Item operations (remove, insert, reorder)
@@ -204,9 +281,15 @@ export class TextSectionBuilder extends BaseSectionBuilder<TextContent> {
204
281
  ? { ...baseStyle, ...item.text_style }
205
282
  : { ...baseStyle }
206
283
  ) as TextStyleDeclaration;
284
+
285
+ const { html, wasTiptap } = resolveText(item.text);
207
286
  const newItem: TextItem = {
208
- text: item.text ?? '',
209
- textStyle,
287
+ text: html,
288
+ textStyle: clearTextStyleTypeIfTiptap(
289
+ textStyle,
290
+ wasTiptap,
291
+ textStyleOptions,
292
+ ),
210
293
  };
211
294
 
212
295
  content.textItems = content.textItems ?? [];
@@ -236,6 +319,23 @@ export class TextSectionBuilder extends BaseSectionBuilder<TextContent> {
236
319
  };
237
320
  }
238
321
 
322
+ // CREATE-mode: the editor's `createInitialTextContent` factory seeds
323
+ // `content.text` with the i18n placeholder "This is a sample text" as a
324
+ // click-to-add affordance for the manual maker UI. That placeholder
325
+ // must not survive an AI-driven create. The AI flow writes resolved
326
+ // copy into `content.textItems` only — never to the legacy single-text
327
+ // `content.text` field — so when the renderer reads `content.text`
328
+ // (non-brandSite path in Text.vue, or any fallback for empty
329
+ // textItems), it falls back to the placeholder.
330
+ //
331
+ // Mirror the resolved first item's text into the legacy field so both
332
+ // renderer paths agree. Same pattern as yesterday's about-section /
333
+ // contact-form / testimonial RTE fix — clear the factory default and
334
+ // align both fields with the AI's actual output.
335
+ if (this.mode === 'create') {
336
+ content.text = content.textItems?.[0]?.text ?? '';
337
+ }
338
+
239
339
  return { request: this.request, model };
240
340
  }
241
341
  }
@@ -3,11 +3,17 @@
3
3
  * Used by BaseSectionBuilder when adding a new section to a page.
4
4
  */
5
5
  import { CONTENT_SETTINGS_CONFIGS } from '../../brand-page-maker/constants/config-settings-constant';
6
- import type { Content, ContentType } from '../../brand-page/models';
6
+ import type { CreateInitialContentOptions } from '../../brand-page-maker/models/content-settings-configs';
7
+ import type {
8
+ BrandPageType,
9
+ Content,
10
+ ContentType,
11
+ } from '../../brand-page/models';
7
12
  import type { SectionType } from '../parsers/section-tool-arguments';
8
13
 
9
14
  export const createDefaultSectionContent = (
10
15
  sectionType: SectionType,
16
+ brandPageType?: BrandPageType,
11
17
  ): Content | null => {
12
18
  const configs = CONTENT_SETTINGS_CONFIGS();
13
19
  const config = configs[sectionType as ContentType];
@@ -16,5 +22,12 @@ export const createDefaultSectionContent = (
16
22
  return null;
17
23
  }
18
24
 
19
- return config.createInitialContent() as Content;
25
+ const options = brandPageType
26
+ ? ({
27
+ brandPageType,
28
+ userState: { emailAddress: '' },
29
+ } as CreateInitialContentOptions)
30
+ : undefined;
31
+
32
+ return config.createInitialContent(options) as Content;
20
33
  };