@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,4 +1,13 @@
1
- import { type BrandPageModel, type Content } from '../../../brand-page/models';
1
+ import {
2
+ BRAND_PAGE_TYPES,
3
+ type BrandPageModel,
4
+ type Content,
5
+ } from '../../../brand-page/models';
6
+ import type { TextStyleOptions } from '../../../brand-page/models/styles.model';
7
+ import {
8
+ type EventTracker,
9
+ TRIGGER_TYPE,
10
+ } from '../../../brand-page-maker/composables/useEventTracker';
2
11
  import type { Logger } from '../../logger';
3
12
  import {
4
13
  BaseMetadataBuilder,
@@ -9,6 +18,7 @@ import type {
9
18
  SectionToolArguments,
10
19
  SectionType,
11
20
  } from '../../parsers/section-tool-arguments';
21
+ import type { ValidationContext } from '../../sanitizers/section-args-validator';
12
22
  import { createDefaultSectionContent } from '../section-content-factory';
13
23
 
14
24
  export interface SectionBuilderPayload {
@@ -18,22 +28,38 @@ export interface SectionBuilderPayload {
18
28
  contentId?: string;
19
29
  /** Target page ID — used for create operations to place the new section on the correct page. */
20
30
  pageId?: string;
31
+ /** Insert/move before this existing content ID (create: position on insert; update: reposition). */
32
+ moveBeforeContentId?: string;
21
33
  }
22
34
 
23
35
  /**
24
36
  * Abstract base for per-section builders.
25
37
  *
26
38
  * Concrete builders implement `buildAsync` directly, using
27
- * `resolveContent()` to obtain the content object to mutate.
39
+ * `resolveAndRepositionContent()` to obtain the content object to mutate.
28
40
  */
29
41
  export abstract class BaseSectionBuilder<
30
42
  C extends Content = Content,
31
43
  > extends BaseMetadataBuilder<SectionBuilderPayload> {
44
+ /**
45
+ * Content ID resolved during `resolveAndRepositionContent` (CREATE: the
46
+ * id of the freshly-created content; UPDATE: the id of the located target).
47
+ * `MetadataExecutor` reads this via `getResolvedContentId()` to surface it
48
+ * on the returned BuilderResult, so callers can anchor follow-up operations
49
+ * (notably the AI retry vacant-slot tracker) to the section we just touched.
50
+ */
51
+ protected resolvedContentId?: string;
52
+
32
53
  constructor(
33
54
  request: MetadataBuilderRequest<SectionBuilderPayload>,
34
55
  logger?: Logger,
56
+ eventTracker?: EventTracker,
35
57
  ) {
36
- super(request, logger);
58
+ super(request, logger, eventTracker);
59
+ }
60
+
61
+ public getResolvedContentId(): string | undefined {
62
+ return this.resolvedContentId;
37
63
  }
38
64
 
39
65
  protected get sectionType(): SectionType {
@@ -48,9 +74,44 @@ export abstract class BaseSectionBuilder<
48
74
  return this.request.payload!.arguments;
49
75
  }
50
76
 
51
- /** Override in subclasses for per-section validation. */
77
+ /**
78
+ * Returns the explicit validate function for this section's AI arguments.
79
+ * Override in concrete builders to return the colocated validate function.
80
+ * Return undefined (default) to skip validation — used by structural
81
+ * builders (delete, move) that have no argument constraints.
82
+ */
83
+ protected get sectionValidate():
84
+ | ((args: Record<string, unknown>, ctx: ValidationContext) => string[])
85
+ | undefined {
86
+ return undefined;
87
+ }
88
+
89
+ /**
90
+ * Returns the model's global text style options. Used by `applyStyleFields`
91
+ * to resolve an existing style's `textStyleType` preset into concrete
92
+ * values before clearing the preset reference when applying an AI override.
93
+ */
94
+ protected getGlobalTextStyles(
95
+ model: BrandPageModel,
96
+ ): TextStyleOptions | undefined {
97
+ return model.styles?.textStyles?.textStyleOptions;
98
+ }
99
+
100
+ /**
101
+ * Returns validation errors for the section's AI arguments.
102
+ * Override in subclasses to add section-specific checks — call super.validateSection()
103
+ * to inherit the base rule enforcement.
104
+ */
52
105
  protected validateSection(): string[] {
53
- return [];
106
+ const validate = this.sectionValidate;
107
+
108
+ if (!validate) return [];
109
+
110
+ // TODO(KP): Pass brandPageType from the request when available, to enforce item caps correctly.
111
+ return validate(this.args as Record<string, unknown>, {
112
+ brandPageType: BRAND_PAGE_TYPES.brandSite,
113
+ mode: this.mode,
114
+ });
54
115
  }
55
116
 
56
117
  async validateAsync(): Promise<{ errors: string[] }> {
@@ -69,7 +130,16 @@ export abstract class BaseSectionBuilder<
69
130
  }
70
131
  }
71
132
 
72
- errors.push(...this.validateSection());
133
+ try {
134
+ errors.push(...this.validateSection());
135
+ } catch (error) {
136
+ // Validation is a background concern — never let a validator bug break the build.
137
+ this.log({
138
+ message:
139
+ 'validateSection failed unexpectedly — skipping arg validation',
140
+ error,
141
+ });
142
+ }
73
143
 
74
144
  return { errors };
75
145
  }
@@ -78,14 +148,32 @@ export abstract class BaseSectionBuilder<
78
148
  * Validates the request, then creates or finds the target content.
79
149
  * Returns `{ content }` on success, or `{ error }` with a BuilderResult on failure.
80
150
  */
81
- protected resolveContent(
151
+ protected resolveAndRepositionContent(
82
152
  model: BrandPageModel,
83
153
  ): { content: C } | { error: BuilderResult } {
84
154
  if (this.mode === 'create') {
85
- return this.createContent(model);
155
+ const created = this.createContent(model);
156
+
157
+ if ('content' in created) {
158
+ this.resolvedContentId = created.content.id;
159
+ }
160
+
161
+ return created;
162
+ }
163
+
164
+ const result = this.findContent(model);
165
+
166
+ if ('error' in result) return result;
167
+
168
+ this.resolvedContentId = result.content.id;
169
+
170
+ const { moveBeforeContentId } = this.request.payload!;
171
+
172
+ if (moveBeforeContentId) {
173
+ this.moveContent(model, result.content, moveBeforeContentId);
86
174
  }
87
175
 
88
- return this.findContent(model);
176
+ return result;
89
177
  }
90
178
 
91
179
  private createContent(
@@ -94,7 +182,10 @@ export abstract class BaseSectionBuilder<
94
182
  const payload = this.request.payload!;
95
183
  const { pageId } = payload;
96
184
 
97
- const content = createDefaultSectionContent(this.sectionType);
185
+ const content = createDefaultSectionContent(
186
+ this.sectionType,
187
+ model.brandPageType,
188
+ );
98
189
 
99
190
  if (!content) {
100
191
  return {
@@ -126,7 +217,28 @@ export abstract class BaseSectionBuilder<
126
217
  };
127
218
  }
128
219
 
129
- targetPage.contents.push(content);
220
+ const { moveBeforeContentId } = payload;
221
+
222
+ if (moveBeforeContentId) {
223
+ const anchorIndex = targetPage.contents.findIndex(
224
+ (c) => c.id === moveBeforeContentId,
225
+ );
226
+
227
+ if (anchorIndex !== -1) {
228
+ targetPage.contents.splice(anchorIndex, 0, content);
229
+ } else {
230
+ targetPage.contents.push(content);
231
+ }
232
+ } else {
233
+ targetPage.contents.push(content);
234
+ }
235
+
236
+ this.eventTracker?.sendAddContentEvent(
237
+ this.sectionType,
238
+ undefined,
239
+ undefined,
240
+ TRIGGER_TYPE.AI_BUILDER,
241
+ );
130
242
 
131
243
  this.log({
132
244
  message: `Created ${this.sectionType} section on page ${targetPage.id}`,
@@ -136,6 +248,32 @@ export abstract class BaseSectionBuilder<
136
248
  return { content: content as C };
137
249
  }
138
250
 
251
+ private moveContent(
252
+ model: BrandPageModel,
253
+ content: C,
254
+ beforeContentId: string,
255
+ ): void {
256
+ for (const page of model.pages) {
257
+ const currentIndex = page.contents.findIndex((c) => c.id === content.id);
258
+
259
+ if (currentIndex === -1) continue;
260
+
261
+ page.contents.splice(currentIndex, 1);
262
+
263
+ const anchorIndex = page.contents.findIndex(
264
+ (c) => c.id === beforeContentId,
265
+ );
266
+
267
+ if (anchorIndex !== -1) {
268
+ page.contents.splice(anchorIndex, 0, content);
269
+ } else {
270
+ page.contents.push(content);
271
+ }
272
+
273
+ return;
274
+ }
275
+ }
276
+
139
277
  private findContent(
140
278
  model: BrandPageModel,
141
279
  ): { content: C } | { error: BuilderResult } {
@@ -0,0 +1,87 @@
1
+ import type {
2
+ BookingSectionContent,
3
+ BrandPageModel,
4
+ TextStyleDeclaration,
5
+ } from '../../../brand-page/models';
6
+ import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
7
+ import type { BuilderResult } from '../../models';
8
+ import {
9
+ isTiptapDocument,
10
+ type BookingSectionArguments,
11
+ } from '../../parsers/section-tool-arguments';
12
+ import {
13
+ applyButtonLink,
14
+ applyScalarFields,
15
+ applyStyleFields,
16
+ resolveGlobalPresetIntoStyle,
17
+ } from '../section-field-utils';
18
+ import { BaseSectionBuilder } from './base-section-builder';
19
+ import { validateBookingSection } from '../section-rules/booking-section.rules';
20
+
21
+ export class BookingSectionBuilder extends BaseSectionBuilder<BookingSectionContent> {
22
+ protected get sectionValidate() {
23
+ return validateBookingSection;
24
+ }
25
+
26
+ async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
27
+ this.log('Build called');
28
+
29
+ const validation = await this.validateAsync();
30
+
31
+ if (validation.errors.length) {
32
+ return { request: this.request, model, errors: validation.errors };
33
+ }
34
+
35
+ const resolved = this.resolveAndRepositionContent(model);
36
+
37
+ if ('error' in resolved) return resolved.error;
38
+
39
+ const bookingArgs = this.args as BookingSectionArguments;
40
+
41
+ applyScalarFields(resolved.content, this.args, this.sectionType);
42
+ applyButtonLink(resolved.content, bookingArgs);
43
+ applyStyleFields(
44
+ resolved.content,
45
+ this.args,
46
+ this.sectionType,
47
+ this.getGlobalTextStyles(model),
48
+ );
49
+
50
+ const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
51
+
52
+ if (bookingArgs.title !== undefined) {
53
+ if (isTiptapDocument(bookingArgs.title)) {
54
+ resolved.content.title = tiptapJsonToHtml(bookingArgs.title);
55
+ resolved.content.titleStyle = resolveGlobalPresetIntoStyle(
56
+ resolved.content.titleStyle,
57
+ textStyleOptions,
58
+ ) as TextStyleDeclaration;
59
+ } else {
60
+ resolved.content.title = bookingArgs.title;
61
+ }
62
+ }
63
+
64
+ if (bookingArgs.description !== undefined) {
65
+ if (isTiptapDocument(bookingArgs.description)) {
66
+ resolved.content.description = tiptapJsonToHtml(
67
+ bookingArgs.description,
68
+ );
69
+ resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(
70
+ resolved.content.descriptionStyle,
71
+ textStyleOptions,
72
+ ) as TextStyleDeclaration;
73
+ } else {
74
+ resolved.content.description = bookingArgs.description;
75
+ }
76
+ }
77
+
78
+ if (bookingArgs.background_color !== undefined) {
79
+ resolved.content.backgroundStyle = {
80
+ ...resolved.content.backgroundStyle,
81
+ backgroundColor: bookingArgs.background_color ?? '',
82
+ };
83
+ }
84
+
85
+ return { request: this.request, model };
86
+ }
87
+ }
@@ -2,8 +2,13 @@ import type { ButtonContent, BrandPageModel } from '../../../brand-page/models';
2
2
  import type { BuilderResult } from '../../models';
3
3
  import { applyScalarFields } from '../section-field-utils';
4
4
  import { BaseSectionBuilder } from './base-section-builder';
5
+ import { validateButtonSection } from '../section-rules/button-section.rules';
5
6
 
6
7
  export class ButtonSectionBuilder extends BaseSectionBuilder<ButtonContent> {
8
+ protected get sectionValidate() {
9
+ return validateButtonSection;
10
+ }
11
+
7
12
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
8
13
  this.log('Build called');
9
14
 
@@ -13,7 +18,7 @@ export class ButtonSectionBuilder extends BaseSectionBuilder<ButtonContent> {
13
18
  return { request: this.request, model, errors: validation.errors };
14
19
  }
15
20
 
16
- const resolved = this.resolveContent(model);
21
+ const resolved = this.resolveAndRepositionContent(model);
17
22
 
18
23
  if ('error' in resolved) return resolved.error;
19
24
 
@@ -1,13 +1,27 @@
1
1
  import type {
2
2
  ContactFormContent,
3
3
  BrandPageModel,
4
+ TextStyleDeclaration,
4
5
  } from '../../../brand-page/models';
5
- import type { ContactFormSectionArguments } from '../../parsers/section-tool-arguments';
6
+ import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
7
+ import {
8
+ isTiptapDocument,
9
+ type ContactFormSectionArguments,
10
+ } from '../../parsers/section-tool-arguments';
6
11
  import type { BuilderResult } from '../../models';
7
- import { applyScalarFields, applyStyleFields } from '../section-field-utils';
12
+ import {
13
+ applyScalarFields,
14
+ applyStyleFields,
15
+ resolveGlobalPresetIntoStyle,
16
+ } from '../section-field-utils';
8
17
  import { BaseSectionBuilder } from './base-section-builder';
18
+ import { validateContactForm } from '../section-rules/contact-form.rules';
9
19
 
10
20
  export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
21
+ protected get sectionValidate() {
22
+ return validateContactForm;
23
+ }
24
+
11
25
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
12
26
  this.log('Build called');
13
27
 
@@ -17,16 +31,58 @@ export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
17
31
  return { request: this.request, model, errors: validation.errors };
18
32
  }
19
33
 
20
- const resolved = this.resolveContent(model);
34
+ const resolved = this.resolveAndRepositionContent(model);
21
35
 
22
36
  if ('error' in resolved) return resolved.error;
23
37
 
24
38
  const content = resolved.content;
25
39
 
26
40
  applyScalarFields(content, this.args, this.sectionType);
27
- applyStyleFields(content, this.args, this.sectionType);
41
+ applyStyleFields(
42
+ content,
43
+ this.args,
44
+ this.sectionType,
45
+ this.getGlobalTextStyles(model),
46
+ );
28
47
 
29
48
  const args = this.args as ContactFormSectionArguments;
49
+ const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
50
+
51
+ if (args.title !== undefined) {
52
+ if (isTiptapDocument(args.title)) {
53
+ content.title = tiptapJsonToHtml(args.title);
54
+ content.titleStyle = resolveGlobalPresetIntoStyle(
55
+ content.titleStyle,
56
+ textStyleOptions,
57
+ ) as TextStyleDeclaration;
58
+ } else {
59
+ content.title = args.title;
60
+ }
61
+ }
62
+
63
+ if (args.description !== undefined) {
64
+ if (isTiptapDocument(args.description)) {
65
+ content.description = tiptapJsonToHtml(args.description);
66
+ content.descriptionStyle = resolveGlobalPresetIntoStyle(
67
+ content.descriptionStyle,
68
+ textStyleOptions,
69
+ ) as TextStyleDeclaration;
70
+ } else {
71
+ content.description = args.description;
72
+ }
73
+ }
74
+
75
+ if (args.success_message !== undefined) {
76
+ if (isTiptapDocument(args.success_message)) {
77
+ content.successMessage = tiptapJsonToHtml(args.success_message);
78
+ content.successMessageStyle = resolveGlobalPresetIntoStyle(
79
+ content.successMessageStyle,
80
+ textStyleOptions,
81
+ ) as TextStyleDeclaration;
82
+ } else {
83
+ content.successMessage = args.success_message;
84
+ }
85
+ }
30
86
 
31
87
  if (args.fields && Array.isArray(args.fields) && content.fields) {
32
88
  for (const toggle of args.fields) {
@@ -45,6 +101,20 @@ export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
45
101
  };
46
102
  }
47
103
 
104
+ if (args.card_style && typeof args.card_style === 'object') {
105
+ const existing = content.cardStyle || {};
106
+
107
+ content.cardStyle = {
108
+ ...existing,
109
+ ...Object.fromEntries(
110
+ Object.entries(args.card_style).map(([k, v]) => [
111
+ k,
112
+ v === null ? '' : v,
113
+ ]),
114
+ ),
115
+ };
116
+ }
117
+
48
118
  return { request: this.request, model };
49
119
  }
50
120
  }
@@ -1,4 +1,8 @@
1
1
  import type { BrandPageModel } from '../../../brand-page/models';
2
+ import {
3
+ type EventTracker,
4
+ TRIGGER_TYPE,
5
+ } from '../../../brand-page-maker/composables/useEventTracker';
2
6
  import {
3
7
  BaseMetadataBuilder,
4
8
  type BuilderResult,
@@ -14,8 +18,9 @@ export class DeleteSectionBuilder extends BaseMetadataBuilder<DeleteSectionPaylo
14
18
  constructor(
15
19
  request: MetadataBuilderRequest<DeleteSectionPayload>,
16
20
  logger?: Logger,
21
+ eventTracker?: EventTracker,
17
22
  ) {
18
- super(request, logger);
23
+ super(request, logger, eventTracker);
19
24
  }
20
25
 
21
26
  async validateAsync(): Promise<{ errors: string[] }> {
@@ -44,8 +49,17 @@ export class DeleteSectionBuilder extends BaseMetadataBuilder<DeleteSectionPaylo
44
49
  const index = page.contents.findIndex((c) => c.id === contentId);
45
50
 
46
51
  if (index !== -1) {
52
+ const deletedContentType = page.contents[index].type;
53
+
47
54
  page.contents.splice(index, 1);
48
55
 
56
+ this.eventTracker?.sendRemoveContentEvent(
57
+ deletedContentType,
58
+ undefined,
59
+ undefined,
60
+ TRIGGER_TYPE.AI_BUILDER,
61
+ );
62
+
49
63
  this.log({
50
64
  message: `Deleted section ${contentId} from page ${page.id}`,
51
65
  });
@@ -6,8 +6,13 @@ import type { BuilderResult } from '../../models';
6
6
  import type { DividerSectionArguments } from '../../parsers/section-tool-arguments';
7
7
  import { applyScalarFields } from '../section-field-utils';
8
8
  import { BaseSectionBuilder } from './base-section-builder';
9
+ import { validateDividerSection } from '../section-rules/divider-section.rules';
9
10
 
10
11
  export class DividerSectionBuilder extends BaseSectionBuilder<DividerSectionContent> {
12
+ protected get sectionValidate() {
13
+ return validateDividerSection;
14
+ }
15
+
11
16
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
12
17
  this.log('Build called');
13
18
 
@@ -17,7 +22,7 @@ export class DividerSectionBuilder extends BaseSectionBuilder<DividerSectionCont
17
22
  return { request: this.request, model, errors: validation.errors };
18
23
  }
19
24
 
20
- const resolved = this.resolveContent(model);
25
+ const resolved = this.resolveAndRepositionContent(model);
21
26
 
22
27
  if ('error' in resolved) return resolved.error;
23
28
 
@@ -32,6 +37,13 @@ export class DividerSectionBuilder extends BaseSectionBuilder<DividerSectionCont
32
37
  };
33
38
  }
34
39
 
40
+ if (dividerArgs.divider_color !== undefined) {
41
+ resolved.content.dividerColor = {
42
+ ...resolved.content.dividerColor,
43
+ backgroundColor: dividerArgs.divider_color ?? '',
44
+ };
45
+ }
46
+
35
47
  return { request: this.request, model };
36
48
  }
37
49
  }
@@ -7,8 +7,9 @@ import type {
7
7
  ImageGallerySectionArguments,
8
8
  } from '../../parsers/section-tool-arguments';
9
9
  import type { BuilderResult } from '../../models';
10
- import { applyScalarFields } from '../section-field-utils';
10
+ import { applyScalarFields, isValidUrl } from '../section-field-utils';
11
11
  import { BaseSectionBuilder } from './base-section-builder';
12
+ import { validateImageGallery } from '../section-rules/image-gallery.rules';
12
13
 
13
14
  const applyGalleryType = (
14
15
  content: ImageGalleryContent,
@@ -24,16 +25,14 @@ const applyGalleryImages = (
24
25
  content: ImageGalleryContent,
25
26
  images: ImageGalleryItem[],
26
27
  ): void => {
27
- content.images = images
28
- .filter((img) => !!img.image_url)
29
- .map((img) => ({
30
- imageUrl: img.image_url || '',
31
- imageTitle: img.caption || '',
32
- width: 0,
33
- height: 0,
34
- mediaType: 'image' as const,
35
- imageLink: '',
36
- }));
28
+ content.images = images.map((img) => ({
29
+ imageUrl: isValidUrl(img.image_url) ? img.image_url! : '',
30
+ imageTitle: img.caption || '',
31
+ width: 0,
32
+ height: 0,
33
+ mediaType: 'image' as const,
34
+ imageLink: '',
35
+ }));
37
36
  };
38
37
 
39
38
  const mergeGalleryImages = (
@@ -41,25 +40,31 @@ const mergeGalleryImages = (
41
40
  images: ImageGalleryItem[],
42
41
  replaceAll: boolean,
43
42
  ): void => {
44
- const updatedImages = images
45
- .map((img, index) => {
46
- const existing = content.images?.[index];
47
- const imageUrl = img.image_url ?? existing?.imageUrl ?? '';
48
-
49
- return {
50
- ...(existing || {}),
51
- imageUrl,
52
- imageTitle: img.caption ?? existing?.imageTitle ?? '',
53
- width: existing?.width ?? 0,
54
- height: existing?.height ?? 0,
55
- mediaType: existing?.mediaType ?? 'image',
56
- imageLink: existing?.imageLink ?? '',
57
- };
58
- })
59
- .filter((item) => !!item.imageUrl);
60
-
61
- if (!replaceAll && content.images && content.images.length > images.length) {
62
- const extras = content.images.slice(images.length).map((img) => ({
43
+ const itemsToMerge = images.filter((img) => img.insert_at === undefined);
44
+
45
+ const updatedImages = itemsToMerge.map((img, index) => {
46
+ const existing = content.images?.[index];
47
+ const imageUrl = isValidUrl(img.image_url)
48
+ ? img.image_url!
49
+ : existing?.imageUrl ?? '';
50
+
51
+ return {
52
+ ...(existing || {}),
53
+ imageUrl,
54
+ imageTitle: img.caption ?? existing?.imageTitle ?? '',
55
+ width: existing?.width ?? 0,
56
+ height: existing?.height ?? 0,
57
+ mediaType: existing?.mediaType ?? 'image',
58
+ imageLink: existing?.imageLink ?? '',
59
+ };
60
+ });
61
+
62
+ if (
63
+ !replaceAll &&
64
+ content.images &&
65
+ content.images.length > itemsToMerge.length
66
+ ) {
67
+ const extras = content.images.slice(itemsToMerge.length).map((img) => ({
63
68
  imageUrl: img.imageUrl ?? '',
64
69
  imageTitle: img.imageTitle ?? '',
65
70
  width: img.width ?? 0,
@@ -74,7 +79,48 @@ const mergeGalleryImages = (
74
79
  content.images = updatedImages;
75
80
  };
76
81
 
82
+ const insertGalleryImages = (
83
+ content: ImageGalleryContent,
84
+ images: ImageGalleryItem[],
85
+ ): void => {
86
+ const inserts = images.filter((img) => img.insert_at !== undefined);
87
+
88
+ if (!inserts.length) return;
89
+
90
+ const sorted = [...inserts].sort(
91
+ (a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0),
92
+ );
93
+
94
+ for (const img of sorted) {
95
+ if (!isValidUrl(img.image_url)) continue;
96
+
97
+ if (content.images?.some((existing) => existing.imageUrl === img.image_url))
98
+ continue;
99
+
100
+ content.images = content.images ?? [];
101
+
102
+ const pos = Math.max(
103
+ 0,
104
+ Math.min(img.insert_at ?? 0, content.images.length),
105
+ );
106
+
107
+ content.images.splice(pos, 0, {
108
+ imageUrl: img.image_url!,
109
+ imageTitle: img.caption ?? '',
110
+ width: 0,
111
+ height: 0,
112
+ mediaType: 'image',
113
+ imageLink: '',
114
+ colorReplacements: [],
115
+ });
116
+ }
117
+ };
118
+
77
119
  export class ImageGalleryBuilder extends BaseSectionBuilder<ImageGalleryContent> {
120
+ protected get sectionValidate() {
121
+ return validateImageGallery;
122
+ }
123
+
78
124
  async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
79
125
  this.log('Build called');
80
126
 
@@ -84,7 +130,7 @@ export class ImageGalleryBuilder extends BaseSectionBuilder<ImageGalleryContent>
84
130
  return { request: this.request, model, errors: validation.errors };
85
131
  }
86
132
 
87
- const resolved = this.resolveContent(model);
133
+ const resolved = this.resolveAndRepositionContent(model);
88
134
 
89
135
  if ('error' in resolved) return resolved.error;
90
136
 
@@ -106,6 +152,20 @@ export class ImageGalleryBuilder extends BaseSectionBuilder<ImageGalleryContent>
106
152
  }
107
153
  }
108
154
 
155
+ if (args._remove_item_indices?.length && content.images) {
156
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
157
+
158
+ for (const idx of sorted) {
159
+ if (idx >= 0 && idx < content.images.length) {
160
+ content.images.splice(idx, 1);
161
+ }
162
+ }
163
+ }
164
+
165
+ if (args.images && Array.isArray(args.images) && this.mode === 'update') {
166
+ insertGalleryImages(content, args.images);
167
+ }
168
+
109
169
  return { request: this.request, model };
110
170
  }
111
171
  }